blob: 9fcbc9c6f0d3572e72d69ba0db9a4530543cc030 [file] [log] [blame]
cristy16881e62012-05-06 14:41:29 +00001/*
cristy3ed852e2009-09-05 21:47:34 +00002%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
cristy7eb1b7a2010-06-26 15:47:49 +00005% IIIII M M AAA GGGG EEEEE %
6% I MM MM A A G E %
7% I M M M AAAAA G GG EEE %
8% I M M A A G G E %
9% IIIII M M A A GGGG EEEEE %
cristy3ed852e2009-09-05 21:47:34 +000010% %
cristycc34c492010-06-26 23:49:12 +000011% V V IIIII EEEEE W W %
12% V V I E W W %
13% V V I EEE W W W %
14% V V I E WW WW %
15% V IIIII EEEEE W W %
cristy3ed852e2009-09-05 21:47:34 +000016% %
17% %
cristy7eb1b7a2010-06-26 15:47:49 +000018% MagickCore Image View Methods %
cristy3ed852e2009-09-05 21:47:34 +000019% %
20% Software Design %
cristyde984cd2013-12-01 14:49:27 +000021% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000022% March 2003 %
23% %
24% %
Cristyf6ff9ea2016-12-05 09:53:35 -050025% Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000026% dedicated to making software imaging solutions freely available. %
27% %
28% You may not use this file except in compliance with the License. You may %
29% obtain a copy of the License at %
30% %
Cristyf19d4142017-04-24 11:34:30 -040031% https://www.imagemagick.org/script/license.php %
cristy3ed852e2009-09-05 21:47:34 +000032% %
33% Unless required by applicable law or agreed to in writing, software %
34% distributed under the License is distributed on an "AS IS" BASIS, %
35% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
36% See the License for the specific language governing permissions and %
37% limitations under the License. %
38% %
39%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40%
41%
42%
43*/
44
45/*
46 Include declarations.
47*/
cristy4c08aed2011-07-01 19:47:50 +000048#include "MagickCore/studio.h"
49#include "MagickCore/MagickCore.h"
50#include "MagickCore/exception-private.h"
51#include "MagickCore/monitor-private.h"
52#include "MagickCore/thread-private.h"
cristy3ed852e2009-09-05 21:47:34 +000053
54/*
55 Typedef declarations.
56*/
cristy7eb1b7a2010-06-26 15:47:49 +000057struct _ImageView
cristy3ed852e2009-09-05 21:47:34 +000058{
cristyc3ebda22010-06-27 17:11:57 +000059 char
60 *description;
61
62 RectangleInfo
63 extent;
cristy3ed852e2009-09-05 21:47:34 +000064
cristy7eb1b7a2010-06-26 15:47:49 +000065 Image
66 *image;
cristy3ed852e2009-09-05 21:47:34 +000067
68 CacheView
69 *view;
70
cristyc3ebda22010-06-27 17:11:57 +000071 ExceptionInfo
72 *exception;
73
cristy3ed852e2009-09-05 21:47:34 +000074 MagickBooleanType
75 debug;
76
cristybb503372010-05-27 20:51:26 +000077 size_t
cristy3ed852e2009-09-05 21:47:34 +000078 signature;
79};
80
81/*
82%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83% %
84% %
85% %
cristy7eb1b7a2010-06-26 15:47:49 +000086% C l o n e I m a g e V i e w %
cristy3ed852e2009-09-05 21:47:34 +000087% %
88% %
89% %
90%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91%
cristy73b7d4c2010-06-27 00:31:00 +000092% CloneImageView() makes a copy of the specified image view.
cristy3ed852e2009-09-05 21:47:34 +000093%
cristy7eb1b7a2010-06-26 15:47:49 +000094% The format of the CloneImageView method is:
cristy3ed852e2009-09-05 21:47:34 +000095%
cristy73b7d4c2010-06-27 00:31:00 +000096% ImageView *CloneImageView(const ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +000097%
98% A description of each parameter follows:
99%
cristy73b7d4c2010-06-27 00:31:00 +0000100% o image_view: the image view.
cristy3ed852e2009-09-05 21:47:34 +0000101%
102*/
cristy73b7d4c2010-06-27 00:31:00 +0000103MagickExport ImageView *CloneImageView(const ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +0000104{
cristy7eb1b7a2010-06-26 15:47:49 +0000105 ImageView
cristy3ed852e2009-09-05 21:47:34 +0000106 *clone_view;
107
cristy73b7d4c2010-06-27 00:31:00 +0000108 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000109 assert(image_view->signature == MagickCoreSignature);
cristy73bd4a52010-10-05 11:24:23 +0000110 clone_view=(ImageView *) AcquireMagickMemory(sizeof(*clone_view));
cristy7eb1b7a2010-06-26 15:47:49 +0000111 if (clone_view == (ImageView *) NULL)
112 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000113 (void) ResetMagickMemory(clone_view,0,sizeof(*clone_view));
cristyc3ebda22010-06-27 17:11:57 +0000114 clone_view->description=ConstantString(image_view->description);
115 clone_view->extent=image_view->extent;
116 clone_view->view=CloneCacheView(image_view->view);
cristy3ed852e2009-09-05 21:47:34 +0000117 clone_view->exception=AcquireExceptionInfo();
cristy73b7d4c2010-06-27 00:31:00 +0000118 InheritException(clone_view->exception,image_view->exception);
cristy73b7d4c2010-06-27 00:31:00 +0000119 clone_view->debug=image_view->debug;
cristye1c94d92015-06-28 12:16:33 +0000120 clone_view->signature=MagickCoreSignature;
cristy3ed852e2009-09-05 21:47:34 +0000121 return(clone_view);
122}
123
124/*
125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126% %
127% %
128% %
cristy7eb1b7a2010-06-26 15:47:49 +0000129% D e s t r o y I m a g e V i e w %
cristy3ed852e2009-09-05 21:47:34 +0000130% %
131% %
132% %
133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134%
cristy73b7d4c2010-06-27 00:31:00 +0000135% DestroyImageView() deallocates memory associated with a image view.
cristy3ed852e2009-09-05 21:47:34 +0000136%
cristy7eb1b7a2010-06-26 15:47:49 +0000137% The format of the DestroyImageView method is:
cristy3ed852e2009-09-05 21:47:34 +0000138%
cristy73b7d4c2010-06-27 00:31:00 +0000139% ImageView *DestroyImageView(ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +0000140%
141% A description of each parameter follows:
142%
cristy73b7d4c2010-06-27 00:31:00 +0000143% o image_view: the image view.
cristy3ed852e2009-09-05 21:47:34 +0000144%
145*/
cristy73b7d4c2010-06-27 00:31:00 +0000146MagickExport ImageView *DestroyImageView(ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +0000147{
cristy73b7d4c2010-06-27 00:31:00 +0000148 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000149 assert(image_view->signature == MagickCoreSignature);
cristyc3ebda22010-06-27 17:11:57 +0000150 if (image_view->description != (char *) NULL)
151 image_view->description=DestroyString(image_view->description);
cristy73b7d4c2010-06-27 00:31:00 +0000152 image_view->view=DestroyCacheView(image_view->view);
153 image_view->exception=DestroyExceptionInfo(image_view->exception);
cristye1c94d92015-06-28 12:16:33 +0000154 image_view->signature=(~MagickCoreSignature);
cristy73b7d4c2010-06-27 00:31:00 +0000155 image_view=(ImageView *) RelinquishMagickMemory(image_view);
156 return(image_view);
cristy3ed852e2009-09-05 21:47:34 +0000157}
158
159/*
160%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161% %
162% %
163% %
cristy7eb1b7a2010-06-26 15:47:49 +0000164% 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 %
cristy3ed852e2009-09-05 21:47:34 +0000165% %
166% %
167% %
168%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169%
cristy73b7d4c2010-06-27 00:31:00 +0000170% DuplexTransferImageViewIterator() iterates over three image views in
cristy3ed852e2009-09-05 21:47:34 +0000171% parallel and calls your transfer method for each scanline of the view. The
cristyc3ebda22010-06-27 17:11:57 +0000172% source and duplex pixel extent is not confined to the image canvas-- that is
cristy3ed852e2009-09-05 21:47:34 +0000173% you can include negative offsets or widths or heights that exceed the image
cristy73b7d4c2010-06-27 00:31:00 +0000174% dimension. However, the destination image view is confined to the image
cristy3ed852e2009-09-05 21:47:34 +0000175% canvas-- that is no negative offsets or widths or heights that exceed the
176% image dimension are permitted.
177%
cristyd6dfc0d2010-06-27 19:30:49 +0000178% The callback signature is:
179%
180% MagickBooleanType DuplexTransferImageViewMethod(const ImageView *source,
181% const ImageView *duplex,ImageView *destination,const ssize_t y,
182% const int thread_id,void *context)
183%
cristy58739472010-06-26 20:27:18 +0000184% Use this pragma if the view is not single threaded:
cristy3ed852e2009-09-05 21:47:34 +0000185%
186% #pragma omp critical
187%
188% to define a section of code in your callback transfer method that must be
189% executed by a single thread at a time.
190%
cristy7eb1b7a2010-06-26 15:47:49 +0000191% The format of the DuplexTransferImageViewIterator method is:
cristy3ed852e2009-09-05 21:47:34 +0000192%
cristy7eb1b7a2010-06-26 15:47:49 +0000193% MagickBooleanType DuplexTransferImageViewIterator(ImageView *source,
194% ImageView *duplex,ImageView *destination,
195% DuplexTransferImageViewMethod transfer,void *context)
cristy3ed852e2009-09-05 21:47:34 +0000196%
197% A description of each parameter follows:
198%
cristy73b7d4c2010-06-27 00:31:00 +0000199% o source: the source image view.
cristy3ed852e2009-09-05 21:47:34 +0000200%
cristy73b7d4c2010-06-27 00:31:00 +0000201% o duplex: the duplex image view.
cristy3ed852e2009-09-05 21:47:34 +0000202%
cristy73b7d4c2010-06-27 00:31:00 +0000203% o destination: the destination image view.
cristy3ed852e2009-09-05 21:47:34 +0000204%
205% o transfer: the transfer callback method.
206%
207% o context: the user defined context.
208%
209*/
cristy7eb1b7a2010-06-26 15:47:49 +0000210MagickExport MagickBooleanType DuplexTransferImageViewIterator(
211 ImageView *source,ImageView *duplex,ImageView *destination,
212 DuplexTransferImageViewMethod transfer,void *context)
cristy3ed852e2009-09-05 21:47:34 +0000213{
cristy3ed852e2009-09-05 21:47:34 +0000214 Image
215 *destination_image,
cristy3ed852e2009-09-05 21:47:34 +0000216 *source_image;
217
cristy3ed852e2009-09-05 21:47:34 +0000218 MagickBooleanType
219 status;
220
cristycee97112010-05-28 00:44:52 +0000221 MagickOffsetType
222 progress;
223
glennrp37618d62012-09-24 17:24:13 +0000224#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000225 size_t
cristy26b64912012-12-16 18:20:09 +0000226 height;
glennrp37618d62012-09-24 17:24:13 +0000227#endif
cristyac245f82012-05-05 17:13:57 +0000228
cristycee97112010-05-28 00:44:52 +0000229 ssize_t
230 y;
231
cristy7eb1b7a2010-06-26 15:47:49 +0000232 assert(source != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000233 assert(source->signature == MagickCoreSignature);
cristy7eb1b7a2010-06-26 15:47:49 +0000234 if (transfer == (DuplexTransferImageViewMethod) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000235 return(MagickFalse);
cristy7eb1b7a2010-06-26 15:47:49 +0000236 source_image=source->image;
cristy7eb1b7a2010-06-26 15:47:49 +0000237 destination_image=destination->image;
cristy7c3af952011-10-20 16:04:16 +0000238 status=SetImageStorageClass(destination_image,DirectClass,
239 destination->exception);
240 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000241 return(MagickFalse);
242 status=MagickTrue;
243 progress=0;
glennrp37618d62012-09-24 17:24:13 +0000244#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000245 height=source->extent.height-source->extent.y;
cristy9a5a52f2012-10-09 14:40:31 +0000246 #pragma omp parallel for schedule(static,4) shared(progress,status) \
cristy5e6b2592012-12-19 14:08:11 +0000247 magick_threads(source_image,destination_image,height,1)
cristy3ed852e2009-09-05 21:47:34 +0000248#endif
cristyc3ebda22010-06-27 17:11:57 +0000249 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000250 {
cristy5c9e6f22010-09-17 17:31:01 +0000251 const int
252 id = GetOpenMPThreadId();
cristyad740052010-07-03 01:38:03 +0000253
cristy3ed852e2009-09-05 21:47:34 +0000254 MagickBooleanType
255 sync;
256
cristy4c08aed2011-07-01 19:47:50 +0000257 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100258 *magick_restrict duplex_pixels,
259 *magick_restrict pixels;
cristy3ed852e2009-09-05 21:47:34 +0000260
cristy4c08aed2011-07-01 19:47:50 +0000261 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100262 *magick_restrict destination_pixels;
cristy3ed852e2009-09-05 21:47:34 +0000263
264 if (status == MagickFalse)
265 continue;
cristyc3ebda22010-06-27 17:11:57 +0000266 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
267 source->extent.width,1,source->exception);
cristy4c08aed2011-07-01 19:47:50 +0000268 if (pixels == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000269 {
270 status=MagickFalse;
271 continue;
272 }
cristyc3ebda22010-06-27 17:11:57 +0000273 duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
274 duplex->extent.width,1,duplex->exception);
cristy4c08aed2011-07-01 19:47:50 +0000275 if (duplex_pixels == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000276 {
277 status=MagickFalse;
278 continue;
279 }
cristy3ed852e2009-09-05 21:47:34 +0000280 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
cristy7c3af952011-10-20 16:04:16 +0000281 destination->extent.x,y,destination->extent.width,1,
282 destination->exception);
cristy4c08aed2011-07-01 19:47:50 +0000283 if (destination_pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000284 {
285 status=MagickFalse;
286 continue;
287 }
cristyc3ebda22010-06-27 17:11:57 +0000288 if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000289 status=MagickFalse;
cristy7c3af952011-10-20 16:04:16 +0000290 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
cristy3ed852e2009-09-05 21:47:34 +0000291 if (sync == MagickFalse)
cristy7c3af952011-10-20 16:04:16 +0000292 status=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000293 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
294 {
295 MagickBooleanType
296 proceed;
297
cristyb5d5f722009-11-04 03:03:49 +0000298#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000299 #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
cristy3ed852e2009-09-05 21:47:34 +0000300#endif
cristyc3ebda22010-06-27 17:11:57 +0000301 proceed=SetImageProgress(source_image,source->description,progress++,
302 source->extent.height);
cristy3ed852e2009-09-05 21:47:34 +0000303 if (proceed == MagickFalse)
304 status=MagickFalse;
305 }
306 }
307 return(status);
308}
309
310/*
311%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312% %
313% %
314% %
cristy7c3af952011-10-20 16:04:16 +0000315% 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 %
cristycc34c492010-06-26 23:49:12 +0000316% %
317% %
318% %
319%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320%
cristy4c08aed2011-07-01 19:47:50 +0000321% GetImageViewAuthenticMetacontent() returns the image view authentic
322% meta-content.
cristycc34c492010-06-26 23:49:12 +0000323%
324% The format of the GetImageViewAuthenticPixels method is:
325%
cristy4c08aed2011-07-01 19:47:50 +0000326% void *GetImageViewAuthenticMetacontent(
327% const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000328%
329% A description of each parameter follows:
330%
cristy73b7d4c2010-06-27 00:31:00 +0000331% o image_view: the image view.
cristycc34c492010-06-26 23:49:12 +0000332%
333*/
cristy4c08aed2011-07-01 19:47:50 +0000334MagickExport void *GetImageViewAuthenticMetacontent(
cristy73b7d4c2010-06-27 00:31:00 +0000335 const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000336{
cristy73b7d4c2010-06-27 00:31:00 +0000337 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000338 assert(image_view->signature == MagickCoreSignature);
cristy4c08aed2011-07-01 19:47:50 +0000339 return(GetCacheViewAuthenticMetacontent(image_view->view));
cristycc34c492010-06-26 23:49:12 +0000340}
341
342/*
343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344% %
345% %
346% %
347% 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 %
348% %
349% %
350% %
351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
352%
cristy73b7d4c2010-06-27 00:31:00 +0000353% GetImageViewAuthenticPixels() returns the image view authentic pixels.
cristycc34c492010-06-26 23:49:12 +0000354%
355% The format of the GetImageViewAuthenticPixels method is:
356%
cristy4c08aed2011-07-01 19:47:50 +0000357% Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000358%
359% A description of each parameter follows:
360%
cristy73b7d4c2010-06-27 00:31:00 +0000361% o image_view: the image view.
cristycc34c492010-06-26 23:49:12 +0000362%
363*/
cristy4c08aed2011-07-01 19:47:50 +0000364MagickExport Quantum *GetImageViewAuthenticPixels(
cristy73b7d4c2010-06-27 00:31:00 +0000365 const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000366{
cristy73b7d4c2010-06-27 00:31:00 +0000367 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000368 assert(image_view->signature == MagickCoreSignature);
cristy73b7d4c2010-06-27 00:31:00 +0000369 return(GetCacheViewAuthenticPixelQueue(image_view->view));
cristycc34c492010-06-26 23:49:12 +0000370}
371
372/*
373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374% %
375% %
376% %
cristy7eb1b7a2010-06-26 15:47:49 +0000377% G e t I m a g e V i e w E x c e p t i o n %
cristy3ed852e2009-09-05 21:47:34 +0000378% %
379% %
380% %
381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382%
cristy7eb1b7a2010-06-26 15:47:49 +0000383% GetImageViewException() returns the severity, reason, and description of any
cristy73b7d4c2010-06-27 00:31:00 +0000384% error that occurs when utilizing a image view.
cristy3ed852e2009-09-05 21:47:34 +0000385%
cristy7eb1b7a2010-06-26 15:47:49 +0000386% The format of the GetImageViewException method is:
cristy3ed852e2009-09-05 21:47:34 +0000387%
cristy73b7d4c2010-06-27 00:31:00 +0000388% char *GetImageViewException(const PixelImage *image_view,
cristy3ed852e2009-09-05 21:47:34 +0000389% ExceptionType *severity)
390%
391% A description of each parameter follows:
392%
cristy73b7d4c2010-06-27 00:31:00 +0000393% o image_view: the pixel image_view.
cristy3ed852e2009-09-05 21:47:34 +0000394%
395% o severity: the severity of the error is returned here.
396%
397*/
cristy73b7d4c2010-06-27 00:31:00 +0000398MagickExport char *GetImageViewException(const ImageView *image_view,
cristy3ed852e2009-09-05 21:47:34 +0000399 ExceptionType *severity)
400{
401 char
402 *description;
403
cristy73b7d4c2010-06-27 00:31:00 +0000404 assert(image_view != (const ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000405 assert(image_view->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000406 assert(severity != (ExceptionType *) NULL);
cristy73b7d4c2010-06-27 00:31:00 +0000407 *severity=image_view->exception->severity;
cristy151b66d2015-04-15 10:50:31 +0000408 description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +0000409 sizeof(*description));
410 if (description == (char *) NULL)
cristy7eb1b7a2010-06-26 15:47:49 +0000411 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000412 *description='\0';
cristy73b7d4c2010-06-27 00:31:00 +0000413 if (image_view->exception->reason != (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000414 (void) CopyMagickString(description,GetLocaleExceptionMessage(
cristy73b7d4c2010-06-27 00:31:00 +0000415 image_view->exception->severity,image_view->exception->reason),
cristy151b66d2015-04-15 10:50:31 +0000416 MagickPathExtent);
cristy73b7d4c2010-06-27 00:31:00 +0000417 if (image_view->exception->description != (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000418 {
cristy151b66d2015-04-15 10:50:31 +0000419 (void) ConcatenateMagickString(description," (",MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +0000420 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
cristy73b7d4c2010-06-27 00:31:00 +0000421 image_view->exception->severity,image_view->exception->description),
cristy151b66d2015-04-15 10:50:31 +0000422 MagickPathExtent);
423 (void) ConcatenateMagickString(description,")",MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +0000424 }
425 return(description);
426}
427
428/*
429%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430% %
431% %
432% %
cristyc3ebda22010-06-27 17:11:57 +0000433% G e t I m a g e V i e w E x t e n t %
cristy3ed852e2009-09-05 21:47:34 +0000434% %
435% %
436% %
437%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438%
cristyc3ebda22010-06-27 17:11:57 +0000439% GetImageViewExtent() returns the image view extent.
cristy3ed852e2009-09-05 21:47:34 +0000440%
cristyc3ebda22010-06-27 17:11:57 +0000441% The format of the GetImageViewExtent method is:
cristy3ed852e2009-09-05 21:47:34 +0000442%
cristyc3ebda22010-06-27 17:11:57 +0000443% RectangleInfo GetImageViewExtent(const ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +0000444%
445% A description of each parameter follows:
446%
cristy73b7d4c2010-06-27 00:31:00 +0000447% o image_view: the image view.
cristy3ed852e2009-09-05 21:47:34 +0000448%
449*/
cristyc3ebda22010-06-27 17:11:57 +0000450MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +0000451{
cristy73b7d4c2010-06-27 00:31:00 +0000452 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000453 assert(image_view->signature == MagickCoreSignature);
cristyc3ebda22010-06-27 17:11:57 +0000454 return(image_view->extent);
cristy73b7d4c2010-06-27 00:31:00 +0000455}
456
457/*
458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459% %
460% %
461% %
462% G e t I m a g e V i e w I m a g e %
463% %
464% %
465% %
466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
467%
468% GetImageViewImage() returns the image associated with the image view.
469%
470% The format of the GetImageViewImage method is:
471%
472% MagickCore *GetImageViewImage(const ImageView *image_view)
473%
474% A description of each parameter follows:
475%
476% o image_view: the image view.
477%
478*/
479MagickExport Image *GetImageViewImage(const ImageView *image_view)
480{
481 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000482 assert(image_view->signature == MagickCoreSignature);
cristy73b7d4c2010-06-27 00:31:00 +0000483 return(image_view->image);
cristy3ed852e2009-09-05 21:47:34 +0000484}
485
486/*
487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488% %
489% %
490% %
cristy7eb1b7a2010-06-26 15:47:49 +0000491% G e t I m a g e V i e w I t e r a t o r %
cristy3ed852e2009-09-05 21:47:34 +0000492% %
493% %
494% %
495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496%
cristy73b7d4c2010-06-27 00:31:00 +0000497% GetImageViewIterator() iterates over the image view in parallel and calls
cristyc3ebda22010-06-27 17:11:57 +0000498% your get method for each scanline of the view. The pixel extent is
cristy3ed852e2009-09-05 21:47:34 +0000499% not confined to the image canvas-- that is you can include negative offsets
500% or widths or heights that exceed the image dimension. Any updates to
501% the pixels in your callback are ignored.
502%
cristyd6dfc0d2010-06-27 19:30:49 +0000503% The callback signature is:
504%
505% MagickBooleanType GetImageViewMethod(const ImageView *source,
506% const ssize_t y,const int thread_id,void *context)
507%
cristy58739472010-06-26 20:27:18 +0000508% Use this pragma if the view is not single threaded:
cristy3ed852e2009-09-05 21:47:34 +0000509%
510% #pragma omp critical
511%
512% to define a section of code in your callback get method that must be
513% executed by a single thread at a time.
514%
cristy7eb1b7a2010-06-26 15:47:49 +0000515% The format of the GetImageViewIterator method is:
cristy3ed852e2009-09-05 21:47:34 +0000516%
cristy7eb1b7a2010-06-26 15:47:49 +0000517% MagickBooleanType GetImageViewIterator(ImageView *source,
518% GetImageViewMethod get,void *context)
cristy3ed852e2009-09-05 21:47:34 +0000519%
520% A description of each parameter follows:
521%
cristy73b7d4c2010-06-27 00:31:00 +0000522% o source: the source image view.
cristy3ed852e2009-09-05 21:47:34 +0000523%
524% o get: the get callback method.
525%
526% o context: the user defined context.
527%
528*/
cristy7eb1b7a2010-06-26 15:47:49 +0000529MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
530 GetImageViewMethod get,void *context)
cristy3ed852e2009-09-05 21:47:34 +0000531{
cristy3ed852e2009-09-05 21:47:34 +0000532 Image
533 *source_image;
534
cristy3ed852e2009-09-05 21:47:34 +0000535 MagickBooleanType
536 status;
537
cristycee97112010-05-28 00:44:52 +0000538 MagickOffsetType
539 progress;
540
glennrp37618d62012-09-24 17:24:13 +0000541#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000542 size_t
cristy26b64912012-12-16 18:20:09 +0000543 height;
glennrp37618d62012-09-24 17:24:13 +0000544#endif
cristyac245f82012-05-05 17:13:57 +0000545
cristycee97112010-05-28 00:44:52 +0000546 ssize_t
547 y;
548
cristy7eb1b7a2010-06-26 15:47:49 +0000549 assert(source != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000550 assert(source->signature == MagickCoreSignature);
cristy7eb1b7a2010-06-26 15:47:49 +0000551 if (get == (GetImageViewMethod) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000552 return(MagickFalse);
cristy7eb1b7a2010-06-26 15:47:49 +0000553 source_image=source->image;
cristy3ed852e2009-09-05 21:47:34 +0000554 status=MagickTrue;
555 progress=0;
glennrp9d9f0e52012-09-24 18:13:12 +0000556#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000557 height=source->extent.height-source->extent.y;
cristy9a5a52f2012-10-09 14:40:31 +0000558 #pragma omp parallel for schedule(static,4) shared(progress,status) \
cristy5e6b2592012-12-19 14:08:11 +0000559 magick_threads(source_image,source_image,height,1)
cristy3ed852e2009-09-05 21:47:34 +0000560#endif
cristyc3ebda22010-06-27 17:11:57 +0000561 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000562 {
cristy5c9e6f22010-09-17 17:31:01 +0000563 const int
564 id = GetOpenMPThreadId();
cristyad740052010-07-03 01:38:03 +0000565
cristy4c08aed2011-07-01 19:47:50 +0000566 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +0000567 *pixels;
568
cristy3ed852e2009-09-05 21:47:34 +0000569 if (status == MagickFalse)
570 continue;
cristyc3ebda22010-06-27 17:11:57 +0000571 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
572 source->extent.width,1,source->exception);
cristy4c08aed2011-07-01 19:47:50 +0000573 if (pixels == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000574 {
575 status=MagickFalse;
576 continue;
577 }
cristyd6dfc0d2010-06-27 19:30:49 +0000578 if (get(source,y,id,context) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000579 status=MagickFalse;
580 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
581 {
582 MagickBooleanType
583 proceed;
584
cristyb5d5f722009-11-04 03:03:49 +0000585#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000586 #pragma omp critical (MagickCore_GetImageViewIterator)
cristy3ed852e2009-09-05 21:47:34 +0000587#endif
cristyc3ebda22010-06-27 17:11:57 +0000588 proceed=SetImageProgress(source_image,source->description,progress++,
589 source->extent.height);
cristy3ed852e2009-09-05 21:47:34 +0000590 if (proceed == MagickFalse)
591 status=MagickFalse;
592 }
593 }
594 return(status);
595}
596
597/*
598%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
599% %
600% %
601% %
cristy4c08aed2011-07-01 19:47:50 +0000602% 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 %
cristycc34c492010-06-26 23:49:12 +0000603% %
604% %
605% %
606%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
607%
cristy4c08aed2011-07-01 19:47:50 +0000608% GetImageViewVirtualMetacontent() returns the image view virtual
609% meta-content.
cristycc34c492010-06-26 23:49:12 +0000610%
cristy4c08aed2011-07-01 19:47:50 +0000611% The format of the GetImageViewVirtualMetacontent method is:
cristycc34c492010-06-26 23:49:12 +0000612%
cristy4c08aed2011-07-01 19:47:50 +0000613% const void *GetImageViewVirtualMetacontent(
cristy73b7d4c2010-06-27 00:31:00 +0000614% const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000615%
616% A description of each parameter follows:
617%
cristy73b7d4c2010-06-27 00:31:00 +0000618% o image_view: the image view.
cristycc34c492010-06-26 23:49:12 +0000619%
620*/
cristy4c08aed2011-07-01 19:47:50 +0000621MagickExport const void *GetImageViewVirtualMetacontent(
cristy73b7d4c2010-06-27 00:31:00 +0000622 const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000623{
cristy73b7d4c2010-06-27 00:31:00 +0000624 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000625 assert(image_view->signature == MagickCoreSignature);
cristy4c08aed2011-07-01 19:47:50 +0000626 return(GetCacheViewVirtualMetacontent(image_view->view));
cristycc34c492010-06-26 23:49:12 +0000627}
628
629/*
630%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
631% %
632% %
633% %
634% 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 %
635% %
636% %
637% %
638%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639%
cristy73b7d4c2010-06-27 00:31:00 +0000640% GetImageViewVirtualPixels() returns the image view virtual pixels.
cristycc34c492010-06-26 23:49:12 +0000641%
642% The format of the GetImageViewVirtualPixels method is:
643%
cristy4c08aed2011-07-01 19:47:50 +0000644% const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000645%
646% A description of each parameter follows:
647%
cristy73b7d4c2010-06-27 00:31:00 +0000648% o image_view: the image view.
cristycc34c492010-06-26 23:49:12 +0000649%
650*/
cristy4c08aed2011-07-01 19:47:50 +0000651MagickExport const Quantum *GetImageViewVirtualPixels(
cristy73b7d4c2010-06-27 00:31:00 +0000652 const ImageView *image_view)
cristycc34c492010-06-26 23:49:12 +0000653{
cristy73b7d4c2010-06-27 00:31:00 +0000654 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000655 assert(image_view->signature == MagickCoreSignature);
cristy73b7d4c2010-06-27 00:31:00 +0000656 return(GetCacheViewVirtualPixelQueue(image_view->view));
cristycc34c492010-06-26 23:49:12 +0000657}
658
659/*
660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
661% %
662% %
663% %
cristy7eb1b7a2010-06-26 15:47:49 +0000664% I s I m a g e V i e w %
cristy3ed852e2009-09-05 21:47:34 +0000665% %
666% %
667% %
668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
669%
cristy73b7d4c2010-06-27 00:31:00 +0000670% IsImageView() returns MagickTrue if the the parameter is verified as a image
671% view object.
cristy3ed852e2009-09-05 21:47:34 +0000672%
cristy7eb1b7a2010-06-26 15:47:49 +0000673% The format of the IsImageView method is:
cristy3ed852e2009-09-05 21:47:34 +0000674%
cristy73b7d4c2010-06-27 00:31:00 +0000675% MagickBooleanType IsImageView(const ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +0000676%
677% A description of each parameter follows:
678%
cristy73b7d4c2010-06-27 00:31:00 +0000679% o image_view: the image view.
cristy3ed852e2009-09-05 21:47:34 +0000680%
681*/
cristy73b7d4c2010-06-27 00:31:00 +0000682MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
cristy3ed852e2009-09-05 21:47:34 +0000683{
cristy73b7d4c2010-06-27 00:31:00 +0000684 if (image_view == (const ImageView *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000685 return(MagickFalse);
cristye1c94d92015-06-28 12:16:33 +0000686 if (image_view->signature != MagickCoreSignature)
cristy3ed852e2009-09-05 21:47:34 +0000687 return(MagickFalse);
688 return(MagickTrue);
689}
690
691/*
692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
693% %
694% %
695% %
cristy7eb1b7a2010-06-26 15:47:49 +0000696% N e w I m a g e V i e w %
cristy3ed852e2009-09-05 21:47:34 +0000697% %
698% %
699% %
700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701%
cristy73b7d4c2010-06-27 00:31:00 +0000702% NewImageView() returns a image view required for all other methods in the
703% Image View API.
cristy3ed852e2009-09-05 21:47:34 +0000704%
cristy7eb1b7a2010-06-26 15:47:49 +0000705% The format of the NewImageView method is:
cristy3ed852e2009-09-05 21:47:34 +0000706%
cristydb070952012-04-20 14:33:00 +0000707% ImageView *NewImageView(MagickCore *wand,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000708%
709% A description of each parameter follows:
710%
cristydb070952012-04-20 14:33:00 +0000711% o image: the image.
712%
713% o exception: return any errors or warnings in this structure.
cristy3ed852e2009-09-05 21:47:34 +0000714%
715*/
cristydb070952012-04-20 14:33:00 +0000716MagickExport ImageView *NewImageView(Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000717{
cristy7eb1b7a2010-06-26 15:47:49 +0000718 ImageView
cristy73b7d4c2010-06-27 00:31:00 +0000719 *image_view;
cristy3ed852e2009-09-05 21:47:34 +0000720
cristy7eb1b7a2010-06-26 15:47:49 +0000721 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000722 assert(image->signature == MagickCoreSignature);
cristy73bd4a52010-10-05 11:24:23 +0000723 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
cristy73b7d4c2010-06-27 00:31:00 +0000724 if (image_view == (ImageView *) NULL)
cristy7eb1b7a2010-06-26 15:47:49 +0000725 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy73b7d4c2010-06-27 00:31:00 +0000726 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
cristyc3ebda22010-06-27 17:11:57 +0000727 image_view->description=ConstantString("ImageView");
cristy73b7d4c2010-06-27 00:31:00 +0000728 image_view->image=image;
cristy46ff2672012-12-14 15:32:26 +0000729 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
cristyc3ebda22010-06-27 17:11:57 +0000730 image_view->extent.width=image->columns;
731 image_view->extent.height=image->rows;
732 image_view->extent.x=0;
733 image_view->extent.y=0;
cristyc3ebda22010-06-27 17:11:57 +0000734 image_view->exception=AcquireExceptionInfo();
cristy73b7d4c2010-06-27 00:31:00 +0000735 image_view->debug=IsEventLogging();
cristye1c94d92015-06-28 12:16:33 +0000736 image_view->signature=MagickCoreSignature;
cristy73b7d4c2010-06-27 00:31:00 +0000737 return(image_view);
cristy3ed852e2009-09-05 21:47:34 +0000738}
739
740/*
741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742% %
743% %
744% %
cristy7eb1b7a2010-06-26 15:47:49 +0000745% N e w I m a g e V i e w R e g i o n %
cristy3ed852e2009-09-05 21:47:34 +0000746% %
747% %
748% %
749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
750%
cristy73b7d4c2010-06-27 00:31:00 +0000751% NewImageViewRegion() returns a image view required for all other methods
752% in the Image View API.
cristy3ed852e2009-09-05 21:47:34 +0000753%
cristy7eb1b7a2010-06-26 15:47:49 +0000754% The format of the NewImageViewRegion method is:
cristy3ed852e2009-09-05 21:47:34 +0000755%
cristy7eb1b7a2010-06-26 15:47:49 +0000756% ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
cristydb070952012-04-20 14:33:00 +0000757% const ssize_t y,const size_t width,const size_t height,
758% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000759%
760% A description of each parameter follows:
761%
762% o wand: the magick wand.
763%
cristyc3ebda22010-06-27 17:11:57 +0000764% o x,y,columns,rows: These values define the perimeter of a extent of
cristy3ed852e2009-09-05 21:47:34 +0000765% pixel_wands view.
766%
cristydb070952012-04-20 14:33:00 +0000767% o exception: return any errors or warnings in this structure.
768%
cristy3ed852e2009-09-05 21:47:34 +0000769*/
cristy7eb1b7a2010-06-26 15:47:49 +0000770MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
cristydb070952012-04-20 14:33:00 +0000771 const ssize_t y,const size_t width,const size_t height,
772 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000773{
cristy7eb1b7a2010-06-26 15:47:49 +0000774 ImageView
cristy73b7d4c2010-06-27 00:31:00 +0000775 *image_view;
cristy3ed852e2009-09-05 21:47:34 +0000776
cristy7eb1b7a2010-06-26 15:47:49 +0000777 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000778 assert(image->signature == MagickCoreSignature);
cristy73bd4a52010-10-05 11:24:23 +0000779 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
cristy73b7d4c2010-06-27 00:31:00 +0000780 if (image_view == (ImageView *) NULL)
cristy7eb1b7a2010-06-26 15:47:49 +0000781 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy73b7d4c2010-06-27 00:31:00 +0000782 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
cristyc3ebda22010-06-27 17:11:57 +0000783 image_view->description=ConstantString("ImageView");
cristy46ff2672012-12-14 15:32:26 +0000784 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
cristy73b7d4c2010-06-27 00:31:00 +0000785 image_view->image=image;
cristyc3ebda22010-06-27 17:11:57 +0000786 image_view->extent.width=width;
787 image_view->extent.height=height;
788 image_view->extent.x=x;
789 image_view->extent.y=y;
cristyc3ebda22010-06-27 17:11:57 +0000790 image_view->exception=AcquireExceptionInfo();
cristy73b7d4c2010-06-27 00:31:00 +0000791 image_view->debug=IsEventLogging();
cristye1c94d92015-06-28 12:16:33 +0000792 image_view->signature=MagickCoreSignature;
cristy73b7d4c2010-06-27 00:31:00 +0000793 return(image_view);
cristy3ed852e2009-09-05 21:47:34 +0000794}
795
796/*
797%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798% %
799% %
800% %
cristyc3ebda22010-06-27 17:11:57 +0000801% S e t I m a g e V i e w D e s c r i p t i o n %
802% %
803% %
804% %
805%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
806%
807% SetImageViewDescription() associates a description with an image view.
808%
809% The format of the SetImageViewDescription method is:
810%
811% void SetImageViewDescription(ImageView *image_view,
812% const char *description)
813%
814% A description of each parameter follows:
815%
816% o image_view: the image view.
817%
818% o description: the image view description.
819%
820*/
821MagickExport void SetImageViewDescription(ImageView *image_view,
822 const char *description)
823{
824 assert(image_view != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000825 assert(image_view->signature == MagickCoreSignature);
cristyc3ebda22010-06-27 17:11:57 +0000826 image_view->description=ConstantString(description);
827}
828
829/*
830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831% %
832% %
833% %
cristy7eb1b7a2010-06-26 15:47:49 +0000834% S e t I m a g e V i e w I t e r a t o r %
cristy3ed852e2009-09-05 21:47:34 +0000835% %
836% %
837% %
838%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
839%
cristy73b7d4c2010-06-27 00:31:00 +0000840% SetImageViewIterator() iterates over the image view in parallel and calls
cristyc3ebda22010-06-27 17:11:57 +0000841% your set method for each scanline of the view. The pixel extent is
cristy3ed852e2009-09-05 21:47:34 +0000842% confined to the image canvas-- that is no negative offsets or widths or
843% heights that exceed the image dimension. The pixels are initiallly
844% undefined and any settings you make in the callback method are automagically
845% synced back to your image.
846%
cristyd6dfc0d2010-06-27 19:30:49 +0000847% The callback signature is:
848%
849% MagickBooleanType SetImageViewMethod(ImageView *destination,
850% const ssize_t y,const int thread_id,void *context)
851%
cristy58739472010-06-26 20:27:18 +0000852% Use this pragma if the view is not single threaded:
cristy3ed852e2009-09-05 21:47:34 +0000853%
854% #pragma omp critical
855%
856% to define a section of code in your callback set method that must be
857% executed by a single thread at a time.
858%
cristy7eb1b7a2010-06-26 15:47:49 +0000859% The format of the SetImageViewIterator method is:
cristy3ed852e2009-09-05 21:47:34 +0000860%
cristy7eb1b7a2010-06-26 15:47:49 +0000861% MagickBooleanType SetImageViewIterator(ImageView *destination,
862% SetImageViewMethod set,void *context)
cristy3ed852e2009-09-05 21:47:34 +0000863%
864% A description of each parameter follows:
865%
cristy73b7d4c2010-06-27 00:31:00 +0000866% o destination: the image view.
cristy3ed852e2009-09-05 21:47:34 +0000867%
868% o set: the set callback method.
869%
870% o context: the user defined context.
871%
872*/
cristy7eb1b7a2010-06-26 15:47:49 +0000873MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
874 SetImageViewMethod set,void *context)
cristy3ed852e2009-09-05 21:47:34 +0000875{
cristy3ed852e2009-09-05 21:47:34 +0000876 Image
877 *destination_image;
878
cristy3ed852e2009-09-05 21:47:34 +0000879 MagickBooleanType
880 status;
881
cristycee97112010-05-28 00:44:52 +0000882 MagickOffsetType
883 progress;
884
glennrp37618d62012-09-24 17:24:13 +0000885#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000886 size_t
cristy26b64912012-12-16 18:20:09 +0000887 height;
glennrp37618d62012-09-24 17:24:13 +0000888#endif
cristyac245f82012-05-05 17:13:57 +0000889
cristycee97112010-05-28 00:44:52 +0000890 ssize_t
891 y;
892
cristy7eb1b7a2010-06-26 15:47:49 +0000893 assert(destination != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000894 assert(destination->signature == MagickCoreSignature);
cristy7eb1b7a2010-06-26 15:47:49 +0000895 if (set == (SetImageViewMethod) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000896 return(MagickFalse);
cristy7eb1b7a2010-06-26 15:47:49 +0000897 destination_image=destination->image;
cristy7c3af952011-10-20 16:04:16 +0000898 status=SetImageStorageClass(destination_image,DirectClass,
899 destination->exception);
900 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000901 return(MagickFalse);
902 status=MagickTrue;
903 progress=0;
glennrp37618d62012-09-24 17:24:13 +0000904#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000905 height=destination->extent.height-destination->extent.y;
cristy9a5a52f2012-10-09 14:40:31 +0000906 #pragma omp parallel for schedule(static,4) shared(progress,status) \
cristy5e6b2592012-12-19 14:08:11 +0000907 magick_threads(destination_image,destination_image,height,1)
cristy3ed852e2009-09-05 21:47:34 +0000908#endif
cristyc3ebda22010-06-27 17:11:57 +0000909 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
cristy3ed852e2009-09-05 21:47:34 +0000910 {
cristy5c9e6f22010-09-17 17:31:01 +0000911 const int
912 id = GetOpenMPThreadId();
cristyad740052010-07-03 01:38:03 +0000913
cristy3ed852e2009-09-05 21:47:34 +0000914 MagickBooleanType
915 sync;
916
cristy4c08aed2011-07-01 19:47:50 +0000917 register Quantum
dirk05d2ff72015-11-18 23:13:43 +0100918 *magick_restrict pixels;
cristy3ed852e2009-09-05 21:47:34 +0000919
920 if (status == MagickFalse)
921 continue;
cristyc3ebda22010-06-27 17:11:57 +0000922 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
cristy7c3af952011-10-20 16:04:16 +0000923 y,destination->extent.width,1,destination->exception);
cristy4c08aed2011-07-01 19:47:50 +0000924 if (pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000925 {
cristy3ed852e2009-09-05 21:47:34 +0000926 status=MagickFalse;
927 continue;
928 }
cristyd6dfc0d2010-06-27 19:30:49 +0000929 if (set(destination,y,id,context) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000930 status=MagickFalse;
cristy7c3af952011-10-20 16:04:16 +0000931 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
cristy3ed852e2009-09-05 21:47:34 +0000932 if (sync == MagickFalse)
cristy7c3af952011-10-20 16:04:16 +0000933 status=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +0000934 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
935 {
936 MagickBooleanType
937 proceed;
938
cristyb5d5f722009-11-04 03:03:49 +0000939#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +0000940 #pragma omp critical (MagickCore_SetImageViewIterator)
cristy3ed852e2009-09-05 21:47:34 +0000941#endif
cristyc3ebda22010-06-27 17:11:57 +0000942 proceed=SetImageProgress(destination_image,destination->description,
943 progress++,destination->extent.height);
cristy3ed852e2009-09-05 21:47:34 +0000944 if (proceed == MagickFalse)
945 status=MagickFalse;
946 }
947 }
948 return(status);
949}
950
951/*
952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953% %
954% %
955% %
cristy7eb1b7a2010-06-26 15:47:49 +0000956% 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 %
cristy3ed852e2009-09-05 21:47:34 +0000957% %
958% %
959% %
960%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961%
cristy73b7d4c2010-06-27 00:31:00 +0000962% TransferImageViewIterator() iterates over two image views in parallel and
cristy3ed852e2009-09-05 21:47:34 +0000963% calls your transfer method for each scanline of the view. The source pixel
cristyc3ebda22010-06-27 17:11:57 +0000964% extent is not confined to the image canvas-- that is you can include
cristy3ed852e2009-09-05 21:47:34 +0000965% negative offsets or widths or heights that exceed the image dimension.
cristy73b7d4c2010-06-27 00:31:00 +0000966% However, the destination image view is confined to the image canvas-- that
cristy3ed852e2009-09-05 21:47:34 +0000967% is no negative offsets or widths or heights that exceed the image dimension
968% are permitted.
969%
cristyd6dfc0d2010-06-27 19:30:49 +0000970% The callback signature is:
971%
972% MagickBooleanType TransferImageViewMethod(const ImageView *source,
973% ImageView *destination,const ssize_t y,const int thread_id,
974% void *context)
975%
cristy58739472010-06-26 20:27:18 +0000976% Use this pragma if the view is not single threaded:
cristy3ed852e2009-09-05 21:47:34 +0000977%
978% #pragma omp critical
979%
980% to define a section of code in your callback transfer method that must be
981% executed by a single thread at a time.
982%
cristy7eb1b7a2010-06-26 15:47:49 +0000983% The format of the TransferImageViewIterator method is:
cristy3ed852e2009-09-05 21:47:34 +0000984%
cristy7eb1b7a2010-06-26 15:47:49 +0000985% MagickBooleanType TransferImageViewIterator(ImageView *source,
986% ImageView *destination,TransferImageViewMethod transfer,void *context)
cristy3ed852e2009-09-05 21:47:34 +0000987%
988% A description of each parameter follows:
989%
cristy73b7d4c2010-06-27 00:31:00 +0000990% o source: the source image view.
cristy3ed852e2009-09-05 21:47:34 +0000991%
cristy73b7d4c2010-06-27 00:31:00 +0000992% o destination: the destination image view.
cristy3ed852e2009-09-05 21:47:34 +0000993%
994% o transfer: the transfer callback method.
995%
996% o context: the user defined context.
997%
998*/
cristy7eb1b7a2010-06-26 15:47:49 +0000999MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1000 ImageView *destination,TransferImageViewMethod transfer,void *context)
cristy3ed852e2009-09-05 21:47:34 +00001001{
cristy3ed852e2009-09-05 21:47:34 +00001002 Image
1003 *destination_image,
1004 *source_image;
1005
cristy3ed852e2009-09-05 21:47:34 +00001006 MagickBooleanType
1007 status;
1008
cristycee97112010-05-28 00:44:52 +00001009 MagickOffsetType
1010 progress;
1011
glennrp37618d62012-09-24 17:24:13 +00001012#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +00001013 size_t
cristy26b64912012-12-16 18:20:09 +00001014 height;
glennrp37618d62012-09-24 17:24:13 +00001015#endif
cristyac245f82012-05-05 17:13:57 +00001016
cristycee97112010-05-28 00:44:52 +00001017 ssize_t
1018 y;
1019
cristy7eb1b7a2010-06-26 15:47:49 +00001020 assert(source != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001021 assert(source->signature == MagickCoreSignature);
cristy7eb1b7a2010-06-26 15:47:49 +00001022 if (transfer == (TransferImageViewMethod) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001023 return(MagickFalse);
cristy7eb1b7a2010-06-26 15:47:49 +00001024 source_image=source->image;
1025 destination_image=destination->image;
cristy7c3af952011-10-20 16:04:16 +00001026 status=SetImageStorageClass(destination_image,DirectClass,
1027 destination->exception);
1028 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001029 return(MagickFalse);
1030 status=MagickTrue;
1031 progress=0;
glennrp37618d62012-09-24 17:24:13 +00001032#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +00001033 height=source->extent.height-source->extent.y;
cristy9a5a52f2012-10-09 14:40:31 +00001034 #pragma omp parallel for schedule(static,4) shared(progress,status) \
cristy5e6b2592012-12-19 14:08:11 +00001035 magick_threads(source_image,destination_image,height,1)
cristy3ed852e2009-09-05 21:47:34 +00001036#endif
cristyc3ebda22010-06-27 17:11:57 +00001037 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
cristy3ed852e2009-09-05 21:47:34 +00001038 {
cristy5c9e6f22010-09-17 17:31:01 +00001039 const int
1040 id = GetOpenMPThreadId();
cristyad740052010-07-03 01:38:03 +00001041
cristy3ed852e2009-09-05 21:47:34 +00001042 MagickBooleanType
1043 sync;
1044
cristy4c08aed2011-07-01 19:47:50 +00001045 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001046 *magick_restrict pixels;
cristy3ed852e2009-09-05 21:47:34 +00001047
cristy4c08aed2011-07-01 19:47:50 +00001048 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01001049 *magick_restrict destination_pixels;
cristy3ed852e2009-09-05 21:47:34 +00001050
1051 if (status == MagickFalse)
1052 continue;
cristyc3ebda22010-06-27 17:11:57 +00001053 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1054 source->extent.width,1,source->exception);
cristy4c08aed2011-07-01 19:47:50 +00001055 if (pixels == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001056 {
1057 status=MagickFalse;
1058 continue;
1059 }
cristy3ed852e2009-09-05 21:47:34 +00001060 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
cristy7c3af952011-10-20 16:04:16 +00001061 destination->extent.x,y,destination->extent.width,1,
1062 destination->exception);
cristy4c08aed2011-07-01 19:47:50 +00001063 if (destination_pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001064 {
1065 status=MagickFalse;
1066 continue;
1067 }
cristyc3ebda22010-06-27 17:11:57 +00001068 if (transfer(source,destination,y,id,context) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001069 status=MagickFalse;
cristy7c3af952011-10-20 16:04:16 +00001070 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
cristy3ed852e2009-09-05 21:47:34 +00001071 if (sync == MagickFalse)
cristy7c3af952011-10-20 16:04:16 +00001072 status=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001073 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1074 {
1075 MagickBooleanType
1076 proceed;
1077
cristyb5d5f722009-11-04 03:03:49 +00001078#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +00001079 #pragma omp critical (MagickCore_TransferImageViewIterator)
cristy3ed852e2009-09-05 21:47:34 +00001080#endif
cristyc3ebda22010-06-27 17:11:57 +00001081 proceed=SetImageProgress(source_image,source->description,progress++,
1082 source->extent.height);
cristy3ed852e2009-09-05 21:47:34 +00001083 if (proceed == MagickFalse)
1084 status=MagickFalse;
1085 }
1086 }
1087 return(status);
1088}
1089
1090/*
1091%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1092% %
1093% %
1094% %
cristy7eb1b7a2010-06-26 15:47:49 +00001095% U p d a t e I m a g e V i e w I t e r a t o r %
cristy3ed852e2009-09-05 21:47:34 +00001096% %
1097% %
1098% %
1099%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1100%
cristy73b7d4c2010-06-27 00:31:00 +00001101% UpdateImageViewIterator() iterates over the image view in parallel and calls
cristyc3ebda22010-06-27 17:11:57 +00001102% your update method for each scanline of the view. The pixel extent is
cristy3ed852e2009-09-05 21:47:34 +00001103% confined to the image canvas-- that is no negative offsets or widths or
1104% heights that exceed the image dimension are permitted. Updates to pixels
1105% in your callback are automagically synced back to the image.
1106%
cristyd6dfc0d2010-06-27 19:30:49 +00001107% The callback signature is:
1108%
1109% MagickBooleanType UpdateImageViewMethod(ImageView *source,
1110% const ssize_t y,const int thread_id,void *context)
1111%
cristy58739472010-06-26 20:27:18 +00001112% Use this pragma if the view is not single threaded:
cristy3ed852e2009-09-05 21:47:34 +00001113%
1114% #pragma omp critical
1115%
1116% to define a section of code in your callback update method that must be
1117% executed by a single thread at a time.
1118%
cristy7eb1b7a2010-06-26 15:47:49 +00001119% The format of the UpdateImageViewIterator method is:
cristy3ed852e2009-09-05 21:47:34 +00001120%
cristy7eb1b7a2010-06-26 15:47:49 +00001121% MagickBooleanType UpdateImageViewIterator(ImageView *source,
1122% UpdateImageViewMethod update,void *context)
cristy3ed852e2009-09-05 21:47:34 +00001123%
1124% A description of each parameter follows:
1125%
cristy73b7d4c2010-06-27 00:31:00 +00001126% o source: the source image view.
cristy3ed852e2009-09-05 21:47:34 +00001127%
1128% o update: the update callback method.
1129%
1130% o context: the user defined context.
1131%
1132*/
cristy7eb1b7a2010-06-26 15:47:49 +00001133MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1134 UpdateImageViewMethod update,void *context)
cristy3ed852e2009-09-05 21:47:34 +00001135{
cristy3ed852e2009-09-05 21:47:34 +00001136 Image
1137 *source_image;
1138
cristy3ed852e2009-09-05 21:47:34 +00001139 MagickBooleanType
1140 status;
1141
cristycee97112010-05-28 00:44:52 +00001142 MagickOffsetType
1143 progress;
1144
glennrp37618d62012-09-24 17:24:13 +00001145#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +00001146 size_t
cristy26b64912012-12-16 18:20:09 +00001147 height;
glennrp37618d62012-09-24 17:24:13 +00001148#endif
cristyac245f82012-05-05 17:13:57 +00001149
cristycee97112010-05-28 00:44:52 +00001150 ssize_t
1151 y;
1152
cristy7eb1b7a2010-06-26 15:47:49 +00001153 assert(source != (ImageView *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001154 assert(source->signature == MagickCoreSignature);
cristy7eb1b7a2010-06-26 15:47:49 +00001155 if (update == (UpdateImageViewMethod) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001156 return(MagickFalse);
cristy7eb1b7a2010-06-26 15:47:49 +00001157 source_image=source->image;
cristy7c3af952011-10-20 16:04:16 +00001158 status=SetImageStorageClass(source_image,DirectClass,source->exception);
1159 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001160 return(MagickFalse);
1161 status=MagickTrue;
1162 progress=0;
glennrp37618d62012-09-24 17:24:13 +00001163#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +00001164 height=source->extent.height-source->extent.y;
cristy9a5a52f2012-10-09 14:40:31 +00001165 #pragma omp parallel for schedule(static,4) shared(progress,status) \
cristy5e6b2592012-12-19 14:08:11 +00001166 magick_threads(source_image,source_image,height,1)
cristy3ed852e2009-09-05 21:47:34 +00001167#endif
cristyc3ebda22010-06-27 17:11:57 +00001168 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
cristy3ed852e2009-09-05 21:47:34 +00001169 {
cristy5c9e6f22010-09-17 17:31:01 +00001170 const int
1171 id = GetOpenMPThreadId();
cristyad740052010-07-03 01:38:03 +00001172
cristy4c08aed2011-07-01 19:47:50 +00001173 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01001174 *magick_restrict pixels;
cristy3ed852e2009-09-05 21:47:34 +00001175
1176 if (status == MagickFalse)
1177 continue;
cristyc3ebda22010-06-27 17:11:57 +00001178 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
cristy7c3af952011-10-20 16:04:16 +00001179 source->extent.width,1,source->exception);
cristy4c08aed2011-07-01 19:47:50 +00001180 if (pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00001181 {
cristy3ed852e2009-09-05 21:47:34 +00001182 status=MagickFalse;
1183 continue;
1184 }
cristyc3ebda22010-06-27 17:11:57 +00001185 if (update(source,y,id,context) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001186 status=MagickFalse;
cristy7c3af952011-10-20 16:04:16 +00001187 status=SyncCacheViewAuthenticPixels(source->view,source->exception);
1188 if (status == MagickFalse)
1189 status=MagickFalse;
cristy3ed852e2009-09-05 21:47:34 +00001190 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1191 {
1192 MagickBooleanType
1193 proceed;
1194
cristyb5d5f722009-11-04 03:03:49 +00001195#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyac245f82012-05-05 17:13:57 +00001196 #pragma omp critical (MagickCore_UpdateImageViewIterator)
cristy3ed852e2009-09-05 21:47:34 +00001197#endif
cristyc3ebda22010-06-27 17:11:57 +00001198 proceed=SetImageProgress(source_image,source->description,progress++,
1199 source->extent.height);
cristy3ed852e2009-09-05 21:47:34 +00001200 if (proceed == MagickFalse)
1201 status=MagickFalse;
1202 }
1203 }
1204 return(status);
1205}