pixel-view.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                      PPPP   IIIII  X   X  EEEEE  L                          %
00007 %                      P   P    I     X X   E      L                          %
00008 %                      PPPP     I      X    EEE    L                          %
00009 %                      P        I     X X   E      L                          %
00010 %                      P      IIIII  X   X  EEEEE  LLLLL                      %
00011 %                                                                             %
00012 %                        V   V  IIIII  EEEEE  W   W                           %
00013 %                        V   V    I    E      W   W                           %
00014 %                        V   V    I    EEE    W W W                           %
00015 %                         V V     I    E      WW WW                           %
00016 %                          V    IIIII  EEEEE  W   W                           %
00017 %                                                                             %
00018 %                                                                             %
00019 %                       MagickWand Pixel View Methods                         %
00020 %                                                                             %
00021 %                              Software Design                                %
00022 %                                John Cristy                                  %
00023 %                                March 2003                                   %
00024 %                                                                             %
00025 %                                                                             %
00026 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
00027 %  dedicated to making software imaging solutions freely available.           %
00028 %                                                                             %
00029 %  You may not use this file except in compliance with the License.  You may  %
00030 %  obtain a copy of the License at                                            %
00031 %                                                                             %
00032 %    http://www.imagemagick.org/script/license.php                            %
00033 %                                                                             %
00034 %  Unless required by applicable law or agreed to in writing, software        %
00035 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00036 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00037 %  See the License for the specific language governing permissions and        %
00038 %  limitations under the License.                                             %
00039 %                                                                             %
00040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00041 %
00042 %
00043 %
00044 */
00045 
00046 /*
00047   Include declarations.
00048 */
00049 #include "wand/studio.h"
00050 #include "wand/MagickWand.h"
00051 #include "wand/magick-wand-private.h"
00052 #include "wand/wand.h"
00053 #include "magick/monitor-private.h"
00054 #include "magick/thread-private.h"
00055 /*
00056  Define declarations.
00057 */
00058 #define PixelViewId  "PixelView"
00059 
00060 /*
00061   Typedef declarations.
00062 */
00063 struct _PixelView
00064 {
00065   unsigned long
00066     id;
00067 
00068   char
00069     name[MaxTextExtent];
00070 
00071   ExceptionInfo
00072     *exception;
00073 
00074   MagickWand
00075     *wand;
00076 
00077   CacheView
00078     *view;
00079 
00080   RectangleInfo
00081     region;
00082 
00083   unsigned long
00084     number_threads;
00085 
00086   PixelWand
00087     ***pixel_wands;
00088 
00089   MagickBooleanType
00090     debug;
00091 
00092   unsigned long
00093     signature;
00094 };
00095 
00096 /*
00097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00098 %                                                                             %
00099 %                                                                             %
00100 %                                                                             %
00101 %   C l o n e P i x e l V i e w                                               %
00102 %                                                                             %
00103 %                                                                             %
00104 %                                                                             %
00105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00106 %
00107 %  ClonePixelView() makes a copy of the specified pixel view.
00108 %
00109 %  The format of the ClonePixelView method is:
00110 %
00111 %      PixelView *ClonePixelView(const PixelView *pixel_view)
00112 %
00113 %  A description of each parameter follows:
00114 %
00115 %    o pixel_view: the pixel view.
00116 %
00117 */
00118 WandExport PixelView *ClonePixelView(const PixelView *pixel_view)
00119 {
00120   PixelView
00121     *clone_view;
00122 
00123   register long
00124     i;
00125 
00126   assert(pixel_view != (PixelView *) NULL);
00127   assert(pixel_view->signature == WandSignature);
00128   if (pixel_view->debug != MagickFalse)
00129     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",pixel_view->name);
00130   clone_view=(PixelView *) AcquireMagickMemory(sizeof(*clone_view));
00131   if (clone_view == (PixelView *) NULL)
00132     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
00133       pixel_view->name);
00134   (void) ResetMagickMemory(clone_view,0,sizeof(*clone_view));
00135   clone_view->id=AcquireWandId();
00136   (void) FormatMagickString(clone_view->name,MaxTextExtent,"%s-%lu",PixelViewId,
00137     clone_view->id);
00138   clone_view->exception=AcquireExceptionInfo();
00139   InheritException(clone_view->exception,pixel_view->exception);
00140   clone_view->view=CloneCacheView(pixel_view->view);
00141   clone_view->region=pixel_view->region;
00142   clone_view->number_threads=pixel_view->number_threads;
00143   for (i=0; i < (long) pixel_view->number_threads; i++)
00144     clone_view->pixel_wands[i]=ClonePixelWands((const PixelWand **)
00145       pixel_view->pixel_wands[i],pixel_view->region.width);
00146   clone_view->debug=pixel_view->debug;
00147   if (clone_view->debug != MagickFalse)
00148     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_view->name);
00149   clone_view->signature=WandSignature;
00150   return(clone_view);
00151 }
00152 
00153 /*
00154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00155 %                                                                             %
00156 %                                                                             %
00157 %                                                                             %
00158 %   D e s t r o y P i x e l V i e w                                           %
00159 %                                                                             %
00160 %                                                                             %
00161 %                                                                             %
00162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00163 %
00164 %  DestroyPixelView() deallocates memory associated with a pixel view.
00165 %
00166 %  The format of the DestroyPixelView method is:
00167 %
00168 %      PixelView *DestroyPixelView(PixelView *pixel_view,
00169 %        const unsigned long number_wands,const unsigned long number_threads)
00170 %
00171 %  A description of each parameter follows:
00172 %
00173 %    o pixel_view: the pixel view.
00174 %
00175 %    o number_wand: the number of pixel wands.
00176 %
00177 %    o number_threads: number of threads.
00178 %
00179 */
00180 
00181 static PixelWand ***DestroyPixelsThreadSet(PixelWand ***pixel_wands,
00182   const unsigned long number_wands,const unsigned long number_threads)
00183 {
00184   register long
00185     i;
00186 
00187   assert(pixel_wands != (PixelWand ***) NULL);
00188   for (i=0; i < (long) number_threads; i++)
00189     if (pixel_wands[i] != (PixelWand **) NULL)
00190       pixel_wands[i]=DestroyPixelWands(pixel_wands[i],number_wands);
00191   pixel_wands=(PixelWand ***) RelinquishAlignedMemory(pixel_wands);
00192   return(pixel_wands);
00193 }
00194 
00195 WandExport PixelView *DestroyPixelView(PixelView *pixel_view)
00196 {
00197   assert(pixel_view != (PixelView *) NULL);
00198   assert(pixel_view->signature == WandSignature);
00199   pixel_view->pixel_wands=DestroyPixelsThreadSet(pixel_view->pixel_wands,
00200     pixel_view->region.width,pixel_view->number_threads);
00201   pixel_view->view=DestroyCacheView(pixel_view->view);
00202   pixel_view->exception=DestroyExceptionInfo(pixel_view->exception);
00203   pixel_view->signature=(~WandSignature);
00204   RelinquishWandId(pixel_view->id);
00205   pixel_view=(PixelView *) RelinquishMagickMemory(pixel_view);
00206   return(pixel_view);
00207 }
00208 
00209 /*
00210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00211 %                                                                             %
00212 %                                                                             %
00213 %                                                                             %
00214 %   D u p l e x T r a n s f e r P i x e l V i e w I t e r a t o r             %
00215 %                                                                             %
00216 %                                                                             %
00217 %                                                                             %
00218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00219 %
00220 %  DuplexTransferPixelViewIterator() iterates over three pixel views in
00221 %  parallel and calls your transfer method for each scanline of the view.  The
00222 %  source and duplex pixel region is not confined to the image canvas-- that is
00223 %  you can include negative offsets or widths or heights that exceed the image
00224 %  dimension.  However, the destination pixel view is confined to the image
00225 %  canvas-- that is no negative offsets or widths or heights that exceed the
00226 %  image dimension are permitted.
00227 %
00228 %  Use this pragma:
00229 %
00230 %    #pragma omp critical
00231 %
00232 %  to define a section of code in your callback transfer method that must be
00233 %  executed by a single thread at a time.
00234 %
00235 %  The format of the DuplexTransferPixelViewIterator method is:
00236 %
00237 %      MagickBooleanType DuplexTransferPixelViewIterator(PixelView *source,
00238 %        PixelView *duplex,PixelView *destination,
00239 %        DuplexTransferPixelViewMethod transfer,void *context)
00240 %
00241 %  A description of each parameter follows:
00242 %
00243 %    o source: the source pixel view.
00244 %
00245 %    o duplex: the duplex pixel view.
00246 %
00247 %    o destination: the destination pixel view.
00248 %
00249 %    o transfer: the transfer callback method.
00250 %
00251 %    o context: the user defined context.
00252 %
00253 */
00254 WandExport MagickBooleanType DuplexTransferPixelViewIterator(
00255   PixelView *source,PixelView *duplex,PixelView *destination,
00256   DuplexTransferPixelViewMethod transfer,void *context)
00257 {
00258 #define DuplexTransferPixelViewTag  "PixelView/DuplexTransfer"
00259 
00260   ExceptionInfo
00261     *exception;
00262 
00263   Image
00264     *destination_image,
00265     *duplex_image,
00266     *source_image;
00267 
00268   long
00269     progress,
00270     y;
00271 
00272   MagickBooleanType
00273     status;
00274 
00275   assert(source != (PixelView *) NULL);
00276   assert(source->signature == WandSignature);
00277   if (transfer == (DuplexTransferPixelViewMethod) NULL)
00278     return(MagickFalse);
00279   source_image=source->wand->images;
00280   duplex_image=duplex->wand->images;
00281   destination_image=destination->wand->images;
00282   if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
00283     return(MagickFalse);
00284   status=MagickTrue;
00285   progress=0;
00286   exception=destination->exception;
00287 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00288   #pragma omp parallel for schedule(static,1) shared(progress,status)
00289 #endif
00290   for (y=source->region.y; y < (long) source->region.height; y++)
00291   {
00292     MagickBooleanType
00293       sync;
00294 
00295     register const IndexPacket
00296       *__restrict duplex_indexes,
00297       *__restrict indexes;
00298 
00299     register const PixelPacket
00300       *__restrict duplex_pixels,
00301       *__restrict pixels;
00302 
00303     register IndexPacket
00304       *__restrict destination_indexes;
00305 
00306     register long
00307       id,
00308       x;
00309 
00310     register PixelPacket
00311       *__restrict destination_pixels;
00312 
00313     if (status == MagickFalse)
00314       continue;
00315     id=GetOpenMPThreadId();
00316     pixels=GetCacheViewVirtualPixels(source->view,source->region.x,y,
00317       source->region.width,1,source->exception);
00318     if (pixels == (const PixelPacket *) NULL)
00319       {
00320         status=MagickFalse;
00321         continue;
00322       }
00323     indexes=GetCacheViewVirtualIndexQueue(source->view);
00324     for (x=0; x < (long) source->region.width; x++)
00325       PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
00326     if (source_image->colorspace == CMYKColorspace)
00327       for (x=0; x < (long) source->region.width; x++)
00328         PixelSetBlackQuantum(source->pixel_wands[id][x],indexes[x]);
00329     if (source_image->storage_class == PseudoClass)
00330       for (x=0; x < (long) source->region.width; x++)
00331         PixelSetIndex(source->pixel_wands[id][x],indexes[x]);
00332     duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->region.x,y,
00333       duplex->region.width,1,duplex->exception);
00334     if (duplex_pixels == (const PixelPacket *) NULL)
00335       {
00336         status=MagickFalse;
00337         continue;
00338       }
00339     duplex_indexes=GetCacheViewVirtualIndexQueue(duplex->view);
00340     for (x=0; x < (long) duplex->region.width; x++)
00341       PixelSetQuantumColor(duplex->pixel_wands[id][x],duplex_pixels+x);
00342     if (duplex_image->colorspace == CMYKColorspace)
00343       for (x=0; x < (long) duplex->region.width; x++)
00344         PixelSetBlackQuantum(duplex->pixel_wands[id][x],duplex_indexes[x]);
00345     if (duplex_image->storage_class == PseudoClass)
00346       for (x=0; x < (long) duplex->region.width; x++)
00347         PixelSetIndex(duplex->pixel_wands[id][x],duplex_indexes[x]);
00348     destination_pixels=GetCacheViewAuthenticPixels(destination->view,
00349       destination->region.x,y,destination->region.width,1,exception);
00350     if (destination_pixels == (PixelPacket *) NULL)
00351       {
00352         status=MagickFalse;
00353         continue;
00354       }
00355     destination_indexes=GetCacheViewAuthenticIndexQueue(destination->view);
00356     for (x=0; x < (long) destination->region.width; x++)
00357       PixelSetQuantumColor(destination->pixel_wands[id][x],
00358         destination_pixels+x);
00359     if (destination_image->colorspace == CMYKColorspace)
00360       for (x=0; x < (long) destination->region.width; x++)
00361         PixelSetBlackQuantum(destination->pixel_wands[id][x],
00362           destination_indexes[x]);
00363     if (destination_image->storage_class == PseudoClass)
00364       for (x=0; x < (long) destination->region.width; x++)
00365         PixelSetIndex(destination->pixel_wands[id][x],destination_indexes[x]);
00366     if (transfer(source,duplex,destination,context) == MagickFalse)
00367       status=MagickFalse;
00368     for (x=0; x < (long) destination->region.width; x++)
00369       PixelGetQuantumColor(destination->pixel_wands[id][x],
00370         destination_pixels+x);
00371     if (destination_image->colorspace == CMYKColorspace)
00372       for (x=0; x < (long) destination->region.width; x++)
00373         destination_indexes[x]=PixelGetBlackQuantum(
00374           destination->pixel_wands[id][x]);
00375     sync=SyncCacheViewAuthenticPixels(destination->view,exception);
00376     if (sync == MagickFalse)
00377       {
00378         InheritException(destination->exception,GetCacheViewException(
00379           source->view));
00380         status=MagickFalse;
00381       }
00382     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
00383       {
00384         MagickBooleanType
00385           proceed;
00386 
00387 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00388   #pragma omp critical (MagickWand_DuplexTransferPixelViewIterator)
00389 #endif
00390         proceed=SetImageProgress(source_image,DuplexTransferPixelViewTag,
00391           progress++,source->region.height);
00392         if (proceed == MagickFalse)
00393           status=MagickFalse;
00394       }
00395   }
00396   return(status);
00397 }
00398 
00399 /*
00400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00401 %                                                                             %
00402 %                                                                             %
00403 %                                                                             %
00404 %   G e t P i x e l V i e w E x c e p t i o n                                 %
00405 %                                                                             %
00406 %                                                                             %
00407 %                                                                             %
00408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00409 %
00410 %  GetPixelViewException() returns the severity, reason, and description of any
00411 %  error that occurs when utilizing a pixel view.
00412 %
00413 %  The format of the GetPixelViewException method is:
00414 %
00415 %      char *GetPixelViewException(const PixelWand *pixel_view,
00416 %        ExceptionType *severity)
00417 %
00418 %  A description of each parameter follows:
00419 %
00420 %    o pixel_view: the pixel pixel_view.
00421 %
00422 %    o severity: the severity of the error is returned here.
00423 %
00424 */
00425 WandExport char *GetPixelViewException(const PixelView *pixel_view,
00426   ExceptionType *severity)
00427 {
00428   char
00429     *description;
00430 
00431   assert(pixel_view != (const PixelView *) NULL);
00432   assert(pixel_view->signature == WandSignature);
00433   if (pixel_view->debug != MagickFalse)
00434     (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",pixel_view->name);
00435   assert(severity != (ExceptionType *) NULL);
00436   *severity=pixel_view->exception->severity;
00437   description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
00438     sizeof(*description));
00439   if (description == (char *) NULL)
00440     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
00441       pixel_view->name);
00442   *description='\0';
00443   if (pixel_view->exception->reason != (char *) NULL)
00444     (void) CopyMagickString(description,GetLocaleExceptionMessage(
00445       pixel_view->exception->severity,pixel_view->exception->reason),
00446         MaxTextExtent);
00447   if (pixel_view->exception->description != (char *) NULL)
00448     {
00449       (void) ConcatenateMagickString(description," (",MaxTextExtent);
00450       (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
00451         pixel_view->exception->severity,pixel_view->exception->description),
00452         MaxTextExtent);
00453       (void) ConcatenateMagickString(description,")",MaxTextExtent);
00454     }
00455   return(description);
00456 }
00457 
00458 /*
00459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00460 %                                                                             %
00461 %                                                                             %
00462 %                                                                             %
00463 %   G e t P i x e l V i e w H e i g h t                                       %
00464 %                                                                             %
00465 %                                                                             %
00466 %                                                                             %
00467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00468 %
00469 %  GetPixelViewHeight() returns the pixel view height.
00470 %
00471 %  The format of the GetPixelViewHeight method is:
00472 %
00473 %      unsigned long GetPixelViewHeight(const PixelView *pixel_view)
00474 %
00475 %  A description of each parameter follows:
00476 %
00477 %    o pixel_view: the pixel view.
00478 %
00479 */
00480 WandExport unsigned long GetPixelViewHeight(const PixelView *pixel_view)
00481 {
00482   assert(pixel_view != (PixelView *) NULL);
00483   assert(pixel_view->signature == WandSignature);
00484   return(pixel_view->region.height);
00485 }
00486 
00487 /*
00488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00489 %                                                                             %
00490 %                                                                             %
00491 %                                                                             %
00492 %   G e t P i x e l V i e w I t e r a t o r                                   %
00493 %                                                                             %
00494 %                                                                             %
00495 %                                                                             %
00496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00497 %
00498 %  GetPixelViewIterator() iterates over the pixel view in parallel and calls
00499 %  your get method for each scanline of the view.  The pixel region is
00500 %  not confined to the image canvas-- that is you can include negative offsets
00501 %  or widths or heights that exceed the image dimension.  Any updates to
00502 %  the pixels in your callback are ignored.
00503 %
00504 %  Use this pragma:
00505 %
00506 %    #pragma omp critical
00507 %
00508 %  to define a section of code in your callback get method that must be
00509 %  executed by a single thread at a time.
00510 %
00511 %  The format of the GetPixelViewIterator method is:
00512 %
00513 %      MagickBooleanType GetPixelViewIterator(PixelView *source,
00514 %        GetPixelViewMethod get,void *context)
00515 %
00516 %  A description of each parameter follows:
00517 %
00518 %    o source: the source pixel view.
00519 %
00520 %    o get: the get callback method.
00521 %
00522 %    o context: the user defined context.
00523 %
00524 */
00525 WandExport MagickBooleanType GetPixelViewIterator(PixelView *source,
00526   GetPixelViewMethod get,void *context)
00527 {
00528 #define GetPixelViewTag  "PixelView/Get"
00529 
00530   Image
00531     *source_image;
00532 
00533   long
00534     progress,
00535     y;
00536 
00537   MagickBooleanType
00538     status;
00539 
00540   assert(source != (PixelView *) NULL);
00541   assert(source->signature == WandSignature);
00542   if (get == (GetPixelViewMethod) NULL)
00543     return(MagickFalse);
00544   source_image=source->wand->images;
00545   status=MagickTrue;
00546   progress=0;
00547 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00548   #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
00549 #endif
00550   for (y=source->region.y; y < (long) source->region.height; y++)
00551   {
00552     register const IndexPacket
00553       *indexes;
00554 
00555     register const PixelPacket
00556       *pixels;
00557 
00558     register long
00559       id,
00560       x;
00561 
00562     if (status == MagickFalse)
00563       continue;
00564     id=GetOpenMPThreadId();
00565     pixels=GetCacheViewVirtualPixels(source->view,source->region.x,y,
00566       source->region.width,1,source->exception);
00567     if (pixels == (const PixelPacket *) NULL)
00568       {
00569         status=MagickFalse;
00570         continue;
00571       }
00572     indexes=GetCacheViewVirtualIndexQueue(source->view);
00573     for (x=0; x < (long) source->region.width; x++)
00574       PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
00575     if (source_image->colorspace == CMYKColorspace)
00576       for (x=0; x < (long) source->region.width; x++)
00577         PixelSetBlackQuantum(source->pixel_wands[id][x],indexes[x]);
00578     if (source_image->storage_class == PseudoClass)
00579       for (x=0; x < (long) source->region.width; x++)
00580         PixelSetIndex(source->pixel_wands[id][x],indexes[x]);
00581     if (get(source,context) == MagickFalse)
00582       status=MagickFalse;
00583     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
00584       {
00585         MagickBooleanType
00586           proceed;
00587 
00588 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00589   #pragma omp critical (MagickWand_GetPixelViewIterator)
00590 #endif
00591         proceed=SetImageProgress(source_image,GetPixelViewTag,progress++,
00592           source->region.height);
00593         if (proceed == MagickFalse)
00594           status=MagickFalse;
00595       }
00596   }
00597   return(status);
00598 }
00599 
00600 /*
00601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00602 %                                                                             %
00603 %                                                                             %
00604 %                                                                             %
00605 %   G e t P i x e l V i e w P i x e l s                                       %
00606 %                                                                             %
00607 %                                                                             %
00608 %                                                                             %
00609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00610 %
00611 %  GetPixelViewPixels() returns the pixel view pixel_wands.
00612 %
00613 %  The format of the GetPixelViewPixels method is:
00614 %
00615 %      PixelWand *GetPixelViewPixels(const PixelView *pixel_view)
00616 %
00617 %  A description of each parameter follows:
00618 %
00619 %    o pixel_view: the pixel view.
00620 %
00621 */
00622 WandExport PixelWand **GetPixelViewPixels(const PixelView *pixel_view)
00623 {
00624   long
00625     id;
00626 
00627   assert(pixel_view != (PixelView *) NULL);
00628   assert(pixel_view->signature == WandSignature);
00629   id=GetOpenMPThreadId();
00630   return(pixel_view->pixel_wands[id]);
00631 }
00632 
00633 /*
00634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00635 %                                                                             %
00636 %                                                                             %
00637 %                                                                             %
00638 %   G e t P i x e l V i e w W a n d                                           %
00639 %                                                                             %
00640 %                                                                             %
00641 %                                                                             %
00642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00643 %
00644 %  GetPixelViewWand() returns the magick wand associated with the pixel view.
00645 %
00646 %  The format of the GetPixelViewWand method is:
00647 %
00648 %      MagickWand *GetPixelViewWand(const PixelView *pixel_view)
00649 %
00650 %  A description of each parameter follows:
00651 %
00652 %    o pixel_view: the pixel view.
00653 %
00654 */
00655 WandExport MagickWand *GetPixelViewWand(const PixelView *pixel_view)
00656 {
00657   assert(pixel_view != (PixelView *) NULL);
00658   assert(pixel_view->signature == WandSignature);
00659   return(pixel_view->wand);
00660 }
00661 
00662 /*
00663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00664 %                                                                             %
00665 %                                                                             %
00666 %                                                                             %
00667 %   G e t P i x e l V i e w W i d t h                                         %
00668 %                                                                             %
00669 %                                                                             %
00670 %                                                                             %
00671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00672 %
00673 %  GetPixelViewWidth() returns the pixel view width.
00674 %
00675 %  The format of the GetPixelViewWidth method is:
00676 %
00677 %      unsigned long GetPixelViewWidth(const PixelView *pixel_view)
00678 %
00679 %  A description of each parameter follows:
00680 %
00681 %    o pixel_view: the pixel view.
00682 %
00683 */
00684 WandExport unsigned long GetPixelViewWidth(const PixelView *pixel_view)
00685 {
00686   assert(pixel_view != (PixelView *) NULL);
00687   assert(pixel_view->signature == WandSignature);
00688   return(pixel_view->region.width);
00689 }
00690 
00691 /*
00692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00693 %                                                                             %
00694 %                                                                             %
00695 %                                                                             %
00696 %   G e t P i x e l V i e w X                                                 %
00697 %                                                                             %
00698 %                                                                             %
00699 %                                                                             %
00700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00701 %
00702 %  GetPixelViewX() returns the pixel view x offset.
00703 %
00704 %  The format of the GetPixelViewX method is:
00705 %
00706 %      long GetPixelViewX(const PixelView *pixel_view)
00707 %
00708 %  A description of each parameter follows:
00709 %
00710 %    o pixel_view: the pixel view.
00711 %
00712 */
00713 WandExport long GetPixelViewX(const PixelView *pixel_view)
00714 {
00715   assert(pixel_view != (PixelView *) NULL);
00716   assert(pixel_view->signature == WandSignature);
00717   return(pixel_view->region.x);
00718 }
00719 
00720 /*
00721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00722 %                                                                             %
00723 %                                                                             %
00724 %                                                                             %
00725 %   G e t P i x e l V i e w Y                                                 %
00726 %                                                                             %
00727 %                                                                             %
00728 %                                                                             %
00729 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00730 %
00731 %  GetPixelViewY() returns the pixel view y offset.
00732 %
00733 %  The format of the GetPixelViewY method is:
00734 %
00735 %      long GetPixelViewY(const PixelView *pixel_view)
00736 %
00737 %  A description of each parameter follows:
00738 %
00739 %    o pixel_view: the pixel view.
00740 %
00741 */
00742 WandExport long GetPixelViewY(const PixelView *pixel_view)
00743 {
00744   assert(pixel_view != (PixelView *) NULL);
00745   assert(pixel_view->signature == WandSignature);
00746   return(pixel_view->region.y);
00747 }
00748 
00749 /*
00750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00751 %                                                                             %
00752 %                                                                             %
00753 %                                                                             %
00754 %   I s P i x e l V i e w                                                     %
00755 %                                                                             %
00756 %                                                                             %
00757 %                                                                             %
00758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00759 %
00760 %  IsPixelView() returns MagickTrue if the the parameter is verified as a pixel
00761 %  view container.
00762 %
00763 %  The format of the IsPixelView method is:
00764 %
00765 %      MagickBooleanType IsPixelView(const PixelView *pixel_view)
00766 %
00767 %  A description of each parameter follows:
00768 %
00769 %    o pixel_view: the pixel view.
00770 %
00771 */
00772 WandExport MagickBooleanType IsPixelView(const PixelView *pixel_view)
00773 {
00774   size_t
00775     length;
00776 
00777   if (pixel_view == (const PixelView *) NULL)
00778     return(MagickFalse);
00779   if (pixel_view->signature != WandSignature)
00780     return(MagickFalse);
00781   length=strlen(PixelViewId);
00782   if (LocaleNCompare(pixel_view->name,PixelViewId,length) != 0)
00783     return(MagickFalse);
00784   return(MagickTrue);
00785 }
00786 
00787 /*
00788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00789 %                                                                             %
00790 %                                                                             %
00791 %                                                                             %
00792 %   N e w P i x e l V i e w                                                   %
00793 %                                                                             %
00794 %                                                                             %
00795 %                                                                             %
00796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00797 %
00798 %  NewPixelView() returns a pixel view required for all other methods in the
00799 %  Pixel View API.
00800 %
00801 %  The format of the NewPixelView method is:
00802 %
00803 %      PixelView *NewPixelView(MagickWand *wand)
00804 %
00805 %  A description of each parameter follows:
00806 %
00807 %    o wand: the wand.
00808 %
00809 */
00810 
00811 static PixelWand ***AcquirePixelsThreadSet(const unsigned long number_wands,
00812   const unsigned long number_threads)
00813 {
00814   PixelWand
00815     ***pixel_wands;
00816 
00817   register long
00818     i;
00819 
00820   pixel_wands=(PixelWand ***) AcquireAlignedMemory(number_threads,
00821     sizeof(*pixel_wands));
00822   if (pixel_wands == (PixelWand ***) NULL)
00823     return((PixelWand ***) NULL);
00824   (void) ResetMagickMemory(pixel_wands,0,number_threads*sizeof(*pixel_wands));
00825   for (i=0; i < (long) number_threads; i++)
00826   {
00827     pixel_wands[i]=NewPixelWands(number_wands);
00828     if (pixel_wands[i] == (PixelWand **) NULL)
00829       return(DestroyPixelsThreadSet(pixel_wands,number_wands,number_threads));
00830   }
00831   return(pixel_wands);
00832 }
00833 
00834 WandExport PixelView *NewPixelView(MagickWand *wand)
00835 {
00836   PixelView
00837     *pixel_view;
00838 
00839   assert(wand != (MagickWand *) NULL);
00840   assert(wand->signature == MagickSignature);
00841   pixel_view=(PixelView *) AcquireMagickMemory(sizeof(*pixel_view));
00842   if (pixel_view == (PixelView *) NULL)
00843     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
00844       GetExceptionMessage(errno));
00845   (void) ResetMagickMemory(pixel_view,0,sizeof(*pixel_view));
00846   pixel_view->id=AcquireWandId();
00847   (void) FormatMagickString(pixel_view->name,MaxTextExtent,"%s-%lu",
00848     PixelViewId,pixel_view->id);
00849   pixel_view->exception=AcquireExceptionInfo();
00850   pixel_view->wand=wand;
00851   pixel_view->view=AcquireCacheView(pixel_view->wand->images);
00852   pixel_view->region.width=wand->images->columns;
00853   pixel_view->region.height=wand->images->rows;
00854   pixel_view->number_threads=GetOpenMPMaximumThreads();
00855   pixel_view->pixel_wands=AcquirePixelsThreadSet(pixel_view->region.width,
00856     pixel_view->number_threads);
00857   if (pixel_view->pixel_wands == (PixelWand ***) NULL)
00858     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
00859       GetExceptionMessage(errno));
00860   pixel_view->debug=IsEventLogging();
00861   pixel_view->signature=WandSignature;
00862   return(pixel_view);
00863 }
00864 
00865 /*
00866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00867 %                                                                             %
00868 %                                                                             %
00869 %                                                                             %
00870 %   N e w P i x e l V i e w R e g i o n                                       %
00871 %                                                                             %
00872 %                                                                             %
00873 %                                                                             %
00874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00875 %
00876 %  NewPixelViewRegion() returns a pixel view required for all other methods
00877 %  in the Pixel View API.
00878 %
00879 %  The format of the NewPixelViewRegion method is:
00880 %
00881 %      PixelView *NewPixelViewRegion(MagickWand *wand,const long x,
00882 %        const long y,const unsigned long width,const unsigned long height)
00883 %
00884 %  A description of each parameter follows:
00885 %
00886 %    o wand: the magick wand.
00887 %
00888 %    o x,y,columns,rows:  These values define the perimeter of a region of
00889 %      pixel_wands view.
00890 %
00891 */
00892 WandExport PixelView *NewPixelViewRegion(MagickWand *wand,const long x,
00893   const long y,const unsigned long width,const unsigned long height)
00894 {
00895   PixelView
00896     *pixel_view;
00897 
00898   assert(wand != (MagickWand *) NULL);
00899   assert(wand->signature == MagickSignature);
00900   pixel_view=(PixelView *) AcquireMagickMemory(sizeof(*pixel_view));
00901   if (pixel_view == (PixelView *) NULL)
00902     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
00903       GetExceptionMessage(errno));
00904   (void) ResetMagickMemory(pixel_view,0,sizeof(*pixel_view));
00905   pixel_view->id=AcquireWandId();
00906   (void) FormatMagickString(pixel_view->name,MaxTextExtent,"%s-%lu",
00907     PixelViewId,pixel_view->id);
00908   pixel_view->exception=AcquireExceptionInfo();
00909   pixel_view->view=AcquireCacheView(pixel_view->wand->images);
00910   pixel_view->wand=wand;
00911   pixel_view->region.width=width;
00912   pixel_view->region.height=height;
00913   pixel_view->region.x=x;
00914   pixel_view->region.y=y;
00915   pixel_view->number_threads=GetOpenMPMaximumThreads();
00916   pixel_view->pixel_wands=AcquirePixelsThreadSet(pixel_view->region.width,
00917     pixel_view->number_threads);
00918   if (pixel_view->pixel_wands == (PixelWand ***) NULL)
00919     ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
00920       GetExceptionMessage(errno));
00921   pixel_view->debug=IsEventLogging();
00922   pixel_view->signature=WandSignature;
00923   return(pixel_view);
00924 }
00925 
00926 /*
00927 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00928 %                                                                             %
00929 %                                                                             %
00930 %                                                                             %
00931 %   S e t P i x e l V i e w I t e r a t o r                                   %
00932 %                                                                             %
00933 %                                                                             %
00934 %                                                                             %
00935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00936 %
00937 %  SetPixelViewIterator() iterates over the pixel view in parallel and calls
00938 %  your set method for each scanline of the view.  The pixel region is
00939 %  confined to the image canvas-- that is no negative offsets or widths or
00940 %  heights that exceed the image dimension.  The pixels are initiallly
00941 %  undefined and any settings you make in the callback method are automagically
00942 %  synced back to your image.
00943 %
00944 %  Use this pragma:
00945 %
00946 %    #pragma omp critical
00947 %
00948 %  to define a section of code in your callback set method that must be
00949 %  executed by a single thread at a time.
00950 %
00951 %  The format of the SetPixelViewIterator method is:
00952 %
00953 %      MagickBooleanType SetPixelViewIterator(PixelView *destination,
00954 %        SetPixelViewMethod set,void *context)
00955 %
00956 %  A description of each parameter follows:
00957 %
00958 %    o destination: the pixel view.
00959 %
00960 %    o set: the set callback method.
00961 %
00962 %    o context: the user defined context.
00963 %
00964 */
00965 WandExport MagickBooleanType SetPixelViewIterator(PixelView *destination,
00966   SetPixelViewMethod set,void *context)
00967 {
00968 #define SetPixelViewTag  "PixelView/Set"
00969 
00970   ExceptionInfo
00971     *exception;
00972 
00973   Image
00974     *destination_image;
00975 
00976   long
00977     progress,
00978     y;
00979 
00980   MagickBooleanType
00981     status;
00982 
00983   assert(destination != (PixelView *) NULL);
00984   assert(destination->signature == WandSignature);
00985   if (set == (SetPixelViewMethod) NULL)
00986     return(MagickFalse);
00987   destination_image=destination->wand->images;
00988   if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
00989     return(MagickFalse);
00990   status=MagickTrue;
00991   progress=0;
00992   exception=destination->exception;
00993 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00994   #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
00995 #endif
00996   for (y=destination->region.y; y < (long) destination->region.height; y++)
00997   {
00998     MagickBooleanType
00999       sync;
01000 
01001     register IndexPacket
01002       *__restrict indexes;
01003 
01004     register long
01005       id,
01006       x;
01007 
01008     register PixelPacket
01009       *__restrict pixels;
01010 
01011     if (status == MagickFalse)
01012       continue;
01013     id=GetOpenMPThreadId();
01014     pixels=GetCacheViewAuthenticPixels(destination->view,destination->region.x,
01015       y,destination->region.width,1,exception);
01016     if (pixels == (PixelPacket *) NULL)
01017       {
01018         InheritException(destination->exception,GetCacheViewException(
01019           destination->view));
01020         status=MagickFalse;
01021         continue;
01022       }
01023     indexes=GetCacheViewAuthenticIndexQueue(destination->view);
01024     if (set(destination,context) == MagickFalse)
01025       status=MagickFalse;
01026     for (x=0; x < (long) destination->region.width; x++)
01027       PixelGetQuantumColor(destination->pixel_wands[id][x],pixels+x);
01028     if (destination_image->colorspace == CMYKColorspace)
01029       for (x=0; x < (long) destination->region.width; x++)
01030         indexes[x]=PixelGetBlackQuantum(destination->pixel_wands[id][x]);
01031     sync=SyncCacheViewAuthenticPixels(destination->view,exception);
01032     if (sync == MagickFalse)
01033       {
01034         InheritException(destination->exception,GetCacheViewException(
01035           destination->view));
01036         status=MagickFalse;
01037       }
01038     if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
01039       {
01040         MagickBooleanType
01041           proceed;
01042 
01043 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01044   #pragma omp critical (MagickWand_SetPixelViewIterator)
01045 #endif
01046         proceed=SetImageProgress(destination_image,SetPixelViewTag,progress++,
01047           destination->region.height);
01048         if (proceed == MagickFalse)
01049           status=MagickFalse;
01050       }
01051   }
01052   return(status);
01053 }
01054 
01055 /*
01056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01057 %                                                                             %
01058 %                                                                             %
01059 %                                                                             %
01060 %   T r a n s f e r P i x e l V i e w I t e r a t o r                         %
01061 %                                                                             %
01062 %                                                                             %
01063 %                                                                             %
01064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01065 %
01066 %  TransferPixelViewIterator() iterates over two pixel views in parallel and
01067 %  calls your transfer method for each scanline of the view.  The source pixel
01068 %  region is not confined to the image canvas-- that is you can include
01069 %  negative offsets or widths or heights that exceed the image dimension.
01070 %  However, the destination pixel view is confined to the image canvas-- that
01071 %  is no negative offsets or widths or heights that exceed the image dimension
01072 %  are permitted.
01073 %
01074 %  Use this pragma:
01075 %
01076 %    #pragma omp critical
01077 %
01078 %  to define a section of code in your callback transfer method that must be
01079 %  executed by a single thread at a time.
01080 %
01081 %  The format of the TransferPixelViewIterator method is:
01082 %
01083 %      MagickBooleanType TransferPixelViewIterator(PixelView *source,
01084 %        PixelView *destination,TransferPixelViewMethod transfer,void *context)
01085 %
01086 %  A description of each parameter follows:
01087 %
01088 %    o source: the source pixel view.
01089 %
01090 %    o destination: the destination pixel view.
01091 %
01092 %    o transfer: the transfer callback method.
01093 %
01094 %    o context: the user defined context.
01095 %
01096 */
01097 WandExport MagickBooleanType TransferPixelViewIterator(PixelView *source,
01098   PixelView *destination,TransferPixelViewMethod transfer,void *context)
01099 {
01100 #define TransferPixelViewTag  "PixelView/Transfer"
01101 
01102   ExceptionInfo
01103     *exception;
01104 
01105   Image
01106     *destination_image,
01107     *source_image;
01108 
01109   long
01110     progress,
01111     y;
01112 
01113   MagickBooleanType
01114     status;
01115 
01116   assert(source != (PixelView *) NULL);
01117   assert(source->signature == WandSignature);
01118   if (transfer == (TransferPixelViewMethod) NULL)
01119     return(MagickFalse);
01120   source_image=source->wand->images;
01121   destination_image=destination->wand->images;
01122   if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
01123     return(MagickFalse);
01124   status=MagickTrue;
01125   progress=0;
01126   exception=destination->exception;
01127 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01128   #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
01129 #endif
01130   for (y=source->region.y; y < (long) source->region.height; y++)
01131   {
01132     MagickBooleanType
01133       sync;
01134 
01135     register const IndexPacket
01136       *__restrict indexes;
01137 
01138     register const PixelPacket
01139       *__restrict pixels;
01140 
01141     register IndexPacket
01142       *__restrict destination_indexes;
01143 
01144     register long
01145       id,
01146       x;
01147 
01148     register PixelPacket
01149       *__restrict destination_pixels;
01150 
01151     if (status == MagickFalse)
01152       continue;
01153     id=GetOpenMPThreadId();
01154     pixels=GetCacheViewVirtualPixels(source->view,source->region.x,y,
01155       source->region.width,1,source->exception);
01156     if (pixels == (const PixelPacket *) NULL)
01157       {
01158         status=MagickFalse;
01159         continue;
01160       }
01161     indexes=GetCacheViewVirtualIndexQueue(source->view);
01162     for (x=0; x < (long) source->region.width; x++)
01163       PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
01164     if (source_image->colorspace == CMYKColorspace)
01165       for (x=0; x < (long) source->region.width; x++)
01166         PixelSetBlackQuantum(source->pixel_wands[id][x],indexes[x]);
01167     if (source_image->storage_class == PseudoClass)
01168       for (x=0; x < (long) source->region.width; x++)
01169         PixelSetIndex(source->pixel_wands[id][x],indexes[x]);
01170     destination_pixels=GetCacheViewAuthenticPixels(destination->view,
01171       destination->region.x,y,destination->region.width,1,exception);
01172     if (destination_pixels == (PixelPacket *) NULL)
01173       {
01174         status=MagickFalse;
01175         continue;
01176       }
01177     destination_indexes=GetCacheViewAuthenticIndexQueue(destination->view);
01178     for (x=0; x < (long) destination->region.width; x++)
01179       PixelSetQuantumColor(destination->pixel_wands[id][x],pixels+x);
01180     if (destination_image->colorspace == CMYKColorspace)
01181       for (x=0; x < (long) destination->region.width; x++)
01182         PixelSetBlackQuantum(destination->pixel_wands[id][x],indexes[x]);
01183     if (destination_image->storage_class == PseudoClass)
01184       for (x=0; x < (long) destination->region.width; x++)
01185         PixelSetIndex(destination->pixel_wands[id][x],indexes[x]);
01186     if (transfer(source,destination,context) == MagickFalse)
01187       status=MagickFalse;
01188     for (x=0; x < (long) destination->region.width; x++)
01189       PixelGetQuantumColor(destination->pixel_wands[id][x],
01190         destination_pixels+x);
01191     if (destination_image->colorspace == CMYKColorspace)
01192       for (x=0; x < (long) destination->region.width; x++)
01193         destination_indexes[x]=PixelGetBlackQuantum(
01194           destination->pixel_wands[id][x]);
01195     sync=SyncCacheViewAuthenticPixels(destination->view,exception);
01196     if (sync == MagickFalse)
01197       {
01198         InheritException(destination->exception,GetCacheViewException(
01199           source->view));
01200         status=MagickFalse;
01201       }
01202     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
01203       {
01204         MagickBooleanType
01205           proceed;
01206 
01207 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01208   #pragma omp critical (MagickWand_TransferPixelViewIterator)
01209 #endif
01210         proceed=SetImageProgress(source_image,TransferPixelViewTag,progress++,
01211           source->region.height);
01212         if (proceed == MagickFalse)
01213           status=MagickFalse;
01214       }
01215   }
01216   return(status);
01217 }
01218 
01219 /*
01220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01221 %                                                                             %
01222 %                                                                             %
01223 %                                                                             %
01224 %   U p d a t e P i x e l V i e w I t e r a t o r                             %
01225 %                                                                             %
01226 %                                                                             %
01227 %                                                                             %
01228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01229 %
01230 %  UpdatePixelViewIterator() iterates over the pixel view in parallel and calls
01231 %  your update method for each scanline of the view.  The pixel region is
01232 %  confined to the image canvas-- that is no negative offsets or widths or
01233 %  heights that exceed the image dimension are permitted.  Updates to pixels
01234 %  in your callback are automagically synced back to the image.
01235 %
01236 %  Use this pragma:
01237 %
01238 %    #pragma omp critical
01239 %
01240 %  to define a section of code in your callback update method that must be
01241 %  executed by a single thread at a time.
01242 %
01243 %  The format of the UpdatePixelViewIterator method is:
01244 %
01245 %      MagickBooleanType UpdatePixelViewIterator(PixelView *source,
01246 %        UpdatePixelViewMethod update,void *context)
01247 %
01248 %  A description of each parameter follows:
01249 %
01250 %    o source: the source pixel view.
01251 %
01252 %    o update: the update callback method.
01253 %
01254 %    o context: the user defined context.
01255 %
01256 */
01257 WandExport MagickBooleanType UpdatePixelViewIterator(PixelView *source,
01258   UpdatePixelViewMethod update,void *context)
01259 {
01260 #define UpdatePixelViewTag  "PixelView/Update"
01261 
01262   ExceptionInfo
01263     *exception;
01264 
01265   Image
01266     *source_image;
01267 
01268   long
01269     progress,
01270     y;
01271 
01272   MagickBooleanType
01273     status;
01274 
01275   assert(source != (PixelView *) NULL);
01276   assert(source->signature == WandSignature);
01277   if (update == (UpdatePixelViewMethod) NULL)
01278     return(MagickFalse);
01279   source_image=source->wand->images;
01280   if (SetImageStorageClass(source_image,DirectClass) == MagickFalse)
01281     return(MagickFalse);
01282   status=MagickTrue;
01283   progress=0;
01284   exception=source->exception;
01285 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01286   #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
01287 #endif
01288   for (y=source->region.y; y < (long) source->region.height; y++)
01289   {
01290     register IndexPacket
01291       *__restrict indexes;
01292 
01293     register long
01294       id,
01295       x;
01296 
01297     register PixelPacket
01298       *__restrict pixels;
01299 
01300     if (status == MagickFalse)
01301       continue;
01302     id=GetOpenMPThreadId();
01303     pixels=GetCacheViewAuthenticPixels(source->view,source->region.x,y,
01304       source->region.width,1,exception);
01305     if (pixels == (PixelPacket *) NULL)
01306       {
01307         InheritException(source->exception,GetCacheViewException(
01308           source->view));
01309         status=MagickFalse;
01310         continue;
01311       }
01312     indexes=GetCacheViewAuthenticIndexQueue(source->view);
01313     for (x=0; x < (long) source->region.width; x++)
01314       PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
01315     if (source_image->colorspace == CMYKColorspace)
01316       for (x=0; x < (long) source->region.width; x++)
01317         PixelSetBlackQuantum(source->pixel_wands[id][x],indexes[x]);
01318     if (update(source,context) == MagickFalse)
01319       status=MagickFalse;
01320     for (x=0; x < (long) source->region.width; x++)
01321       PixelGetQuantumColor(source->pixel_wands[id][x],pixels+x);
01322     if (source_image->colorspace == CMYKColorspace)
01323       for (x=0; x < (long) source->region.width; x++)
01324         indexes[x]=PixelGetBlackQuantum(source->pixel_wands[id][x]);
01325     if (SyncCacheViewAuthenticPixels(source->view,exception) == MagickFalse)
01326       {
01327         InheritException(source->exception,GetCacheViewException(source->view));
01328         status=MagickFalse;
01329       }
01330     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
01331       {
01332         MagickBooleanType
01333           proceed;
01334 
01335 #if defined(MAGICKCORE_OPENMP_SUPPORT)
01336   #pragma omp critical (MagickWand_UpdatePixelViewIterator)
01337 #endif
01338         proceed=SetImageProgress(source_image,UpdatePixelViewTag,progress++,
01339           source->region.height);
01340         if (proceed == MagickFalse)
01341           status=MagickFalse;
01342       }
01343   }
01344   return(status);
01345 }

Generated on 19 Nov 2009 for MagickWand by  doxygen 1.6.1