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