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