|
MagickCore
6.7.7
|
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 }