blob: 86cf24ade40b29cfbae5082d9026ad1b9beaa49c [file] [log] [blame]
cristyda06ed12009-10-14 18:36:54 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% AAA TTTTT TTTTT RRRR IIIII BBBB U U TTTTT EEEEE %
7% A A T T R R I B B U U T E %
8% AAAAA T T RRRR I BBBB U U T EEE %
9% A A T T R R I B B U U T E %
10% A A T T R R IIIII BBBB UUU T EEEEE %
11% %
12% %
13% MagickCore Get / Set Image Attributes %
14% %
15% Software Design %
16% John Cristy %
17% October 2002 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristyda06ed12009-10-14 18:36:54 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37%
38*/
39
40/*
41 Include declarations.
42*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
44#include "MagickCore/attribute.h"
45#include "MagickCore/blob.h"
46#include "MagickCore/blob-private.h"
47#include "MagickCore/cache.h"
48#include "MagickCore/cache-view.h"
49#include "MagickCore/client.h"
50#include "MagickCore/color.h"
51#include "MagickCore/color-private.h"
52#include "MagickCore/colormap.h"
53#include "MagickCore/colormap-private.h"
54#include "MagickCore/colorspace.h"
cristycca1bfa2011-09-12 12:39:53 +000055#include "MagickCore/colorspace-private.h"
cristy4c08aed2011-07-01 19:47:50 +000056#include "MagickCore/composite.h"
57#include "MagickCore/composite-private.h"
58#include "MagickCore/constitute.h"
59#include "MagickCore/draw.h"
60#include "MagickCore/draw-private.h"
61#include "MagickCore/effect.h"
62#include "MagickCore/enhance.h"
63#include "MagickCore/exception.h"
64#include "MagickCore/exception-private.h"
65#include "MagickCore/geometry.h"
66#include "MagickCore/histogram.h"
67#include "MagickCore/identify.h"
68#include "MagickCore/image.h"
69#include "MagickCore/image-private.h"
70#include "MagickCore/list.h"
71#include "MagickCore/log.h"
72#include "MagickCore/memory_.h"
73#include "MagickCore/magick.h"
74#include "MagickCore/monitor.h"
75#include "MagickCore/monitor-private.h"
76#include "MagickCore/paint.h"
77#include "MagickCore/pixel.h"
78#include "MagickCore/pixel-accessor.h"
79#include "MagickCore/property.h"
80#include "MagickCore/quantize.h"
81#include "MagickCore/quantum-private.h"
82#include "MagickCore/random_.h"
83#include "MagickCore/resource_.h"
84#include "MagickCore/semaphore.h"
85#include "MagickCore/segment.h"
86#include "MagickCore/splay-tree.h"
87#include "MagickCore/string_.h"
88#include "MagickCore/thread-private.h"
89#include "MagickCore/threshold.h"
90#include "MagickCore/transform.h"
91#include "MagickCore/utility.h"
cristyda06ed12009-10-14 18:36:54 +000092
93/*
94%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
95% %
96% %
97% %
98+ G e t I m a g e B o u n d i n g B o x %
99% %
100% %
101% %
102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103%
104% GetImageBoundingBox() returns the bounding box of an image canvas.
105%
106% The format of the GetImageBoundingBox method is:
107%
108% RectangleInfo GetImageBoundingBox(const Image *image,
109% ExceptionInfo *exception)
110%
111% A description of each parameter follows:
112%
113% o bounds: Method GetImageBoundingBox returns the bounding box of an
114% image canvas.
115%
116% o image: the image.
117%
118% o exception: return any errors or warnings in this structure.
119%
120*/
121MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
122 ExceptionInfo *exception)
123{
cristyc4c8d132010-01-07 01:58:38 +0000124 CacheView
125 *image_view;
126
cristyda06ed12009-10-14 18:36:54 +0000127 MagickBooleanType
128 status;
129
cristy4c08aed2011-07-01 19:47:50 +0000130 PixelInfo
cristyda06ed12009-10-14 18:36:54 +0000131 target[3],
132 zero;
133
134 RectangleInfo
135 bounds;
136
cristy4c08aed2011-07-01 19:47:50 +0000137 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000138 *p;
139
cristy9d314ff2011-03-09 01:30:28 +0000140 ssize_t
141 y;
142
cristyda06ed12009-10-14 18:36:54 +0000143 assert(image != (Image *) NULL);
144 assert(image->signature == MagickSignature);
145 if (image->debug != MagickFalse)
146 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
147 bounds.width=0;
148 bounds.height=0;
cristybb503372010-05-27 20:51:26 +0000149 bounds.x=(ssize_t) image->columns;
150 bounds.y=(ssize_t) image->rows;
cristy4c08aed2011-07-01 19:47:50 +0000151 GetPixelInfo(image,&target[0]);
cristyda06ed12009-10-14 18:36:54 +0000152 image_view=AcquireCacheView(image);
153 p=GetCacheViewVirtualPixels(image_view,0,0,1,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000154 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000155 {
156 image_view=DestroyCacheView(image_view);
157 return(bounds);
158 }
cristy4c08aed2011-07-01 19:47:50 +0000159 SetPixelInfo(image,p,&target[0]);
160 GetPixelInfo(image,&target[1]);
cristybb503372010-05-27 20:51:26 +0000161 p=GetCacheViewVirtualPixels(image_view,(ssize_t) image->columns-1,0,1,1,
cristyda06ed12009-10-14 18:36:54 +0000162 exception);
cristy4c08aed2011-07-01 19:47:50 +0000163 SetPixelInfo(image,p,&target[1]);
164 GetPixelInfo(image,&target[2]);
cristy4cb39ab2010-06-07 13:59:16 +0000165 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-1,1,1,
166 exception);
cristy4c08aed2011-07-01 19:47:50 +0000167 SetPixelInfo(image,p,&target[2]);
cristyda06ed12009-10-14 18:36:54 +0000168 status=MagickTrue;
cristy4c08aed2011-07-01 19:47:50 +0000169 GetPixelInfo(image,&zero);
cristyb5d5f722009-11-04 03:03:49 +0000170#if defined(MAGICKCORE_OPENMP_SUPPORT)
171 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000172#endif
cristybb503372010-05-27 20:51:26 +0000173 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000174 {
cristy4c08aed2011-07-01 19:47:50 +0000175 PixelInfo
cristyda06ed12009-10-14 18:36:54 +0000176 pixel;
177
178 RectangleInfo
179 bounding_box;
180
cristy4c08aed2011-07-01 19:47:50 +0000181 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +0000182 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000183
cristybb503372010-05-27 20:51:26 +0000184 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000185 x;
186
187 if (status == MagickFalse)
188 continue;
cristyb5d5f722009-11-04 03:03:49 +0000189#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyda06ed12009-10-14 18:36:54 +0000190# pragma omp critical (MagickCore_GetImageBoundingBox)
191#endif
192 bounding_box=bounds;
193 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000194 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000195 {
196 status=MagickFalse;
197 continue;
198 }
cristyda06ed12009-10-14 18:36:54 +0000199 pixel=zero;
cristybb503372010-05-27 20:51:26 +0000200 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000201 {
cristy4c08aed2011-07-01 19:47:50 +0000202 SetPixelInfo(image,p,&pixel);
cristyda06ed12009-10-14 18:36:54 +0000203 if ((x < bounding_box.x) &&
cristy4c08aed2011-07-01 19:47:50 +0000204 (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
cristyda06ed12009-10-14 18:36:54 +0000205 bounding_box.x=x;
cristybb503372010-05-27 20:51:26 +0000206 if ((x > (ssize_t) bounding_box.width) &&
cristy4c08aed2011-07-01 19:47:50 +0000207 (IsFuzzyEquivalencePixelInfo(&pixel,&target[1]) == MagickFalse))
cristybb503372010-05-27 20:51:26 +0000208 bounding_box.width=(size_t) x;
cristyda06ed12009-10-14 18:36:54 +0000209 if ((y < bounding_box.y) &&
cristy4c08aed2011-07-01 19:47:50 +0000210 (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
cristyda06ed12009-10-14 18:36:54 +0000211 bounding_box.y=y;
cristybb503372010-05-27 20:51:26 +0000212 if ((y > (ssize_t) bounding_box.height) &&
cristy4c08aed2011-07-01 19:47:50 +0000213 (IsFuzzyEquivalencePixelInfo(&pixel,&target[2]) == MagickFalse))
cristybb503372010-05-27 20:51:26 +0000214 bounding_box.height=(size_t) y;
cristyed231572011-07-14 02:18:59 +0000215 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000216 }
cristyb5d5f722009-11-04 03:03:49 +0000217#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyda06ed12009-10-14 18:36:54 +0000218# pragma omp critical (MagickCore_GetImageBoundingBox)
219#endif
220 {
221 if (bounding_box.x < bounds.x)
222 bounds.x=bounding_box.x;
223 if (bounding_box.y < bounds.y)
224 bounds.y=bounding_box.y;
225 if (bounding_box.width > bounds.width)
226 bounds.width=bounding_box.width;
227 if (bounding_box.height > bounds.height)
228 bounds.height=bounding_box.height;
229 }
230 }
231 image_view=DestroyCacheView(image_view);
232 if ((bounds.width == 0) || (bounds.height == 0))
233 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
234 "GeometryDoesNotContainImage","`%s'",image->filename);
235 else
236 {
237 bounds.width-=(bounds.x-1);
238 bounds.height-=(bounds.y-1);
239 }
240 return(bounds);
241}
242
243/*
244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245% %
246% %
247% %
cristyfefab1b2011-07-05 00:33:22 +0000248% G e t I m a g e D e p t h %
cristyda06ed12009-10-14 18:36:54 +0000249% %
250% %
251% %
252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253%
cristyfefab1b2011-07-05 00:33:22 +0000254% GetImageDepth() returns the depth of a particular image channel.
cristyda06ed12009-10-14 18:36:54 +0000255%
cristyfefab1b2011-07-05 00:33:22 +0000256% The format of the GetImageDepth method is:
cristyda06ed12009-10-14 18:36:54 +0000257%
cristybb503372010-05-27 20:51:26 +0000258% size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
cristyda06ed12009-10-14 18:36:54 +0000259%
260% A description of each parameter follows:
261%
262% o image: the image.
263%
cristyda06ed12009-10-14 18:36:54 +0000264% o exception: return any errors or warnings in this structure.
265%
266*/
cristyfefab1b2011-07-05 00:33:22 +0000267MagickExport size_t GetImageDepth(const Image *image,
268 ExceptionInfo *exception)
cristyda06ed12009-10-14 18:36:54 +0000269{
cristyc4c8d132010-01-07 01:58:38 +0000270 CacheView
271 *image_view;
272
cristyda06ed12009-10-14 18:36:54 +0000273 MagickBooleanType
274 status;
275
cristybb503372010-05-27 20:51:26 +0000276 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000277 id;
278
cristybb503372010-05-27 20:51:26 +0000279 size_t
cristyda06ed12009-10-14 18:36:54 +0000280 *current_depth,
281 depth,
282 number_threads;
283
cristy9d314ff2011-03-09 01:30:28 +0000284 ssize_t
285 y;
286
cristyda06ed12009-10-14 18:36:54 +0000287 /*
288 Compute image depth.
289 */
290 assert(image != (Image *) NULL);
291 assert(image->signature == MagickSignature);
292 if (image->debug != MagickFalse)
293 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
294 number_threads=GetOpenMPMaximumThreads();
cristybb503372010-05-27 20:51:26 +0000295 current_depth=(size_t *) AcquireQuantumMemory(number_threads,
cristyda06ed12009-10-14 18:36:54 +0000296 sizeof(*current_depth));
cristybb503372010-05-27 20:51:26 +0000297 if (current_depth == (size_t *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000298 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
299 status=MagickTrue;
cristybb503372010-05-27 20:51:26 +0000300 for (id=0; id < (ssize_t) number_threads; id++)
cristyda06ed12009-10-14 18:36:54 +0000301 current_depth[id]=1;
302 if ((image->storage_class == PseudoClass) && (image->matte == MagickFalse))
303 {
cristy101ab702011-10-13 13:06:32 +0000304 register const PixelInfo
cristyc47d1f82009-11-26 01:44:43 +0000305 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000306
cristybb503372010-05-27 20:51:26 +0000307 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000308 i;
309
310 p=image->colormap;
cristyb5d5f722009-11-04 03:03:49 +0000311#if defined(MAGICKCORE_OPENMP_SUPPORT)
312 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000313#endif
cristybb503372010-05-27 20:51:26 +0000314 for (i=0; i < (ssize_t) image->colors; i++)
cristyda06ed12009-10-14 18:36:54 +0000315 {
cristy5c9e6f22010-09-17 17:31:01 +0000316 const int
317 id = GetOpenMPThreadId();
318
cristyda06ed12009-10-14 18:36:54 +0000319 if (status == MagickFalse)
320 continue;
cristyda06ed12009-10-14 18:36:54 +0000321 while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
322 {
323 MagickStatusType
324 status;
325
326 QuantumAny
cristyb6d6f7c2010-06-09 13:17:57 +0000327 range;
cristyda06ed12009-10-14 18:36:54 +0000328
329 status=0;
cristyb6d6f7c2010-06-09 13:17:57 +0000330 range=GetQuantumRange(current_depth[id]);
cristyed231572011-07-14 02:18:59 +0000331 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000332 status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,
cristyb6d6f7c2010-06-09 13:17:57 +0000333 range),range);
cristyed231572011-07-14 02:18:59 +0000334 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000335 status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green,
cristyb6d6f7c2010-06-09 13:17:57 +0000336 range),range);
cristyed231572011-07-14 02:18:59 +0000337 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000338 status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,
cristyb6d6f7c2010-06-09 13:17:57 +0000339 range),range);
cristyda06ed12009-10-14 18:36:54 +0000340 if (status == 0)
341 break;
342 current_depth[id]++;
343 }
344 p++;
345 }
346 depth=current_depth[0];
cristybb503372010-05-27 20:51:26 +0000347 for (id=1; id < (ssize_t) number_threads; id++)
cristyda06ed12009-10-14 18:36:54 +0000348 if (depth < current_depth[id])
349 depth=current_depth[id];
cristybb503372010-05-27 20:51:26 +0000350 current_depth=(size_t *) RelinquishMagickMemory(current_depth);
cristyda06ed12009-10-14 18:36:54 +0000351 return(depth);
352 }
353 image_view=AcquireCacheView(image);
cristyb5d5f722009-11-04 03:03:49 +0000354#if defined(MAGICKCORE_OPENMP_SUPPORT)
355 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000356#endif
cristybb503372010-05-27 20:51:26 +0000357 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000358 {
cristy5c9e6f22010-09-17 17:31:01 +0000359 const int
360 id = GetOpenMPThreadId();
cristy6ebe97c2010-07-03 01:17:28 +0000361
cristy4c08aed2011-07-01 19:47:50 +0000362 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +0000363 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000364
cristybb503372010-05-27 20:51:26 +0000365 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000366 x;
367
368 if (status == MagickFalse)
369 continue;
cristyda06ed12009-10-14 18:36:54 +0000370 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000371 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000372 continue;
cristybb503372010-05-27 20:51:26 +0000373 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000374 {
375 while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
376 {
377 MagickStatusType
378 status;
379
380 QuantumAny
cristyb6d6f7c2010-06-09 13:17:57 +0000381 range;
cristyda06ed12009-10-14 18:36:54 +0000382
383 status=0;
cristyb6d6f7c2010-06-09 13:17:57 +0000384 range=GetQuantumRange(current_depth[id]);
cristyed231572011-07-14 02:18:59 +0000385 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000386 status|=GetPixelRed(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
387 GetPixelRed(image,p),range),range);
cristyed231572011-07-14 02:18:59 +0000388 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000389 status|=GetPixelGreen(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
390 GetPixelGreen(image,p),range),range);
cristyed231572011-07-14 02:18:59 +0000391 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000392 status|=GetPixelBlue(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
393 GetPixelBlue(image,p),range),range);
cristyed231572011-07-14 02:18:59 +0000394 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
cristy2b9582a2011-07-04 17:38:56 +0000395 (image->matte != MagickFalse))
cristy4c08aed2011-07-01 19:47:50 +0000396 status|=GetPixelAlpha(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
397 GetPixelAlpha(image,p),range),range);
cristyed231572011-07-14 02:18:59 +0000398 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
cristyda06ed12009-10-14 18:36:54 +0000399 (image->colorspace == CMYKColorspace))
cristy4c08aed2011-07-01 19:47:50 +0000400 status|=GetPixelBlack(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
401 GetPixelBlack(image,p),range),range);
cristyda06ed12009-10-14 18:36:54 +0000402 if (status == 0)
403 break;
404 current_depth[id]++;
405 }
cristyed231572011-07-14 02:18:59 +0000406 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000407 }
408 if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
409 status=MagickFalse;
410 }
411 image_view=DestroyCacheView(image_view);
412 depth=current_depth[0];
cristybb503372010-05-27 20:51:26 +0000413 for (id=1; id < (ssize_t) number_threads; id++)
cristyda06ed12009-10-14 18:36:54 +0000414 if (depth < current_depth[id])
415 depth=current_depth[id];
cristybb503372010-05-27 20:51:26 +0000416 current_depth=(size_t *) RelinquishMagickMemory(current_depth);
cristyda06ed12009-10-14 18:36:54 +0000417 return(depth);
418}
419
420/*
421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422% %
423% %
424% %
425% G e t I m a g e Q u a n t u m D e p t h %
426% %
427% %
428% %
429%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430%
431% GetImageQuantumDepth() returns the depth of the image rounded to a legal
432% quantum depth: 8, 16, or 32.
433%
434% The format of the GetImageQuantumDepth method is:
435%
cristybb503372010-05-27 20:51:26 +0000436% size_t GetImageQuantumDepth(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000437% const MagickBooleanType constrain)
438%
439% A description of each parameter follows:
440%
441% o image: the image.
442%
443% o constrain: A value other than MagickFalse, constrains the depth to
444% a maximum of MAGICKCORE_QUANTUM_DEPTH.
445%
446*/
447
448static inline double MagickMin(const double x,const double y)
449{
450 if (x < y)
451 return(x);
452 return(y);
453}
454
cristybb503372010-05-27 20:51:26 +0000455MagickExport size_t GetImageQuantumDepth(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000456 const MagickBooleanType constrain)
457{
cristybb503372010-05-27 20:51:26 +0000458 size_t
cristyda06ed12009-10-14 18:36:54 +0000459 depth;
460
461 depth=image->depth;
462 if (depth <= 8)
463 depth=8;
464 else
465 if (depth <= 16)
466 depth=16;
467 else
468 if (depth <= 32)
469 depth=32;
470 else
471 if (depth <= 64)
472 depth=64;
473 if (constrain != MagickFalse)
cristybb503372010-05-27 20:51:26 +0000474 depth=(size_t) MagickMin((double) depth,(double)
cristyda06ed12009-10-14 18:36:54 +0000475 MAGICKCORE_QUANTUM_DEPTH);
476 return(depth);
477}
478
479/*
480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481% %
482% %
483% %
484% G e t I m a g e T y p e %
485% %
486% %
487% %
488%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489%
490% GetImageType() returns the potential type of image:
491%
492% Bilevel Grayscale GrayscaleMatte
493% Palette PaletteMatte TrueColor
494% TrueColorMatte ColorSeparation ColorSeparationMatte
495%
496% To ensure the image type matches its potential, use SetImageType():
497%
498% (void) SetImageType(image,GetImageType(image));
499%
500% The format of the GetImageType method is:
501%
502% ImageType GetImageType(const Image *image,ExceptionInfo *exception)
503%
504% A description of each parameter follows:
505%
506% o image: the image.
507%
508% o exception: return any errors or warnings in this structure.
509%
510*/
511MagickExport ImageType GetImageType(const Image *image,ExceptionInfo *exception)
512{
513 assert(image != (Image *) NULL);
514 assert(image->signature == MagickSignature);
515 if (image->debug != MagickFalse)
516 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
517 if (image->colorspace == CMYKColorspace)
518 {
519 if (image->matte == MagickFalse)
520 return(ColorSeparationType);
521 return(ColorSeparationMatteType);
522 }
cristy4c08aed2011-07-01 19:47:50 +0000523 if (IsImageMonochrome(image,exception) != MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000524 return(BilevelType);
cristy4c08aed2011-07-01 19:47:50 +0000525 if (IsImageGray(image,exception) != MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000526 {
527 if (image->matte != MagickFalse)
528 return(GrayscaleMatteType);
529 return(GrayscaleType);
530 }
531 if (IsPaletteImage(image,exception) != MagickFalse)
532 {
533 if (image->matte != MagickFalse)
534 return(PaletteMatteType);
535 return(PaletteType);
536 }
537 if (image->matte != MagickFalse)
538 return(TrueColorMatteType);
539 return(TrueColorType);
540}
541
542/*
543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544% %
545% %
546% %
cristy4c08aed2011-07-01 19:47:50 +0000547% I s I m a g e G r a y %
cristyda06ed12009-10-14 18:36:54 +0000548% %
549% %
550% %
551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
552%
cristy4c08aed2011-07-01 19:47:50 +0000553% IsImageGray() returns MagickTrue if all the pixels in the image have the
cristyda06ed12009-10-14 18:36:54 +0000554% same red, green, and blue intensities.
555%
cristy4c08aed2011-07-01 19:47:50 +0000556% The format of the IsImageGray method is:
cristyda06ed12009-10-14 18:36:54 +0000557%
cristy4c08aed2011-07-01 19:47:50 +0000558% MagickBooleanType IsImageGray(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000559% ExceptionInfo *exception)
560%
561% A description of each parameter follows:
562%
563% o image: the image.
564%
565% o exception: return any errors or warnings in this structure.
566%
567*/
cristy4c08aed2011-07-01 19:47:50 +0000568MagickExport MagickBooleanType IsImageGray(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000569 ExceptionInfo *exception)
570{
cristy0910f242010-04-01 18:55:09 +0000571 CacheView
572 *image_view;
573
cristyda06ed12009-10-14 18:36:54 +0000574 ImageType
575 type;
576
cristy4c08aed2011-07-01 19:47:50 +0000577 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000578 *p;
579
cristybb503372010-05-27 20:51:26 +0000580 register ssize_t
cristy0910f242010-04-01 18:55:09 +0000581 x;
582
cristy95802a72010-09-05 19:07:17 +0000583 ssize_t
584 y;
585
cristyda06ed12009-10-14 18:36:54 +0000586 assert(image != (Image *) NULL);
587 assert(image->signature == MagickSignature);
588 if (image->debug != MagickFalse)
589 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
590 if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
591 (image->type == GrayscaleMatteType))
592 return(MagickTrue);
cristycca1bfa2011-09-12 12:39:53 +0000593 if (IsRGBColorspace(image->colorspace) == MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000594 return(MagickFalse);
595 type=BilevelType;
cristy0910f242010-04-01 18:55:09 +0000596 image_view=AcquireCacheView(image);
cristybb503372010-05-27 20:51:26 +0000597 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000598 {
cristy0910f242010-04-01 18:55:09 +0000599 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000600 if (p == (const Quantum *) NULL)
cristy0910f242010-04-01 18:55:09 +0000601 break;
cristybb503372010-05-27 20:51:26 +0000602 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000603 {
cristy4c08aed2011-07-01 19:47:50 +0000604 if (IsPixelGray(image,p) == MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000605 {
cristy5f1c1ff2010-12-23 21:38:06 +0000606 type=UndefinedType;
cristyda06ed12009-10-14 18:36:54 +0000607 break;
cristy0910f242010-04-01 18:55:09 +0000608 }
cristybd5a96c2011-08-21 00:04:26 +0000609 if ((type == BilevelType) &&
610 (IsPixelMonochrome(image,p) == MagickFalse))
cristy0910f242010-04-01 18:55:09 +0000611 type=GrayscaleType;
cristyed231572011-07-14 02:18:59 +0000612 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000613 }
cristy5f1c1ff2010-12-23 21:38:06 +0000614 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000615 break;
cristyda06ed12009-10-14 18:36:54 +0000616 }
cristy0910f242010-04-01 18:55:09 +0000617 image_view=DestroyCacheView(image_view);
cristy5f1c1ff2010-12-23 21:38:06 +0000618 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000619 return(MagickFalse);
620 ((Image *) image)->type=type;
621 if ((type == GrayscaleType) && (image->matte != MagickFalse))
622 ((Image *) image)->type=GrayscaleMatteType;
623 return(MagickTrue);
624}
625
626/*
627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628% %
629% %
630% %
cristy4c08aed2011-07-01 19:47:50 +0000631% I s I m a g e M o n o c h r o m e %
cristyda06ed12009-10-14 18:36:54 +0000632% %
633% %
634% %
635%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636%
cristy4c08aed2011-07-01 19:47:50 +0000637% IsImageMonochrome() returns MagickTrue if all the pixels in the image have
cristyda06ed12009-10-14 18:36:54 +0000638% the same red, green, and blue intensities and the intensity is either
639% 0 or QuantumRange.
640%
cristy4c08aed2011-07-01 19:47:50 +0000641% The format of the IsImageMonochrome method is:
cristyda06ed12009-10-14 18:36:54 +0000642%
cristy4c08aed2011-07-01 19:47:50 +0000643% MagickBooleanType IsImageMonochrome(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000644% ExceptionInfo *exception)
645%
646% A description of each parameter follows:
647%
648% o image: the image.
649%
650% o exception: return any errors or warnings in this structure.
651%
652*/
cristy4c08aed2011-07-01 19:47:50 +0000653MagickExport MagickBooleanType IsImageMonochrome(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000654 ExceptionInfo *exception)
655{
cristy0910f242010-04-01 18:55:09 +0000656 CacheView
657 *image_view;
658
cristyda06ed12009-10-14 18:36:54 +0000659 ImageType
660 type;
661
cristybb503372010-05-27 20:51:26 +0000662 register ssize_t
cristy0910f242010-04-01 18:55:09 +0000663 x;
664
cristy4c08aed2011-07-01 19:47:50 +0000665 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000666 *p;
667
cristy9d314ff2011-03-09 01:30:28 +0000668 ssize_t
669 y;
670
cristyda06ed12009-10-14 18:36:54 +0000671 assert(image != (Image *) NULL);
672 assert(image->signature == MagickSignature);
673 if (image->debug != MagickFalse)
674 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
675 if (image->type == BilevelType)
676 return(MagickTrue);
cristycca1bfa2011-09-12 12:39:53 +0000677 if (IsRGBColorspace(image->colorspace) == MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000678 return(MagickFalse);
679 type=BilevelType;
cristy0910f242010-04-01 18:55:09 +0000680 image_view=AcquireCacheView(image);
cristybb503372010-05-27 20:51:26 +0000681 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000682 {
cristy0910f242010-04-01 18:55:09 +0000683 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000684 if (p == (const Quantum *) NULL)
cristy0910f242010-04-01 18:55:09 +0000685 break;
cristybb503372010-05-27 20:51:26 +0000686 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000687 {
cristy4c08aed2011-07-01 19:47:50 +0000688 if (IsPixelMonochrome(image,p) == MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000689 {
cristy5f1c1ff2010-12-23 21:38:06 +0000690 type=UndefinedType;
cristyda06ed12009-10-14 18:36:54 +0000691 break;
cristy0910f242010-04-01 18:55:09 +0000692 }
cristyed231572011-07-14 02:18:59 +0000693 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000694 }
cristy5f1c1ff2010-12-23 21:38:06 +0000695 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000696 break;
cristyda06ed12009-10-14 18:36:54 +0000697 }
cristy0910f242010-04-01 18:55:09 +0000698 image_view=DestroyCacheView(image_view);
cristy5f1c1ff2010-12-23 21:38:06 +0000699 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000700 return(MagickFalse);
701 ((Image *) image)->type=type;
702 return(MagickTrue);
703}
704
705/*
706%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707% %
708% %
709% %
cristy4c08aed2011-07-01 19:47:50 +0000710% I s I m a g e O p a q u e %
cristyda06ed12009-10-14 18:36:54 +0000711% %
712% %
713% %
714%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715%
cristy4c08aed2011-07-01 19:47:50 +0000716% IsImageOpaque() returns MagickTrue if none of the pixels in the image have
cristyda06ed12009-10-14 18:36:54 +0000717% an opacity value other than opaque (0).
718%
cristy4c08aed2011-07-01 19:47:50 +0000719% The format of the IsImageOpaque method is:
cristyda06ed12009-10-14 18:36:54 +0000720%
cristy4c08aed2011-07-01 19:47:50 +0000721% MagickBooleanType IsImageOpaque(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000722% ExceptionInfo *exception)
723%
724% A description of each parameter follows:
725%
726% o image: the image.
727%
728% o exception: return any errors or warnings in this structure.
729%
730*/
cristy4c08aed2011-07-01 19:47:50 +0000731MagickExport MagickBooleanType IsImageOpaque(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000732 ExceptionInfo *exception)
733{
cristyc4c8d132010-01-07 01:58:38 +0000734 CacheView
735 *image_view;
736
cristy4c08aed2011-07-01 19:47:50 +0000737 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000738 *p;
739
cristybb503372010-05-27 20:51:26 +0000740 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000741 x;
742
cristy9d314ff2011-03-09 01:30:28 +0000743 ssize_t
744 y;
745
cristyda06ed12009-10-14 18:36:54 +0000746 /*
747 Determine if image is opaque.
748 */
749 assert(image != (Image *) NULL);
750 assert(image->signature == MagickSignature);
751 if (image->debug != MagickFalse)
752 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
753 if (image->matte == MagickFalse)
754 return(MagickTrue);
755 image_view=AcquireCacheView(image);
cristybb503372010-05-27 20:51:26 +0000756 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000757 {
758 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000759 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000760 break;
cristybb503372010-05-27 20:51:26 +0000761 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000762 {
cristy4c08aed2011-07-01 19:47:50 +0000763 if (GetPixelAlpha(image,p) != OpaqueAlpha)
cristyda06ed12009-10-14 18:36:54 +0000764 break;
cristyed231572011-07-14 02:18:59 +0000765 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000766 }
cristybb503372010-05-27 20:51:26 +0000767 if (x < (ssize_t) image->columns)
cristyda06ed12009-10-14 18:36:54 +0000768 break;
769 }
770 image_view=DestroyCacheView(image_view);
cristybb503372010-05-27 20:51:26 +0000771 return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
cristyda06ed12009-10-14 18:36:54 +0000772}
773
774/*
775%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
776% %
777% %
778% %
cristyfefab1b2011-07-05 00:33:22 +0000779% S e t I m a g e D e p t h %
cristyda06ed12009-10-14 18:36:54 +0000780% %
781% %
782% %
783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784%
cristyfefab1b2011-07-05 00:33:22 +0000785% SetImageDepth() sets the depth of the image.
cristyda06ed12009-10-14 18:36:54 +0000786%
cristyfefab1b2011-07-05 00:33:22 +0000787% The format of the SetImageDepth method is:
cristyda06ed12009-10-14 18:36:54 +0000788%
cristybb503372010-05-27 20:51:26 +0000789% MagickBooleanType SetImageDepth(Image *image,const size_t depth)
cristyfefab1b2011-07-05 00:33:22 +0000790% MagickBooleanType SetImageDepth(Image *image,
cristybb503372010-05-27 20:51:26 +0000791% const ChannelType channel,const size_t depth)
cristyda06ed12009-10-14 18:36:54 +0000792%
793% A description of each parameter follows:
794%
795% o image: the image.
796%
797% o channel: the channel.
798%
799% o depth: the image depth.
800%
801*/
cristyda06ed12009-10-14 18:36:54 +0000802MagickExport MagickBooleanType SetImageDepth(Image *image,
cristybb503372010-05-27 20:51:26 +0000803 const size_t depth)
cristyda06ed12009-10-14 18:36:54 +0000804{
cristyc4c8d132010-01-07 01:58:38 +0000805 CacheView
806 *image_view;
807
cristyda06ed12009-10-14 18:36:54 +0000808 ExceptionInfo
809 *exception;
810
cristyda06ed12009-10-14 18:36:54 +0000811 MagickBooleanType
812 status;
813
814 QuantumAny
cristyb6d6f7c2010-06-09 13:17:57 +0000815 range;
cristyda06ed12009-10-14 18:36:54 +0000816
cristy9d314ff2011-03-09 01:30:28 +0000817 ssize_t
818 y;
819
cristyda06ed12009-10-14 18:36:54 +0000820 assert(image != (Image *) NULL);
821 if (image->debug != MagickFalse)
822 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
823 assert(image->signature == MagickSignature);
cristybb503372010-05-27 20:51:26 +0000824 if (GetImageDepth(image,&image->exception) <= (size_t)
cristyda06ed12009-10-14 18:36:54 +0000825 MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH))
826 {
827 image->depth=depth;
828 return(MagickTrue);
829 }
830 /*
831 Scale pixels to desired depth.
832 */
833 status=MagickTrue;
cristyb6d6f7c2010-06-09 13:17:57 +0000834 range=GetQuantumRange(depth);
cristyda06ed12009-10-14 18:36:54 +0000835 exception=(&image->exception);
836 image_view=AcquireCacheView(image);
cristyb5d5f722009-11-04 03:03:49 +0000837#if defined(MAGICKCORE_OPENMP_SUPPORT)
838 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000839#endif
cristybb503372010-05-27 20:51:26 +0000840 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000841 {
cristybb503372010-05-27 20:51:26 +0000842 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000843 x;
844
cristy4c08aed2011-07-01 19:47:50 +0000845 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000846 *restrict q;
cristyda06ed12009-10-14 18:36:54 +0000847
848 if (status == MagickFalse)
849 continue;
850 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
851 exception);
cristyacd2ed22011-08-30 01:44:23 +0000852 if (q == (Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000853 {
854 status=MagickFalse;
855 continue;
856 }
cristybb503372010-05-27 20:51:26 +0000857 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000858 {
cristyed231572011-07-14 02:18:59 +0000859 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000860 SetPixelRed(image,ScaleAnyToQuantum(ScaleQuantumToAny(
861 GetPixelRed(image,q),range),range),q);
cristyed231572011-07-14 02:18:59 +0000862 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000863 SetPixelGreen(image,ScaleAnyToQuantum(ScaleQuantumToAny(
864 GetPixelGreen(image,q),range),range),q);
cristyed231572011-07-14 02:18:59 +0000865 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000866 SetPixelBlue(image,ScaleAnyToQuantum(ScaleQuantumToAny(
867 GetPixelBlue(image,q),range),range),q);
cristyed231572011-07-14 02:18:59 +0000868 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
cristyda06ed12009-10-14 18:36:54 +0000869 (image->colorspace == CMYKColorspace))
cristy4c08aed2011-07-01 19:47:50 +0000870 SetPixelBlack(image,ScaleAnyToQuantum(ScaleQuantumToAny(
871 GetPixelBlack(image,q),range),range),q);
cristyed231572011-07-14 02:18:59 +0000872 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
cristy2b9582a2011-07-04 17:38:56 +0000873 (image->matte != MagickFalse))
cristy4c08aed2011-07-01 19:47:50 +0000874 SetPixelAlpha(image,ScaleAnyToQuantum(ScaleQuantumToAny(
875 GetPixelAlpha(image,q),range),range),q);
cristyed231572011-07-14 02:18:59 +0000876 q+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000877 }
878 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
879 {
880 status=MagickFalse;
881 continue;
882 }
883 }
884 image_view=DestroyCacheView(image_view);
885 if (image->storage_class == PseudoClass)
886 {
cristy101ab702011-10-13 13:06:32 +0000887 register PixelInfo
cristyc47d1f82009-11-26 01:44:43 +0000888 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000889
cristy1c300ae2011-10-09 22:27:43 +0000890 register ssize_t
891 i;
892
cristyda06ed12009-10-14 18:36:54 +0000893 p=image->colormap;
cristyb5d5f722009-11-04 03:03:49 +0000894#if defined(MAGICKCORE_OPENMP_SUPPORT)
895 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000896#endif
cristybb503372010-05-27 20:51:26 +0000897 for (i=0; i < (ssize_t) image->colors; i++)
cristyda06ed12009-10-14 18:36:54 +0000898 {
cristyed231572011-07-14 02:18:59 +0000899 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
cristy9384eed2011-06-13 14:16:32 +0000900 p->red=ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range),range);
cristyed231572011-07-14 02:18:59 +0000901 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
cristy9384eed2011-06-13 14:16:32 +0000902 p->green=ScaleAnyToQuantum(ScaleQuantumToAny(p->green,range),range);
cristyed231572011-07-14 02:18:59 +0000903 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
cristy9384eed2011-06-13 14:16:32 +0000904 p->blue=ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range),range);
cristyed231572011-07-14 02:18:59 +0000905 if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000906 p->alpha=ScaleAnyToQuantum(ScaleQuantumToAny(p->alpha,range),range);
cristyda06ed12009-10-14 18:36:54 +0000907 p++;
908 }
909 }
910 image->depth=depth;
911 return(status);
912}