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