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