MagickCore  6.9.13-3
Convert, Edit, Or Compose Bitmap Images
 All Data Structures
colorspace.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % CCCC OOO L OOO RRRR SSSSS PPPP AAA CCCC EEEEE %
7 % C O O L O O R R SS P P A A C E %
8 % C O O L O O RRRR SSS PPPP AAAAA C EEE %
9 % C O O L O O R R SS P A A C E %
10 % CCCC OOO LLLLL OOO R R SSSSS P A A CCCC EEEEE %
11 % %
12 % %
13 % MagickCore Image Colorspace Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % July 1992 %
18 % %
19 % %
20 % Copyright 1999 ImageMagick Studio LLC, a non-profit organization %
21 % 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 % https://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  Include declarations.
41 */
42 #include "magick/studio.h"
43 #include "magick/attribute.h"
44 #include "magick/cache.h"
45 #include "magick/cache-private.h"
46 #include "magick/cache-view.h"
47 #include "magick/color.h"
48 #include "magick/color-private.h"
49 #include "magick/colorspace.h"
50 #include "magick/colorspace-private.h"
51 #include "magick/exception.h"
52 #include "magick/exception-private.h"
53 #include "magick/enhance.h"
54 #include "magick/image.h"
55 #include "magick/image-private.h"
56 #include "magick/gem.h"
57 #include "magick/gem-private.h"
58 #include "magick/memory_.h"
59 #include "magick/monitor.h"
60 #include "magick/monitor-private.h"
61 #include "magick/pixel-private.h"
62 #include "magick/property.h"
63 #include "magick/quantize.h"
64 #include "magick/quantum.h"
65 #include "magick/resource_.h"
66 #include "magick/string_.h"
67 #include "magick/string-private.h"
68 #include "magick/utility.h"
69 
70 /*
71  Typedef declarations.
72 */
73 typedef struct _TransformPacket
74 {
75  MagickRealType
76  x,
77  y,
78  z;
80 
81 /*
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 % %
84 % %
85 % %
86 % G e t I m a g e C o l o r s p a c e T y p e %
87 % %
88 % %
89 % %
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 %
92 % GetImageColorspaceType() returns the potential colorspace of image:
93 % sRGBColorspaceType, RGBColorspaceType, GRAYColorspaceType, etc.
94 %
95 % To ensure the image type matches its potential, use SetImageColorspaceType():
96 %
97 % (void) SetImageColorspaceType(image,GetImageColorspaceType(image),
98 % exception);
99 %
100 % The format of the GetImageColorspaceType method is:
101 %
102 % ColorspaceType GetImageColorspaceType(const Image *image,
103 % ExceptionInfo *exception)
104 %
105 % A description of each parameter follows:
106 %
107 % o image: the image.
108 %
109 % o exception: return any errors or warnings in this structure.
110 %
111 */
112 MagickExport ColorspaceType GetImageColorspaceType(const Image *image,
113  ExceptionInfo *exception)
114 {
115  ColorspaceType
116  colorspace;
117 
118  ImageType
119  type;
120 
121  assert(image != (Image *) NULL);
122  assert(image->signature == MagickCoreSignature);
123  if (IsEventLogging() != MagickFalse)
124  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
125  colorspace=image->colorspace;
126  type=IdentifyImageType(image,exception);
127  if ((type == BilevelType) || (type == GrayscaleType) ||
128  (type == GrayscaleMatteType))
129  colorspace=GRAYColorspace;
130  return(colorspace);
131 }
132 
133 /*
134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % %
136 % %
137 % %
138 + R G B T r a n s f o r m I m a g e %
139 % %
140 % %
141 % %
142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 %
144 % RGBTransformImage() converts the reference image from sRGB to an alternate
145 % colorspace. The transformation matrices are not the standard ones: the
146 % weights are rescaled to normalized the range of the transformed values to
147 % be [0..QuantumRange].
148 %
149 % The format of the RGBTransformImage method is:
150 %
151 % MagickBooleanType RGBTransformImage(Image *image,
152 % const ColorspaceType colorspace)
153 %
154 % A description of each parameter follows:
155 %
156 % o image: the image.
157 %
158 % o colorspace: the colorspace to transform the image to.
159 %
160 */
161 
162 static inline void ConvertRGBToCMY(const Quantum red,const Quantum green,
163  const Quantum blue,double *cyan,double *magenta,double *yellow)
164 {
165  *cyan=QuantumScale*((double) QuantumRange-(double) red);
166  *magenta=QuantumScale*((double) QuantumRange-(double) green);
167  *yellow=QuantumScale*((double) QuantumRange-(double) blue);
168 }
169 
170 static void ConvertRGBToLab(const Quantum red,const Quantum green,
171  const Quantum blue,double *L,double *a,double *b)
172 {
173  double
174  X,
175  Y,
176  Z;
177 
178  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
179  ConvertXYZToLab(X,Y,Z,L,a,b);
180 }
181 
182 static inline void ConvertXYZToLMS(const double x,const double y,
183  const double z,double *L,double *M,double *S)
184 {
185  *L=0.7328*x+0.4296*y-0.1624*z;
186  *M=(-0.7036*x+1.6975*y+0.0061*z);
187  *S=0.0030*x+0.0136*y+0.9834*z;
188 }
189 
190 static void ConvertRGBToLMS(const Quantum red,const Quantum green,
191  const Quantum blue,double *L,double *M,double *S)
192 {
193  double
194  X,
195  Y,
196  Z;
197 
198  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
199  ConvertXYZToLMS(X,Y,Z,L,M,S);
200 }
201 
202 static void ConvertRGBToLuv(const Quantum red,const Quantum green,
203  const Quantum blue,double *L,double *u,double *v)
204 {
205  double
206  X,
207  Y,
208  Z;
209 
210  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
211  ConvertXYZToLuv(X,Y,Z,L,u,v);
212 }
213 
214 static void ConvertRGBToxyY(const Quantum red,const Quantum green,
215  const Quantum blue,double *low_x,double *low_y,double *cap_Y)
216 {
217  double
218  gamma,
219  X,
220  Y,
221  Z;
222 
223  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
224  gamma=PerceptibleReciprocal(X+Y+Z);
225  *low_x=gamma*X;
226  *low_y=gamma*Y;
227  *cap_Y=Y;
228 }
229 
230 static void ConvertRGBToYPbPr(const Quantum red,const Quantum green,
231  const Quantum blue,double *Y,double *Pb,double *Pr)
232 {
233  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
234  (double) blue);
235  *Pb=QuantumScale*((-0.1687367)*(double) red-0.331264*(double) green+0.5*
236  (double) blue)+0.5;
237  *Pr=QuantumScale*(0.5*(double) red-0.418688*(double) green-0.081312*
238  (double) blue)+0.5;
239 }
240 
241 static void ConvertRGBToYCbCr(const Quantum red,const Quantum green,
242  const Quantum blue,double *Y,double *Cb,double *Cr)
243 {
244  ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
245 }
246 
247 static void ConvertRGBToYUV(const Quantum red,const Quantum green,
248  const Quantum blue,double *Y,double *U,double *V)
249 {
250  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
251  (double) blue);
252  *U=QuantumScale*((-0.147)*(double) red-0.289*(double) green+0.436*
253  (double) blue)+0.5;
254  *V=QuantumScale*(0.615*(double) red-0.515*(double) green-0.100*
255  (double) blue)+0.5;
256 }
257 
258 static void ConvertRGBToYDbDr(const Quantum red,const Quantum green,
259  const Quantum blue,double *Y,double *Db,double *Dr)
260 {
261  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
262  (double) blue);
263  *Db=QuantumScale*(-0.450*(double) red-0.883*(double) green+1.333*
264  (double) blue)+0.5;
265  *Dr=QuantumScale*(-1.333*(double) red+1.116*(double) green+0.217*
266  (double) blue)+0.5;
267 }
268 
269 static void ConvertRGBToYIQ(const Quantum red,const Quantum green,
270  const Quantum blue,double *Y,double *I,double *Q)
271 {
272  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
273  (double) blue);
274  *I=QuantumScale*(0.595716*(double) red-0.274453*(double) green-0.321263*
275  (double) blue)+0.5;
276  *Q=QuantumScale*(0.211456*(double) red-0.522591*(double) green+0.311135*
277  (double) blue)+0.5;
278 }
279 
280 MagickExport MagickBooleanType RGBTransformImage(Image *image,
281  const ColorspaceType colorspace)
282 {
283 #define RGBTransformImageTag "RGBTransform/Image"
284 
285  CacheView
286  *image_view;
287 
289  *exception;
290 
291  MagickBooleanType
292  status;
293 
294  MagickOffsetType
295  progress;
296 
298  primary_info;
299 
300  ssize_t
301  i;
302 
303  ssize_t
304  y;
305 
307  *x_map,
308  *y_map,
309  *z_map;
310 
311  assert(image != (Image *) NULL);
312  assert(image->signature == MagickCoreSignature);
313  assert(colorspace != sRGBColorspace);
314  assert(colorspace != TransparentColorspace);
315  assert(colorspace != UndefinedColorspace);
316  if (IsEventLogging() != MagickFalse)
317  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
318  status=MagickTrue;
319  progress=0;
320  exception=(&image->exception);
321  switch (colorspace)
322  {
323  case CMYKColorspace:
324  {
326  zero;
327 
328  /*
329  Convert RGB to CMYK colorspace.
330  */
331  if (image->storage_class == PseudoClass)
332  {
333  if (SyncImage(image) == MagickFalse)
334  return(MagickFalse);
335  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
336  return(MagickFalse);
337  }
338  if (SetImageColorspace(image,colorspace) == MagickFalse)
339  return(MagickFalse);
340  GetMagickPixelPacket(image,&zero);
341  image_view=AcquireAuthenticCacheView(image,exception);
342 #if defined(MAGICKCORE_OPENMP_SUPPORT)
343  #pragma omp parallel for schedule(static) shared(status) \
344  magick_number_threads(image,image,image->rows,1)
345 #endif
346  for (y=0; y < (ssize_t) image->rows; y++)
347  {
348  MagickBooleanType
349  sync;
350 
352  pixel;
353 
354  IndexPacket
355  *magick_restrict indexes;
356 
357  ssize_t
358  x;
359 
361  *magick_restrict q;
362 
363  if (status == MagickFalse)
364  continue;
365  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
366  exception);
367  if (q == (PixelPacket *) NULL)
368  {
369  status=MagickFalse;
370  continue;
371  }
372  indexes=GetCacheViewAuthenticIndexQueue(image_view);
373  pixel=zero;
374  for (x=0; x < (ssize_t) image->columns; x++)
375  {
376  SetMagickPixelPacket(image,q,indexes+x,&pixel);
377  pixel.red=(MagickRealType) pixel.red;
378  pixel.green=(MagickRealType) pixel.green;
379  pixel.blue=(MagickRealType) pixel.blue;
380  ConvertRGBToCMYK(&pixel);
381  SetPixelPacket(image,&pixel,q,indexes+x);
382  q++;
383  }
384  sync=SyncCacheViewAuthenticPixels(image_view,exception);
385  if (sync == MagickFalse)
386  status=MagickFalse;
387  }
388  image_view=DestroyCacheView(image_view);
389  image->type=image->matte == MagickFalse ? ColorSeparationType :
390  ColorSeparationMatteType;
391  if (SetImageColorspace(image,colorspace) == MagickFalse)
392  return(MagickFalse);
393  return(status);
394  }
395  case LinearGRAYColorspace:
396  {
397  /*
398  Transform image from sRGB to GRAY.
399  */
400  if (image->storage_class == PseudoClass)
401  {
402  if (SyncImage(image) == MagickFalse)
403  return(MagickFalse);
404  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
405  return(MagickFalse);
406  }
407  image_view=AcquireAuthenticCacheView(image,exception);
408 #if defined(MAGICKCORE_OPENMP_SUPPORT)
409  #pragma omp parallel for schedule(static) shared(status) \
410  magick_number_threads(image,image,image->rows,1)
411 #endif
412  for (y=0; y < (ssize_t) image->rows; y++)
413  {
414  MagickBooleanType
415  sync;
416 
417  ssize_t
418  x;
419 
421  *magick_restrict q;
422 
423  if (status == MagickFalse)
424  continue;
425  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
426  exception);
427  if (q == (PixelPacket *) NULL)
428  {
429  status=MagickFalse;
430  continue;
431  }
432  for (x=0; x < (ssize_t) image->columns; x++)
433  {
434  MagickRealType
435  gray;
436 
437  gray=0.212656*DecodePixelGamma(GetPixelRed(q))+0.715158*
438  DecodePixelGamma(GetPixelGreen(q))+0.072186*
439  DecodePixelGamma(GetPixelBlue(q));
440  SetPixelGray(q,ClampToQuantum(gray));
441  q++;
442  }
443  sync=SyncCacheViewAuthenticPixels(image_view,exception);
444  if (sync == MagickFalse)
445  status=MagickFalse;
446  }
447  image_view=DestroyCacheView(image_view);
448  if (SetImageColorspace(image,colorspace) == MagickFalse)
449  return(MagickFalse);
450  image->type=GrayscaleType;
451  return(status);
452  }
453  case GRAYColorspace:
454  {
455  /*
456  Transform image from sRGB to GRAY.
457  */
458  if (image->storage_class == PseudoClass)
459  {
460  if (SyncImage(image) == MagickFalse)
461  return(MagickFalse);
462  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
463  return(MagickFalse);
464  }
465  image_view=AcquireAuthenticCacheView(image,exception);
466 #if defined(MAGICKCORE_OPENMP_SUPPORT)
467  #pragma omp parallel for schedule(static) shared(status) \
468  magick_number_threads(image,image,image->rows,1)
469 #endif
470  for (y=0; y < (ssize_t) image->rows; y++)
471  {
472  MagickBooleanType
473  sync;
474 
475  ssize_t
476  x;
477 
479  *magick_restrict q;
480 
481  if (status == MagickFalse)
482  continue;
483  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
484  exception);
485  if (q == (PixelPacket *) NULL)
486  {
487  status=MagickFalse;
488  continue;
489  }
490  for (x=0; x < (ssize_t) image->columns; x++)
491  {
492  MagickRealType
493  gray;
494 
495  gray=0.212656*(double) GetPixelRed(q)+0.715158*(double)
496  GetPixelGreen(q)+0.072186*(double) GetPixelBlue(q);
497  SetPixelGray(q,ClampToQuantum(gray));
498  q++;
499  }
500  sync=SyncCacheViewAuthenticPixels(image_view,exception);
501  if (sync == MagickFalse)
502  status=MagickFalse;
503  }
504  image_view=DestroyCacheView(image_view);
505  if (SetImageColorspace(image,colorspace) == MagickFalse)
506  return(MagickFalse);
507  image->type=GrayscaleType;
508  return(status);
509  }
510  case CMYColorspace:
511  case HCLColorspace:
512  case HCLpColorspace:
513  case HSBColorspace:
514  case HSIColorspace:
515  case HSLColorspace:
516  case HSVColorspace:
517  case HWBColorspace:
518  case LabColorspace:
519  case LCHColorspace:
520  case LCHabColorspace:
521  case LCHuvColorspace:
522  case LMSColorspace:
523  case LuvColorspace:
524  case xyYColorspace:
525  case XYZColorspace:
526  case YCbCrColorspace:
527  case YDbDrColorspace:
528  case YIQColorspace:
529  case YPbPrColorspace:
530  case YUVColorspace:
531  {
532  /*
533  Transform image from sRGB to HSI.
534  */
535  if (image->storage_class == PseudoClass)
536  {
537  if (SyncImage(image) == MagickFalse)
538  return(MagickFalse);
539  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
540  return(MagickFalse);
541  }
542  image_view=AcquireAuthenticCacheView(image,exception);
543 #if defined(MAGICKCORE_OPENMP_SUPPORT)
544  #pragma omp parallel for schedule(static) shared(status) \
545  magick_number_threads(image,image,image->rows,1)
546 #endif
547  for (y=0; y < (ssize_t) image->rows; y++)
548  {
549  MagickBooleanType
550  sync;
551 
552  ssize_t
553  x;
554 
556  *magick_restrict q;
557 
558  if (status == MagickFalse)
559  continue;
560  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
561  exception);
562  if (q == (PixelPacket *) NULL)
563  {
564  status=MagickFalse;
565  continue;
566  }
567  for (x=0; x < (ssize_t) image->columns; x++)
568  {
569  double
570  X,
571  Y,
572  Z;
573 
574  Quantum
575  blue,
576  green,
577  red;
578 
579  red=ClampToQuantum((MagickRealType) GetPixelRed(q));
580  green=ClampToQuantum((MagickRealType) GetPixelGreen(q));
581  blue=ClampToQuantum((MagickRealType) GetPixelBlue(q));
582  switch (colorspace)
583  {
584  case CMYColorspace:
585  {
586  ConvertRGBToCMY(red,green,blue,&X,&Y,&Z);
587  break;
588  }
589  case HCLColorspace:
590  {
591  ConvertRGBToHCL(red,green,blue,&X,&Y,&Z);
592  break;
593  }
594  case HCLpColorspace:
595  {
596  ConvertRGBToHCLp(red,green,blue,&X,&Y,&Z);
597  break;
598  }
599  case HSBColorspace:
600  {
601  ConvertRGBToHSB(red,green,blue,&X,&Y,&Z);
602  break;
603  }
604  case HSIColorspace:
605  {
606  ConvertRGBToHSI(red,green,blue,&X,&Y,&Z);
607  break;
608  }
609  case HSLColorspace:
610  {
611  ConvertRGBToHSL(red,green,blue,&X,&Y,&Z);
612  break;
613  }
614  case HSVColorspace:
615  {
616  ConvertRGBToHSV(red,green,blue,&X,&Y,&Z);
617  break;
618  }
619  case HWBColorspace:
620  {
621  ConvertRGBToHWB(red,green,blue,&X,&Y,&Z);
622  break;
623  }
624  case LabColorspace:
625  {
626  ConvertRGBToLab(red,green,blue,&X,&Y,&Z);
627  break;
628  }
629  case LCHColorspace:
630  case LCHabColorspace:
631  {
632  ConvertRGBToLCHab(red,green,blue,&X,&Y,&Z);
633  break;
634  }
635  case LCHuvColorspace:
636  {
637  ConvertRGBToLCHuv(red,green,blue,&X,&Y,&Z);
638  break;
639  }
640  case LMSColorspace:
641  {
642  ConvertRGBToLMS(red,green,blue,&X,&Y,&Z);
643  break;
644  }
645  case LuvColorspace:
646  {
647  ConvertRGBToLuv(red,green,blue,&X,&Y,&Z);
648  break;
649  }
650  case xyYColorspace:
651  {
652  ConvertRGBToxyY(red,green,blue,&X,&Y,&Z);
653  break;
654  }
655  case XYZColorspace:
656  {
657  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
658  break;
659  }
660  case YCbCrColorspace:
661  {
662  ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z);
663  break;
664  }
665  case YDbDrColorspace:
666  {
667  ConvertRGBToYDbDr(red,green,blue,&X,&Y,&Z);
668  break;
669  }
670  case YIQColorspace:
671  {
672  ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z);
673  break;
674  }
675  case YPbPrColorspace:
676  {
677  ConvertRGBToYPbPr(red,green,blue,&X,&Y,&Z);
678  break;
679  }
680  case YUVColorspace:
681  {
682  ConvertRGBToYUV(red,green,blue,&X,&Y,&Z);
683  break;
684  }
685  default:
686  {
687  X=QuantumScale*(double) red;
688  Y=QuantumScale*(double) green;
689  Z=QuantumScale*(double) blue;
690  break;
691  }
692  }
693  SetPixelRed(q,ClampToQuantum((MagickRealType) QuantumRange*X));
694  SetPixelGreen(q,ClampToQuantum((MagickRealType) QuantumRange*Y));
695  SetPixelBlue(q,ClampToQuantum((MagickRealType) QuantumRange*Z));
696  q++;
697  }
698  sync=SyncCacheViewAuthenticPixels(image_view,exception);
699  if (sync == MagickFalse)
700  status=MagickFalse;
701  }
702  image_view=DestroyCacheView(image_view);
703  if (SetImageColorspace(image,colorspace) == MagickFalse)
704  return(MagickFalse);
705  return(status);
706  }
707  case LogColorspace:
708  {
709 #define DisplayGamma (1.0/1.7)
710 #define FilmGamma 0.6
711 #define ReferenceBlack 95.0
712 #define ReferenceWhite 685.0
713 
714  const char
715  *value;
716 
717  double
718  black,
719  density,
720  film_gamma,
721  gamma,
722  reference_black,
723  reference_white;
724 
725  Quantum
726  *logmap;
727 
728  /*
729  Transform RGB to Log colorspace.
730  */
731  density=DisplayGamma;
732  gamma=DisplayGamma;
733  value=GetImageProperty(image,"gamma");
734  if (value != (const char *) NULL)
735  gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
736  film_gamma=FilmGamma;
737  value=GetImageProperty(image,"film-gamma");
738  if (value != (const char *) NULL)
739  film_gamma=StringToDouble(value,(char **) NULL);
740  reference_black=ReferenceBlack;
741  value=GetImageProperty(image,"reference-black");
742  if (value != (const char *) NULL)
743  reference_black=StringToDouble(value,(char **) NULL);
744  reference_white=ReferenceWhite;
745  value=GetImageProperty(image,"reference-white");
746  if (value != (const char *) NULL)
747  reference_white=StringToDouble(value,(char **) NULL);
748  logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
749  sizeof(*logmap));
750  if (logmap == (Quantum *) NULL)
751  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
752  image->filename);
753  black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002*
754  PerceptibleReciprocal(film_gamma));
755 #if defined(MAGICKCORE_OPENMP_SUPPORT)
756  #pragma omp parallel for schedule(static)
757 #endif
758  for (i=0; i <= (ssize_t) MaxMap; i++)
759  logmap[i]=ScaleMapToQuantum((MagickRealType) (MaxMap*(reference_white+
760  log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002*
761  PerceptibleReciprocal(film_gamma)))/1024.0));
762  image_view=AcquireAuthenticCacheView(image,exception);
763 #if defined(MAGICKCORE_OPENMP_SUPPORT)
764  #pragma omp parallel for schedule(static) shared(status) \
765  magick_number_threads(image,image,image->rows,1)
766 #endif
767  for (y=0; y < (ssize_t) image->rows; y++)
768  {
769  MagickBooleanType
770  sync;
771 
772  ssize_t
773  x;
774 
776  *magick_restrict q;
777 
778  if (status == MagickFalse)
779  continue;
780  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
781  exception);
782  if (q == (PixelPacket *) NULL)
783  {
784  status=MagickFalse;
785  continue;
786  }
787  for (x=(ssize_t) image->columns; x != 0; x--)
788  {
789  Quantum
790  blue,
791  green,
792  red;
793 
794  red=ClampToQuantum(DecodePixelGamma((MagickRealType)
795  GetPixelRed(q)));
796  green=ClampToQuantum(DecodePixelGamma((MagickRealType)
797  GetPixelGreen(q)));
798  blue=ClampToQuantum(DecodePixelGamma((MagickRealType)
799  GetPixelBlue(q)));
800  SetPixelRed(q,logmap[ScaleQuantumToMap(red)]);
801  SetPixelGreen(q,logmap[ScaleQuantumToMap(green)]);
802  SetPixelBlue(q,logmap[ScaleQuantumToMap(blue)]);
803  q++;
804  }
805  sync=SyncCacheViewAuthenticPixels(image_view,exception);
806  if (sync == MagickFalse)
807  status=MagickFalse;
808  }
809  image_view=DestroyCacheView(image_view);
810  logmap=(Quantum *) RelinquishMagickMemory(logmap);
811  if (SetImageColorspace(image,colorspace) == MagickFalse)
812  return(MagickFalse);
813  return(status);
814  }
815  case RGBColorspace:
816  case scRGBColorspace:
817  {
818  /*
819  Transform image from sRGB to linear RGB.
820  */
821  if (image->storage_class == PseudoClass)
822  {
823  if (SyncImage(image) == MagickFalse)
824  return(MagickFalse);
825  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
826  return(MagickFalse);
827  }
828  image_view=AcquireAuthenticCacheView(image,exception);
829 #if defined(MAGICKCORE_OPENMP_SUPPORT)
830  #pragma omp parallel for schedule(static) shared(status) \
831  magick_number_threads(image,image,image->rows,1)
832 #endif
833  for (y=0; y < (ssize_t) image->rows; y++)
834  {
835  MagickBooleanType
836  sync;
837 
838  ssize_t
839  x;
840 
842  *magick_restrict q;
843 
844  if (status == MagickFalse)
845  continue;
846  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
847  exception);
848  if (q == (PixelPacket *) NULL)
849  {
850  status=MagickFalse;
851  continue;
852  }
853  for (x=0; x < (ssize_t) image->columns; x++)
854  {
855  Quantum
856  blue,
857  green,
858  red;
859 
860  red=ClampToQuantum(DecodePixelGamma((MagickRealType)
861  GetPixelRed(q)));
862  green=ClampToQuantum(DecodePixelGamma((MagickRealType)
863  GetPixelGreen(q)));
864  blue=ClampToQuantum(DecodePixelGamma((MagickRealType)
865  GetPixelBlue(q)));
866  SetPixelRed(q,red);
867  SetPixelGreen(q,green);
868  SetPixelBlue(q,blue);
869  q++;
870  }
871  sync=SyncCacheViewAuthenticPixels(image_view,exception);
872  if (sync == MagickFalse)
873  status=MagickFalse;
874  }
875  image_view=DestroyCacheView(image_view);
876  if (SetImageColorspace(image,colorspace) == MagickFalse)
877  return(MagickFalse);
878  return(status);
879  }
880  default:
881  break;
882  }
883  /*
884  Allocate the tables.
885  */
886  x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
887  sizeof(*x_map));
888  y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
889  sizeof(*y_map));
890  z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
891  sizeof(*z_map));
892  if ((x_map == (TransformPacket *) NULL) ||
893  (y_map == (TransformPacket *) NULL) ||
894  (z_map == (TransformPacket *) NULL))
895  {
896  if (x_map != (TransformPacket *) NULL)
897  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
898  if (y_map != (TransformPacket *) NULL)
899  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
900  if (z_map != (TransformPacket *) NULL)
901  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
902  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
903  image->filename);
904  }
905  (void) memset(&primary_info,0,sizeof(primary_info));
906  switch (colorspace)
907  {
908  case OHTAColorspace:
909  {
910  /*
911  Initialize OHTA tables:
912 
913  I1 = 0.33333*R+0.33334*G+0.33333*B
914  I2 = 0.50000*R+0.00000*G-0.50000*B
915  I3 =-0.25000*R+0.50000*G-0.25000*B
916 
917  I and Q, normally -0.5 through 0.5, are normalized to the range 0
918  through QuantumRange.
919  */
920  primary_info.y=(MagickRealType) ((MaxMap+1)/2);
921  primary_info.z=(MagickRealType) ((MaxMap+1)/2);
922 #if defined(MAGICKCORE_OPENMP_SUPPORT)
923  #pragma omp parallel for schedule(static)
924 #endif
925  for (i=0; i <= (ssize_t) MaxMap; i++)
926  {
927  x_map[i].x=(MagickRealType) (0.33333*(double) i);
928  x_map[i].y=(MagickRealType) (0.50000*(double) i);
929  x_map[i].z=(MagickRealType) (-0.25000*(double) i);
930  y_map[i].x=(MagickRealType) (0.33334*(double) i);
931  y_map[i].y=(MagickRealType) (0.00000*(double) i);
932  y_map[i].z=(MagickRealType) (0.50000*(double) i);
933  z_map[i].x=(MagickRealType) (0.33333*(double) i);
934  z_map[i].y=(MagickRealType) (-0.50000*(double) i);
935  z_map[i].z=(MagickRealType) (-0.25000*(double) i);
936  }
937  break;
938  }
939  case Rec601LumaColorspace:
940  {
941  /*
942  Initialize Rec601 luma tables:
943 
944  G = 0.298839*R+0.586811*G+0.114350*B
945  */
946 #if defined(MAGICKCORE_OPENMP_SUPPORT)
947  #pragma omp parallel for schedule(static)
948 #endif
949  for (i=0; i <= (ssize_t) MaxMap; i++)
950  {
951  x_map[i].x=(MagickRealType) (0.298839*(double) i);
952  x_map[i].y=(MagickRealType) (0.298839*(double) i);
953  x_map[i].z=(MagickRealType) (0.298839*(double) i);
954  y_map[i].x=(MagickRealType) (0.586811*(double) i);
955  y_map[i].y=(MagickRealType) (0.586811*(double) i);
956  y_map[i].z=(MagickRealType) (0.586811*(double) i);
957  z_map[i].x=(MagickRealType) (0.114350*(double) i);
958  z_map[i].y=(MagickRealType) (0.114350*(double) i);
959  z_map[i].z=(MagickRealType) (0.114350*(double) i);
960  }
961  break;
962  }
963  case Rec601YCbCrColorspace:
964  {
965  /*
966  Initialize YCbCr tables (ITU-R BT.601):
967 
968  Y = 0.2988390*R+0.5868110*G+0.1143500*B
969  Cb= -0.1687367*R-0.3312640*G+0.5000000*B
970  Cr= 0.5000000*R-0.4186880*G-0.0813120*B
971 
972  Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
973  through QuantumRange.
974  */
975  primary_info.y=(MagickRealType) ((MaxMap+1)/2);
976  primary_info.z=(MagickRealType) ((MaxMap+1)/2);
977 #if defined(MAGICKCORE_OPENMP_SUPPORT)
978  #pragma omp parallel for schedule(static)
979 #endif
980  for (i=0; i <= (ssize_t) MaxMap; i++)
981  {
982  x_map[i].x=(MagickRealType) (0.298839*(double) i);
983  x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
984  x_map[i].z=(MagickRealType) (0.500000*(double) i);
985  y_map[i].x=(MagickRealType) (0.586811*(double) i);
986  y_map[i].y=(MagickRealType) (-0.331264*(double) i);
987  y_map[i].z=(MagickRealType) (-0.418688*(double) i);
988  z_map[i].x=(MagickRealType) (0.114350*(double) i);
989  z_map[i].y=(MagickRealType) (0.500000*(double) i);
990  z_map[i].z=(MagickRealType) (-0.081312*(double) i);
991  }
992  break;
993  }
994  case Rec709LumaColorspace:
995  {
996  /*
997  Initialize Rec709 luma tables:
998 
999  G = 0.212656*R+0.715158*G+0.072186*B
1000  */
1001 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1002  #pragma omp parallel for schedule(static)
1003 #endif
1004  for (i=0; i <= (ssize_t) MaxMap; i++)
1005  {
1006  x_map[i].x=(MagickRealType) (0.212656*(double) i);
1007  x_map[i].y=(MagickRealType) (0.212656*(double) i);
1008  x_map[i].z=(MagickRealType) (0.212656*(double) i);
1009  y_map[i].x=(MagickRealType) (0.715158*(double) i);
1010  y_map[i].y=(MagickRealType) (0.715158*(double) i);
1011  y_map[i].z=(MagickRealType) (0.715158*(double) i);
1012  z_map[i].x=(MagickRealType) (0.072186*(double) i);
1013  z_map[i].y=(MagickRealType) (0.072186*(double) i);
1014  z_map[i].z=(MagickRealType) (0.072186*(double) i);
1015  }
1016  break;
1017  }
1018  case Rec709YCbCrColorspace:
1019  {
1020  /*
1021  Initialize YCbCr tables (ITU-R BT.709):
1022 
1023  Y = 0.212656*R+0.715158*G+0.072186*B
1024  Cb= -0.114572*R-0.385428*G+0.500000*B
1025  Cr= 0.500000*R-0.454153*G-0.045847*B
1026 
1027  Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
1028  through QuantumRange.
1029  */
1030  primary_info.y=(MagickRealType) ((MaxMap+1)/2);
1031  primary_info.z=(MagickRealType) ((MaxMap+1)/2);
1032 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1033  #pragma omp parallel for schedule(static)
1034 #endif
1035  for (i=0; i <= (ssize_t) MaxMap; i++)
1036  {
1037  x_map[i].x=(MagickRealType) (0.212656*(double) i);
1038  x_map[i].y=(MagickRealType) (-0.114572*(double) i);
1039  x_map[i].z=(MagickRealType) (0.500000*(double) i);
1040  y_map[i].x=(MagickRealType) (0.715158*(double) i);
1041  y_map[i].y=(MagickRealType) (-0.385428*(double) i);
1042  y_map[i].z=(MagickRealType) (-0.454153*(double) i);
1043  z_map[i].x=(MagickRealType) (0.072186*(double) i);
1044  z_map[i].y=(MagickRealType) (0.500000*(double) i);
1045  z_map[i].z=(MagickRealType) (-0.045847*(double) i);
1046  }
1047  break;
1048  }
1049  case YCCColorspace:
1050  {
1051  /*
1052  Initialize YCC tables:
1053 
1054  Y = 0.298839*R+0.586811*G+0.114350*B
1055  C1= -0.298839*R-0.586811*G+0.88600*B
1056  C2= 0.70100*R-0.586811*G-0.114350*B
1057 
1058  YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
1059  */
1060  primary_info.y=(MagickRealType) ScaleQuantumToMap(
1061  ScaleCharToQuantum(156));
1062  primary_info.z=(MagickRealType) ScaleQuantumToMap(
1063  ScaleCharToQuantum(137));
1064  for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
1065  {
1066  x_map[i].x=0.005382*i;
1067  x_map[i].y=(-0.003296)*i;
1068  x_map[i].z=0.009410*i;
1069  y_map[i].x=0.010566*i;
1070  y_map[i].y=(-0.006471)*i;
1071  y_map[i].z=(-0.007880)*i;
1072  z_map[i].x=0.002052*i;
1073  z_map[i].y=0.009768*i;
1074  z_map[i].z=(-0.001530)*i;
1075  }
1076  for ( ; i <= (ssize_t) MaxMap; i++)
1077  {
1078  x_map[i].x=0.298839*(1.099*i-0.099);
1079  x_map[i].y=(-0.298839)*(1.099*i-0.099);
1080  x_map[i].z=0.70100*(1.099*i-0.099);
1081  y_map[i].x=0.586811*(1.099*i-0.099);
1082  y_map[i].y=(-0.586811)*(1.099*i-0.099);
1083  y_map[i].z=(-0.586811)*(1.099*i-0.099);
1084  z_map[i].x=0.114350*(1.099*i-0.099);
1085  z_map[i].y=0.88600*(1.099*i-0.099);
1086  z_map[i].z=(-0.114350)*(1.099*i-0.099);
1087  }
1088  break;
1089  }
1090  default:
1091  {
1092  /*
1093  Linear conversion tables.
1094  */
1095 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1096  #pragma omp parallel for schedule(static)
1097 #endif
1098  for (i=0; i <= (ssize_t) MaxMap; i++)
1099  {
1100  x_map[i].x=(MagickRealType) (1.0*(double) i);
1101  y_map[i].x=(MagickRealType) 0.0;
1102  z_map[i].x=(MagickRealType) 0.0;
1103  x_map[i].y=(MagickRealType) 0.0;
1104  y_map[i].y=(MagickRealType) (1.0*(double) i);
1105  z_map[i].y=(MagickRealType) 0.0;
1106  x_map[i].z=(MagickRealType) 0.0;
1107  y_map[i].z=(MagickRealType) 0.0;
1108  z_map[i].z=(MagickRealType) (1.0*(double) i);
1109  }
1110  break;
1111  }
1112  }
1113  /*
1114  Convert from sRGB.
1115  */
1116  switch (image->storage_class)
1117  {
1118  case DirectClass:
1119  default:
1120  {
1121  /*
1122  Convert DirectClass image.
1123  */
1124  image_view=AcquireAuthenticCacheView(image,exception);
1125 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1126  #pragma omp parallel for schedule(static) shared(status) \
1127  magick_number_threads(image,image,image->rows,1)
1128 #endif
1129  for (y=0; y < (ssize_t) image->rows; y++)
1130  {
1131  MagickBooleanType
1132  sync;
1133 
1135  pixel;
1136 
1137  ssize_t
1138  x;
1139 
1140  PixelPacket
1141  *magick_restrict q;
1142 
1143  size_t
1144  blue,
1145  green,
1146  red;
1147 
1148  if (status == MagickFalse)
1149  continue;
1150  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1151  exception);
1152  if (q == (PixelPacket *) NULL)
1153  {
1154  status=MagickFalse;
1155  continue;
1156  }
1157  for (x=0; x < (ssize_t) image->columns; x++)
1158  {
1159  red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1160  GetPixelRed(q)));
1161  green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1162  GetPixelGreen(q)));
1163  blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1164  GetPixelBlue(q)));
1165  pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
1166  (MagickRealType) primary_info.x;
1167  pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
1168  (MagickRealType) primary_info.y;
1169  pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
1170  (MagickRealType) primary_info.z;
1171  SetPixelRed(q,ScaleMapToQuantum(pixel.red));
1172  SetPixelGreen(q,ScaleMapToQuantum(pixel.green));
1173  SetPixelBlue(q,ScaleMapToQuantum(pixel.blue));
1174  q++;
1175  }
1176  sync=SyncCacheViewAuthenticPixels(image_view,exception);
1177  if (sync == MagickFalse)
1178  status=MagickFalse;
1179  if (image->progress_monitor != (MagickProgressMonitor) NULL)
1180  {
1181  MagickBooleanType
1182  proceed;
1183 
1184 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1185  #pragma omp atomic
1186 #endif
1187  progress++;
1188  proceed=SetImageProgress(image,RGBTransformImageTag,progress,
1189  image->rows);
1190  if (proceed == MagickFalse)
1191  status=MagickFalse;
1192  }
1193  }
1194  image_view=DestroyCacheView(image_view);
1195  break;
1196  }
1197  case PseudoClass:
1198  {
1199  size_t
1200  blue,
1201  green,
1202  red;
1203 
1204  /*
1205  Convert PseudoClass image.
1206  */
1207  for (i=0; i < (ssize_t) image->colors; i++)
1208  {
1210  pixel;
1211 
1212  red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1213  image->colormap[i].red));
1214  green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1215  image->colormap[i].green));
1216  blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1217  image->colormap[i].blue));
1218  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1219  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1220  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1221  image->colormap[i].red=ScaleMapToQuantum(pixel.red);
1222  image->colormap[i].green=ScaleMapToQuantum(pixel.green);
1223  image->colormap[i].blue=ScaleMapToQuantum(pixel.blue);
1224  }
1225  (void) SyncImage(image);
1226  break;
1227  }
1228  }
1229  /*
1230  Relinquish resources.
1231  */
1232  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1233  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1234  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1235  if (SetImageColorspace(image,colorspace) == MagickFalse)
1236  return(MagickFalse);
1237  return(status);
1238 }
1239 
1240 /*
1241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1242 % %
1243 % %
1244 % %
1245 % S e t I m a g e C o l o r s p a c e %
1246 % %
1247 % %
1248 % %
1249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1250 %
1251 % SetImageColorspace() sets the colorspace member of the Image structure.
1252 %
1253 % The format of the SetImageColorspace method is:
1254 %
1255 % MagickBooleanType SetImageColorspace(Image *image,
1256 % const ColorspaceType colorspace)
1257 %
1258 % A description of each parameter follows:
1259 %
1260 % o image: the image.
1261 %
1262 % o colorspace: the colorspace.
1263 %
1264 */
1265 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1266  const ColorspaceType colorspace)
1267 {
1268  ImageType
1269  type;
1270 
1271  MagickBooleanType
1272  status;
1273 
1274  assert(image != (Image *) NULL);
1275  assert(image->signature == MagickCoreSignature);
1276  if (IsEventLogging() != MagickFalse)
1277  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1278  if (image->colorspace == colorspace)
1279  return(MagickTrue);
1280  image->colorspace=colorspace;
1281  image->rendering_intent=UndefinedIntent;
1282  image->gamma=1.000/2.200;
1283  (void) memset(&image->chromaticity,0,sizeof(image->chromaticity));
1284  type=image->type;
1285  if (IsGrayColorspace(colorspace) != MagickFalse)
1286  {
1287  if (colorspace == LinearGRAYColorspace)
1288  image->gamma=1.0;
1289  type=GrayscaleType;
1290  }
1291  else
1292  if ((IsRGBColorspace(colorspace) != MagickFalse) ||
1293  (colorspace == XYZColorspace) || (colorspace == xyYColorspace))
1294  image->gamma=1.0;
1295  else
1296  {
1297  image->rendering_intent=PerceptualIntent;
1298  image->chromaticity.red_primary.x=0.6400;
1299  image->chromaticity.red_primary.y=0.3300;
1300  image->chromaticity.red_primary.z=0.0300;
1301  image->chromaticity.green_primary.x=0.3000;
1302  image->chromaticity.green_primary.y=0.6000;
1303  image->chromaticity.green_primary.z=0.1000;
1304  image->chromaticity.blue_primary.x=0.1500;
1305  image->chromaticity.blue_primary.y=0.0600;
1306  image->chromaticity.blue_primary.z=0.7900;
1307  image->chromaticity.white_point.x=0.3127;
1308  image->chromaticity.white_point.y=0.3290;
1309  image->chromaticity.white_point.z=0.3583;
1310  }
1311  status=SyncImagePixelCache(image,&image->exception);
1312  image->type=type;
1313  return(status);
1314 }
1315 
1316 /*
1317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318 % %
1319 % %
1320 % %
1321 % S e t I m a g e G r a y %
1322 % %
1323 % %
1324 % %
1325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326 %
1327 % SetImageGray() returns MagickTrue if all the pixels in the image have the
1328 % same red, green, and blue intensities and changes the type of the image to
1329 % bi-level or grayscale.
1330 %
1331 % The format of the SetImageGray method is:
1332 %
1333 % MagickBooleanType SetImageGray(const Image *image,
1334 % ExceptionInfo *exception)
1335 %
1336 % A description of each parameter follows:
1337 %
1338 % o image: the image.
1339 %
1340 % o exception: return any errors or warnings in this structure.
1341 %
1342 */
1343 MagickExport MagickBooleanType SetImageGray(Image *image,
1344  ExceptionInfo *exception)
1345 {
1346  const char
1347  *value;
1348 
1349  CacheView
1350  *image_view;
1351 
1352  ImageType
1353  type;
1354 
1355  const PixelPacket
1356  *p;
1357 
1358  ssize_t
1359  x;
1360 
1361  ssize_t
1362  y;
1363 
1364  assert(image != (Image *) NULL);
1365  assert(image->signature == MagickCoreSignature);
1366  if (IsEventLogging() != MagickFalse)
1367  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1368  if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
1369  (image->type == GrayscaleMatteType))
1370  return(MagickTrue);
1371  if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
1372  (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
1373  return(MagickFalse);
1374  value=GetImageProperty(image,"colorspace:auto-grayscale");
1375  if (IsStringNotFalse(value) == MagickFalse)
1376  return(MagickFalse);
1377  type=BilevelType;
1378  image_view=AcquireVirtualCacheView(image,exception);
1379  for (y=0; y < (ssize_t) image->rows; y++)
1380  {
1381  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1382  if (p == (const PixelPacket *) NULL)
1383  break;
1384  for (x=0; x < (ssize_t) image->columns; x++)
1385  {
1386  if (IsGrayPixel(p) == MagickFalse)
1387  {
1388  type=UndefinedType;
1389  break;
1390  }
1391  if ((type == BilevelType) && (IsMonochromePixel(p) == MagickFalse))
1392  type=GrayscaleType;
1393  p++;
1394  }
1395  if (type == UndefinedType)
1396  break;
1397  }
1398  image_view=DestroyCacheView(image_view);
1399  if (type == UndefinedType)
1400  return(MagickFalse);
1401  image->colorspace=GRAYColorspace;
1402  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
1403  return(MagickFalse);
1404  image->type=type;
1405  if ((type == GrayscaleType) && (image->matte != MagickFalse))
1406  image->type=GrayscaleMatteType;
1407  return(MagickTrue);
1408 }
1409 
1410 /*
1411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1412 % %
1413 % %
1414 % %
1415 % S e t I m a g e M o n o c h r o m e %
1416 % %
1417 % %
1418 % %
1419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1420 %
1421 % SetImageMonochrome() returns MagickTrue if all the pixels in the image have
1422 % the same red, green, and blue intensities and the intensity is either
1423 % 0 or QuantumRange and changes the type of the image to bi-level.
1424 %
1425 % The format of the SetImageMonochrome method is:
1426 %
1427 % MagickBooleanType SetImageMonochrome(const Image *image,
1428 % ExceptionInfo *exception)
1429 %
1430 % A description of each parameter follows:
1431 %
1432 % o image: the image.
1433 %
1434 % o exception: return any errors or warnings in this structure.
1435 %
1436 */
1437 MagickExport MagickBooleanType SetImageMonochrome(Image *image,
1438  ExceptionInfo *exception)
1439 {
1440  const char
1441  *value;
1442 
1443  CacheView
1444  *image_view;
1445 
1446  ImageType
1447  type;
1448 
1449  ssize_t
1450  x;
1451 
1452  const PixelPacket
1453  *p;
1454 
1455  ssize_t
1456  y;
1457 
1458  assert(image != (Image *) NULL);
1459  assert(image->signature == MagickCoreSignature);
1460  if (IsEventLogging() != MagickFalse)
1461  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1462  if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1463  return(MagickTrue);
1464  if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
1465  (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
1466  return(MagickFalse);
1467  value=GetImageProperty(image,"colorspace:auto-grayscale");
1468  if (IsStringNotFalse(value) == MagickFalse)
1469  return(MagickFalse);
1470  type=BilevelType;
1471  image_view=AcquireVirtualCacheView(image,exception);
1472  for (y=0; y < (ssize_t) image->rows; y++)
1473  {
1474  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1475  if (p == (const PixelPacket *) NULL)
1476  break;
1477  for (x=0; x < (ssize_t) image->columns; x++)
1478  {
1479  if (IsMonochromePixel(p) == MagickFalse)
1480  {
1481  type=UndefinedType;
1482  break;
1483  }
1484  p++;
1485  }
1486  if (type == UndefinedType)
1487  break;
1488  }
1489  image_view=DestroyCacheView(image_view);
1490  if (type == UndefinedType)
1491  return(MagickFalse);
1492  image->colorspace=GRAYColorspace;
1493  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
1494  return(MagickFalse);
1495  image->type=type;
1496  return(MagickTrue);
1497 }
1498 
1499 /*
1500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1501 % %
1502 % %
1503 % %
1504 % T r a n s f o r m I m a g e C o l o r s p a c e %
1505 % %
1506 % %
1507 % %
1508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1509 %
1510 % TransformImageColorspace() transforms an image colorspace.
1511 %
1512 % The format of the TransformImageColorspace method is:
1513 %
1514 % MagickBooleanType TransformImageColorspace(Image *image,
1515 % const ColorspaceType colorspace)
1516 %
1517 % A description of each parameter follows:
1518 %
1519 % o image: the image.
1520 %
1521 % o colorspace: the colorspace.
1522 %
1523 */
1524 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1525  const ColorspaceType colorspace)
1526 {
1527  MagickBooleanType
1528  status;
1529 
1530  assert(image != (Image *) NULL);
1531  assert(image->signature == MagickCoreSignature);
1532  if (IsEventLogging() != MagickFalse)
1533  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1534  if (image->colorspace == colorspace)
1535  return(MagickTrue);
1536  (void) DeleteImageProfile(image,"icc");
1537  (void) DeleteImageProfile(image,"icm");
1538  if (colorspace == UndefinedColorspace)
1539  return(SetImageColorspace(image,colorspace));
1540  /*
1541  Convert the reference image from an alternate colorspace to sRGB.
1542  */
1543  if (IssRGBColorspace(colorspace) != MagickFalse)
1544  return(TransformRGBImage(image,image->colorspace));
1545  status=MagickTrue;
1546  if (IssRGBColorspace(image->colorspace) == MagickFalse)
1547  status=TransformRGBImage(image,image->colorspace);
1548  if (status == MagickFalse)
1549  return(status);
1550  /*
1551  Convert the reference image from sRGB to an alternate colorspace.
1552  */
1553  if (RGBTransformImage(image,colorspace) == MagickFalse)
1554  status=MagickFalse;
1555  return(status);
1556 }
1557 
1558 /*
1559 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1560 % %
1561 % %
1562 % %
1563 + T r a n s f o r m R G B I m a g e %
1564 % %
1565 % %
1566 % %
1567 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1568 %
1569 % TransformRGBImage() converts the reference image from an alternate
1570 % colorspace to sRGB. The transformation matrices are not the standard ones:
1571 % the weights are rescaled to normalize the range of the transformed values to
1572 % be [0..QuantumRange].
1573 %
1574 % The format of the TransformRGBImage method is:
1575 %
1576 % MagickBooleanType TransformRGBImage(Image *image,
1577 % const ColorspaceType colorspace)
1578 %
1579 % A description of each parameter follows:
1580 %
1581 % o image: the image.
1582 %
1583 % o colorspace: the colorspace to transform the image to.
1584 %
1585 */
1586 
1587 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1588  const double yellow,Quantum *red,Quantum *green,Quantum *blue)
1589 {
1590  *red=ClampToQuantum((MagickRealType) QuantumRange*(1.0-cyan));
1591  *green=ClampToQuantum((MagickRealType) QuantumRange*(1.0-magenta));
1592  *blue=ClampToQuantum((MagickRealType) QuantumRange*(1.0-yellow));
1593 }
1594 
1595 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1596  double *X,double *Y,double *Z)
1597 {
1598  *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1599  *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1600  *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1601 }
1602 
1603 static inline void ConvertLMSToRGB(const double L,const double M,
1604  const double S,Quantum *red,Quantum *green,Quantum *blue)
1605 {
1606  double
1607  X,
1608  Y,
1609  Z;
1610 
1611  ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1612  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1613 }
1614 
1615 static inline void ConvertLuvToRGB(const double L,const double u,
1616  const double v,Quantum *red,Quantum *green,Quantum *blue)
1617 {
1618  double
1619  X,
1620  Y,
1621  Z;
1622 
1623  ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1624  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1625 }
1626 
1627 static inline ssize_t RoundToYCC(const MagickRealType value)
1628 {
1629  if (value <= 0.0)
1630  return(0);
1631  if (value >= 1388.0)
1632  return(1388);
1633  return((ssize_t) (value+0.5));
1634 }
1635 
1636 static inline void ConvertLabToRGB(const double L,const double a,
1637  const double b,Quantum *red,Quantum *green,Quantum *blue)
1638 {
1639  double
1640  X,
1641  Y,
1642  Z;
1643 
1644  ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1645  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1646 }
1647 
1648 static inline void ConvertxyYToRGB(const double low_x,const double low_y,
1649  const double cap_Y,Quantum *red,Quantum *green,Quantum *blue)
1650 {
1651  double
1652  gamma,
1653  X,
1654  Y,
1655  Z;
1656 
1657  gamma=PerceptibleReciprocal(low_y);
1658  X=gamma*cap_Y*low_x;
1659  Y=cap_Y;
1660  Z=gamma*cap_Y*(1.0-low_x-low_y);
1661  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1662 }
1663 
1664 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1665  Quantum *red,Quantum *green,Quantum *blue)
1666 {
1667  *red=ClampToQuantum((MagickRealType) QuantumRange*(0.99999999999914679361*Y-
1668  1.2188941887145875e-06*(Pb-0.5)+1.4019995886561440468*(Pr-0.5)));
1669  *green=ClampToQuantum((MagickRealType) QuantumRange*(0.99999975910502514331*Y-
1670  0.34413567816504303521*(Pb-0.5)-0.71413649331646789076*(Pr-0.5)));
1671  *blue=ClampToQuantum((MagickRealType) QuantumRange*(1.00000124040004623180*Y+
1672  1.77200006607230409200*(Pb-0.5)+2.1453384174593273e-06*(Pr-0.5)));
1673 }
1674 
1675 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1676  const double Cr,Quantum *red,Quantum *green,Quantum *blue)
1677 {
1678  ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1679 }
1680 
1681 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
1682  Quantum *red,Quantum *green,Quantum *blue)
1683 {
1684  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y+9.2303716147657e-05*
1685  (Db-0.5)-0.52591263066186533*(Dr-0.5)));
1686  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.12913289889050927*
1687  (Db-0.5)+0.26789932820759876*(Dr-0.5)));
1688  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y+0.66467905997895482*
1689  (Db-0.5)-7.9202543533108e-05*(Dr-0.5)));
1690 }
1691 
1692 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1693  Quantum *red,Quantum *green,Quantum *blue)
1694 {
1695  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y+0.9562957197589482261*
1696  (I-0.5)+0.6210244164652610754*(Q-0.5)));
1697  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.2721220993185104464*
1698  (I-0.5)-0.6473805968256950427*(Q-0.5)));
1699  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y-1.1069890167364901945*
1700  (I-0.5)+1.7046149983646481374*(Q-0.5)));
1701 }
1702 
1703 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1704  Quantum *red,Quantum *green,Quantum *blue)
1705 {
1706  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y-3.945707070708279e-05*
1707  (U-0.5)+1.1398279671717170825*(V-0.5)));
1708  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.3946101641414141437*
1709  (U-0.5)-0.5805003156565656797*(V-0.5)));
1710  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y+2.0319996843434342537*
1711  (U-0.5)-4.813762626262513e-04*(V-0.5)));
1712 }
1713 
1714 MagickExport MagickBooleanType TransformRGBImage(Image *image,
1715  const ColorspaceType colorspace)
1716 {
1717 #define TransformRGBImageTag "Transform/Image"
1718 
1719  static const float
1720  YCCMap[1389] =
1721  {
1722  0.000000, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1723  0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1724  0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1725  0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1726  0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1727  0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1728  0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1729  0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1730  0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1731  0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1732  0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1733  0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1734  0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1735  0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1736  0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1737  0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1738  0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1739  0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1740  0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1741  0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1742  0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1743  0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1744  0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1745  0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1746  0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1747  0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1748  0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1749  0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1750  0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1751  0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1752  0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1753  0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1754  0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1755  0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1756  0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1757  0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1758  0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1759  0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1760  0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1761  0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1762  0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1763  0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1764  0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1765  0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1766  0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1767  0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1768  0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1769  0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1770  0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1771  0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1772  0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1773  0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1774  0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1775  0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1776  0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1777  0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1778  0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1779  0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1780  0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1781  0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1782  0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1783  0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1784  0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1785  0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1786  0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1787  0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1788  0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1789  0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1790  0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1791  0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1792  0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1793  0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1794  0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1795  0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1796  0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1797  0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1798  0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1799  0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1800  0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1801  0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1802  0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1803  0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1804  0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1805  0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1806  0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1807  0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1808  0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1809  0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1810  0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1811  0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1812  0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1813  0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1814  0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1815  0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1816  0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1817  0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1818  0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1819  0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1820  0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1821  0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1822  0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1823  0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1824  0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1825  0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1826  0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1827  0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1828  0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1829  0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1830  0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1831  0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1832  0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1833  0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1834  0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1835  0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1836  0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1837  0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1838  0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1839  0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1840  0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1841  0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1842  0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1843  0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1844  0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1845  0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1846  0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1847  0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1848  0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1849  0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1850  0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1851  0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1852  0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1853  0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1854  0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1855  0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1856  0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1857  0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1858  0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1859  0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1860  0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1861  0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1862  0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1863  0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1864  0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1865  0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1866  0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1867  0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1868  0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1869  0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1870  0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1871  0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1872  0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1873  0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1874  0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1875  0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1876  0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1877  0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1878  0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1879  0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1880  0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1881  0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1882  0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1883  0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1884  0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1885  0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1886  0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1887  0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1888  0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1889  0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1890  0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1891  0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1892  0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1893  0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1894  0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1895  0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1896  0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1897  0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1898  0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1899  0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1900  0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1901  0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1902  0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1903  0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1904  0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1905  0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1906  0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1907  0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1908  0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1909  0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1910  0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1911  0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1912  0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1913  0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1914  0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1915  0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1916  0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1917  0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1918  0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1919  0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1920  0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1921  0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1922  0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1923  0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1924  0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1925  0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1926  0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1927  0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1928  0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1929  0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1930  0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1931  0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1932  0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1933  0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1934  0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1935  0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1936  0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1937  0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1938  0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1939  0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1940  0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1941  0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1942  0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1943  0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1944  0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1945  0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1946  0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1947  0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1948  0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1949  0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1950  0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1951  0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1952  0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1953  0.998559f, 0.999280f, 1.000000
1954  };
1955 
1956  CacheView
1957  *image_view;
1958 
1960  *exception;
1961 
1962  MagickBooleanType
1963  status;
1964 
1965  MagickOffsetType
1966  progress;
1967 
1968  ssize_t
1969  i;
1970 
1971  ssize_t
1972  y;
1973 
1975  *y_map,
1976  *x_map,
1977  *z_map;
1978 
1979  assert(image != (Image *) NULL);
1980  assert(image->signature == MagickCoreSignature);
1981  if (IsEventLogging() != MagickFalse)
1982  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1983  status=MagickTrue;
1984  progress=0;
1985  exception=(&image->exception);
1986  switch (colorspace)
1987  {
1988  case CMYKColorspace:
1989  {
1991  zero;
1992 
1993  /*
1994  Transform image from CMYK to sRGB.
1995  */
1996  if (image->storage_class == PseudoClass)
1997  {
1998  if (SyncImage(image) == MagickFalse)
1999  return(MagickFalse);
2000  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2001  return(MagickFalse);
2002  }
2003  GetMagickPixelPacket(image,&zero);
2004  image_view=AcquireAuthenticCacheView(image,exception);
2005 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2006  #pragma omp parallel for schedule(static) shared(status) \
2007  magick_number_threads(image,image,image->rows,1)
2008 #endif
2009  for (y=0; y < (ssize_t) image->rows; y++)
2010  {
2011  MagickBooleanType
2012  sync;
2013 
2015  pixel;
2016 
2017  IndexPacket
2018  *magick_restrict indexes;
2019 
2020  ssize_t
2021  x;
2022 
2023  PixelPacket
2024  *magick_restrict q;
2025 
2026  if (status == MagickFalse)
2027  continue;
2028  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2029  exception);
2030  if (q == (PixelPacket *) NULL)
2031  {
2032  status=MagickFalse;
2033  continue;
2034  }
2035  indexes=GetCacheViewAuthenticIndexQueue(image_view);
2036  pixel=zero;
2037  for (x=0; x < (ssize_t) image->columns; x++)
2038  {
2039  SetMagickPixelPacket(image,q,indexes+x,&pixel);
2040  ConvertCMYKToRGB(&pixel);
2041  SetPixelPacket(image,&pixel,q,indexes+x);
2042  q++;
2043  }
2044  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2045  if (sync == MagickFalse)
2046  status=MagickFalse;
2047  }
2048  image_view=DestroyCacheView(image_view);
2049  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2050  return(MagickFalse);
2051  return(status);
2052  }
2053  case LinearGRAYColorspace:
2054  case Rec601LumaColorspace:
2055  {
2056  /*
2057  Transform linear RGB to sRGB colorspace.
2058  */
2059  if (image->storage_class == PseudoClass)
2060  {
2061  if (SyncImage(image) == MagickFalse)
2062  return(MagickFalse);
2063  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2064  return(MagickFalse);
2065  }
2066  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2067  return(MagickFalse);
2068  image_view=AcquireAuthenticCacheView(image,exception);
2069 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2070  #pragma omp parallel for schedule(static) shared(status) \
2071  magick_number_threads(image,image,image->rows,1)
2072 #endif
2073  for (y=0; y < (ssize_t) image->rows; y++)
2074  {
2075  MagickBooleanType
2076  sync;
2077 
2078  ssize_t
2079  x;
2080 
2081  PixelPacket
2082  *magick_restrict q;
2083 
2084  if (status == MagickFalse)
2085  continue;
2086  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2087  exception);
2088  if (q == (PixelPacket *) NULL)
2089  {
2090  status=MagickFalse;
2091  continue;
2092  }
2093  for (x=(ssize_t) image->columns; x != 0; x--)
2094  {
2095  MagickRealType
2096  gray;
2097 
2098  gray=0.212656*EncodePixelGamma(GetPixelRed(q))+0.715158*
2099  EncodePixelGamma(GetPixelGreen(q))+0.072186*
2100  EncodePixelGamma(GetPixelBlue(q));
2101  SetPixelRed(q,ClampToQuantum(gray));
2102  SetPixelGreen(q,ClampToQuantum(gray));
2103  SetPixelBlue(q,ClampToQuantum(gray));
2104  q++;
2105  }
2106  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2107  if (sync == MagickFalse)
2108  status=MagickFalse;
2109  }
2110  image_view=DestroyCacheView(image_view);
2111  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2112  return(MagickFalse);
2113  return(status);
2114  }
2115  case GRAYColorspace:
2116  case Rec709LumaColorspace:
2117  {
2118  /*
2119  Transform linear RGB to sRGB colorspace.
2120  */
2121  if (image->storage_class == PseudoClass)
2122  {
2123  if (SyncImage(image) == MagickFalse)
2124  return(MagickFalse);
2125  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2126  return(MagickFalse);
2127  }
2128  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2129  return(MagickFalse);
2130  image_view=AcquireAuthenticCacheView(image,exception);
2131 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2132  #pragma omp parallel for schedule(static) shared(status) \
2133  magick_number_threads(image,image,image->rows,1)
2134 #endif
2135  for (y=0; y < (ssize_t) image->rows; y++)
2136  {
2137  MagickBooleanType
2138  sync;
2139 
2140  ssize_t
2141  x;
2142 
2143  PixelPacket
2144  *magick_restrict q;
2145 
2146  if (status == MagickFalse)
2147  continue;
2148  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2149  exception);
2150  if (q == (PixelPacket *) NULL)
2151  {
2152  status=MagickFalse;
2153  continue;
2154  }
2155  for (x=(ssize_t) image->columns; x != 0; x--)
2156  {
2157  MagickRealType
2158  gray;
2159 
2160  gray=(MagickRealType) (0.212656*(double) GetPixelRed(q)+0.715158*
2161  (double) GetPixelGreen(q)+0.072186*(double) GetPixelBlue(q));
2162  SetPixelRed(q,ClampToQuantum(gray));
2163  SetPixelGreen(q,ClampToQuantum(gray));
2164  SetPixelBlue(q,ClampToQuantum(gray));
2165  q++;
2166  }
2167  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2168  if (sync == MagickFalse)
2169  status=MagickFalse;
2170  }
2171  image_view=DestroyCacheView(image_view);
2172  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2173  return(MagickFalse);
2174  return(status);
2175  }
2176  case CMYColorspace:
2177  case HCLColorspace:
2178  case HCLpColorspace:
2179  case HSBColorspace:
2180  case HSIColorspace:
2181  case HSLColorspace:
2182  case HSVColorspace:
2183  case HWBColorspace:
2184  case LabColorspace:
2185  case LCHColorspace:
2186  case LCHabColorspace:
2187  case LCHuvColorspace:
2188  case LMSColorspace:
2189  case LuvColorspace:
2190  case xyYColorspace:
2191  case XYZColorspace:
2192  case YCbCrColorspace:
2193  case YDbDrColorspace:
2194  case YIQColorspace:
2195  case YPbPrColorspace:
2196  case YUVColorspace:
2197  {
2198  /*
2199  Transform image from source colorspace to sRGB.
2200  */
2201  if (image->storage_class == PseudoClass)
2202  {
2203  if (SyncImage(image) == MagickFalse)
2204  return(MagickFalse);
2205  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2206  return(MagickFalse);
2207  }
2208  image_view=AcquireAuthenticCacheView(image,exception);
2209 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2210  #pragma omp parallel for schedule(static) shared(status) \
2211  magick_number_threads(image,image,image->rows,1)
2212 #endif
2213  for (y=0; y < (ssize_t) image->rows; y++)
2214  {
2215  MagickBooleanType
2216  sync;
2217 
2218  ssize_t
2219  x;
2220 
2221  PixelPacket
2222  *magick_restrict q;
2223 
2224  if (status == MagickFalse)
2225  continue;
2226  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2227  exception);
2228  if (q == (PixelPacket *) NULL)
2229  {
2230  status=MagickFalse;
2231  continue;
2232  }
2233  for (x=0; x < (ssize_t) image->columns; x++)
2234  {
2235  double
2236  X,
2237  Y,
2238  Z;
2239 
2240  Quantum
2241  blue,
2242  green,
2243  red;
2244 
2245  X=QuantumScale*(double) GetPixelRed(q);
2246  Y=QuantumScale*(double) GetPixelGreen(q);
2247  Z=QuantumScale*(double) GetPixelBlue(q);
2248  switch (colorspace)
2249  {
2250  case CMYColorspace:
2251  {
2252  ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
2253  break;
2254  }
2255  case HCLColorspace:
2256  {
2257  ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
2258  break;
2259  }
2260  case HCLpColorspace:
2261  {
2262  ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
2263  break;
2264  }
2265  case HSBColorspace:
2266  {
2267  ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
2268  break;
2269  }
2270  case HSIColorspace:
2271  {
2272  ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
2273  break;
2274  }
2275  case HSLColorspace:
2276  {
2277  ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
2278  break;
2279  }
2280  case HSVColorspace:
2281  {
2282  ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
2283  break;
2284  }
2285  case HWBColorspace:
2286  {
2287  ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
2288  break;
2289  }
2290  case LabColorspace:
2291  {
2292  ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
2293  break;
2294  }
2295  case LCHColorspace:
2296  case LCHabColorspace:
2297  {
2298  ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
2299  break;
2300  }
2301  case LCHuvColorspace:
2302  {
2303  ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
2304  break;
2305  }
2306  case LMSColorspace:
2307  {
2308  ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
2309  break;
2310  }
2311  case LuvColorspace:
2312  {
2313  ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
2314  break;
2315  }
2316  case xyYColorspace:
2317  {
2318  ConvertxyYToRGB(X,Y,Z,&red,&green,&blue);
2319  break;
2320  }
2321  case XYZColorspace:
2322  {
2323  ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2324  break;
2325  }
2326  case YCbCrColorspace:
2327  {
2328  ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
2329  break;
2330  }
2331  case YDbDrColorspace:
2332  {
2333  ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
2334  break;
2335  }
2336  case YIQColorspace:
2337  {
2338  ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
2339  break;
2340  }
2341  case YPbPrColorspace:
2342  {
2343  ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
2344  break;
2345  }
2346  case YUVColorspace:
2347  {
2348  ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
2349  break;
2350  }
2351  default:
2352  {
2353  red=ClampToQuantum((MagickRealType) QuantumRange*X);
2354  green=ClampToQuantum((MagickRealType) QuantumRange*Y);
2355  blue=ClampToQuantum((MagickRealType) QuantumRange*Z);
2356  break;
2357  }
2358  }
2359  SetPixelRed(q,ClampToQuantum((MagickRealType) red));
2360  SetPixelGreen(q,ClampToQuantum((MagickRealType) green));
2361  SetPixelBlue(q,ClampToQuantum((MagickRealType) blue));
2362  q++;
2363  }
2364  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2365  if (sync == MagickFalse)
2366  status=MagickFalse;
2367  }
2368  image_view=DestroyCacheView(image_view);
2369  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2370  return(MagickFalse);
2371  return(status);
2372  }
2373  case LogColorspace:
2374  {
2375  const char
2376  *value;
2377 
2378  double
2379  black,
2380  density,
2381  film_gamma,
2382  gamma,
2383  reference_black,
2384  reference_white;
2385 
2386  Quantum
2387  *logmap;
2388 
2389  /*
2390  Transform Log to sRGB colorspace.
2391  */
2392  density=DisplayGamma;
2393  gamma=DisplayGamma;
2394  value=GetImageProperty(image,"gamma");
2395  if (value != (const char *) NULL)
2396  gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
2397  film_gamma=FilmGamma;
2398  value=GetImageProperty(image,"film-gamma");
2399  if (value != (const char *) NULL)
2400  film_gamma=StringToDouble(value,(char **) NULL);
2401  reference_black=ReferenceBlack;
2402  value=GetImageProperty(image,"reference-black");
2403  if (value != (const char *) NULL)
2404  reference_black=StringToDouble(value,(char **) NULL);
2405  reference_white=ReferenceWhite;
2406  value=GetImageProperty(image,"reference-white");
2407  if (value != (const char *) NULL)
2408  reference_white=StringToDouble(value,(char **) NULL);
2409  logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2410  sizeof(*logmap));
2411  if (logmap == (Quantum *) NULL)
2412  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2413  image->filename);
2414  black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002*
2415  PerceptibleReciprocal(film_gamma));
2416  for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
2417  logmap[i]=(Quantum) 0;
2418  for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
2419  logmap[i]=ClampToQuantum((MagickRealType) QuantumRange/(1.0-black)*
2420  (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002*
2421  PerceptibleReciprocal(film_gamma))-black));
2422  for ( ; i <= (ssize_t) MaxMap; i++)
2423  logmap[i]=QuantumRange;
2424  if (image->storage_class == PseudoClass)
2425  {
2426  if (SyncImage(image) == MagickFalse)
2427  return(MagickFalse);
2428  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2429  return(MagickFalse);
2430  }
2431  image_view=AcquireAuthenticCacheView(image,exception);
2432 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2433  #pragma omp parallel for schedule(static) shared(status) \
2434  magick_number_threads(image,image,image->rows,1)
2435 #endif
2436  for (y=0; y < (ssize_t) image->rows; y++)
2437  {
2438  MagickBooleanType
2439  sync;
2440 
2441  ssize_t
2442  x;
2443 
2444  PixelPacket
2445  *magick_restrict q;
2446 
2447  if (status == MagickFalse)
2448  continue;
2449  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2450  exception);
2451  if (q == (PixelPacket *) NULL)
2452  {
2453  status=MagickFalse;
2454  continue;
2455  }
2456  for (x=(ssize_t) image->columns; x != 0; x--)
2457  {
2458  Quantum
2459  blue,
2460  green,
2461  red;
2462 
2463  red=ClampToQuantum(EncodePixelGamma((MagickRealType)
2464  logmap[ScaleQuantumToMap(GetPixelRed(q))]));
2465  green=ClampToQuantum(EncodePixelGamma((MagickRealType)
2466  logmap[ScaleQuantumToMap(GetPixelGreen(q))]));
2467  blue=ClampToQuantum(EncodePixelGamma((MagickRealType)
2468  logmap[ScaleQuantumToMap(GetPixelBlue(q))]));
2469  SetPixelRed(q,red);
2470  SetPixelGreen(q,green);
2471  SetPixelBlue(q,blue);
2472  q++;
2473  }
2474  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2475  if (sync == MagickFalse)
2476  status=MagickFalse;
2477  }
2478  image_view=DestroyCacheView(image_view);
2479  logmap=(Quantum *) RelinquishMagickMemory(logmap);
2480  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2481  return(MagickFalse);
2482  return(status);
2483  }
2484  case RGBColorspace:
2485  case scRGBColorspace:
2486  {
2487  /*
2488  Transform linear RGB to sRGB colorspace.
2489  */
2490  if (image->storage_class == PseudoClass)
2491  {
2492  if (SyncImage(image) == MagickFalse)
2493  return(MagickFalse);
2494  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2495  return(MagickFalse);
2496  }
2497  image_view=AcquireAuthenticCacheView(image,exception);
2498 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2499  #pragma omp parallel for schedule(static) shared(status) \
2500  magick_number_threads(image,image,image->rows,1)
2501 #endif
2502  for (y=0; y < (ssize_t) image->rows; y++)
2503  {
2504  MagickBooleanType
2505  sync;
2506 
2507  ssize_t
2508  x;
2509 
2510  PixelPacket
2511  *magick_restrict q;
2512 
2513  if (status == MagickFalse)
2514  continue;
2515  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2516  exception);
2517  if (q == (PixelPacket *) NULL)
2518  {
2519  status=MagickFalse;
2520  continue;
2521  }
2522  for (x=(ssize_t) image->columns; x != 0; x--)
2523  {
2524  Quantum
2525  blue,
2526  green,
2527  red;
2528 
2529  red=ClampToQuantum(EncodePixelGamma((MagickRealType) GetPixelRed(q)));
2530  green=ClampToQuantum(EncodePixelGamma((MagickRealType)
2531  GetPixelGreen(q)));
2532  blue=ClampToQuantum(EncodePixelGamma((MagickRealType)
2533  GetPixelBlue(q)));
2534  SetPixelRed(q,red);
2535  SetPixelGreen(q,green);
2536  SetPixelBlue(q,blue);
2537  q++;
2538  }
2539  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2540  if (sync == MagickFalse)
2541  status=MagickFalse;
2542  }
2543  image_view=DestroyCacheView(image_view);
2544  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2545  return(MagickFalse);
2546  return(status);
2547  }
2548  default:
2549  break;
2550  }
2551  /*
2552  Allocate the tables.
2553  */
2554  x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2555  sizeof(*x_map));
2556  y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2557  sizeof(*y_map));
2558  z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2559  sizeof(*z_map));
2560  if ((x_map == (TransformPacket *) NULL) ||
2561  (y_map == (TransformPacket *) NULL) ||
2562  (z_map == (TransformPacket *) NULL))
2563  {
2564  if (z_map != (TransformPacket *) NULL)
2565  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2566  if (y_map != (TransformPacket *) NULL)
2567  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2568  if (x_map != (TransformPacket *) NULL)
2569  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2570  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2571  image->filename);
2572  }
2573  switch (colorspace)
2574  {
2575  case OHTAColorspace:
2576  {
2577  /*
2578  Initialize OHTA tables:
2579 
2580  R = I1+1.00000*I2-0.66668*I3
2581  G = I1+0.00000*I2+1.33333*I3
2582  B = I1-1.00000*I2-0.66668*I3
2583 
2584  I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2585  through QuantumRange.
2586  */
2587 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2588  #pragma omp parallel for schedule(static)
2589 #endif
2590  for (i=0; i <= (ssize_t) MaxMap; i++)
2591  {
2592  x_map[i].x=(1.0*(double) i);
2593  y_map[i].x=(0.5*1.00000*(2.0*(double) i-MaxMap));
2594  z_map[i].x=(-0.5*0.66668*(2.0*(double) i-MaxMap));
2595  x_map[i].y=(1.0*(double) i);
2596  y_map[i].y=(0.5*0.00000*(2.0*(double) i-MaxMap));
2597  z_map[i].y=(0.5*1.33333*(2.0*(double) i-MaxMap));
2598  x_map[i].z=(1.0*(double) i);
2599  y_map[i].z=(-0.5*1.00000*(2.0*(double) i-MaxMap));
2600  z_map[i].z=(-0.5*0.66668*(2.0*(double) i-MaxMap));
2601  }
2602  break;
2603  }
2604  case Rec601YCbCrColorspace:
2605  {
2606  /*
2607  Initialize YCbCr tables:
2608 
2609  R = Y +1.402000*Cr
2610  G = Y-0.344136*Cb-0.714136*Cr
2611  B = Y+1.772000*Cb
2612 
2613  Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2614  through QuantumRange.
2615  */
2616 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2617  #pragma omp parallel for schedule(static)
2618 #endif
2619  for (i=0; i <= (ssize_t) MaxMap; i++)
2620  {
2621  x_map[i].x=0.99999999999914679361*(double) i;
2622  y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2623  z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2624  x_map[i].y=0.99999975910502514331*(double) i;
2625  y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2626  z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2627  x_map[i].z=1.00000124040004623180*(double) i;
2628  y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2629  z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2630  }
2631  break;
2632  }
2633  case Rec709YCbCrColorspace:
2634  {
2635  /*
2636  Initialize YCbCr tables:
2637 
2638  R = Y +1.574800*Cr
2639  G = Y-0.187324*Cb-0.468124*Cr
2640  B = Y+1.855600*Cb
2641 
2642  Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2643  through QuantumRange.
2644  */
2645 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2646  #pragma omp parallel for schedule(static)
2647 #endif
2648  for (i=0; i <= (ssize_t) MaxMap; i++)
2649  {
2650  x_map[i].x=(MagickRealType) (1.0*(double) i);
2651  y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*(double) i-MaxMap));
2652  z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*(double) i-MaxMap));
2653  x_map[i].y=(MagickRealType) (1.0*(double) i);
2654  y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*(double) i-MaxMap));
2655  z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*(double) i-MaxMap));
2656  x_map[i].z=(MagickRealType) (1.0*(double) i);
2657  y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*(double) i-MaxMap));
2658  z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*(double) i-MaxMap));
2659  }
2660  break;
2661  }
2662  case YCCColorspace:
2663  {
2664  /*
2665  Initialize YCC tables:
2666 
2667  R = Y +1.340762*C2
2668  G = Y-0.317038*C1-0.682243*C2
2669  B = Y+1.632639*C1
2670 
2671  YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2672  */
2673 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2674  #pragma omp parallel for schedule(static)
2675 #endif
2676  for (i=0; i <= (ssize_t) MaxMap; i++)
2677  {
2678  x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2679  y_map[i].x=(MagickRealType) (0.0000000);
2680  z_map[i].x=(MagickRealType) (1.8215000*((double) i-(MagickRealType)
2681  ScaleQuantumToMap(ScaleCharToQuantum(137))));
2682  x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2683  y_map[i].y=(MagickRealType) ((-0.4302726)*((double) i-(MagickRealType)
2684  ScaleQuantumToMap(ScaleCharToQuantum(156))));
2685  z_map[i].y=(MagickRealType) ((-0.9271435)*((double) i-(MagickRealType)
2686  ScaleQuantumToMap(ScaleCharToQuantum(137))));
2687  x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2688  y_map[i].z=(MagickRealType) (2.2179000*((double) i-(MagickRealType)
2689  ScaleQuantumToMap(ScaleCharToQuantum(156))));
2690  z_map[i].z=(MagickRealType) (0.0000000);
2691  }
2692  break;
2693  }
2694  default:
2695  {
2696  /*
2697  Linear conversion tables.
2698  */
2699 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2700  #pragma omp parallel for schedule(static)
2701 #endif
2702  for (i=0; i <= (ssize_t) MaxMap; i++)
2703  {
2704  x_map[i].x=(MagickRealType) (1.0*(double) i);
2705  y_map[i].x=(MagickRealType) 0.0;
2706  z_map[i].x=(MagickRealType) 0.0;
2707  x_map[i].y=(MagickRealType) 0.0;
2708  y_map[i].y=(MagickRealType) (1.0*(double) i);
2709  z_map[i].y=(MagickRealType) 0.0;
2710  x_map[i].z=(MagickRealType) 0.0;
2711  y_map[i].z=(MagickRealType) 0.0;
2712  z_map[i].z=(MagickRealType) (1.0*(double) i);
2713  }
2714  break;
2715  }
2716  }
2717  /*
2718  Convert to sRGB.
2719  */
2720  switch (image->storage_class)
2721  {
2722  case DirectClass:
2723  default:
2724  {
2725  /*
2726  Convert DirectClass image.
2727  */
2728  image_view=AcquireAuthenticCacheView(image,exception);
2729 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2730  #pragma omp parallel for schedule(static) shared(status) \
2731  magick_number_threads(image,image,image->rows,1)
2732 #endif
2733  for (y=0; y < (ssize_t) image->rows; y++)
2734  {
2735  MagickBooleanType
2736  sync;
2737 
2739  pixel;
2740 
2741  ssize_t
2742  x;
2743 
2744  PixelPacket
2745  *magick_restrict q;
2746 
2747  if (status == MagickFalse)
2748  continue;
2749  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2750  exception);
2751  if (q == (PixelPacket *) NULL)
2752  {
2753  status=MagickFalse;
2754  continue;
2755  }
2756  for (x=0; x < (ssize_t) image->columns; x++)
2757  {
2758  size_t
2759  blue,
2760  green,
2761  red;
2762 
2763  red=ScaleQuantumToMap(GetPixelRed(q));
2764  green=ScaleQuantumToMap(GetPixelGreen(q));
2765  blue=ScaleQuantumToMap(GetPixelBlue(q));
2766  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2767  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2768  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2769  if (colorspace == YCCColorspace)
2770  {
2771  pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2772  (double) MaxMap)];
2773  pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2774  (double) MaxMap)];
2775  pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2776  (double) MaxMap)];
2777  }
2778  else
2779  {
2780  pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2781  pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2782  pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2783  }
2784  SetPixelRed(q,ClampToQuantum(pixel.red));
2785  SetPixelGreen(q,ClampToQuantum(pixel.green));
2786  SetPixelBlue(q,ClampToQuantum(pixel.blue));
2787  q++;
2788  }
2789  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2790  if (sync == MagickFalse)
2791  status=MagickFalse;
2792  if (image->progress_monitor != (MagickProgressMonitor) NULL)
2793  {
2794  MagickBooleanType
2795  proceed;
2796 
2797 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2798  #pragma omp atomic
2799 #endif
2800  progress++;
2801  proceed=SetImageProgress(image,TransformRGBImageTag,progress,
2802  image->rows);
2803  if (proceed == MagickFalse)
2804  status=MagickFalse;
2805  }
2806  }
2807  image_view=DestroyCacheView(image_view);
2808  break;
2809  }
2810  case PseudoClass:
2811  {
2812  /*
2813  Convert PseudoClass image.
2814  */
2815 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2816  #pragma omp parallel for schedule(static) shared(status) \
2817  magick_number_threads(image,image,image->colors,1)
2818 #endif
2819  for (i=0; i < (ssize_t) image->colors; i++)
2820  {
2822  pixel;
2823 
2824  size_t
2825  blue,
2826  green,
2827  red;
2828 
2829  red=ScaleQuantumToMap(image->colormap[i].red);
2830  green=ScaleQuantumToMap(image->colormap[i].green);
2831  blue=ScaleQuantumToMap(image->colormap[i].blue);
2832  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2833  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2834  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2835  if (colorspace == YCCColorspace)
2836  {
2837  pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2838  (double) MaxMap)];
2839  pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2840  (double) MaxMap)];
2841  pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2842  (double) MaxMap)];
2843  }
2844  else
2845  {
2846  pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2847  pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2848  pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2849  }
2850  image->colormap[i].red=ClampToQuantum(pixel.red);
2851  image->colormap[i].green=ClampToQuantum(pixel.green);
2852  image->colormap[i].blue=ClampToQuantum(pixel.blue);
2853  }
2854  (void) SyncImage(image);
2855  break;
2856  }
2857  }
2858  /*
2859  Relinquish resources.
2860  */
2861  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2862  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2863  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2864  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2865  return(MagickFalse);
2866  return(MagickTrue);
2867 }
Definition: image.h:152