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