blob: 6237fd74afcbbeb91a00e777703b6e4832408636 [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"
55#include "MagickCore/composite.h"
56#include "MagickCore/composite-private.h"
57#include "MagickCore/constitute.h"
58#include "MagickCore/draw.h"
59#include "MagickCore/draw-private.h"
60#include "MagickCore/effect.h"
61#include "MagickCore/enhance.h"
62#include "MagickCore/exception.h"
63#include "MagickCore/exception-private.h"
64#include "MagickCore/geometry.h"
65#include "MagickCore/histogram.h"
66#include "MagickCore/identify.h"
67#include "MagickCore/image.h"
68#include "MagickCore/image-private.h"
69#include "MagickCore/list.h"
70#include "MagickCore/log.h"
71#include "MagickCore/memory_.h"
72#include "MagickCore/magick.h"
73#include "MagickCore/monitor.h"
74#include "MagickCore/monitor-private.h"
75#include "MagickCore/paint.h"
76#include "MagickCore/pixel.h"
77#include "MagickCore/pixel-accessor.h"
78#include "MagickCore/property.h"
79#include "MagickCore/quantize.h"
80#include "MagickCore/quantum-private.h"
81#include "MagickCore/random_.h"
82#include "MagickCore/resource_.h"
83#include "MagickCore/semaphore.h"
84#include "MagickCore/segment.h"
85#include "MagickCore/splay-tree.h"
86#include "MagickCore/string_.h"
87#include "MagickCore/thread-private.h"
88#include "MagickCore/threshold.h"
89#include "MagickCore/transform.h"
90#include "MagickCore/utility.h"
cristyda06ed12009-10-14 18:36:54 +000091
92/*
93%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94% %
95% %
96% %
97+ G e t I m a g e B o u n d i n g B o x %
98% %
99% %
100% %
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102%
103% GetImageBoundingBox() returns the bounding box of an image canvas.
104%
105% The format of the GetImageBoundingBox method is:
106%
107% RectangleInfo GetImageBoundingBox(const Image *image,
108% ExceptionInfo *exception)
109%
110% A description of each parameter follows:
111%
112% o bounds: Method GetImageBoundingBox returns the bounding box of an
113% image canvas.
114%
115% o image: the image.
116%
117% o exception: return any errors or warnings in this structure.
118%
119*/
120MagickExport RectangleInfo GetImageBoundingBox(const Image *image,
121 ExceptionInfo *exception)
122{
cristyc4c8d132010-01-07 01:58:38 +0000123 CacheView
124 *image_view;
125
cristyda06ed12009-10-14 18:36:54 +0000126 MagickBooleanType
127 status;
128
cristy4c08aed2011-07-01 19:47:50 +0000129 PixelInfo
cristyda06ed12009-10-14 18:36:54 +0000130 target[3],
131 zero;
132
133 RectangleInfo
134 bounds;
135
cristy4c08aed2011-07-01 19:47:50 +0000136 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000137 *p;
138
cristy9d314ff2011-03-09 01:30:28 +0000139 ssize_t
140 y;
141
cristyda06ed12009-10-14 18:36:54 +0000142 assert(image != (Image *) NULL);
143 assert(image->signature == MagickSignature);
144 if (image->debug != MagickFalse)
145 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
146 bounds.width=0;
147 bounds.height=0;
cristybb503372010-05-27 20:51:26 +0000148 bounds.x=(ssize_t) image->columns;
149 bounds.y=(ssize_t) image->rows;
cristy4c08aed2011-07-01 19:47:50 +0000150 GetPixelInfo(image,&target[0]);
cristyda06ed12009-10-14 18:36:54 +0000151 image_view=AcquireCacheView(image);
152 p=GetCacheViewVirtualPixels(image_view,0,0,1,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000153 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000154 {
155 image_view=DestroyCacheView(image_view);
156 return(bounds);
157 }
cristy4c08aed2011-07-01 19:47:50 +0000158 SetPixelInfo(image,p,&target[0]);
159 GetPixelInfo(image,&target[1]);
cristybb503372010-05-27 20:51:26 +0000160 p=GetCacheViewVirtualPixels(image_view,(ssize_t) image->columns-1,0,1,1,
cristyda06ed12009-10-14 18:36:54 +0000161 exception);
cristy4c08aed2011-07-01 19:47:50 +0000162 SetPixelInfo(image,p,&target[1]);
163 GetPixelInfo(image,&target[2]);
cristy4cb39ab2010-06-07 13:59:16 +0000164 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-1,1,1,
165 exception);
cristy4c08aed2011-07-01 19:47:50 +0000166 SetPixelInfo(image,p,&target[2]);
cristyda06ed12009-10-14 18:36:54 +0000167 status=MagickTrue;
cristy4c08aed2011-07-01 19:47:50 +0000168 GetPixelInfo(image,&zero);
cristyb5d5f722009-11-04 03:03:49 +0000169#if defined(MAGICKCORE_OPENMP_SUPPORT)
170 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000171#endif
cristybb503372010-05-27 20:51:26 +0000172 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000173 {
cristy4c08aed2011-07-01 19:47:50 +0000174 PixelInfo
cristyda06ed12009-10-14 18:36:54 +0000175 pixel;
176
177 RectangleInfo
178 bounding_box;
179
cristy4c08aed2011-07-01 19:47:50 +0000180 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +0000181 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000182
cristybb503372010-05-27 20:51:26 +0000183 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000184 x;
185
186 if (status == MagickFalse)
187 continue;
cristyb5d5f722009-11-04 03:03:49 +0000188#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyda06ed12009-10-14 18:36:54 +0000189# pragma omp critical (MagickCore_GetImageBoundingBox)
190#endif
191 bounding_box=bounds;
192 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000193 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000194 {
195 status=MagickFalse;
196 continue;
197 }
cristyda06ed12009-10-14 18:36:54 +0000198 pixel=zero;
cristybb503372010-05-27 20:51:26 +0000199 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000200 {
cristy4c08aed2011-07-01 19:47:50 +0000201 SetPixelInfo(image,p,&pixel);
cristyda06ed12009-10-14 18:36:54 +0000202 if ((x < bounding_box.x) &&
cristy4c08aed2011-07-01 19:47:50 +0000203 (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
cristyda06ed12009-10-14 18:36:54 +0000204 bounding_box.x=x;
cristybb503372010-05-27 20:51:26 +0000205 if ((x > (ssize_t) bounding_box.width) &&
cristy4c08aed2011-07-01 19:47:50 +0000206 (IsFuzzyEquivalencePixelInfo(&pixel,&target[1]) == MagickFalse))
cristybb503372010-05-27 20:51:26 +0000207 bounding_box.width=(size_t) x;
cristyda06ed12009-10-14 18:36:54 +0000208 if ((y < bounding_box.y) &&
cristy4c08aed2011-07-01 19:47:50 +0000209 (IsFuzzyEquivalencePixelInfo(&pixel,&target[0]) == MagickFalse))
cristyda06ed12009-10-14 18:36:54 +0000210 bounding_box.y=y;
cristybb503372010-05-27 20:51:26 +0000211 if ((y > (ssize_t) bounding_box.height) &&
cristy4c08aed2011-07-01 19:47:50 +0000212 (IsFuzzyEquivalencePixelInfo(&pixel,&target[2]) == MagickFalse))
cristybb503372010-05-27 20:51:26 +0000213 bounding_box.height=(size_t) y;
cristy4c08aed2011-07-01 19:47:50 +0000214 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000215 }
cristyb5d5f722009-11-04 03:03:49 +0000216#if defined(MAGICKCORE_OPENMP_SUPPORT)
cristyda06ed12009-10-14 18:36:54 +0000217# pragma omp critical (MagickCore_GetImageBoundingBox)
218#endif
219 {
220 if (bounding_box.x < bounds.x)
221 bounds.x=bounding_box.x;
222 if (bounding_box.y < bounds.y)
223 bounds.y=bounding_box.y;
224 if (bounding_box.width > bounds.width)
225 bounds.width=bounding_box.width;
226 if (bounding_box.height > bounds.height)
227 bounds.height=bounding_box.height;
228 }
229 }
230 image_view=DestroyCacheView(image_view);
231 if ((bounds.width == 0) || (bounds.height == 0))
232 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
233 "GeometryDoesNotContainImage","`%s'",image->filename);
234 else
235 {
236 bounds.width-=(bounds.x-1);
237 bounds.height-=(bounds.y-1);
238 }
239 return(bounds);
240}
241
242/*
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244% %
245% %
246% %
247% G e t I m a g e C h a n n e l D e p t h %
248% %
249% %
250% %
251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252%
253% GetImageChannelDepth() returns the depth of a particular image channel.
254%
255% The format of the GetImageChannelDepth method is:
256%
cristybb503372010-05-27 20:51:26 +0000257% size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
258% size_t GetImageChannelDepth(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000259% const ChannelType channel,ExceptionInfo *exception)
260%
261% A description of each parameter follows:
262%
263% o image: the image.
264%
265% o channel: the channel.
266%
267% o exception: return any errors or warnings in this structure.
268%
269*/
cristye8c25f92010-06-03 00:53:06 +0000270MagickExport size_t GetImageDepth(const Image *image,ExceptionInfo *exception)
cristyda06ed12009-10-14 18:36:54 +0000271{
cristy9a9230e2011-04-26 14:56:14 +0000272 return(GetImageChannelDepth(image,CompositeChannels,exception));
cristyda06ed12009-10-14 18:36:54 +0000273}
274
cristybb503372010-05-27 20:51:26 +0000275MagickExport size_t GetImageChannelDepth(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000276 const ChannelType channel,ExceptionInfo *exception)
277{
cristyc4c8d132010-01-07 01:58:38 +0000278 CacheView
279 *image_view;
280
cristyda06ed12009-10-14 18:36:54 +0000281 MagickBooleanType
282 status;
283
cristybb503372010-05-27 20:51:26 +0000284 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000285 id;
286
cristybb503372010-05-27 20:51:26 +0000287 size_t
cristyda06ed12009-10-14 18:36:54 +0000288 *current_depth,
289 depth,
290 number_threads;
291
cristy9d314ff2011-03-09 01:30:28 +0000292 ssize_t
293 y;
294
cristyda06ed12009-10-14 18:36:54 +0000295 /*
296 Compute image depth.
297 */
298 assert(image != (Image *) NULL);
299 assert(image->signature == MagickSignature);
300 if (image->debug != MagickFalse)
301 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
302 number_threads=GetOpenMPMaximumThreads();
cristybb503372010-05-27 20:51:26 +0000303 current_depth=(size_t *) AcquireQuantumMemory(number_threads,
cristyda06ed12009-10-14 18:36:54 +0000304 sizeof(*current_depth));
cristybb503372010-05-27 20:51:26 +0000305 if (current_depth == (size_t *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000306 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
307 status=MagickTrue;
cristybb503372010-05-27 20:51:26 +0000308 for (id=0; id < (ssize_t) number_threads; id++)
cristyda06ed12009-10-14 18:36:54 +0000309 current_depth[id]=1;
310 if ((image->storage_class == PseudoClass) && (image->matte == MagickFalse))
311 {
312 register const PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000313 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000314
cristybb503372010-05-27 20:51:26 +0000315 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000316 i;
317
318 p=image->colormap;
cristyb5d5f722009-11-04 03:03:49 +0000319#if defined(MAGICKCORE_OPENMP_SUPPORT)
320 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000321#endif
cristybb503372010-05-27 20:51:26 +0000322 for (i=0; i < (ssize_t) image->colors; i++)
cristyda06ed12009-10-14 18:36:54 +0000323 {
cristy5c9e6f22010-09-17 17:31:01 +0000324 const int
325 id = GetOpenMPThreadId();
326
cristyda06ed12009-10-14 18:36:54 +0000327 if (status == MagickFalse)
328 continue;
cristyda06ed12009-10-14 18:36:54 +0000329 while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
330 {
331 MagickStatusType
332 status;
333
334 QuantumAny
cristyb6d6f7c2010-06-09 13:17:57 +0000335 range;
cristyda06ed12009-10-14 18:36:54 +0000336
337 status=0;
cristyb6d6f7c2010-06-09 13:17:57 +0000338 range=GetQuantumRange(current_depth[id]);
cristy2b9582a2011-07-04 17:38:56 +0000339 if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000340 status|=p->red != ScaleAnyToQuantum(ScaleQuantumToAny(p->red,
cristyb6d6f7c2010-06-09 13:17:57 +0000341 range),range);
cristy2b9582a2011-07-04 17:38:56 +0000342 if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000343 status|=p->green != ScaleAnyToQuantum(ScaleQuantumToAny(p->green,
cristyb6d6f7c2010-06-09 13:17:57 +0000344 range),range);
cristy2b9582a2011-07-04 17:38:56 +0000345 if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000346 status|=p->blue != ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,
cristyb6d6f7c2010-06-09 13:17:57 +0000347 range),range);
cristyda06ed12009-10-14 18:36:54 +0000348 if (status == 0)
349 break;
350 current_depth[id]++;
351 }
352 p++;
353 }
354 depth=current_depth[0];
cristybb503372010-05-27 20:51:26 +0000355 for (id=1; id < (ssize_t) number_threads; id++)
cristyda06ed12009-10-14 18:36:54 +0000356 if (depth < current_depth[id])
357 depth=current_depth[id];
cristybb503372010-05-27 20:51:26 +0000358 current_depth=(size_t *) RelinquishMagickMemory(current_depth);
cristyda06ed12009-10-14 18:36:54 +0000359 return(depth);
360 }
361 image_view=AcquireCacheView(image);
cristyb5d5f722009-11-04 03:03:49 +0000362#if defined(MAGICKCORE_OPENMP_SUPPORT)
363 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000364#endif
cristybb503372010-05-27 20:51:26 +0000365 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000366 {
cristy5c9e6f22010-09-17 17:31:01 +0000367 const int
368 id = GetOpenMPThreadId();
cristy6ebe97c2010-07-03 01:17:28 +0000369
cristy4c08aed2011-07-01 19:47:50 +0000370 register const Quantum
cristyc47d1f82009-11-26 01:44:43 +0000371 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000372
cristybb503372010-05-27 20:51:26 +0000373 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000374 x;
375
376 if (status == MagickFalse)
377 continue;
cristyda06ed12009-10-14 18:36:54 +0000378 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000379 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000380 continue;
cristybb503372010-05-27 20:51:26 +0000381 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000382 {
383 while (current_depth[id] < MAGICKCORE_QUANTUM_DEPTH)
384 {
385 MagickStatusType
386 status;
387
388 QuantumAny
cristyb6d6f7c2010-06-09 13:17:57 +0000389 range;
cristyda06ed12009-10-14 18:36:54 +0000390
391 status=0;
cristyb6d6f7c2010-06-09 13:17:57 +0000392 range=GetQuantumRange(current_depth[id]);
cristy2b9582a2011-07-04 17:38:56 +0000393 if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000394 status|=GetPixelRed(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
395 GetPixelRed(image,p),range),range);
cristy2b9582a2011-07-04 17:38:56 +0000396 if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000397 status|=GetPixelGreen(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
398 GetPixelGreen(image,p),range),range);
cristy2b9582a2011-07-04 17:38:56 +0000399 if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000400 status|=GetPixelBlue(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
401 GetPixelBlue(image,p),range),range);
cristy2b9582a2011-07-04 17:38:56 +0000402 if (((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0) &&
403 (image->matte != MagickFalse))
cristy4c08aed2011-07-01 19:47:50 +0000404 status|=GetPixelAlpha(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
405 GetPixelAlpha(image,p),range),range);
cristy2b9582a2011-07-04 17:38:56 +0000406 if (((GetPixelBlackTraits(image) & ActivePixelTrait) != 0) &&
cristyda06ed12009-10-14 18:36:54 +0000407 (image->colorspace == CMYKColorspace))
cristy4c08aed2011-07-01 19:47:50 +0000408 status|=GetPixelBlack(image,p) != ScaleAnyToQuantum(ScaleQuantumToAny(
409 GetPixelBlack(image,p),range),range);
cristyda06ed12009-10-14 18:36:54 +0000410 if (status == 0)
411 break;
412 current_depth[id]++;
413 }
cristy4c08aed2011-07-01 19:47:50 +0000414 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000415 }
416 if (current_depth[id] == MAGICKCORE_QUANTUM_DEPTH)
417 status=MagickFalse;
418 }
419 image_view=DestroyCacheView(image_view);
420 depth=current_depth[0];
cristybb503372010-05-27 20:51:26 +0000421 for (id=1; id < (ssize_t) number_threads; id++)
cristyda06ed12009-10-14 18:36:54 +0000422 if (depth < current_depth[id])
423 depth=current_depth[id];
cristybb503372010-05-27 20:51:26 +0000424 current_depth=(size_t *) RelinquishMagickMemory(current_depth);
cristyda06ed12009-10-14 18:36:54 +0000425 return(depth);
426}
427
428/*
429%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430% %
431% %
432% %
433% G e t I m a g e Q u a n t u m D e p t h %
434% %
435% %
436% %
437%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438%
439% GetImageQuantumDepth() returns the depth of the image rounded to a legal
440% quantum depth: 8, 16, or 32.
441%
442% The format of the GetImageQuantumDepth method is:
443%
cristybb503372010-05-27 20:51:26 +0000444% size_t GetImageQuantumDepth(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000445% const MagickBooleanType constrain)
446%
447% A description of each parameter follows:
448%
449% o image: the image.
450%
451% o constrain: A value other than MagickFalse, constrains the depth to
452% a maximum of MAGICKCORE_QUANTUM_DEPTH.
453%
454*/
455
456static inline double MagickMin(const double x,const double y)
457{
458 if (x < y)
459 return(x);
460 return(y);
461}
462
cristybb503372010-05-27 20:51:26 +0000463MagickExport size_t GetImageQuantumDepth(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000464 const MagickBooleanType constrain)
465{
cristybb503372010-05-27 20:51:26 +0000466 size_t
cristyda06ed12009-10-14 18:36:54 +0000467 depth;
468
469 depth=image->depth;
470 if (depth <= 8)
471 depth=8;
472 else
473 if (depth <= 16)
474 depth=16;
475 else
476 if (depth <= 32)
477 depth=32;
478 else
479 if (depth <= 64)
480 depth=64;
481 if (constrain != MagickFalse)
cristybb503372010-05-27 20:51:26 +0000482 depth=(size_t) MagickMin((double) depth,(double)
cristyda06ed12009-10-14 18:36:54 +0000483 MAGICKCORE_QUANTUM_DEPTH);
484 return(depth);
485}
486
487/*
488%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
489% %
490% %
491% %
492% G e t I m a g e T y p e %
493% %
494% %
495% %
496%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497%
498% GetImageType() returns the potential type of image:
499%
500% Bilevel Grayscale GrayscaleMatte
501% Palette PaletteMatte TrueColor
502% TrueColorMatte ColorSeparation ColorSeparationMatte
503%
504% To ensure the image type matches its potential, use SetImageType():
505%
506% (void) SetImageType(image,GetImageType(image));
507%
508% The format of the GetImageType method is:
509%
510% ImageType GetImageType(const Image *image,ExceptionInfo *exception)
511%
512% A description of each parameter follows:
513%
514% o image: the image.
515%
516% o exception: return any errors or warnings in this structure.
517%
518*/
519MagickExport ImageType GetImageType(const Image *image,ExceptionInfo *exception)
520{
521 assert(image != (Image *) NULL);
522 assert(image->signature == MagickSignature);
523 if (image->debug != MagickFalse)
524 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
525 if (image->colorspace == CMYKColorspace)
526 {
527 if (image->matte == MagickFalse)
528 return(ColorSeparationType);
529 return(ColorSeparationMatteType);
530 }
cristy4c08aed2011-07-01 19:47:50 +0000531 if (IsImageMonochrome(image,exception) != MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000532 return(BilevelType);
cristy4c08aed2011-07-01 19:47:50 +0000533 if (IsImageGray(image,exception) != MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000534 {
535 if (image->matte != MagickFalse)
536 return(GrayscaleMatteType);
537 return(GrayscaleType);
538 }
539 if (IsPaletteImage(image,exception) != MagickFalse)
540 {
541 if (image->matte != MagickFalse)
542 return(PaletteMatteType);
543 return(PaletteType);
544 }
545 if (image->matte != MagickFalse)
546 return(TrueColorMatteType);
547 return(TrueColorType);
548}
549
550/*
551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
552% %
553% %
554% %
cristy4c08aed2011-07-01 19:47:50 +0000555% I s I m a g e G r a y %
cristyda06ed12009-10-14 18:36:54 +0000556% %
557% %
558% %
559%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
560%
cristy4c08aed2011-07-01 19:47:50 +0000561% IsImageGray() returns MagickTrue if all the pixels in the image have the
cristyda06ed12009-10-14 18:36:54 +0000562% same red, green, and blue intensities.
563%
cristy4c08aed2011-07-01 19:47:50 +0000564% The format of the IsImageGray method is:
cristyda06ed12009-10-14 18:36:54 +0000565%
cristy4c08aed2011-07-01 19:47:50 +0000566% MagickBooleanType IsImageGray(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000567% ExceptionInfo *exception)
568%
569% A description of each parameter follows:
570%
571% o image: the image.
572%
573% o exception: return any errors or warnings in this structure.
574%
575*/
cristy4c08aed2011-07-01 19:47:50 +0000576MagickExport MagickBooleanType IsImageGray(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000577 ExceptionInfo *exception)
578{
cristy0910f242010-04-01 18:55:09 +0000579 CacheView
580 *image_view;
581
cristyda06ed12009-10-14 18:36:54 +0000582 ImageType
583 type;
584
cristy4c08aed2011-07-01 19:47:50 +0000585 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000586 *p;
587
cristybb503372010-05-27 20:51:26 +0000588 register ssize_t
cristy0910f242010-04-01 18:55:09 +0000589 x;
590
cristy95802a72010-09-05 19:07:17 +0000591 ssize_t
592 y;
593
cristyda06ed12009-10-14 18:36:54 +0000594 assert(image != (Image *) NULL);
595 assert(image->signature == MagickSignature);
596 if (image->debug != MagickFalse)
597 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
598 if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
599 (image->type == GrayscaleMatteType))
600 return(MagickTrue);
601 if (image->colorspace == CMYKColorspace)
602 return(MagickFalse);
603 type=BilevelType;
cristy0910f242010-04-01 18:55:09 +0000604 image_view=AcquireCacheView(image);
cristybb503372010-05-27 20:51:26 +0000605 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000606 {
cristy0910f242010-04-01 18:55:09 +0000607 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000608 if (p == (const Quantum *) NULL)
cristy0910f242010-04-01 18:55:09 +0000609 break;
cristybb503372010-05-27 20:51:26 +0000610 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000611 {
cristy4c08aed2011-07-01 19:47:50 +0000612 if (IsPixelGray(image,p) == MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000613 {
cristy5f1c1ff2010-12-23 21:38:06 +0000614 type=UndefinedType;
cristyda06ed12009-10-14 18:36:54 +0000615 break;
cristy0910f242010-04-01 18:55:09 +0000616 }
cristy4c08aed2011-07-01 19:47:50 +0000617 if ((type == BilevelType) &&
618 (IsPixelMonochrome(image,p) == MagickFalse))
cristy0910f242010-04-01 18:55:09 +0000619 type=GrayscaleType;
cristy4c08aed2011-07-01 19:47:50 +0000620 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000621 }
cristy5f1c1ff2010-12-23 21:38:06 +0000622 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000623 break;
cristyda06ed12009-10-14 18:36:54 +0000624 }
cristy0910f242010-04-01 18:55:09 +0000625 image_view=DestroyCacheView(image_view);
cristy5f1c1ff2010-12-23 21:38:06 +0000626 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000627 return(MagickFalse);
628 ((Image *) image)->type=type;
629 if ((type == GrayscaleType) && (image->matte != MagickFalse))
630 ((Image *) image)->type=GrayscaleMatteType;
631 return(MagickTrue);
632}
633
634/*
635%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636% %
637% %
638% %
cristy4c08aed2011-07-01 19:47:50 +0000639% I s I m a g e M o n o c h r o m e %
cristyda06ed12009-10-14 18:36:54 +0000640% %
641% %
642% %
643%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644%
cristy4c08aed2011-07-01 19:47:50 +0000645% IsImageMonochrome() returns MagickTrue if all the pixels in the image have
cristyda06ed12009-10-14 18:36:54 +0000646% the same red, green, and blue intensities and the intensity is either
647% 0 or QuantumRange.
648%
cristy4c08aed2011-07-01 19:47:50 +0000649% The format of the IsImageMonochrome method is:
cristyda06ed12009-10-14 18:36:54 +0000650%
cristy4c08aed2011-07-01 19:47:50 +0000651% MagickBooleanType IsImageMonochrome(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000652% ExceptionInfo *exception)
653%
654% A description of each parameter follows:
655%
656% o image: the image.
657%
658% o exception: return any errors or warnings in this structure.
659%
660*/
cristy4c08aed2011-07-01 19:47:50 +0000661MagickExport MagickBooleanType IsImageMonochrome(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000662 ExceptionInfo *exception)
663{
cristy0910f242010-04-01 18:55:09 +0000664 CacheView
665 *image_view;
666
cristyda06ed12009-10-14 18:36:54 +0000667 ImageType
668 type;
669
cristybb503372010-05-27 20:51:26 +0000670 register ssize_t
cristy0910f242010-04-01 18:55:09 +0000671 x;
672
cristy4c08aed2011-07-01 19:47:50 +0000673 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000674 *p;
675
cristy9d314ff2011-03-09 01:30:28 +0000676 ssize_t
677 y;
678
cristyda06ed12009-10-14 18:36:54 +0000679 assert(image != (Image *) NULL);
680 assert(image->signature == MagickSignature);
681 if (image->debug != MagickFalse)
682 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
683 if (image->type == BilevelType)
684 return(MagickTrue);
685 if (image->colorspace == CMYKColorspace)
686 return(MagickFalse);
687 type=BilevelType;
cristy0910f242010-04-01 18:55:09 +0000688 image_view=AcquireCacheView(image);
cristybb503372010-05-27 20:51:26 +0000689 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000690 {
cristy0910f242010-04-01 18:55:09 +0000691 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000692 if (p == (const Quantum *) NULL)
cristy0910f242010-04-01 18:55:09 +0000693 break;
cristybb503372010-05-27 20:51:26 +0000694 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000695 {
cristy4c08aed2011-07-01 19:47:50 +0000696 if (IsPixelMonochrome(image,p) == MagickFalse)
cristyda06ed12009-10-14 18:36:54 +0000697 {
cristy5f1c1ff2010-12-23 21:38:06 +0000698 type=UndefinedType;
cristyda06ed12009-10-14 18:36:54 +0000699 break;
cristy0910f242010-04-01 18:55:09 +0000700 }
cristy4c08aed2011-07-01 19:47:50 +0000701 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000702 }
cristy5f1c1ff2010-12-23 21:38:06 +0000703 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000704 break;
cristyda06ed12009-10-14 18:36:54 +0000705 }
cristy0910f242010-04-01 18:55:09 +0000706 image_view=DestroyCacheView(image_view);
cristy5f1c1ff2010-12-23 21:38:06 +0000707 if (type == UndefinedType)
cristyda06ed12009-10-14 18:36:54 +0000708 return(MagickFalse);
709 ((Image *) image)->type=type;
710 return(MagickTrue);
711}
712
713/*
714%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715% %
716% %
717% %
cristy4c08aed2011-07-01 19:47:50 +0000718% I s I m a g e O p a q u e %
cristyda06ed12009-10-14 18:36:54 +0000719% %
720% %
721% %
722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723%
cristy4c08aed2011-07-01 19:47:50 +0000724% IsImageOpaque() returns MagickTrue if none of the pixels in the image have
cristyda06ed12009-10-14 18:36:54 +0000725% an opacity value other than opaque (0).
726%
cristy4c08aed2011-07-01 19:47:50 +0000727% The format of the IsImageOpaque method is:
cristyda06ed12009-10-14 18:36:54 +0000728%
cristy4c08aed2011-07-01 19:47:50 +0000729% MagickBooleanType IsImageOpaque(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000730% ExceptionInfo *exception)
731%
732% A description of each parameter follows:
733%
734% o image: the image.
735%
736% o exception: return any errors or warnings in this structure.
737%
738*/
cristy4c08aed2011-07-01 19:47:50 +0000739MagickExport MagickBooleanType IsImageOpaque(const Image *image,
cristyda06ed12009-10-14 18:36:54 +0000740 ExceptionInfo *exception)
741{
cristyc4c8d132010-01-07 01:58:38 +0000742 CacheView
743 *image_view;
744
cristy4c08aed2011-07-01 19:47:50 +0000745 register const Quantum
cristyda06ed12009-10-14 18:36:54 +0000746 *p;
747
cristybb503372010-05-27 20:51:26 +0000748 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000749 x;
750
cristy9d314ff2011-03-09 01:30:28 +0000751 ssize_t
752 y;
753
cristyda06ed12009-10-14 18:36:54 +0000754 /*
755 Determine if image is opaque.
756 */
757 assert(image != (Image *) NULL);
758 assert(image->signature == MagickSignature);
759 if (image->debug != MagickFalse)
760 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
761 if (image->matte == MagickFalse)
762 return(MagickTrue);
763 image_view=AcquireCacheView(image);
cristybb503372010-05-27 20:51:26 +0000764 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000765 {
766 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000767 if (p == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000768 break;
cristybb503372010-05-27 20:51:26 +0000769 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000770 {
cristy4c08aed2011-07-01 19:47:50 +0000771 if (GetPixelAlpha(image,p) != OpaqueAlpha)
cristyda06ed12009-10-14 18:36:54 +0000772 break;
cristy4c08aed2011-07-01 19:47:50 +0000773 p+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000774 }
cristybb503372010-05-27 20:51:26 +0000775 if (x < (ssize_t) image->columns)
cristyda06ed12009-10-14 18:36:54 +0000776 break;
777 }
778 image_view=DestroyCacheView(image_view);
cristybb503372010-05-27 20:51:26 +0000779 return(y < (ssize_t) image->rows ? MagickFalse : MagickTrue);
cristyda06ed12009-10-14 18:36:54 +0000780}
781
782/*
783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784% %
785% %
786% %
787% S e t I m a g e C h a n n e l D e p t h %
788% %
789% %
790% %
791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792%
793% SetImageChannelDepth() sets the depth of the image.
794%
795% The format of the SetImageChannelDepth method is:
796%
cristybb503372010-05-27 20:51:26 +0000797% MagickBooleanType SetImageDepth(Image *image,const size_t depth)
cristyda06ed12009-10-14 18:36:54 +0000798% MagickBooleanType SetImageChannelDepth(Image *image,
cristybb503372010-05-27 20:51:26 +0000799% const ChannelType channel,const size_t depth)
cristyda06ed12009-10-14 18:36:54 +0000800%
801% A description of each parameter follows:
802%
803% o image: the image.
804%
805% o channel: the channel.
806%
807% o depth: the image depth.
808%
809*/
cristyda06ed12009-10-14 18:36:54 +0000810MagickExport MagickBooleanType SetImageDepth(Image *image,
cristybb503372010-05-27 20:51:26 +0000811 const size_t depth)
cristyda06ed12009-10-14 18:36:54 +0000812{
cristy9a9230e2011-04-26 14:56:14 +0000813 return(SetImageChannelDepth(image,CompositeChannels,depth));
cristyda06ed12009-10-14 18:36:54 +0000814}
815
816MagickExport MagickBooleanType SetImageChannelDepth(Image *image,
cristybb503372010-05-27 20:51:26 +0000817 const ChannelType channel,const size_t depth)
cristyda06ed12009-10-14 18:36:54 +0000818{
cristyc4c8d132010-01-07 01:58:38 +0000819 CacheView
820 *image_view;
821
cristyda06ed12009-10-14 18:36:54 +0000822 ExceptionInfo
823 *exception;
824
cristyda06ed12009-10-14 18:36:54 +0000825 MagickBooleanType
826 status;
827
828 QuantumAny
cristyb6d6f7c2010-06-09 13:17:57 +0000829 range;
cristyda06ed12009-10-14 18:36:54 +0000830
cristy9d314ff2011-03-09 01:30:28 +0000831 ssize_t
832 y;
833
cristyda06ed12009-10-14 18:36:54 +0000834 assert(image != (Image *) NULL);
835 if (image->debug != MagickFalse)
836 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
837 assert(image->signature == MagickSignature);
cristybb503372010-05-27 20:51:26 +0000838 if (GetImageDepth(image,&image->exception) <= (size_t)
cristyda06ed12009-10-14 18:36:54 +0000839 MagickMin((double) depth,(double) MAGICKCORE_QUANTUM_DEPTH))
840 {
841 image->depth=depth;
842 return(MagickTrue);
843 }
844 /*
845 Scale pixels to desired depth.
846 */
847 status=MagickTrue;
cristyb6d6f7c2010-06-09 13:17:57 +0000848 range=GetQuantumRange(depth);
cristyda06ed12009-10-14 18:36:54 +0000849 exception=(&image->exception);
850 image_view=AcquireCacheView(image);
cristyb5d5f722009-11-04 03:03:49 +0000851#if defined(MAGICKCORE_OPENMP_SUPPORT)
852 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000853#endif
cristybb503372010-05-27 20:51:26 +0000854 for (y=0; y < (ssize_t) image->rows; y++)
cristyda06ed12009-10-14 18:36:54 +0000855 {
cristybb503372010-05-27 20:51:26 +0000856 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000857 x;
858
cristy4c08aed2011-07-01 19:47:50 +0000859 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000860 *restrict q;
cristyda06ed12009-10-14 18:36:54 +0000861
862 if (status == MagickFalse)
863 continue;
864 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
865 exception);
cristy4c08aed2011-07-01 19:47:50 +0000866 if (q == (const Quantum *) NULL)
cristyda06ed12009-10-14 18:36:54 +0000867 {
868 status=MagickFalse;
869 continue;
870 }
cristybb503372010-05-27 20:51:26 +0000871 for (x=0; x < (ssize_t) image->columns; x++)
cristyda06ed12009-10-14 18:36:54 +0000872 {
cristy2b9582a2011-07-04 17:38:56 +0000873 if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000874 SetPixelRed(image,ScaleAnyToQuantum(ScaleQuantumToAny(
875 GetPixelRed(image,q),range),range),q);
cristy2b9582a2011-07-04 17:38:56 +0000876 if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000877 SetPixelGreen(image,ScaleAnyToQuantum(ScaleQuantumToAny(
878 GetPixelGreen(image,q),range),range),q);
cristy2b9582a2011-07-04 17:38:56 +0000879 if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000880 SetPixelBlue(image,ScaleAnyToQuantum(ScaleQuantumToAny(
881 GetPixelBlue(image,q),range),range),q);
cristy2b9582a2011-07-04 17:38:56 +0000882 if (((GetPixelBlackTraits(image) & ActivePixelTrait) != 0) &&
cristyda06ed12009-10-14 18:36:54 +0000883 (image->colorspace == CMYKColorspace))
cristy4c08aed2011-07-01 19:47:50 +0000884 SetPixelBlack(image,ScaleAnyToQuantum(ScaleQuantumToAny(
885 GetPixelBlack(image,q),range),range),q);
cristy2b9582a2011-07-04 17:38:56 +0000886 if (((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0) &&
887 (image->matte != MagickFalse))
cristy4c08aed2011-07-01 19:47:50 +0000888 SetPixelAlpha(image,ScaleAnyToQuantum(ScaleQuantumToAny(
889 GetPixelAlpha(image,q),range),range),q);
890 q+=GetPixelChannels(image);
cristyda06ed12009-10-14 18:36:54 +0000891 }
892 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
893 {
894 status=MagickFalse;
895 continue;
896 }
897 }
898 image_view=DestroyCacheView(image_view);
899 if (image->storage_class == PseudoClass)
900 {
cristybb503372010-05-27 20:51:26 +0000901 register ssize_t
cristyda06ed12009-10-14 18:36:54 +0000902 i;
903
904 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000905 *restrict p;
cristyda06ed12009-10-14 18:36:54 +0000906
907 p=image->colormap;
cristyb5d5f722009-11-04 03:03:49 +0000908#if defined(MAGICKCORE_OPENMP_SUPPORT)
909 #pragma omp parallel for schedule(dynamic,4) shared(status)
cristyda06ed12009-10-14 18:36:54 +0000910#endif
cristybb503372010-05-27 20:51:26 +0000911 for (i=0; i < (ssize_t) image->colors; i++)
cristyda06ed12009-10-14 18:36:54 +0000912 {
cristy2b9582a2011-07-04 17:38:56 +0000913 if ((GetPixelRedTraits(image) & ActivePixelTrait) != 0)
cristy9384eed2011-06-13 14:16:32 +0000914 p->red=ScaleAnyToQuantum(ScaleQuantumToAny(p->red,range),range);
cristy2b9582a2011-07-04 17:38:56 +0000915 if ((GetPixelGreenTraits(image) & ActivePixelTrait) != 0)
cristy9384eed2011-06-13 14:16:32 +0000916 p->green=ScaleAnyToQuantum(ScaleQuantumToAny(p->green,range),range);
cristy2b9582a2011-07-04 17:38:56 +0000917 if ((GetPixelBlueTraits(image) & ActivePixelTrait) != 0)
cristy9384eed2011-06-13 14:16:32 +0000918 p->blue=ScaleAnyToQuantum(ScaleQuantumToAny(p->blue,range),range);
cristy2b9582a2011-07-04 17:38:56 +0000919 if ((GetPixelAlphaTraits(image) & ActivePixelTrait) != 0)
cristy4c08aed2011-07-01 19:47:50 +0000920 p->alpha=ScaleAnyToQuantum(ScaleQuantumToAny(p->alpha,range),range);
cristyda06ed12009-10-14 18:36:54 +0000921 p++;
922 }
923 }
924 image->depth=depth;
925 return(status);
926}