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