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