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