source: ImageMagick/trunk/MagickCore/colorspace.c @ 8257

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