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