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