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