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