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