2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 %
13 % MagickCore Image Colorspace Methods %
20 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/property.h"
44 #include "MagickCore/cache.h"
45 #include "MagickCore/cache-private.h"
46 #include "MagickCore/cache-view.h"
47 #include "MagickCore/color.h"
48 #include "MagickCore/color-private.h"
49 #include "MagickCore/colorspace.h"
50 #include "MagickCore/colorspace-private.h"
51 #include "MagickCore/exception.h"
52 #include "MagickCore/exception-private.h"
53 #include "MagickCore/image.h"
54 #include "MagickCore/image-private.h"
55 #include "MagickCore/gem.h"
56 #include "MagickCore/gem-private.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/monitor.h"
59 #include "MagickCore/monitor-private.h"
60 #include "MagickCore/pixel-accessor.h"
61 #include "MagickCore/pixel-private.h"
62 #include "MagickCore/quantize.h"
63 #include "MagickCore/quantum.h"
64 #include "MagickCore/quantum-private.h"
65 #include "MagickCore/resource_.h"
66 #include "MagickCore/string_.h"
67 #include "MagickCore/string-private.h"
68 #include "MagickCore/utility.h"
73 typedef struct _TransformPacket
84 static MagickBooleanType
85 TransformsRGBImage(Image *,const ColorspaceType,ExceptionInfo *);
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 + s R G B T r a n s f o r m I m a g e %
96 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98 % sRGBTransformImage() converts the reference image from sRGB to an alternate
99 % colorspace. The transformation matrices are not the standard ones: the
100 % weights are rescaled to normalized the range of the transformed values to
101 % be [0..QuantumRange].
103 % The format of the sRGBTransformImage method is:
105 % MagickBooleanType sRGBTransformImage(Image *image,
106 % const ColorspaceType colorspace,EsceptionInfo *exception)
108 % A description of each parameter follows:
110 % o image: the image.
112 % o colorspace: the colorspace to transform the image to.
114 % o exception: return any errors or warnings in this structure.
118 static inline void ConvertXYZToLMS(const double x,const double y,
119 const double z,double *L,double *M,double *S)
127 Convert XYZ to LMS colorspace.
129 assert(L != (double *) NULL);
130 assert(M != (double *) NULL);
131 assert(S != (double *) NULL);
132 l=0.7328*x+0.4296*y-0.1624*z;
133 m=(-0.7036*x+1.6975*y+0.0415*z);
134 s=0.0030*x+0.0136*y+0.9834*z;
140 static inline void ConvertRGBToXYZ(const double red,const double green,
141 const double blue,double *X,double *Y,double *Z)
148 assert(X != (double *) NULL);
149 assert(Y != (double *) NULL);
150 assert(Z != (double *) NULL);
152 g=QuantumScale*green;
154 *X=0.41239558896741421610*r+0.35758343076371481710*g+0.18049264738170157350*b;
155 *Y=0.21258623078559555160*r+0.71517030370341084990*g+0.07220049864333622685*b;
156 *Z=0.01929721549174694484*r+0.11918386458084853180*g+0.95049712513157976600*b;
159 static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
160 double *L,double *a,double *b)
162 #define D65X (0.950470)
164 #define D65Z (1.088830)
165 #define CIEEpsilon (216.0/24389.0)
166 #define CIEK (24389.0/27.0)
173 assert(L != (double *) NULL);
174 assert(a != (double *) NULL);
175 assert(b != (double *) NULL);
176 if ((X/D65X) > CIEEpsilon)
177 x=pow(X/D65X,1.0/3.0);
179 x=(CIEK*X/D65X+16.0)/116.0;
180 if ((Y/D65Y) > CIEEpsilon)
181 y=pow(Y/D65Y,1.0/3.0);
183 y=(CIEK*Y/D65Y+16.0)/116.0;
184 if ((Z/D65Z) > CIEEpsilon)
185 z=pow(Z/D65Z,1.0/3.0);
187 z=(CIEK*Z/D65Z+16.0)/116.0;
188 *L=((116.0*y)-16.0)/100.0;
189 *a=(500.0*(x-y))/255.0+0.5;
190 *b=(200.0*(y-z))/255.0+0.5;
193 static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
194 double *L,double *u,double *v)
199 assert(L != (double *) NULL);
200 assert(u != (double *) NULL);
201 assert(v != (double *) NULL);
202 if ((Y/D65Y) > CIEEpsilon)
203 *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
206 alpha=MagickEpsilonReciprocal(X+15.0*Y+3.0*Z);
207 *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
208 *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
214 static MagickBooleanType sRGBTransformImage(Image *image,
215 const ColorspaceType colorspace,ExceptionInfo *exception)
217 #define sRGBTransformImageTag "RGBTransform/Image"
242 assert(image != (Image *) NULL);
243 assert(image->signature == MagickSignature);
244 if (image->debug != MagickFalse)
245 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
246 assert(colorspace != sRGBColorspace);
247 assert(colorspace != TransparentColorspace);
248 assert(colorspace != UndefinedColorspace);
256 Convert RGB to CMY colorspace.
258 if (image->storage_class == PseudoClass)
260 if (SyncImage(image,exception) == MagickFalse)
262 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
265 image_view=AcquireAuthenticCacheView(image,exception);
266 #if defined(MAGICKCORE_OPENMP_SUPPORT)
267 #pragma omp parallel for schedule(static,4) shared(status) \
268 dynamic_number_threads(image,image->columns,image->rows,1)
270 for (y=0; y < (ssize_t) image->rows; y++)
281 if (status == MagickFalse)
283 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
285 if (q == (Quantum *) NULL)
290 for (x=0; x < (ssize_t) image->columns; x++)
297 cyan=InversesRGBCompandor((double) GetPixelCyan(image,q));
298 magenta=InversesRGBCompandor((double) GetPixelMagenta(image,q));
299 yellow=InversesRGBCompandor((double) GetPixelYellow(image,q));
300 SetPixelCyan(image,ClampToQuantum(QuantumRange-cyan),q);
301 SetPixelMagenta(image,ClampToQuantum(QuantumRange-magenta),q);
302 SetPixelYellow(image,ClampToQuantum(QuantumRange-yellow),q);
303 q+=GetPixelChannels(image);
305 sync=SyncCacheViewAuthenticPixels(image_view,exception);
306 if (sync == MagickFalse)
309 image_view=DestroyCacheView(image_view);
310 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
311 ColorSeparationMatteType;
312 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
322 Convert RGB to CMYK colorspace.
324 if (image->storage_class == PseudoClass)
326 if (SyncImage(image,exception) == MagickFalse)
328 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
331 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
333 GetPixelInfo(image,&zero);
334 image_view=AcquireAuthenticCacheView(image,exception);
335 #if defined(MAGICKCORE_OPENMP_SUPPORT)
336 #pragma omp parallel for schedule(static,4) shared(status) \
337 dynamic_number_threads(image,image->columns,image->rows,1)
339 for (y=0; y < (ssize_t) image->rows; y++)
353 if (status == MagickFalse)
355 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
357 if (q == (Quantum *) NULL)
363 for (x=0; x < (ssize_t) image->columns; x++)
365 GetPixelInfoPixel(image,q,&pixel);
366 pixel.red=InversesRGBCompandor(pixel.red);
367 pixel.green=InversesRGBCompandor(pixel.green);
368 pixel.blue=InversesRGBCompandor(pixel.blue);
369 ConvertRGBToCMYK(&pixel);
370 SetPixelInfoPixel(image,&pixel,q);
371 q+=GetPixelChannels(image);
373 sync=SyncCacheViewAuthenticPixels(image_view,exception);
374 if (sync == MagickFalse)
377 image_view=DestroyCacheView(image_view);
378 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
379 ColorSeparationMatteType;
380 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
385 case Rec601LumaColorspace:
388 Transform image from sRGB to GRAY.
390 if (image->storage_class == PseudoClass)
392 if (SyncImage(image,exception) == MagickFalse)
394 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
397 image_view=AcquireAuthenticCacheView(image,exception);
398 #if defined(MAGICKCORE_OPENMP_SUPPORT)
399 #pragma omp parallel for schedule(static,4) shared(status) \
400 dynamic_number_threads(image,image->columns,image->rows,1)
402 for (y=0; y < (ssize_t) image->rows; y++)
413 if (status == MagickFalse)
415 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
417 if (q == (Quantum *) NULL)
422 for (x=0; x < (ssize_t) image->columns; x++)
430 red=InversesRGBCompandor((double) GetPixelRed(image,q));
431 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
432 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
433 gray=0.298839*red+0.586811*green+0.114350*blue;
434 SetPixelGray(image,ClampToQuantum(gray),q);
435 q+=GetPixelChannels(image);
437 sync=SyncCacheViewAuthenticPixels(image_view,exception);
438 if (sync == MagickFalse)
441 image_view=DestroyCacheView(image_view);
442 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
444 image->type=GrayscaleType;
450 Transform image from sRGB to HCL.
452 if (image->storage_class == PseudoClass)
454 if (SyncImage(image,exception) == MagickFalse)
456 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
459 image_view=AcquireAuthenticCacheView(image,exception);
460 #if defined(MAGICKCORE_OPENMP_SUPPORT)
461 #pragma omp parallel for schedule(static,4) shared(status) \
462 dynamic_number_threads(image,image->columns,image->rows,1)
464 for (y=0; y < (ssize_t) image->rows; y++)
475 if (status == MagickFalse)
477 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
479 if (q == (Quantum *) NULL)
484 for (x=0; x < (ssize_t) image->columns; x++)
494 red=InversesRGBCompandor((double) GetPixelRed(image,q));
495 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
496 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
497 ConvertRGBToHCL(red,green,blue,&hue,&chroma,&luma);
498 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
499 SetPixelGreen(image,ClampToQuantum(QuantumRange*chroma),q);
500 SetPixelBlue(image,ClampToQuantum(QuantumRange*luma),q);
501 q+=GetPixelChannels(image);
503 sync=SyncCacheViewAuthenticPixels(image_view,exception);
504 if (sync == MagickFalse)
507 image_view=DestroyCacheView(image_view);
508 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
515 Transform image from sRGB to HSB.
517 if (image->storage_class == PseudoClass)
519 if (SyncImage(image,exception) == MagickFalse)
521 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
524 image_view=AcquireAuthenticCacheView(image,exception);
525 #if defined(MAGICKCORE_OPENMP_SUPPORT)
526 #pragma omp parallel for schedule(static,4) shared(status) \
527 dynamic_number_threads(image,image->columns,image->rows,1)
529 for (y=0; y < (ssize_t) image->rows; y++)
540 if (status == MagickFalse)
542 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
544 if (q == (Quantum *) NULL)
549 for (x=0; x < (ssize_t) image->columns; x++)
559 red=InversesRGBCompandor((double) GetPixelRed(image,q));
560 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
561 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
562 ConvertRGBToHSB(red,green,blue,&hue,&saturation,&brightness);
563 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
564 SetPixelGreen(image,ClampToQuantum(QuantumRange*saturation),q);
565 SetPixelBlue(image,ClampToQuantum(QuantumRange*brightness),q);
566 q+=GetPixelChannels(image);
568 sync=SyncCacheViewAuthenticPixels(image_view,exception);
569 if (sync == MagickFalse)
572 image_view=DestroyCacheView(image_view);
573 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
580 Transform image from sRGB to HSL.
582 if (image->storage_class == PseudoClass)
584 if (SyncImage(image,exception) == MagickFalse)
586 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
589 image_view=AcquireAuthenticCacheView(image,exception);
590 #if defined(MAGICKCORE_OPENMP_SUPPORT)
591 #pragma omp parallel for schedule(static,4) shared(status) \
592 dynamic_number_threads(image,image->columns,image->rows,1)
594 for (y=0; y < (ssize_t) image->rows; y++)
605 if (status == MagickFalse)
607 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
609 if (q == (Quantum *) NULL)
614 for (x=0; x < (ssize_t) image->columns; x++)
624 red=InversesRGBCompandor((double) GetPixelRed(image,q));
625 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
626 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
627 ConvertRGBToHSL(red,green,blue,&hue,&saturation,&lightness);
628 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
629 SetPixelGreen(image,ClampToQuantum(QuantumRange*saturation),q);
630 SetPixelBlue(image,ClampToQuantum(QuantumRange*lightness),q);
631 q+=GetPixelChannels(image);
633 sync=SyncCacheViewAuthenticPixels(image_view,exception);
634 if (sync == MagickFalse)
637 image_view=DestroyCacheView(image_view);
638 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
645 Transform image from sRGB to HWB.
647 if (image->storage_class == PseudoClass)
649 if (SyncImage(image,exception) == MagickFalse)
651 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
654 image_view=AcquireAuthenticCacheView(image,exception);
655 #if defined(MAGICKCORE_OPENMP_SUPPORT)
656 #pragma omp parallel for schedule(static,4) shared(status) \
657 dynamic_number_threads(image,image->columns,image->rows,1)
659 for (y=0; y < (ssize_t) image->rows; y++)
670 if (status == MagickFalse)
672 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
674 if (q == (Quantum *) NULL)
679 for (x=0; x < (ssize_t) image->columns; x++)
689 red=InversesRGBCompandor((double) GetPixelRed(image,q));
690 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
691 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
692 ConvertRGBToHWB(red,green,blue,&hue,&whiteness,&blackness);
693 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
694 SetPixelGreen(image,ClampToQuantum(QuantumRange*whiteness),q);
695 SetPixelBlue(image,ClampToQuantum(QuantumRange*blackness),q);
696 q+=GetPixelChannels(image);
698 sync=SyncCacheViewAuthenticPixels(image_view,exception);
699 if (sync == MagickFalse)
702 image_view=DestroyCacheView(image_view);
703 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
710 Transform image from sRGB to Lab.
712 if (image->storage_class == PseudoClass)
714 if (SyncImage(image,exception) == MagickFalse)
716 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
719 image_view=AcquireAuthenticCacheView(image,exception);
720 #if defined(MAGICKCORE_OPENMP_SUPPORT)
721 #pragma omp parallel for schedule(static,4) shared(status) \
722 dynamic_number_threads(image,image->columns,image->rows,1)
724 for (y=0; y < (ssize_t) image->rows; y++)
735 if (status == MagickFalse)
737 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
739 if (q == (Quantum *) NULL)
744 for (x=0; x < (ssize_t) image->columns; x++)
757 red=InversesRGBCompandor((double) GetPixelRed(image,q));
758 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
759 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
760 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
761 ConvertXYZToLab(X,Y,Z,&L,&a,&b);
762 SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
763 SetPixelGreen(image,ClampToQuantum(QuantumRange*a),q);
764 SetPixelBlue(image,ClampToQuantum(QuantumRange*b),q);
765 q+=GetPixelChannels(image);
767 sync=SyncCacheViewAuthenticPixels(image_view,exception);
768 if (sync == MagickFalse)
771 image_view=DestroyCacheView(image_view);
772 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
779 Transform image from sRGB to LCH.
781 if (image->storage_class == PseudoClass)
783 if (SyncImage(image,exception) == MagickFalse)
785 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
788 image_view=AcquireAuthenticCacheView(image,exception);
789 #if defined(MAGICKCORE_OPENMP_SUPPORT)
790 #pragma omp parallel for schedule(static,4) shared(status) \
791 dynamic_number_threads(image,image->columns,image->rows,1)
793 for (y=0; y < (ssize_t) image->rows; y++)
804 if (status == MagickFalse)
806 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
808 if (q == (Quantum *) NULL)
813 for (x=0; x < (ssize_t) image->columns; x++)
828 red=InversesRGBCompandor((double) GetPixelRed(image,q));
829 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
830 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
831 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
832 ConvertXYZToLab(X,Y,Z,&L,&a,&b);
834 H=atan2(b,a)*180.0/MagickPI;
837 SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
838 SetPixelGreen(image,ClampToQuantum(QuantumRange*C),q);
839 SetPixelBlue(image,ClampToQuantum(QuantumRange*H),q);
840 q+=GetPixelChannels(image);
842 sync=SyncCacheViewAuthenticPixels(image_view,exception);
843 if (sync == MagickFalse)
846 image_view=DestroyCacheView(image_view);
847 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
854 Transform image from sRGB to LMS.
856 if (image->storage_class == PseudoClass)
858 if (SyncImage(image,exception) == MagickFalse)
860 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
863 image_view=AcquireAuthenticCacheView(image,exception);
864 #if defined(MAGICKCORE_OPENMP_SUPPORT)
865 #pragma omp parallel for schedule(static,4) shared(status) \
866 dynamic_number_threads(image,image->columns,image->rows,1)
868 for (y=0; y < (ssize_t) image->rows; y++)
879 if (status == MagickFalse)
881 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
883 if (q == (Quantum *) NULL)
888 for (x=0; x < (ssize_t) image->columns; x++)
901 red=InversesRGBCompandor((double) GetPixelRed(image,q));
902 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
903 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
904 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
905 ConvertXYZToLMS(X,Y,Z,&L,&M,&S);
906 SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
907 SetPixelGreen(image,ClampToQuantum(QuantumRange*M),q);
908 SetPixelBlue(image,ClampToQuantum(QuantumRange*S),q);
909 q+=GetPixelChannels(image);
911 sync=SyncCacheViewAuthenticPixels(image_view,exception);
912 if (sync == MagickFalse)
915 image_view=DestroyCacheView(image_view);
916 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
922 #define DisplayGamma (1.0/1.7)
923 #define FilmGamma 0.6
924 #define ReferenceBlack 95.0
925 #define ReferenceWhite 685.0
942 Transform RGB to Log colorspace.
944 density=DisplayGamma;
946 value=GetImageProperty(image,"gamma",exception);
947 if (value != (const char *) NULL)
948 gamma=MagickEpsilonReciprocal(StringToDouble(value,(char **) NULL));
949 film_gamma=FilmGamma;
950 value=GetImageProperty(image,"film-gamma",exception);
951 if (value != (const char *) NULL)
952 film_gamma=StringToDouble(value,(char **) NULL);
953 reference_black=ReferenceBlack;
954 value=GetImageProperty(image,"reference-black",exception);
955 if (value != (const char *) NULL)
956 reference_black=StringToDouble(value,(char **) NULL);
957 reference_white=ReferenceWhite;
958 value=GetImageProperty(image,"reference-white",exception);
959 if (value != (const char *) NULL)
960 reference_white=StringToDouble(value,(char **) NULL);
961 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
963 if (logmap == (Quantum *) NULL)
964 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
966 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*
968 #if defined(MAGICKCORE_OPENMP_SUPPORT)
969 #pragma omp parallel for schedule(static) \
970 dynamic_number_threads(image,image->columns,1,1)
972 for (i=0; i <= (ssize_t) MaxMap; i++)
973 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+
974 log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*
975 0.002/film_gamma))/1024.0));
976 image_view=AcquireAuthenticCacheView(image,exception);
977 #if defined(MAGICKCORE_OPENMP_SUPPORT)
978 #pragma omp parallel for schedule(static,4) shared(status) \
979 dynamic_number_threads(image,image->columns,image->rows,1)
981 for (y=0; y < (ssize_t) image->rows; y++)
992 if (status == MagickFalse)
994 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
996 if (q == (Quantum *) NULL)
1001 for (x=(ssize_t) image->columns; x != 0; x--)
1008 red=InversesRGBCompandor((double) GetPixelRed(image,q));
1009 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
1010 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
1011 SetPixelRed(image,logmap[ScaleQuantumToMap(
1012 ClampToQuantum(red))],q);
1013 SetPixelGreen(image,logmap[ScaleQuantumToMap(
1014 ClampToQuantum(green))],q);
1015 SetPixelBlue(image,logmap[ScaleQuantumToMap(
1016 ClampToQuantum(blue))],q);
1017 q+=GetPixelChannels(image);
1019 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1020 if (sync == MagickFalse)
1023 image_view=DestroyCacheView(image_view);
1024 logmap=(Quantum *) RelinquishMagickMemory(logmap);
1025 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1026 return(MagickFalse);
1032 Transform image from sRGB to Luv.
1034 if (image->storage_class == PseudoClass)
1036 if (SyncImage(image,exception) == MagickFalse)
1037 return(MagickFalse);
1038 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1039 return(MagickFalse);
1041 image_view=AcquireAuthenticCacheView(image,exception);
1042 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1043 #pragma omp parallel for schedule(static,4) shared(status) \
1044 dynamic_number_threads(image,image->columns,image->rows,1)
1046 for (y=0; y < (ssize_t) image->rows; y++)
1057 if (status == MagickFalse)
1059 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1061 if (q == (Quantum *) NULL)
1066 for (x=0; x < (ssize_t) image->columns; x++)
1079 red=InversesRGBCompandor((double) GetPixelRed(image,q));
1080 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
1081 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
1082 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1083 ConvertXYZToLuv(X,Y,Z,&L,&u,&v);
1084 SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
1085 SetPixelGreen(image,ClampToQuantum(QuantumRange*u),q);
1086 SetPixelBlue(image,ClampToQuantum(QuantumRange*v),q);
1087 q+=GetPixelChannels(image);
1089 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1090 if (sync == MagickFalse)
1093 image_view=DestroyCacheView(image_view);
1094 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1095 return(MagickFalse);
1098 case Rec709LumaColorspace:
1101 Transform image from sRGB to Rec709Luma.
1103 if (image->storage_class == PseudoClass)
1105 if (SyncImage(image,exception) == MagickFalse)
1106 return(MagickFalse);
1107 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1108 return(MagickFalse);
1110 image_view=AcquireAuthenticCacheView(image,exception);
1111 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1112 #pragma omp parallel for schedule(static,4) shared(status) \
1113 dynamic_number_threads(image,image->columns,image->rows,1)
1115 for (y=0; y < (ssize_t) image->rows; y++)
1126 if (status == MagickFalse)
1128 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1130 if (q == (Quantum *) NULL)
1135 for (x=0; x < (ssize_t) image->columns; x++)
1143 red=InversesRGBCompandor((double) GetPixelRed(image,q));
1144 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
1145 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
1146 gray=0.212600*red+0.715200*green+0.072200*blue;
1147 SetPixelGray(image,ClampToQuantum(gray),q);
1148 q+=GetPixelChannels(image);
1150 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1151 if (sync == MagickFalse)
1154 image_view=DestroyCacheView(image_view);
1155 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1156 return(MagickFalse);
1157 image->type=GrayscaleType;
1163 Transform image from sRGB to linear RGB.
1165 if (image->storage_class == PseudoClass)
1167 if (SyncImage(image,exception) == MagickFalse)
1168 return(MagickFalse);
1169 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1170 return(MagickFalse);
1172 image_view=AcquireAuthenticCacheView(image,exception);
1173 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1174 #pragma omp parallel for schedule(static,4) shared(status) \
1175 dynamic_number_threads(image,image->columns,image->rows,1)
1177 for (y=0; y < (ssize_t) image->rows; y++)
1188 if (status == MagickFalse)
1190 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1192 if (q == (Quantum *) NULL)
1197 for (x=0; x < (ssize_t) image->columns; x++)
1204 red=InversesRGBCompandor((double) GetPixelRed(image,q));
1205 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
1206 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
1207 SetPixelRed(image,ClampToQuantum(red),q);
1208 SetPixelGreen(image,ClampToQuantum(green),q);
1209 SetPixelBlue(image,ClampToQuantum(blue),q);
1210 q+=GetPixelChannels(image);
1212 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1213 if (sync == MagickFalse)
1216 image_view=DestroyCacheView(image_view);
1217 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1218 return(MagickFalse);
1224 Transform image from sRGB to XYZ.
1226 if (image->storage_class == PseudoClass)
1228 if (SyncImage(image,exception) == MagickFalse)
1229 return(MagickFalse);
1230 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1231 return(MagickFalse);
1233 image_view=AcquireAuthenticCacheView(image,exception);
1234 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1235 #pragma omp parallel for schedule(static,4) shared(status) \
1236 dynamic_number_threads(image,image->columns,image->rows,1)
1238 for (y=0; y < (ssize_t) image->rows; y++)
1249 if (status == MagickFalse)
1251 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1253 if (q == (Quantum *) NULL)
1258 for (x=0; x < (ssize_t) image->columns; x++)
1268 red=InversesRGBCompandor((double) GetPixelRed(image,q));
1269 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
1270 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
1271 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1272 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
1273 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
1274 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q);
1275 q+=GetPixelChannels(image);
1277 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1278 if (sync == MagickFalse)
1281 image_view=DestroyCacheView(image_view);
1282 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1283 return(MagickFalse);
1290 Allocate the tables.
1292 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1294 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1296 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1298 if ((x_map == (TransformPacket *) NULL) ||
1299 (y_map == (TransformPacket *) NULL) ||
1300 (z_map == (TransformPacket *) NULL))
1301 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1303 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
1306 case OHTAColorspace:
1309 Initialize OHTA tables:
1311 I1 = 0.33333*R+0.33334*G+0.33333*B
1312 I2 = 0.50000*R+0.00000*G-0.50000*B
1313 I3 =-0.25000*R+0.50000*G-0.25000*B
1315 I and Q, normally -0.5 through 0.5, are normalized to the range 0
1316 through QuantumRange.
1318 primary_info.y=(double) (MaxMap+1.0)/2.0;
1319 primary_info.z=(double) (MaxMap+1.0)/2.0;
1320 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1321 #pragma omp parallel for schedule(static) \
1322 dynamic_number_threads(image,image->columns,1,1)
1324 for (i=0; i <= (ssize_t) MaxMap; i++)
1326 x_map[i].x=0.33333*i;
1327 y_map[i].x=0.33334*i;
1328 z_map[i].x=0.33333*i;
1329 x_map[i].y=0.50000*i;
1330 y_map[i].y=0.00000*i;
1331 z_map[i].y=(-0.50000)*i;
1332 x_map[i].z=(-0.25000)*i;
1333 y_map[i].z=0.50000*i;
1334 z_map[i].z=(-0.25000)*i;
1338 case Rec601YCbCrColorspace:
1339 case YCbCrColorspace:
1342 Initialize YCbCr tables (ITU-R BT.601):
1344 Y = 0.2988390*R+0.5868110*G+0.1143500*B
1345 Cb= -0.1687367*R-0.3312640*G+0.5000000*B
1346 Cr= 0.5000000*R-0.4186880*G-0.0813120*B
1348 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
1349 through QuantumRange.
1351 primary_info.y=(double) (MaxMap+1.0)/2.0;
1352 primary_info.z=(double) (MaxMap+1.0)/2.0;
1353 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1354 #pragma omp parallel for schedule(static) \
1355 dynamic_number_threads(image,image->columns,1,1)
1357 for (i=0; i <= (ssize_t) MaxMap; i++)
1359 x_map[i].x=0.298839*i;
1360 y_map[i].x=0.586811*i;
1361 z_map[i].x=0.114350*i;
1362 x_map[i].y=(-0.1687367)*i;
1363 y_map[i].y=(-0.331264)*i;
1364 z_map[i].y=0.500000*i;
1365 x_map[i].z=0.500000*i;
1366 y_map[i].z=(-0.418688)*i;
1367 z_map[i].z=(-0.081312)*i;
1371 case Rec709YCbCrColorspace:
1374 Initialize YCbCr tables (ITU-R BT.709):
1376 Y = 0.212600*R+0.715200*G+0.072200*B
1377 Cb= -0.114572*R-0.385428*G+0.500000*B
1378 Cr= 0.500000*R-0.454153*G-0.045847*B
1380 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
1381 through QuantumRange.
1383 primary_info.y=(double) (MaxMap+1.0)/2.0;
1384 primary_info.z=(double) (MaxMap+1.0)/2.0;
1385 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1386 #pragma omp parallel for schedule(static) \
1387 dynamic_number_threads(image,image->columns,1,1)
1389 for (i=0; i <= (ssize_t) MaxMap; i++)
1391 x_map[i].x=0.212600*i;
1392 y_map[i].x=0.715200*i;
1393 z_map[i].x=0.072200*i;
1394 x_map[i].y=(-0.114572)*i;
1395 y_map[i].y=(-0.385428)*i;
1396 z_map[i].y=0.500000*i;
1397 x_map[i].z=0.500000*i;
1398 y_map[i].z=(-0.454153)*i;
1399 z_map[i].z=(-0.045847)*i;
1406 Initialize YCC tables:
1408 Y = 0.298839*R+0.586811*G+0.114350*B
1409 C1= -0.298839*R-0.586811*G+0.88600*B
1410 C2= 0.70100*R-0.586811*G-0.114350*B
1412 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
1414 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
1415 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
1416 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
1418 x_map[i].x=0.003962014134275617*i;
1419 y_map[i].x=0.007778268551236748*i;
1420 z_map[i].x=0.001510600706713781*i;
1421 x_map[i].y=(-0.002426619775463276)*i;
1422 y_map[i].y=(-0.004763965913702149)*i;
1423 z_map[i].y=0.007190585689165425*i;
1424 x_map[i].z=0.006927257754597858*i;
1425 y_map[i].z=(-0.005800713697502058)*i;
1426 z_map[i].z=(-0.0011265440570958)*i;
1428 for ( ; i <= (ssize_t) MaxMap; i++)
1430 x_map[i].x=0.2201118963486454*(1.099*i-0.099);
1431 y_map[i].x=0.4321260306242638*(1.099*i-0.099);
1432 z_map[i].x=0.08392226148409894*(1.099*i-0.099);
1433 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
1434 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
1435 z_map[i].y=0.3994769827314126*(1.099*i-0.099);
1436 x_map[i].z=0.3848476530332144*(1.099*i-0.099);
1437 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
1438 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
1445 Initialize YIQ tables:
1447 Y = 0.298839*R+0.586811*G+0.114350*B
1448 I = 0.595716*R-0.274453*G-0.321263*B
1449 Q = 0.211456*R-0.522591*G+0.311135*B
1451 I and Q, normally -0.5 through 0.5, are normalized to the range 0
1452 through QuantumRange.
1454 primary_info.y=(double) (MaxMap+1.0)/2.0;
1455 primary_info.z=(double) (MaxMap+1.0)/2.0;
1456 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1457 #pragma omp parallel for schedule(static) \
1458 dynamic_number_threads(image,image->columns,1,1)
1460 for (i=0; i <= (ssize_t) MaxMap; i++)
1462 x_map[i].x=0.298839*i;
1463 y_map[i].x=0.586811*i;
1464 z_map[i].x=0.114350*i;
1465 x_map[i].y=0.595716*i;
1466 y_map[i].y=(-0.274453)*i;
1467 z_map[i].y=(-0.321263)*i;
1468 x_map[i].z=0.211456*i;
1469 y_map[i].z=(-0.522591)*i;
1470 z_map[i].z=0.311135*i;
1474 case YPbPrColorspace:
1477 Initialize YPbPr tables (ITU-R BT.601):
1479 Y = 0.2988390*R+0.5868110*G+0.1143500*B
1480 Pb= -0.1687367*R-0.3312640*G+0.5000000*B
1481 Pr= 0.5000000*R-0.4186880*G-0.0813120*B
1483 Pb and Pr, normally -0.5 through 0.5, are normalized to the range 0
1484 through QuantumRange.
1486 primary_info.y=(double) (MaxMap+1.0)/2.0;
1487 primary_info.z=(double) (MaxMap+1.0)/2.0;
1488 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1489 #pragma omp parallel for schedule(static) \
1490 dynamic_number_threads(image,image->columns,1,1)
1492 for (i=0; i <= (ssize_t) MaxMap; i++)
1494 x_map[i].x=0.298839*i;
1495 y_map[i].x=0.586811*i;
1496 z_map[i].x=0.114350*i;
1497 x_map[i].y=(-0.1687367)*i;
1498 y_map[i].y=(-0.331264)*i;
1499 z_map[i].y=0.500000*i;
1500 x_map[i].z=0.500000*i;
1501 y_map[i].z=(-0.418688)*i;
1502 z_map[i].z=(-0.081312)*i;
1509 Initialize YUV tables:
1511 Y = 0.298839*R+0.586811*G+0.114350*B
1512 U = -0.147130*R-0.288860*G+0.436000*B
1513 V = 0.615000*R-0.514990*G-0.100010*B
1515 U and V, normally -0.5 through 0.5, are normalized to the range 0
1516 through QuantumRange. Note that U = 0.493*(B-Y), V = 0.877*(R-Y).
1518 primary_info.y=(double) (MaxMap+1.0)/2.0;
1519 primary_info.z=(double) (MaxMap+1.0)/2.0;
1520 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1521 #pragma omp parallel for schedule(static) \
1522 dynamic_number_threads(image,image->columns,1,1)
1524 for (i=0; i <= (ssize_t) MaxMap; i++)
1526 x_map[i].x=0.298839*i;
1527 y_map[i].x=0.586811*i;
1528 z_map[i].x=0.114350*i;
1529 x_map[i].y=(-0.147130)*i;
1530 y_map[i].y=(-0.288860)*i;
1531 z_map[i].y=0.436000*i;
1532 x_map[i].z=0.615000*i;
1533 y_map[i].z=(-0.514990)*i;
1534 z_map[i].z=(-0.100001)*i;
1541 Linear conversion tables.
1543 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1544 #pragma omp parallel for schedule(static) \
1545 dynamic_number_threads(image,image->columns,1,1)
1547 for (i=0; i <= (ssize_t) MaxMap; i++)
1565 switch (image->storage_class)
1571 Convert DirectClass image.
1573 image_view=AcquireAuthenticCacheView(image,exception);
1574 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1575 #pragma omp parallel for schedule(static,4) shared(status) \
1576 dynamic_number_threads(image,image->columns,image->rows,1)
1578 for (y=0; y < (ssize_t) image->rows; y++)
1592 register unsigned int
1597 if (status == MagickFalse)
1599 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1601 if (q == (Quantum *) NULL)
1606 for (x=0; x < (ssize_t) image->columns; x++)
1608 red=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor((double)
1609 GetPixelRed(image,q))));
1610 green=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor((double)
1611 GetPixelGreen(image,q))));
1612 blue=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor((double)
1613 GetPixelBlue(image,q))));
1614 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
1616 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
1618 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
1620 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
1621 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
1622 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
1623 q+=GetPixelChannels(image);
1625 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1626 if (sync == MagickFalse)
1628 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1633 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1634 #pragma omp critical (MagickCore_sRGBTransformImage)
1636 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
1638 if (proceed == MagickFalse)
1642 image_view=DestroyCacheView(image_view);
1647 register unsigned int
1653 Convert PseudoClass image.
1655 for (i=0; i < (ssize_t) image->colors; i++)
1660 red=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor(
1661 image->colormap[i].red)));
1662 green=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor(
1663 image->colormap[i].green)));
1664 blue=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor(
1665 image->colormap[i].blue)));
1666 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1667 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1668 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1669 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
1670 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
1671 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
1673 (void) SyncImage(image,exception);
1678 Relinquish resources.
1680 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1681 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1682 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1683 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1684 return(MagickFalse);
1689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693 % S e t I m a g e C o l o r s p a c e %
1697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1699 % SetImageColorspace() sets the colorspace member of the Image structure.
1701 % The format of the SetImageColorspace method is:
1703 % MagickBooleanType SetImageColorspace(Image *image,
1704 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1706 % A description of each parameter follows:
1708 % o image: the image.
1710 % o colorspace: the colorspace.
1712 % o exception: return any errors or warnings in this structure.
1715 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1716 const ColorspaceType colorspace,ExceptionInfo *exception)
1718 if (image->colorspace == colorspace)
1720 image->colorspace=colorspace;
1721 image->rendering_intent=UndefinedIntent;
1723 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1724 if (IssRGBColorspace(colorspace) != MagickFalse)
1726 image->rendering_intent=PerceptualIntent;
1727 image->gamma=1.000/2.200;
1728 image->chromaticity.red_primary.x=0.6400;
1729 image->chromaticity.red_primary.y=0.3300;
1730 image->chromaticity.red_primary.z=0.0300;
1731 image->chromaticity.green_primary.x=0.3000;
1732 image->chromaticity.green_primary.y=0.6000;
1733 image->chromaticity.green_primary.z=0.1000;
1734 image->chromaticity.blue_primary.x=0.1500;
1735 image->chromaticity.blue_primary.y=0.0600;
1736 image->chromaticity.blue_primary.z=0.7900;
1737 image->chromaticity.white_point.x=0.3127;
1738 image->chromaticity.white_point.y=0.3290;
1739 image->chromaticity.white_point.z=0.3583f;
1741 if (IsGrayColorspace(colorspace) != MagickFalse)
1742 image->type=GrayscaleType;
1743 return(SyncImagePixelCache(image,exception));
1747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1751 % T r a n s f o r m I m a g e C o l o r s p a c e %
1755 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1757 % TransformImageColorspace() transforms an image colorspace, changing the
1758 % image data to reflect the new colorspace.
1760 % The format of the TransformImageColorspace method is:
1762 % MagickBooleanType TransformImageColorspace(Image *image,
1763 % const ColorspaceType colorspace,ExceptionInfo *exception)
1765 % A description of each parameter follows:
1767 % o image: the image.
1769 % o colorspace: the colorspace.
1771 % o exception: return any errors or warnings in this structure.
1774 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1775 const ColorspaceType colorspace,ExceptionInfo *exception)
1780 assert(image != (Image *) NULL);
1781 assert(image->signature == MagickSignature);
1782 if (image->debug != MagickFalse)
1783 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1784 if (colorspace == UndefinedColorspace)
1785 return(SetImageColorspace(image,colorspace,exception));
1786 if (image->colorspace == colorspace)
1787 return(MagickTrue); /* same colorspace: no op */
1789 Convert the reference image from an alternate colorspace to sRGB.
1791 (void) DeleteImageProfile(image,"icc");
1792 (void) DeleteImageProfile(image,"icm");
1793 if (IssRGBColorspace(colorspace) != MagickFalse)
1794 return(TransformsRGBImage(image,colorspace,exception));
1796 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1797 status=TransformsRGBImage(image,image->colorspace,exception);
1798 if (status == MagickFalse)
1801 Convert the reference image from sRGB to an alternate colorspace.
1803 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1813 + T r a n s f o r m s R G B I m a g e %
1817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1819 % TransformsRGBImage() converts the reference image from an alternate
1820 % colorspace to sRGB. The transformation matrices are not the standard ones:
1821 % the weights are rescaled to normalize the range of the transformed values
1822 % to be [0..QuantumRange].
1824 % The format of the TransformsRGBImage method is:
1826 % MagickBooleanType TransformsRGBImage(Image *image,
1827 % const ColorspaceType colorspace,ExceptionInfo *exception)
1829 % A description of each parameter follows:
1831 % o image: the image.
1833 % o colorspace: the colorspace to transform the image to.
1835 % o exception: return any errors or warnings in this structure.
1839 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1840 double *X,double *Y,double *Z)
1847 assert(X != (double *) NULL);
1848 assert(Y != (double *) NULL);
1849 assert(Z != (double *) NULL);
1853 *X=1.096123820835514*l-0.278869000218287*m+0.182745179382773*s;
1854 *Y=0.454369041975359*l+0.473533154307412*m+0.072097803717229*s;
1855 *Z=(-0.009627608738429)*l-0.005698031216113*m+1.015325639954543*s;
1858 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
1859 double *X,double *Y,double *Z)
1866 assert(X != (double *) NULL);
1867 assert(Y != (double *) NULL);
1868 assert(Z != (double *) NULL);
1869 y=(100.0*L+16.0)/116.0;
1870 x=y+255.0*(a-0.5)/500.0;
1871 z=y-255.0*(b-0.5)/200.0;
1872 if ((x*x*x) > CIEEpsilon)
1875 x=(116.0*x-16.0)/CIEK;
1876 if ((y*y*y) > CIEEpsilon)
1880 if ((z*z*z) > CIEEpsilon)
1883 z=(116*z-16.0)/CIEK;
1889 static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
1890 double *X,double *Y,double *Z)
1892 assert(X != (double *) NULL);
1893 assert(Y != (double *) NULL);
1894 assert(Z != (double *) NULL);
1895 if ((100.0*L) > (CIEK*CIEEpsilon))
1896 *Y=(double) pow(((100.0*L)+16.0)/116.0,3.0);
1899 *X=((*Y*((39.0*(100.0*L)/((262.0*v-140.0)+13.0*(100.0*L)*(9.0*D65Y/(D65X+
1900 15.0*D65Y+3.0*D65Z))))-5.0))+5.0*(*Y))/((((52.0*(100.0*L)/((354.0*u-134.0)+
1901 13.0*(100.0*L)*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
1902 *Z=(*X*(((52.0*(100.0*L)/((354.0*u-134.0)+13.0*(100.0*L)*(4.0*D65X/(D65X+
1903 15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-5.0*(*Y);
1906 static inline ssize_t RoundToYCC(const double value)
1910 if (value >= 1388.0)
1912 return((ssize_t) (value+0.5));
1915 static inline void ConvertXYZToRGB(const double x,const double y,
1916 const double z,double *red,double *green,double *blue)
1924 Convert XYZ to sRGB colorspace.
1926 assert(red != (double *) NULL);
1927 assert(green != (double *) NULL);
1928 assert(blue != (double *) NULL);
1929 r=3.2406*x-1.5372*y-0.4986*z;
1930 g=(-0.9689*x+1.8758*y+0.0415*z);
1931 b=0.0557*x-0.2040*y+1.0570*z;
1932 *red=QuantumRange*r;
1933 *green=QuantumRange*g;
1934 *blue=QuantumRange*b;
1937 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1939 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1940 (QuantumRange-pixel->black)+pixel->black)));
1941 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1942 (QuantumRange-pixel->black)+pixel->black)));
1943 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1944 (QuantumRange-pixel->black)+pixel->black)));
1947 static MagickBooleanType TransformsRGBImage(Image *image,
1948 const ColorspaceType colorspace,ExceptionInfo *exception)
1950 #define TransformsRGBImageTag "Transform/Image"
1952 #if !defined(MAGICKCORE_HDRI_SUPPORT)
1956 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1957 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1958 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1959 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1960 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1961 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1962 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1963 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1964 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1965 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1966 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1967 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1968 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1969 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1970 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1971 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1972 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1973 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1974 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1975 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1976 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1977 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1978 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1979 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1980 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1981 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1982 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1983 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1984 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1985 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1986 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1987 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1988 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1989 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1990 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1991 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1992 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1993 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1994 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1995 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1996 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1997 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1998 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1999 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
2000 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
2001 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
2002 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
2003 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
2004 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
2005 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
2006 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
2007 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
2008 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
2009 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
2010 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
2011 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
2012 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
2013 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
2014 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
2015 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
2016 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
2017 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
2018 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
2019 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
2020 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
2021 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
2022 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
2023 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
2024 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
2025 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
2026 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
2027 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
2028 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
2029 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
2030 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
2031 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
2032 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
2033 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
2034 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
2035 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
2036 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
2037 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
2038 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
2039 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
2040 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
2041 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
2042 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
2043 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
2044 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
2045 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
2046 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
2047 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
2048 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
2049 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
2050 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
2051 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
2052 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
2053 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
2054 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
2055 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
2056 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
2057 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
2058 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
2059 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
2060 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
2061 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
2062 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
2063 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
2064 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
2065 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
2066 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
2067 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
2068 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
2069 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
2070 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
2071 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
2072 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
2073 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
2074 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
2075 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
2076 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
2077 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
2078 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
2079 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
2080 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
2081 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
2082 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
2083 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
2084 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
2085 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
2086 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
2087 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
2088 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
2089 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
2090 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
2091 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
2092 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
2093 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
2094 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
2095 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
2096 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
2097 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
2098 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
2099 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
2100 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
2101 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
2102 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
2103 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
2104 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
2105 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
2106 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
2107 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
2108 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
2109 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
2110 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
2111 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
2112 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
2113 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
2114 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
2115 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
2116 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
2117 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
2118 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
2119 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
2120 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
2121 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
2122 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
2123 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
2124 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
2125 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
2126 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
2127 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
2128 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
2129 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
2130 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
2131 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
2132 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
2133 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
2134 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
2135 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
2136 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
2137 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
2138 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
2139 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
2140 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
2141 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
2142 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
2143 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
2144 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
2145 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
2146 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
2147 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
2148 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
2149 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
2150 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
2151 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
2152 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
2153 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
2154 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
2155 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
2156 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
2157 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
2158 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
2159 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
2160 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
2161 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
2162 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
2163 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
2164 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
2165 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
2166 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
2167 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
2168 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
2169 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
2170 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
2171 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
2172 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
2173 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
2174 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
2175 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
2176 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
2177 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
2178 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
2179 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
2180 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
2181 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
2182 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
2183 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
2184 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
2185 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
2186 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
2187 0.998559f, 0.999280f, 1.000000f
2211 assert(image != (Image *) NULL);
2212 assert(image->signature == MagickSignature);
2213 if (image->debug != MagickFalse)
2214 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2217 switch (image->colorspace)
2222 Transform image from CMY to sRGB.
2224 if (image->storage_class == PseudoClass)
2226 if (SyncImage(image,exception) == MagickFalse)
2227 return(MagickFalse);
2228 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2229 return(MagickFalse);
2231 image_view=AcquireAuthenticCacheView(image,exception);
2232 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2233 #pragma omp parallel for schedule(static,4) shared(status) \
2234 dynamic_number_threads(image,image->columns,image->rows,1)
2236 for (y=0; y < (ssize_t) image->rows; y++)
2247 if (status == MagickFalse)
2249 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2251 if (q == (Quantum *) NULL)
2256 for (x=0; x < (ssize_t) image->columns; x++)
2263 cyan=sRGBCompandor((double) (QuantumRange-
2264 GetPixelCyan(image,q)));
2265 magenta=sRGBCompandor((double) (QuantumRange-
2266 GetPixelMagenta(image,q)));
2267 yellow=sRGBCompandor((double) (QuantumRange-
2268 GetPixelYellow(image,q)));
2269 SetPixelCyan(image,ClampToQuantum(cyan),q);
2270 SetPixelMagenta(image,ClampToQuantum(magenta),q);
2271 SetPixelYellow(image,ClampToQuantum(yellow),q);
2272 q+=GetPixelChannels(image);
2274 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2275 if (sync == MagickFalse)
2278 image_view=DestroyCacheView(image_view);
2279 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2280 return(MagickFalse);
2283 case CMYKColorspace:
2289 Transform image from CMYK to sRGB.
2291 if (image->storage_class == PseudoClass)
2293 if (SyncImage(image,exception) == MagickFalse)
2294 return(MagickFalse);
2295 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2296 return(MagickFalse);
2298 GetPixelInfo(image,&zero);
2299 image_view=AcquireAuthenticCacheView(image,exception);
2300 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2301 #pragma omp parallel for schedule(static,4) shared(status) \
2302 dynamic_number_threads(image,image->columns,image->rows,1)
2304 for (y=0; y < (ssize_t) image->rows; y++)
2318 if (status == MagickFalse)
2320 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2322 if (q == (Quantum *) NULL)
2328 for (x=0; x < (ssize_t) image->columns; x++)
2330 GetPixelInfoPixel(image,q,&pixel);
2331 ConvertCMYKToRGB(&pixel);
2332 pixel.red=sRGBCompandor(pixel.red);
2333 pixel.green=sRGBCompandor(pixel.green);
2334 pixel.blue=sRGBCompandor(pixel.blue);
2335 SetPixelInfoPixel(image,&pixel,q);
2336 q+=GetPixelChannels(image);
2338 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2339 if (sync == MagickFalse)
2342 image_view=DestroyCacheView(image_view);
2343 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2344 return(MagickFalse);
2347 case GRAYColorspace:
2348 case Rec601LumaColorspace:
2349 case Rec709LumaColorspace:
2352 Transform linear GRAY to sRGB colorspace.
2354 if (image->storage_class == PseudoClass)
2356 if (SyncImage(image,exception) == MagickFalse)
2357 return(MagickFalse);
2358 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2359 return(MagickFalse);
2361 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2362 return(MagickFalse);
2363 image_view=AcquireAuthenticCacheView(image,exception);
2364 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2365 #pragma omp parallel for schedule(static,4) shared(status) \
2366 dynamic_number_threads(image,image->columns,image->rows,1)
2368 for (y=0; y < (ssize_t) image->rows; y++)
2379 if (status == MagickFalse)
2381 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2383 if (q == (Quantum *) NULL)
2388 for (x=(ssize_t) image->columns; x != 0; x--)
2393 gray=sRGBCompandor((double) GetPixelGray(image,q));
2394 SetPixelRed(image,ClampToQuantum(gray),q);
2395 SetPixelGreen(image,ClampToQuantum(gray),q);
2396 SetPixelBlue(image,ClampToQuantum(gray),q);
2397 q+=GetPixelChannels(image);
2399 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2400 if (sync == MagickFalse)
2403 image_view=DestroyCacheView(image_view);
2404 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2405 return(MagickFalse);
2411 Transform image from HCL to sRGB.
2413 if (image->storage_class == PseudoClass)
2415 if (SyncImage(image,exception) == MagickFalse)
2416 return(MagickFalse);
2417 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2418 return(MagickFalse);
2420 image_view=AcquireAuthenticCacheView(image,exception);
2421 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2422 #pragma omp parallel for schedule(static,4) shared(status) \
2423 dynamic_number_threads(image,image->columns,image->rows,1)
2425 for (y=0; y < (ssize_t) image->rows; y++)
2436 if (status == MagickFalse)
2438 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2440 if (q == (Quantum *) NULL)
2445 for (x=0; x < (ssize_t) image->columns; x++)
2455 hue=(double) (QuantumScale*GetPixelRed(image,q));
2456 chroma=(double) (QuantumScale*GetPixelGreen(image,q));
2457 luma=(double) (QuantumScale*GetPixelBlue(image,q));
2458 ConvertHCLToRGB(hue,chroma,luma,&red,&green,&blue);
2459 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2460 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2461 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2462 q+=GetPixelChannels(image);
2464 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2465 if (sync == MagickFalse)
2468 image_view=DestroyCacheView(image_view);
2469 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2470 return(MagickFalse);
2476 Transform image from HSB to sRGB.
2478 if (image->storage_class == PseudoClass)
2480 if (SyncImage(image,exception) == MagickFalse)
2481 return(MagickFalse);
2482 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2483 return(MagickFalse);
2485 image_view=AcquireAuthenticCacheView(image,exception);
2486 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2487 #pragma omp parallel for schedule(static,4) shared(status) \
2488 dynamic_number_threads(image,image->columns,image->rows,1)
2490 for (y=0; y < (ssize_t) image->rows; y++)
2501 if (status == MagickFalse)
2503 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2505 if (q == (Quantum *) NULL)
2510 for (x=0; x < (ssize_t) image->columns; x++)
2520 hue=(double) (QuantumScale*GetPixelRed(image,q));
2521 saturation=(double) (QuantumScale*GetPixelGreen(image,q));
2522 brightness=(double) (QuantumScale*GetPixelBlue(image,q));
2523 ConvertHSBToRGB(hue,saturation,brightness,&red,&green,&blue);
2524 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2525 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2526 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2527 q+=GetPixelChannels(image);
2529 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2530 if (sync == MagickFalse)
2533 image_view=DestroyCacheView(image_view);
2534 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2535 return(MagickFalse);
2541 Transform image from HSL to sRGB.
2543 if (image->storage_class == PseudoClass)
2545 if (SyncImage(image,exception) == MagickFalse)
2546 return(MagickFalse);
2547 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2548 return(MagickFalse);
2550 image_view=AcquireAuthenticCacheView(image,exception);
2551 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2552 #pragma omp parallel for schedule(static,4) shared(status) \
2553 dynamic_number_threads(image,image->columns,image->rows,1)
2555 for (y=0; y < (ssize_t) image->rows; y++)
2566 if (status == MagickFalse)
2568 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2570 if (q == (Quantum *) NULL)
2575 for (x=0; x < (ssize_t) image->columns; x++)
2585 hue=(double) (QuantumScale*GetPixelRed(image,q));
2586 saturation=(double) (QuantumScale*GetPixelGreen(image,q));
2587 lightness=(double) (QuantumScale*GetPixelBlue(image,q));
2588 ConvertHSLToRGB(hue,saturation,lightness,&red,&green,&blue);
2589 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2590 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2591 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2592 q+=GetPixelChannels(image);
2594 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2595 if (sync == MagickFalse)
2598 image_view=DestroyCacheView(image_view);
2599 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2600 return(MagickFalse);
2606 Transform image from HWB to sRGB.
2608 if (image->storage_class == PseudoClass)
2610 if (SyncImage(image,exception) == MagickFalse)
2611 return(MagickFalse);
2612 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2613 return(MagickFalse);
2615 image_view=AcquireAuthenticCacheView(image,exception);
2616 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2617 #pragma omp parallel for schedule(static,4) shared(status) \
2618 dynamic_number_threads(image,image->columns,image->rows,1)
2620 for (y=0; y < (ssize_t) image->rows; y++)
2631 if (status == MagickFalse)
2633 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2635 if (q == (Quantum *) NULL)
2640 for (x=0; x < (ssize_t) image->columns; x++)
2650 hue=(double) (QuantumScale*GetPixelRed(image,q));
2651 whiteness=(double) (QuantumScale*GetPixelGreen(image,q));
2652 blackness=(double) (QuantumScale*GetPixelBlue(image,q));
2653 ConvertHWBToRGB(hue,whiteness,blackness,&red,&green,&blue);
2654 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2655 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2656 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2657 q+=GetPixelChannels(image);
2659 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2660 if (sync == MagickFalse)
2663 image_view=DestroyCacheView(image_view);
2664 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2665 return(MagickFalse);
2671 Transform image from Lab to sRGB.
2673 if (image->storage_class == PseudoClass)
2675 if (SyncImage(image,exception) == MagickFalse)
2676 return(MagickFalse);
2677 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2678 return(MagickFalse);
2680 image_view=AcquireAuthenticCacheView(image,exception);
2681 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2682 #pragma omp parallel for schedule(static,4) shared(status) \
2683 dynamic_number_threads(image,image->columns,image->rows,1)
2685 for (y=0; y < (ssize_t) image->rows; y++)
2696 if (status == MagickFalse)
2698 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2700 if (q == (Quantum *) NULL)
2705 for (x=0; x < (ssize_t) image->columns; x++)
2718 L=QuantumScale*GetPixelRed(image,q);
2719 a=QuantumScale*GetPixelGreen(image,q);
2720 b=QuantumScale*GetPixelBlue(image,q);
2721 ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
2722 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2723 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2724 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2725 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2726 q+=GetPixelChannels(image);
2728 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2729 if (sync == MagickFalse)
2732 image_view=DestroyCacheView(image_view);
2733 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2734 return(MagickFalse);
2740 Transform image from LCH to sRGB.
2742 if (image->storage_class == PseudoClass)
2744 if (SyncImage(image,exception) == MagickFalse)
2745 return(MagickFalse);
2746 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2747 return(MagickFalse);
2749 image_view=AcquireAuthenticCacheView(image,exception);
2750 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2751 #pragma omp parallel for schedule(static,4) shared(status) \
2752 dynamic_number_threads(image,image->columns,image->rows,1)
2754 for (y=0; y < (ssize_t) image->rows; y++)
2765 if (status == MagickFalse)
2767 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2769 if (q == (Quantum *) NULL)
2774 for (x=0; x < (ssize_t) image->columns; x++)
2789 L=QuantumScale*GetPixelRed(image,q);
2790 C=QuantumScale*GetPixelGreen(image,q);
2791 H=QuantumScale*GetPixelBlue(image,q);
2792 a=C*cos(H*(MagickPI/180.0));
2793 b=C*sin(H*(MagickPI/180.0));
2794 ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
2795 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2796 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2797 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2798 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2799 q+=GetPixelChannels(image);
2801 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2802 if (sync == MagickFalse)
2805 image_view=DestroyCacheView(image_view);
2806 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2807 return(MagickFalse);
2813 Transform image from LMS to sRGB.
2815 if (image->storage_class == PseudoClass)
2817 if (SyncImage(image,exception) == MagickFalse)
2818 return(MagickFalse);
2819 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2820 return(MagickFalse);
2822 image_view=AcquireAuthenticCacheView(image,exception);
2823 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2824 #pragma omp parallel for schedule(static,4) shared(status) \
2825 dynamic_number_threads(image,image->columns,image->rows,1)
2827 for (y=0; y < (ssize_t) image->rows; y++)
2838 if (status == MagickFalse)
2840 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2842 if (q == (Quantum *) NULL)
2847 for (x=0; x < (ssize_t) image->columns; x++)
2860 L=QuantumScale*GetPixelRed(image,q);
2861 M=QuantumScale*GetPixelGreen(image,q);
2862 S=QuantumScale*GetPixelBlue(image,q);
2863 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
2864 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2865 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2866 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2867 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2868 q+=GetPixelChannels(image);
2870 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2871 if (sync == MagickFalse)
2874 image_view=DestroyCacheView(image_view);
2875 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2876 return(MagickFalse);
2896 Transform Log to sRGB colorspace.
2898 density=DisplayGamma;
2900 value=GetImageProperty(image,"gamma",exception);
2901 if (value != (const char *) NULL)
2902 gamma=MagickEpsilonReciprocal(StringToDouble(value,(char **) NULL));
2903 film_gamma=FilmGamma;
2904 value=GetImageProperty(image,"film-gamma",exception);
2905 if (value != (const char *) NULL)
2906 film_gamma=StringToDouble(value,(char **) NULL);
2907 reference_black=ReferenceBlack;
2908 value=GetImageProperty(image,"reference-black",exception);
2909 if (value != (const char *) NULL)
2910 reference_black=StringToDouble(value,(char **) NULL);
2911 reference_white=ReferenceWhite;
2912 value=GetImageProperty(image,"reference-white",exception);
2913 if (value != (const char *) NULL)
2914 reference_white=StringToDouble(value,(char **) NULL);
2915 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2917 if (logmap == (Quantum *) NULL)
2918 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2920 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*
2922 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
2923 logmap[i]=(Quantum) 0;
2924 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
2925 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
2926 (pow(10.0,(1024.0*i/MaxMap-reference_white)*
2927 (gamma/density)*0.002/film_gamma)-black));
2928 for ( ; i <= (ssize_t) MaxMap; i++)
2929 logmap[i]=QuantumRange;
2930 if (image->storage_class == PseudoClass)
2932 if (SyncImage(image,exception) == MagickFalse)
2933 return(MagickFalse);
2934 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2935 return(MagickFalse);
2937 image_view=AcquireAuthenticCacheView(image,exception);
2938 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2939 #pragma omp parallel for schedule(static,4) shared(status) \
2940 dynamic_number_threads(image,image->columns,image->rows,1)
2942 for (y=0; y < (ssize_t) image->rows; y++)
2953 if (status == MagickFalse)
2955 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2957 if (q == (Quantum *) NULL)
2962 for (x=(ssize_t) image->columns; x != 0; x--)
2969 red=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2970 GetPixelRed(image,q))]);
2971 green=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2972 GetPixelGreen(image,q))]);
2973 blue=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2974 GetPixelBlue(image,q))]);
2975 SetPixelRed(image,ClampToQuantum(red),q);
2976 SetPixelGreen(image,ClampToQuantum(green),q);
2977 SetPixelBlue(image,ClampToQuantum(blue),q);
2978 q+=GetPixelChannels(image);
2980 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2981 if (sync == MagickFalse)
2984 image_view=DestroyCacheView(image_view);
2985 logmap=(Quantum *) RelinquishMagickMemory(logmap);
2986 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2987 return(MagickFalse);
2993 Transform image from Luv to sRGB.
2995 if (image->storage_class == PseudoClass)
2997 if (SyncImage(image,exception) == MagickFalse)
2998 return(MagickFalse);
2999 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
3000 return(MagickFalse);
3002 image_view=AcquireAuthenticCacheView(image,exception);
3003 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3004 #pragma omp parallel for schedule(static,4) shared(status) \
3005 dynamic_number_threads(image,image->columns,image->rows,1)
3007 for (y=0; y < (ssize_t) image->rows; y++)
3018 if (status == MagickFalse)
3020 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
3022 if (q == (Quantum *) NULL)
3027 for (x=0; x < (ssize_t) image->columns; x++)
3040 L=QuantumScale*GetPixelRed(image,q);
3041 u=QuantumScale*GetPixelGreen(image,q);
3042 v=QuantumScale*GetPixelBlue(image,q);
3043 ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
3044 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
3045 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
3046 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
3047 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
3048 q+=GetPixelChannels(image);
3050 sync=SyncCacheViewAuthenticPixels(image_view,exception);
3051 if (sync == MagickFalse)
3054 image_view=DestroyCacheView(image_view);
3055 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
3056 return(MagickFalse);
3062 Transform linear RGB to sRGB colorspace.
3064 if (image->storage_class == PseudoClass)
3066 if (SyncImage(image,exception) == MagickFalse)
3067 return(MagickFalse);
3068 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
3069 return(MagickFalse);
3071 image_view=AcquireAuthenticCacheView(image,exception);
3072 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3073 #pragma omp parallel for schedule(static,4) shared(status) \
3074 dynamic_number_threads(image,image->columns,image->rows,1)
3076 for (y=0; y < (ssize_t) image->rows; y++)
3087 if (status == MagickFalse)
3089 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
3091 if (q == (Quantum *) NULL)
3096 for (x=(ssize_t) image->columns; x != 0; x--)
3103 red=sRGBCompandor((double) GetPixelRed(image,q));
3104 green=sRGBCompandor((double) GetPixelGreen(image,q));
3105 blue=sRGBCompandor((double) GetPixelBlue(image,q));
3106 SetPixelRed(image,ClampToQuantum(red),q);
3107 SetPixelGreen(image,ClampToQuantum(green),q);
3108 SetPixelBlue(image,ClampToQuantum(blue),q);
3109 q+=GetPixelChannels(image);
3111 sync=SyncCacheViewAuthenticPixels(image_view,exception);
3112 if (sync == MagickFalse)
3115 image_view=DestroyCacheView(image_view);
3116 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
3117 return(MagickFalse);
3123 Transform image from XYZ to sRGB.
3125 if (image->storage_class == PseudoClass)
3127 if (SyncImage(image,exception) == MagickFalse)
3128 return(MagickFalse);
3129 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
3130 return(MagickFalse);
3132 image_view=AcquireAuthenticCacheView(image,exception);
3133 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3134 #pragma omp parallel for schedule(static,4) shared(status) \
3135 dynamic_number_threads(image,image->columns,image->rows,1)
3137 for (y=0; y < (ssize_t) image->rows; y++)
3148 if (status == MagickFalse)
3150 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
3152 if (q == (Quantum *) NULL)
3157 for (x=0; x < (ssize_t) image->columns; x++)
3167 X=QuantumScale*GetPixelRed(image,q);
3168 Y=QuantumScale*GetPixelGreen(image,q);
3169 Z=QuantumScale*GetPixelBlue(image,q);
3170 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
3171 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
3172 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
3173 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
3174 q+=GetPixelChannels(image);
3176 sync=SyncCacheViewAuthenticPixels(image_view,exception);
3177 if (sync == MagickFalse)
3180 image_view=DestroyCacheView(image_view);
3181 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
3182 return(MagickFalse);
3189 Allocate the tables.
3191 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
3193 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
3195 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
3197 if ((x_map == (TransformPacket *) NULL) ||
3198 (y_map == (TransformPacket *) NULL) ||
3199 (z_map == (TransformPacket *) NULL))
3201 if (z_map != (TransformPacket *) NULL)
3202 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
3203 if (y_map != (TransformPacket *) NULL)
3204 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
3205 if (x_map != (TransformPacket *) NULL)
3206 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
3207 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
3210 switch (image->colorspace)
3212 case OHTAColorspace:
3215 Initialize OHTA tables:
3217 R = I1+1.00000*I2-0.66668*I3
3218 G = I1+0.00000*I2+1.33333*I3
3219 B = I1-1.00000*I2-0.66668*I3
3221 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
3222 through QuantumRange.
3224 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3225 #pragma omp parallel for schedule(static) \
3226 dynamic_number_threads(image,image->columns,1,1)
3228 for (i=0; i <= (ssize_t) MaxMap; i++)
3231 y_map[i].x=0.5*(2.0*i-MaxMap);
3232 z_map[i].x=(-0.333340)*(2.0*i-MaxMap);
3234 y_map[i].y=0.000000;
3235 z_map[i].y=0.666665*(2.0*i-MaxMap);
3237 y_map[i].z=(-0.500000)*(2.0*i-MaxMap);
3238 z_map[i].z=(-0.333340)*(2.0*i-MaxMap);
3242 case Rec601YCbCrColorspace:
3243 case YCbCrColorspace:
3246 Initialize YCbCr tables:
3249 G = Y-0.344136*Cb-0.714136*Cr
3252 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
3253 through QuantumRange.
3255 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3256 #pragma omp parallel for schedule(static) \
3257 dynamic_number_threads(image,image->columns,1,1)
3259 for (i=0; i <= (ssize_t) MaxMap; i++)
3261 x_map[i].x=0.99999999999914679361*i;
3262 y_map[i].x=(1.2188941887145875e-06)*i;
3263 z_map[i].x=0.5*1.4019995886561440468*(2.00*i-MaxMap);
3264 x_map[i].y=0.99999975910502514331*i;
3265 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*i-MaxMap);
3266 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*i-MaxMap);
3267 x_map[i].z=1.00000124040004623180*i;
3268 y_map[i].z=0.5*1.77200006607230409200*(2.00*i-MaxMap);
3269 z_map[i].z=2.1453384174593273e-06*i;
3273 case Rec709YCbCrColorspace:
3276 Initialize YCbCr tables:
3279 G = Y-0.187324*Cb-0.468124*Cr
3282 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
3283 through QuantumRange.
3285 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3286 #pragma omp parallel for schedule(static) \
3287 dynamic_number_threads(image,image->columns,1,1)
3289 for (i=0; i <= (ssize_t) MaxMap; i++)
3292 y_map[i].x=0.000000*(2.0*i-MaxMap);
3293 z_map[i].x=0.5*1.574800*(2.0*i-MaxMap);
3295 y_map[i].y=0.5*(-0.187324)*(2.0*i-MaxMap);
3296 z_map[i].y=0.5*(-0.468124)*(2.0*i-MaxMap);
3298 y_map[i].z=0.5*1.855600*(2.0*i-MaxMap);
3299 z_map[i].z=0.000000*(2.0*i-MaxMap);
3306 Initialize YCC tables:
3309 G = Y-0.317038*C1-0.682243*C2
3312 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
3314 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3315 #pragma omp parallel for schedule(static) \
3316 dynamic_number_threads(image,image->columns,1,1)
3318 for (i=0; i <= (ssize_t) MaxMap; i++)
3320 x_map[i].x=1.3584000*i;
3321 y_map[i].x=0.0000000;
3322 z_map[i].x=1.8215000*(1.0*i-(double)
3323 ScaleQuantumToMap(ScaleCharToQuantum(137)));
3324 x_map[i].y=1.3584000*i;
3325 y_map[i].y=(-0.4302726)*(1.0*i-(double)
3326 ScaleQuantumToMap(ScaleCharToQuantum(156)));
3327 z_map[i].y=(-0.9271435)*(1.0*i-(double)
3328 ScaleQuantumToMap(ScaleCharToQuantum(137)));
3329 x_map[i].z=1.3584000*i;
3330 y_map[i].z=2.2179000*(1.0*i-(double)
3331 ScaleQuantumToMap(ScaleCharToQuantum(156)));
3332 z_map[i].z=0.0000000;
3339 Initialize YIQ tables:
3341 R = Y+0.95620*I+0.62140*Q
3342 G = Y-0.27270*I-0.64680*Q
3343 B = Y-1.10370*I+1.70060*Q
3345 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
3346 through QuantumRange.
3348 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3349 #pragma omp parallel for schedule(static) \
3350 dynamic_number_threads(image,image->columns,1,1)
3352 for (i=0; i <= (ssize_t) MaxMap; i++)
3355 y_map[i].x=0.5*0.9562957197589482261*(2.00000*i-MaxMap);
3356 z_map[i].x=0.5*0.6210244164652610754*(2.00000*i-MaxMap);
3358 y_map[i].y=0.5*(-0.2721220993185104464)*(2.00000*i-MaxMap);
3359 z_map[i].y=0.5*(-0.6473805968256950427)*(2.00000*i-MaxMap);
3361 y_map[i].z=0.5*(-1.1069890167364901945)*(2.00000*i-MaxMap);
3362 z_map[i].z=0.5*1.7046149983646481374*(2.00000*i-MaxMap);
3366 case YPbPrColorspace:
3369 Initialize YPbPr tables:
3372 G = Y-0.344136*C1+0.714136*C2
3375 Pb and Pr, normally -0.5 through 0.5, must be normalized to the range 0
3376 through QuantumRange.
3378 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3379 #pragma omp parallel for schedule(static) \
3380 dynamic_number_threads(image,image->columns,1,1)
3382 for (i=0; i <= (ssize_t) MaxMap; i++)
3384 x_map[i].x=0.99999999999914679361*i;
3385 y_map[i].x=(-1.2188941887145875e-06)*(2.0*i-MaxMap);
3386 z_map[i].x=0.5*1.4019995886561440468*(2.0*i-MaxMap);
3387 x_map[i].y=0.99999975910502514331*i;
3388 y_map[i].y=0.5*(-0.34413567816504303521)*(2.0*i-MaxMap);
3389 z_map[i].y=0.5*(-0.71413649331646789076)*(2.0*i-MaxMap);
3390 x_map[i].z=1.00000124040004623180*i;
3391 y_map[i].z=0.5*1.77200006607230409200*(2.0*i-MaxMap);
3392 z_map[i].z=2.1453384174593273e-06*(2.0*i-MaxMap);
3399 Initialize YUV tables:
3402 G = Y-0.39464*U-0.58060*V
3405 U and V, normally -0.5 through 0.5, must be normalized to the range 0
3406 through QuantumRange.
3408 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3409 #pragma omp parallel for schedule(static) \
3410 dynamic_number_threads(image,image->columns,1,1)
3412 for (i=0; i <= (ssize_t) MaxMap; i++)
3415 y_map[i].x=(-3.945707070708279e-05)*(2.0*i-MaxMap);
3416 z_map[i].x=0.5*1.1398279671717170825*(2.0*i-MaxMap);
3418 y_map[i].y=0.5*(-0.3946101641414141437)*(2.0*i-MaxMap);
3419 z_map[i].y=0.5*(-0.5805003156565656797)*(2.0*i-MaxMap);
3421 y_map[i].z=0.5*2.0319996843434342537*(2.0*i-MaxMap);
3422 z_map[i].z=(-4.813762626262513e-04)*(2.0*i-MaxMap);
3429 Linear conversion tables.
3431 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3432 #pragma omp parallel for schedule(static) \
3433 dynamic_number_threads(image,image->columns,1,1)
3435 for (i=0; i <= (ssize_t) MaxMap; i++)
3453 switch (image->storage_class)
3459 Convert DirectClass image.
3461 image_view=AcquireAuthenticCacheView(image,exception);
3462 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3463 #pragma omp parallel for schedule(static,4) shared(status) \
3464 dynamic_number_threads(image,image->columns,image->rows,1)
3466 for (y=0; y < (ssize_t) image->rows; y++)
3480 if (status == MagickFalse)
3482 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
3484 if (q == (Quantum *) NULL)
3489 for (x=0; x < (ssize_t) image->columns; x++)
3496 red=ScaleQuantumToMap(GetPixelRed(image,q));
3497 green=ScaleQuantumToMap(GetPixelGreen(image,q));
3498 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
3499 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
3500 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
3501 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
3502 if (colorspace == YCCColorspace)
3504 #if !defined(MAGICKCORE_HDRI_SUPPORT)
3505 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3507 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3509 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3513 SetPixelRed(image,ClampToQuantum(sRGBCompandor((double)
3514 ScaleMapToQuantum(pixel.red))),q);
3515 SetPixelGreen(image,ClampToQuantum(sRGBCompandor((double)
3516 ScaleMapToQuantum(pixel.green))),q);
3517 SetPixelBlue(image,ClampToQuantum(sRGBCompandor((double)
3518 ScaleMapToQuantum(pixel.blue))),q);
3519 q+=GetPixelChannels(image);
3521 sync=SyncCacheViewAuthenticPixels(image_view,exception);
3522 if (sync == MagickFalse)
3524 if (image->progress_monitor != (MagickProgressMonitor) NULL)
3529 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3530 #pragma omp critical (MagickCore_TransformsRGBImage)
3532 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
3534 if (proceed == MagickFalse)
3538 image_view=DestroyCacheView(image_view);
3544 Convert PseudoClass image.
3546 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3547 #pragma omp parallel for schedule(static,4) shared(status) \
3548 dynamic_number_threads(image,image->columns,1,1)
3550 for (i=0; i < (ssize_t) image->colors; i++)
3560 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
3561 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
3562 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
3563 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
3564 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
3565 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
3566 if (colorspace == YCCColorspace)
3568 #if !defined(MAGICKCORE_HDRI_SUPPORT)
3569 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3571 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3573 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3577 image->colormap[i].red=(double) ClampToQuantum(
3578 sRGBCompandor((double) ScaleMapToQuantum(pixel.red)));
3579 image->colormap[i].green=(double) ClampToQuantum(
3580 sRGBCompandor((double) ScaleMapToQuantum(pixel.green)));
3581 image->colormap[i].blue=(double) ClampToQuantum(
3582 sRGBCompandor((double) ScaleMapToQuantum(pixel.blue)));
3584 (void) SyncImage(image,exception);
3589 Relinquish resources.
3591 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
3592 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
3593 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
3594 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
3595 return(MagickFalse);