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