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