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