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