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