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-2013 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 *,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)
122 Convert XYZ to LMS colorspace.
124 assert(L != (double *) NULL);
125 assert(M != (double *) NULL);
126 assert(S != (double *) NULL);
127 *L=0.7328*x+0.4296*y-0.1624*z;
128 *M=(-0.7036*x+1.6975*y+0.0061*z);
129 *S=0.0030*x+0.0136*y+0.9834*z;
132 static void ConvertRGBToLMS(const double red,const double green,
133 const double blue,double *L,double *M,double *S)
140 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
141 ConvertXYZToLMS(X,Y,Z,L,M,S);
144 static void ConvertRGBToLab(const double red,const double green,
145 const double blue,double *L,double *a,double *b)
152 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
153 ConvertXYZToLab(X,Y,Z,L,a,b);
156 static void ConvertRGBToLuv(const double red,const double green,
157 const double blue,double *L,double *u,double *v)
164 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
165 ConvertXYZToLuv(X,Y,Z,L,u,v);
168 static void ConvertRGBToYIQ(const double red,const double green,
169 const double blue,double *Y,double *I,double *Q)
172 Convert RGB to YIQ colorspace.
174 assert(Y != (double *) NULL);
175 assert(I != (double *) NULL);
176 assert(Q != (double *) NULL);
177 *Y=0.298839*red+0.586811*green+0.114350*blue;
178 *I=0.595716*red-0.274453*green-0.321263*blue+0.5;
179 *Q=0.211456*red-0.522591*green+0.311135*blue+0.5;
182 static void ConvertRGBToYPbPr(const double red,const double green,
183 const double blue,double *Y,double *Pb,double *Pr)
186 Convert RGB to YPbPr colorspace.
188 assert(Y != (double *) NULL);
189 assert(Pb != (double *) NULL);
190 assert(Pr != (double *) NULL);
191 *Y=0.298839*QuantumScale*red+0.586811*QuantumScale*green+0.114350*
193 *Pb=(-0.1687367)*QuantumScale*red-0.331264*QuantumScale*green+0.5*
194 QuantumScale*blue+0.5;
195 *Pr=0.5*QuantumScale*red-0.418688*QuantumScale*green-0.081312*
196 QuantumScale*blue+0.5;
199 static void ConvertRGBToYCbCr(const double red,const double green,
200 const double blue,double *Y,double *Cb,double *Cr)
203 Convert RGB to -YCbCr colorspace.
205 assert(Y != (double *) NULL);
206 assert(Cb != (double *) NULL);
207 assert(Cr != (double *) NULL);
208 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
211 static void ConvertRGBToYUV(const double red,const double green,
212 const double blue,double *Y,double *U,double *V)
215 Convert RGB to YUV colorspace.
217 assert(Y != (double *) NULL);
218 assert(U != (double *) NULL);
219 assert(V != (double *) NULL);
220 *Y=0.298839*red+0.586811*green+0.114350*blue;
221 *U=(-0.147)*red-0.289*green+0.436*blue+0.5;
222 *V=0.615*red-0.515*green-0.100*blue+0.5;
225 static MagickBooleanType sRGBTransformImage(Image *image,
226 const ColorspaceType colorspace,ExceptionInfo *exception)
228 #define sRGBTransformImageTag "RGBTransform/Image"
253 assert(image != (Image *) NULL);
254 assert(image->signature == MagickSignature);
255 if (image->debug != MagickFalse)
256 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
257 assert(colorspace != sRGBColorspace);
258 assert(colorspace != TransparentColorspace);
259 assert(colorspace != UndefinedColorspace);
267 Convert RGB to CMY colorspace.
269 if (image->storage_class == PseudoClass)
271 if (SyncImage(image,exception) == MagickFalse)
273 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
276 image_view=AcquireAuthenticCacheView(image,exception);
277 #if defined(MAGICKCORE_OPENMP_SUPPORT)
278 #pragma omp parallel for schedule(static,4) shared(status) \
279 magick_threads(image,image,image->rows,1)
281 for (y=0; y < (ssize_t) image->rows; y++)
292 if (status == MagickFalse)
294 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
296 if (q == (Quantum *) NULL)
301 for (x=0; x < (ssize_t) image->columns; x++)
308 cyan=(MagickRealType) GetPixelCyan(image,q);
309 magenta=(MagickRealType) GetPixelMagenta(image,q);
310 yellow=(MagickRealType) GetPixelYellow(image,q);
311 SetPixelCyan(image,ClampToQuantum(QuantumRange-cyan),q);
312 SetPixelMagenta(image,ClampToQuantum(QuantumRange-magenta),q);
313 SetPixelYellow(image,ClampToQuantum(QuantumRange-yellow),q);
314 q+=GetPixelChannels(image);
316 sync=SyncCacheViewAuthenticPixels(image_view,exception);
317 if (sync == MagickFalse)
320 image_view=DestroyCacheView(image_view);
321 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
322 ColorSeparationMatteType;
323 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
333 Convert RGB to CMYK colorspace.
335 if (image->storage_class == PseudoClass)
337 if (SyncImage(image,exception) == MagickFalse)
339 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
342 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
344 GetPixelInfo(image,&zero);
345 image_view=AcquireAuthenticCacheView(image,exception);
346 #if defined(MAGICKCORE_OPENMP_SUPPORT)
347 #pragma omp parallel for schedule(static,4) shared(status) \
348 magick_threads(image,image,image->rows,1)
350 for (y=0; y < (ssize_t) image->rows; y++)
364 if (status == MagickFalse)
366 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
368 if (q == (Quantum *) NULL)
374 for (x=0; x < (ssize_t) image->columns; x++)
376 GetPixelInfoPixel(image,q,&pixel);
377 ConvertRGBToCMYK(&pixel);
378 SetPixelInfoPixel(image,&pixel,q);
379 q+=GetPixelChannels(image);
381 sync=SyncCacheViewAuthenticPixels(image_view,exception);
382 if (sync == MagickFalse)
385 image_view=DestroyCacheView(image_view);
386 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
387 ColorSeparationMatteType;
388 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
395 Transform image from sRGB to GRAY.
397 if (image->storage_class == PseudoClass)
399 if (SyncImage(image,exception) == MagickFalse)
401 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
404 image_view=AcquireAuthenticCacheView(image,exception);
405 #if defined(MAGICKCORE_OPENMP_SUPPORT)
406 #pragma omp parallel for schedule(static,4) shared(status) \
407 magick_threads(image,image,image->rows,1)
409 for (y=0; y < (ssize_t) image->rows; y++)
420 if (status == MagickFalse)
422 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
424 if (q == (Quantum *) NULL)
429 for (x=0; x < (ssize_t) image->columns; x++)
431 SetPixelGray(image,ClampToQuantum(GetPixelIntensity(image,q)),q);
432 q+=GetPixelChannels(image);
434 sync=SyncCacheViewAuthenticPixels(image_view,exception);
435 if (sync == MagickFalse)
438 image_view=DestroyCacheView(image_view);
439 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
441 image->type=GrayscaleType;
453 case LCHabColorspace:
454 case LCHuvColorspace:
458 case YCbCrColorspace:
460 case YPbPrColorspace:
464 Transform image from sRGB to target colorspace.
466 if (image->storage_class == PseudoClass)
468 if (SyncImage(image,exception) == MagickFalse)
470 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
473 image_view=AcquireAuthenticCacheView(image,exception);
474 #if defined(MAGICKCORE_OPENMP_SUPPORT)
475 #pragma omp parallel for schedule(static,4) shared(status) \
476 magick_threads(image,image,image->rows,1)
478 for (y=0; y < (ssize_t) image->rows; y++)
489 if (status == MagickFalse)
491 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
493 if (q == (Quantum *) NULL)
498 for (x=0; x < (ssize_t) image->columns; x++)
508 red=(double) GetPixelRed(image,q);
509 green=(double) GetPixelGreen(image,q);
510 blue=(double) GetPixelBlue(image,q);
515 ConvertRGBToHCL(red,green,blue,&X,&Y,&Z);
520 ConvertRGBToHCLp(red,green,blue,&X,&Y,&Z);
525 ConvertRGBToHSB(red,green,blue,&X,&Y,&Z);
530 ConvertRGBToHSI(red,green,blue,&X,&Y,&Z);
535 ConvertRGBToHSL(red,green,blue,&X,&Y,&Z);
540 ConvertRGBToHSV(red,green,blue,&X,&Y,&Z);
545 ConvertRGBToHWB(red,green,blue,&X,&Y,&Z);
550 ConvertRGBToLab(red,green,blue,&X,&Y,&Z);
554 case LCHabColorspace:
556 ConvertRGBToLCHab(red,green,blue,&X,&Y,&Z);
559 case LCHuvColorspace:
561 ConvertRGBToLCHuv(red,green,blue,&X,&Y,&Z);
566 ConvertRGBToLMS(red,green,blue,&X,&Y,&Z);
571 ConvertRGBToLuv(red,green,blue,&X,&Y,&Z);
576 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
579 case YCbCrColorspace:
581 ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z);
586 ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z);
589 case YPbPrColorspace:
591 ConvertRGBToYPbPr(red,green,blue,&X,&Y,&Z);
596 ConvertRGBToYUV(red,green,blue,&X,&Y,&Z);
602 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
603 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
604 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q);
605 q+=GetPixelChannels(image);
607 sync=SyncCacheViewAuthenticPixels(image_view,exception);
608 if (sync == MagickFalse)
611 image_view=DestroyCacheView(image_view);
612 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
618 #define DisplayGamma (1.0/1.7)
619 #define FilmGamma 0.6
620 #define ReferenceBlack 95.0
621 #define ReferenceWhite 685.0
638 Transform RGB to Log colorspace.
640 density=DisplayGamma;
642 value=GetImageProperty(image,"gamma",exception);
643 if (value != (const char *) NULL)
644 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
645 film_gamma=FilmGamma;
646 value=GetImageProperty(image,"film-gamma",exception);
647 if (value != (const char *) NULL)
648 film_gamma=StringToDouble(value,(char **) NULL);
649 reference_black=ReferenceBlack;
650 value=GetImageProperty(image,"reference-black",exception);
651 if (value != (const char *) NULL)
652 reference_black=StringToDouble(value,(char **) NULL);
653 reference_white=ReferenceWhite;
654 value=GetImageProperty(image,"reference-white",exception);
655 if (value != (const char *) NULL)
656 reference_white=StringToDouble(value,(char **) NULL);
657 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
659 if (logmap == (Quantum *) NULL)
660 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
662 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
664 #if defined(MAGICKCORE_OPENMP_SUPPORT)
665 #pragma omp parallel for schedule(static,4) \
666 magick_threads(image,image,1,1)
668 for (i=0; i <= (ssize_t) MaxMap; i++)
669 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+
670 log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002/
671 film_gamma))/1024.0));
672 image_view=AcquireAuthenticCacheView(image,exception);
673 #if defined(MAGICKCORE_OPENMP_SUPPORT)
674 #pragma omp parallel for schedule(static,4) shared(status) \
675 magick_threads(image,image,image->rows,1)
677 for (y=0; y < (ssize_t) image->rows; y++)
688 if (status == MagickFalse)
690 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
692 if (q == (Quantum *) NULL)
697 for (x=(ssize_t) image->columns; x != 0; x--)
704 red=(double) GetPixelRed(image,q);
705 green=(double) GetPixelGreen(image,q);
706 blue=(double) GetPixelBlue(image,q);
707 SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q);
708 SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))],
710 SetPixelBlue(image,logmap[ScaleQuantumToMap(ClampToQuantum(blue))],q);
711 q+=GetPixelChannels(image);
713 sync=SyncCacheViewAuthenticPixels(image_view,exception);
714 if (sync == MagickFalse)
717 image_view=DestroyCacheView(image_view);
718 logmap=(Quantum *) RelinquishMagickMemory(logmap);
719 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
724 case scRGBColorspace:
727 Transform image from sRGB to linear RGB.
729 if (image->storage_class == PseudoClass)
731 if (SyncImage(image,exception) == MagickFalse)
733 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
736 image_view=AcquireAuthenticCacheView(image,exception);
737 #if defined(MAGICKCORE_OPENMP_SUPPORT)
738 #pragma omp parallel for schedule(static,4) shared(status) \
739 magick_threads(image,image,image->rows,1)
741 for (y=0; y < (ssize_t) image->rows; y++)
752 if (status == MagickFalse)
754 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
756 if (q == (Quantum *) NULL)
761 for (x=0; x < (ssize_t) image->columns; x++)
768 red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
769 green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
770 blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
771 SetPixelRed(image,ClampToQuantum(red),q);
772 SetPixelGreen(image,ClampToQuantum(green),q);
773 SetPixelBlue(image,ClampToQuantum(blue),q);
774 q+=GetPixelChannels(image);
776 sync=SyncCacheViewAuthenticPixels(image_view,exception);
777 if (sync == MagickFalse)
780 image_view=DestroyCacheView(image_view);
781 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
791 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
793 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
795 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
797 if ((x_map == (TransformPacket *) NULL) ||
798 (y_map == (TransformPacket *) NULL) ||
799 (z_map == (TransformPacket *) NULL))
800 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
802 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
808 Initialize OHTA tables:
810 I1 = 0.33333*R+0.33334*G+0.33333*B
811 I2 = 0.50000*R+0.00000*G-0.50000*B
812 I3 =-0.25000*R+0.50000*G-0.25000*B
814 I and Q, normally -0.5 through 0.5, are normalized to the range 0
815 through QuantumRange.
817 primary_info.y=(double) (MaxMap+1.0)/2.0;
818 primary_info.z=(double) (MaxMap+1.0)/2.0;
819 #if defined(MAGICKCORE_OPENMP_SUPPORT)
820 #pragma omp parallel for schedule(static,4) \
821 magick_threads(image,image,1,1)
823 for (i=0; i <= (ssize_t) MaxMap; i++)
825 x_map[i].x=(MagickRealType) (0.33333*(double) i);
826 y_map[i].x=(MagickRealType) (0.33334*(double) i);
827 z_map[i].x=(MagickRealType) (0.33333*(double) i);
828 x_map[i].y=(MagickRealType) (0.50000*(double) i);
829 y_map[i].y=(MagickRealType) (0.00000*(double) i);
830 z_map[i].y=(MagickRealType) (-0.50000*(double) i);
831 x_map[i].z=(MagickRealType) (-0.25000*(double) i);
832 y_map[i].z=(MagickRealType) (0.50000*(double) i);
833 z_map[i].z=(MagickRealType) (-0.25000*(double) i);
837 case Rec601YCbCrColorspace:
840 Initialize YCbCr tables (ITU-R BT.601):
842 Y = 0.2988390*R+0.5868110*G+0.1143500*B
843 Cb= -0.1687367*R-0.3312640*G+0.5000000*B
844 Cr= 0.5000000*R-0.4186880*G-0.0813120*B
846 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
847 through QuantumRange.
849 primary_info.y=(double) (MaxMap+1.0)/2.0;
850 primary_info.z=(double) (MaxMap+1.0)/2.0;
851 #if defined(MAGICKCORE_OPENMP_SUPPORT)
852 #pragma omp parallel for schedule(static,4) \
853 magick_threads(image,image,1,1)
855 for (i=0; i <= (ssize_t) MaxMap; i++)
857 x_map[i].x=(MagickRealType) (0.298839*(double) i);
858 y_map[i].x=(MagickRealType) (0.586811*(double) i);
859 z_map[i].x=(MagickRealType) (0.114350*(double) i);
860 x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
861 y_map[i].y=(MagickRealType) (-0.331264*(double) i);
862 z_map[i].y=(MagickRealType) (0.500000*(double) i);
863 x_map[i].z=(MagickRealType) (0.500000*(double) i);
864 y_map[i].z=(MagickRealType) (-0.418688*(double) i);
865 z_map[i].z=(MagickRealType) (-0.081312*(double) i);
869 case Rec709YCbCrColorspace:
872 Initialize YCbCr tables (ITU-R BT.709):
874 Y = 0.212600*R+0.715200*G+0.072200*B
875 Cb= -0.114572*R-0.385428*G+0.500000*B
876 Cr= 0.500000*R-0.454153*G-0.045847*B
878 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
879 through QuantumRange.
881 primary_info.y=(double) (MaxMap+1.0)/2.0;
882 primary_info.z=(double) (MaxMap+1.0)/2.0;
883 #if defined(MAGICKCORE_OPENMP_SUPPORT)
884 #pragma omp parallel for schedule(static,4) \
885 magick_threads(image,image,1,1)
887 for (i=0; i <= (ssize_t) MaxMap; i++)
889 x_map[i].x=(MagickRealType) (0.212600*(double) i);
890 y_map[i].x=(MagickRealType) (0.715200*(double) i);
891 z_map[i].x=(MagickRealType) (0.072200*(double) i);
892 x_map[i].y=(MagickRealType) (-0.114572*(double) i);
893 y_map[i].y=(MagickRealType) (-0.385428*(double) i);
894 z_map[i].y=(MagickRealType) (0.500000*(double) i);
895 x_map[i].z=(MagickRealType) (0.500000*(double) i);
896 y_map[i].z=(MagickRealType) (-0.454153*(double) i);
897 z_map[i].z=(MagickRealType) (-0.045847*(double) i);
904 Initialize YCC tables:
906 Y = 0.298839*R+0.586811*G+0.114350*B
907 C1= -0.298839*R-0.586811*G+0.88600*B
908 C2= 0.70100*R-0.586811*G-0.114350*B
910 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
912 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
913 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
914 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
916 x_map[i].x=0.003962014134275617*i;
917 y_map[i].x=0.007778268551236748*i;
918 z_map[i].x=0.001510600706713781*i;
919 x_map[i].y=(-0.002426619775463276)*i;
920 y_map[i].y=(-0.004763965913702149)*i;
921 z_map[i].y=0.007190585689165425*i;
922 x_map[i].z=0.006927257754597858*i;
923 y_map[i].z=(-0.005800713697502058)*i;
924 z_map[i].z=(-0.0011265440570958)*i;
926 for ( ; i <= (ssize_t) MaxMap; i++)
928 x_map[i].x=0.2201118963486454*(1.099*i-0.099);
929 y_map[i].x=0.4321260306242638*(1.099*i-0.099);
930 z_map[i].x=0.08392226148409894*(1.099*i-0.099);
931 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
932 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
933 z_map[i].y=0.3994769827314126*(1.099*i-0.099);
934 x_map[i].z=0.3848476530332144*(1.099*i-0.099);
935 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
936 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
943 Linear conversion tables.
945 #if defined(MAGICKCORE_OPENMP_SUPPORT)
946 #pragma omp parallel for schedule(static,4) \
947 magick_threads(image,image,1,1)
949 for (i=0; i <= (ssize_t) MaxMap; i++)
951 x_map[i].x=(MagickRealType) (1.0*(double) i);
952 y_map[i].x=(MagickRealType) 0.0;
953 z_map[i].x=(MagickRealType) 0.0;
954 x_map[i].y=(MagickRealType) 0.0;
955 y_map[i].y=(MagickRealType) (1.0*(double) i);
956 z_map[i].y=(MagickRealType) 0.0;
957 x_map[i].z=(MagickRealType) 0.0;
958 y_map[i].z=(MagickRealType) 0.0;
959 z_map[i].z=(MagickRealType) (1.0*(double) i);
967 switch (image->storage_class)
973 Convert DirectClass image.
975 image_view=AcquireAuthenticCacheView(image,exception);
976 #if defined(MAGICKCORE_OPENMP_SUPPORT)
977 #pragma omp parallel for schedule(static,4) shared(status) \
978 magick_threads(image,image,image->rows,1)
980 for (y=0; y < (ssize_t) image->rows; y++)
994 register unsigned int
999 if (status == MagickFalse)
1001 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1003 if (q == (Quantum *) NULL)
1008 for (x=0; x < (ssize_t) image->columns; x++)
1010 red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1011 GetPixelRed(image,q)));
1012 green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1013 GetPixelGreen(image,q)));
1014 blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1015 GetPixelBlue(image,q)));
1016 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
1018 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
1020 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
1022 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
1023 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
1024 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
1025 q+=GetPixelChannels(image);
1027 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1028 if (sync == MagickFalse)
1030 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1035 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1036 #pragma omp critical (MagickCore_sRGBTransformImage)
1038 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
1040 if (proceed == MagickFalse)
1044 image_view=DestroyCacheView(image_view);
1049 register unsigned int
1055 Convert PseudoClass image.
1057 for (i=0; i < (ssize_t) image->colors; i++)
1062 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
1063 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
1064 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
1065 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1066 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1067 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1068 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
1069 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
1070 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
1072 (void) SyncImage(image,exception);
1077 Relinquish resources.
1079 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1080 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1081 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1082 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1083 return(MagickFalse);
1088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1092 % S e t I m a g e C o l o r s p a c e %
1096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1098 % SetImageColorspace() sets the colorspace member of the Image structure.
1100 % The format of the SetImageColorspace method is:
1102 % MagickBooleanType SetImageColorspace(Image *image,
1103 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1105 % A description of each parameter follows:
1107 % o image: the image.
1109 % o colorspace: the colorspace.
1111 % o exception: return any errors or warnings in this structure.
1114 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1115 const ColorspaceType colorspace,ExceptionInfo *exception)
1117 if (image->colorspace == colorspace)
1119 image->colorspace=colorspace;
1120 image->rendering_intent=UndefinedIntent;
1122 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1123 if (IsGrayColorspace(colorspace) != MagickFalse)
1125 if ((image->intensity != Rec601LuminancePixelIntensityMethod) &&
1126 (image->intensity != Rec709LuminancePixelIntensityMethod) &&
1127 (image->intensity != UndefinedPixelIntensityMethod))
1128 image->gamma=1.000/2.200;
1129 image->type=GrayscaleType;
1132 if (IssRGBColorspace(colorspace) != MagickFalse)
1133 image->gamma=1.000/2.200;
1134 if (image->gamma == (1.000/2.200))
1136 image->rendering_intent=PerceptualIntent;
1137 image->gamma=1.000/2.200;
1138 image->chromaticity.red_primary.x=0.6400;
1139 image->chromaticity.red_primary.y=0.3300;
1140 image->chromaticity.red_primary.z=0.0300;
1141 image->chromaticity.green_primary.x=0.3000;
1142 image->chromaticity.green_primary.y=0.6000;
1143 image->chromaticity.green_primary.z=0.1000;
1144 image->chromaticity.blue_primary.x=0.1500;
1145 image->chromaticity.blue_primary.y=0.0600;
1146 image->chromaticity.blue_primary.z=0.7900;
1147 image->chromaticity.white_point.x=0.3127;
1148 image->chromaticity.white_point.y=0.3290;
1149 image->chromaticity.white_point.z=0.3583;
1151 if (IsGrayColorspace(colorspace) != MagickFalse)
1152 image->type=GrayscaleType;
1153 return(SyncImagePixelCache(image,exception));
1157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1161 % T r a n s f o r m I m a g e C o l o r s p a c e %
1165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1167 % TransformImageColorspace() transforms an image colorspace, changing the
1168 % image data to reflect the new colorspace.
1170 % The format of the TransformImageColorspace method is:
1172 % MagickBooleanType TransformImageColorspace(Image *image,
1173 % const ColorspaceType colorspace,ExceptionInfo *exception)
1175 % A description of each parameter follows:
1177 % o image: the image.
1179 % o colorspace: the colorspace.
1181 % o exception: return any errors or warnings in this structure.
1184 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1185 const ColorspaceType colorspace,ExceptionInfo *exception)
1190 assert(image != (Image *) NULL);
1191 assert(image->signature == MagickSignature);
1192 if (image->debug != MagickFalse)
1193 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1194 if (colorspace == UndefinedColorspace)
1195 return(SetImageColorspace(image,colorspace,exception));
1196 if (image->colorspace == colorspace)
1197 return(MagickTrue); /* same colorspace: no op */
1199 Convert the reference image from an alternate colorspace to sRGB.
1201 (void) DeleteImageProfile(image,"icc");
1202 (void) DeleteImageProfile(image,"icm");
1203 if (IssRGBColorspace(colorspace) != MagickFalse)
1204 return(TransformsRGBImage(image,exception));
1206 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1207 status=TransformsRGBImage(image,exception);
1208 if (status == MagickFalse)
1211 Convert the reference image from sRGB to an alternate colorspace.
1213 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1223 + T r a n s f o r m s R G B I m a g e %
1227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1229 % TransformsRGBImage() converts the reference image from an alternate
1230 % colorspace to sRGB. The transformation matrices are not the standard ones:
1231 % the weights are rescaled to normalize the range of the transformed values
1232 % to be [0..QuantumRange].
1234 % The format of the TransformsRGBImage method is:
1236 % MagickBooleanType TransformsRGBImage(Image *image,
1237 % ExceptionInfo *exception)
1239 % A description of each parameter follows:
1241 % o image: the image.
1243 % o exception: return any errors or warnings in this structure.
1247 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1248 double *X,double *Y,double *Z)
1250 assert(X != (double *) NULL);
1251 assert(Y != (double *) NULL);
1252 assert(Z != (double *) NULL);
1253 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1254 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1255 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1258 static inline void ConvertLMSToRGB(const double L,const double M,
1259 const double S,double *red,double *green,double *blue)
1266 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1267 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1270 static inline void ConvertLuvToRGB(const double L,const double u,
1271 const double v,double *red,double *green,double *blue)
1278 ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
1279 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1282 static inline ssize_t RoundToYCC(const double value)
1286 if (value >= 1388.0)
1288 return((ssize_t) (value+0.5));
1291 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1293 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1294 (QuantumRange-pixel->black)+pixel->black)));
1295 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1296 (QuantumRange-pixel->black)+pixel->black)));
1297 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1298 (QuantumRange-pixel->black)+pixel->black)));
1301 static inline void ConvertLabToRGB(const double L,const double a,
1302 const double b,double *red,double *green,double *blue)
1309 ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
1310 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1313 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1314 double *red,double *green,double *blue)
1317 Convert YPbPr to RGB colorspace.
1319 assert(red != (double *) NULL);
1320 assert(green != (double *) NULL);
1321 assert(blue != (double *) NULL);
1322 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
1323 1.4019995886561440468*(Pr-0.5));
1324 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
1325 0.71413649331646789076*(Pr-0.5));
1326 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
1327 2.1453384174593273e-06*(Pr-0.5));
1330 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1331 const double Cr,double *red,double *green,double *blue)
1334 Convert -YCbCr to RGB colorspace.
1336 assert(red != (double *) NULL);
1337 assert(green != (double *) NULL);
1338 assert(blue != (double *) NULL);
1339 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1342 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1343 double *red,double *green,double *blue)
1346 Convert YIQ to RGB colorspace.
1348 assert(red != (double *) NULL);
1349 assert(green != (double *) NULL);
1350 assert(blue != (double *) NULL);
1351 *red=Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*(Q-0.5);
1352 *green=Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*(Q-0.5);
1353 *blue=Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*(Q-0.5);
1356 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1357 double *red,double *green,double *blue)
1360 Convert YUV to RGB colorspace.
1362 assert(red != (double *) NULL);
1363 assert(green != (double *) NULL);
1364 assert(blue != (double *) NULL);
1365 *red=Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*(V-0.5);
1366 *green=Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*(V-0.5);
1367 *blue=Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*(V-0.5);
1370 static MagickBooleanType TransformsRGBImage(Image *image,
1371 ExceptionInfo *exception)
1373 #define TransformsRGBImageTag "Transform/Image"
1378 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1379 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1380 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1381 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1382 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1383 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1384 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1385 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1386 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1387 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1388 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1389 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1390 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1391 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1392 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1393 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1394 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1395 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1396 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1397 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1398 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1399 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1400 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1401 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1402 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1403 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1404 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1405 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1406 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1407 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1408 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1409 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1410 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1411 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1412 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1413 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1414 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1415 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1416 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1417 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1418 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1419 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1420 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1421 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1422 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1423 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1424 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1425 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1426 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1427 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1428 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1429 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1430 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1431 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1432 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1433 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1434 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1435 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1436 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1437 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1438 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1439 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1440 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1441 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1442 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1443 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1444 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1445 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1446 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1447 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1448 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1449 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1450 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1451 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1452 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1453 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1454 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1455 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1456 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1457 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1458 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1459 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1460 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1461 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1462 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1463 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1464 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1465 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1466 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1467 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1468 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1469 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1470 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1471 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1472 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1473 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1474 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1475 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1476 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1477 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1478 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1479 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1480 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1481 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1482 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1483 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1484 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1485 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1486 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1487 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1488 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1489 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1490 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1491 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1492 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1493 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1494 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1495 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1496 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1497 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1498 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1499 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1500 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1501 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1502 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1503 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1504 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1505 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1506 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1507 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1508 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1509 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1510 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1511 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1512 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1513 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1514 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1515 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1516 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1517 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1518 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1519 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1520 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1521 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1522 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1523 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1524 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1525 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1526 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1527 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1528 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1529 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1530 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1531 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1532 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1533 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1534 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1535 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1536 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1537 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1538 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1539 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1540 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1541 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1542 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1543 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1544 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1545 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1546 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1547 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1548 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1549 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1550 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1551 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1552 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1553 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1554 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1555 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1556 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1557 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1558 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1559 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1560 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1561 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1562 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1563 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1564 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1565 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1566 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1567 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1568 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1569 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1570 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1571 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1572 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1573 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1574 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1575 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1576 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1577 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1578 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1579 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1580 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1581 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1582 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1583 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1584 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1585 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1586 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1587 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1588 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1589 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1590 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1591 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1592 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1593 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1594 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1595 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1596 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1597 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1598 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1599 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1600 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1601 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1602 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1603 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1604 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1605 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1606 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1607 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1608 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1609 0.998559f, 0.999280f, 1.000000f
1632 assert(image != (Image *) NULL);
1633 assert(image->signature == MagickSignature);
1634 if (image->debug != MagickFalse)
1635 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1638 switch (image->colorspace)
1643 Transform image from CMY to sRGB.
1645 if (image->storage_class == PseudoClass)
1647 if (SyncImage(image,exception) == MagickFalse)
1648 return(MagickFalse);
1649 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1650 return(MagickFalse);
1652 image_view=AcquireAuthenticCacheView(image,exception);
1653 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1654 #pragma omp parallel for schedule(static,4) shared(status) \
1655 magick_threads(image,image,image->rows,1)
1657 for (y=0; y < (ssize_t) image->rows; y++)
1668 if (status == MagickFalse)
1670 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1672 if (q == (Quantum *) NULL)
1677 for (x=0; x < (ssize_t) image->columns; x++)
1684 cyan=(MagickRealType) (QuantumRange-GetPixelCyan(image,q));
1685 magenta=(MagickRealType) (QuantumRange-GetPixelMagenta(image,q));
1686 yellow=(MagickRealType) (QuantumRange-GetPixelYellow(image,q));
1687 SetPixelCyan(image,ClampToQuantum(cyan),q);
1688 SetPixelMagenta(image,ClampToQuantum(magenta),q);
1689 SetPixelYellow(image,ClampToQuantum(yellow),q);
1690 q+=GetPixelChannels(image);
1692 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1693 if (sync == MagickFalse)
1696 image_view=DestroyCacheView(image_view);
1697 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1698 return(MagickFalse);
1701 case CMYKColorspace:
1707 Transform image from CMYK to sRGB.
1709 if (image->storage_class == PseudoClass)
1711 if (SyncImage(image,exception) == MagickFalse)
1712 return(MagickFalse);
1713 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1714 return(MagickFalse);
1716 GetPixelInfo(image,&zero);
1717 image_view=AcquireAuthenticCacheView(image,exception);
1718 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1719 #pragma omp parallel for schedule(static,4) shared(status) \
1720 magick_threads(image,image,image->rows,1)
1722 for (y=0; y < (ssize_t) image->rows; y++)
1736 if (status == MagickFalse)
1738 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1740 if (q == (Quantum *) NULL)
1746 for (x=0; x < (ssize_t) image->columns; x++)
1748 GetPixelInfoPixel(image,q,&pixel);
1749 ConvertCMYKToRGB(&pixel);
1750 SetPixelInfoPixel(image,&pixel,q);
1751 q+=GetPixelChannels(image);
1753 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1754 if (sync == MagickFalse)
1757 image_view=DestroyCacheView(image_view);
1758 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1759 return(MagickFalse);
1762 case GRAYColorspace:
1765 Transform linear GRAY to sRGB colorspace.
1767 if (image->storage_class == PseudoClass)
1769 if (SyncImage(image,exception) == MagickFalse)
1770 return(MagickFalse);
1771 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1772 return(MagickFalse);
1774 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1775 return(MagickFalse);
1776 image_view=AcquireAuthenticCacheView(image,exception);
1777 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1778 #pragma omp parallel for schedule(static,4) shared(status) \
1779 magick_threads(image,image,image->rows,1)
1781 for (y=0; y < (ssize_t) image->rows; y++)
1792 if (status == MagickFalse)
1794 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1796 if (q == (Quantum *) NULL)
1801 for (x=(ssize_t) image->columns; x != 0; x--)
1806 gray=EncodePixelGamma((MagickRealType) GetPixelGray(image,q));
1807 SetPixelRed(image,ClampToQuantum(gray),q);
1808 SetPixelGreen(image,ClampToQuantum(gray),q);
1809 SetPixelBlue(image,ClampToQuantum(gray),q);
1810 q+=GetPixelChannels(image);
1812 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1813 if (sync == MagickFalse)
1816 image_view=DestroyCacheView(image_view);
1817 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1818 return(MagickFalse);
1822 case HCLpColorspace:
1830 case LCHabColorspace:
1831 case LCHuvColorspace:
1835 case YCbCrColorspace:
1837 case YPbPrColorspace:
1841 Transform image from source colorspace to sRGB.
1843 if (image->storage_class == PseudoClass)
1845 if (SyncImage(image,exception) == MagickFalse)
1846 return(MagickFalse);
1847 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1848 return(MagickFalse);
1850 image_view=AcquireAuthenticCacheView(image,exception);
1851 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1852 #pragma omp parallel for schedule(static,4) shared(status) \
1853 magick_threads(image,image,image->rows,1)
1855 for (y=0; y < (ssize_t) image->rows; y++)
1866 if (status == MagickFalse)
1868 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1870 if (q == (Quantum *) NULL)
1875 for (x=0; x < (ssize_t) image->columns; x++)
1885 X=QuantumScale*GetPixelRed(image,q);
1886 Y=QuantumScale*GetPixelGreen(image,q);
1887 Z=QuantumScale*GetPixelBlue(image,q);
1888 switch (image->colorspace)
1892 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
1895 case HCLpColorspace:
1897 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
1902 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
1907 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
1912 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
1917 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
1922 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
1927 ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
1931 case LCHabColorspace:
1933 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
1936 case LCHuvColorspace:
1938 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
1943 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
1948 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
1953 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
1956 case YCbCrColorspace:
1958 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
1963 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
1966 case YPbPrColorspace:
1968 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
1973 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
1979 SetPixelRed(image,ClampToQuantum(red),q);
1980 SetPixelGreen(image,ClampToQuantum(green),q);
1981 SetPixelBlue(image,ClampToQuantum(blue),q);
1982 q+=GetPixelChannels(image);
1984 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1985 if (sync == MagickFalse)
1988 image_view=DestroyCacheView(image_view);
1989 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1990 return(MagickFalse);
2010 Transform Log to sRGB colorspace.
2012 density=DisplayGamma;
2014 value=GetImageProperty(image,"gamma",exception);
2015 if (value != (const char *) NULL)
2016 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
2017 film_gamma=FilmGamma;
2018 value=GetImageProperty(image,"film-gamma",exception);
2019 if (value != (const char *) NULL)
2020 film_gamma=StringToDouble(value,(char **) NULL);
2021 reference_black=ReferenceBlack;
2022 value=GetImageProperty(image,"reference-black",exception);
2023 if (value != (const char *) NULL)
2024 reference_black=StringToDouble(value,(char **) NULL);
2025 reference_white=ReferenceWhite;
2026 value=GetImageProperty(image,"reference-white",exception);
2027 if (value != (const char *) NULL)
2028 reference_white=StringToDouble(value,(char **) NULL);
2029 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2031 if (logmap == (Quantum *) NULL)
2032 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2034 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
2036 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
2037 logmap[i]=(Quantum) 0;
2038 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
2039 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
2040 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/
2041 film_gamma)-black));
2042 for ( ; i <= (ssize_t) MaxMap; i++)
2043 logmap[i]=QuantumRange;
2044 if (image->storage_class == PseudoClass)
2046 if (SyncImage(image,exception) == MagickFalse)
2047 return(MagickFalse);
2048 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2049 return(MagickFalse);
2051 image_view=AcquireAuthenticCacheView(image,exception);
2052 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2053 #pragma omp parallel for schedule(static,4) shared(status) \
2054 magick_threads(image,image,image->rows,1)
2056 for (y=0; y < (ssize_t) image->rows; y++)
2067 if (status == MagickFalse)
2069 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2071 if (q == (Quantum *) NULL)
2076 for (x=(ssize_t) image->columns; x != 0; x--)
2083 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
2084 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
2085 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
2086 SetPixelRed(image,ClampToQuantum(red),q);
2087 SetPixelGreen(image,ClampToQuantum(green),q);
2088 SetPixelBlue(image,ClampToQuantum(blue),q);
2089 q+=GetPixelChannels(image);
2091 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2092 if (sync == MagickFalse)
2095 image_view=DestroyCacheView(image_view);
2096 logmap=(Quantum *) RelinquishMagickMemory(logmap);
2097 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2098 return(MagickFalse);
2102 case scRGBColorspace:
2105 Transform linear RGB to sRGB colorspace.
2107 if (image->storage_class == PseudoClass)
2109 if (SyncImage(image,exception) == MagickFalse)
2110 return(MagickFalse);
2111 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2112 return(MagickFalse);
2114 image_view=AcquireAuthenticCacheView(image,exception);
2115 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2116 #pragma omp parallel for schedule(static,4) shared(status) \
2117 magick_threads(image,image,image->rows,1)
2119 for (y=0; y < (ssize_t) image->rows; y++)
2130 if (status == MagickFalse)
2132 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2134 if (q == (Quantum *) NULL)
2139 for (x=(ssize_t) image->columns; x != 0; x--)
2146 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q));
2147 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q));
2148 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q));
2149 SetPixelRed(image,ClampToQuantum(red),q);
2150 SetPixelGreen(image,ClampToQuantum(green),q);
2151 SetPixelBlue(image,ClampToQuantum(blue),q);
2152 q+=GetPixelChannels(image);
2154 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2155 if (sync == MagickFalse)
2158 image_view=DestroyCacheView(image_view);
2159 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2160 return(MagickFalse);
2167 Allocate the tables.
2169 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2171 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2173 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2175 if ((x_map == (TransformPacket *) NULL) ||
2176 (y_map == (TransformPacket *) NULL) ||
2177 (z_map == (TransformPacket *) NULL))
2179 if (z_map != (TransformPacket *) NULL)
2180 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2181 if (y_map != (TransformPacket *) NULL)
2182 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2183 if (x_map != (TransformPacket *) NULL)
2184 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2185 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2188 switch (image->colorspace)
2190 case OHTAColorspace:
2193 Initialize OHTA tables:
2195 R = I1+1.00000*I2-0.66668*I3
2196 G = I1+0.00000*I2+1.33333*I3
2197 B = I1-1.00000*I2-0.66668*I3
2199 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2200 through QuantumRange.
2202 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2203 #pragma omp parallel for schedule(static,4) \
2204 magick_threads(image,image,1,1)
2206 for (i=0; i <= (ssize_t) MaxMap; i++)
2208 x_map[i].x=(MagickRealType) (1.0*(double) i);
2209 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap));
2210 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2211 x_map[i].y=(MagickRealType) (1.0*(double) i);
2212 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap));
2213 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap));
2214 x_map[i].z=(MagickRealType) (1.0*(double) i);
2215 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap));
2216 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2220 case Rec601YCbCrColorspace:
2223 Initialize YCbCr tables:
2226 G = Y-0.344136*Cb-0.714136*Cr
2229 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2230 through QuantumRange.
2232 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2233 #pragma omp parallel for schedule(static,4) \
2234 magick_threads(image,image,1,1)
2236 for (i=0; i <= (ssize_t) MaxMap; i++)
2238 x_map[i].x=0.99999999999914679361*(double) i;
2239 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2240 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2241 x_map[i].y=0.99999975910502514331*(double) i;
2242 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2243 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2244 x_map[i].z=1.00000124040004623180*(double) i;
2245 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2246 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2250 case Rec709YCbCrColorspace:
2253 Initialize YCbCr tables:
2256 G = Y-0.187324*Cb-0.468124*Cr
2259 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2260 through QuantumRange.
2262 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2263 #pragma omp parallel for schedule(static,4) \
2264 magick_threads(image,image,1,1)
2266 for (i=0; i <= (ssize_t) MaxMap; i++)
2268 x_map[i].x=(MagickRealType) (1.0*i);
2269 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2270 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap));
2271 x_map[i].y=(MagickRealType) (1.0*i);
2272 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap));
2273 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap));
2274 x_map[i].z=(MagickRealType) (1.0*i);
2275 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap));
2276 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2283 Initialize YCC tables:
2286 G = Y-0.317038*C1-0.682243*C2
2289 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2291 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2292 #pragma omp parallel for schedule(static,4) \
2293 magick_threads(image,image,1,1)
2295 for (i=0; i <= (ssize_t) MaxMap; i++)
2297 x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2298 y_map[i].x=(MagickRealType) 0.0000000;
2299 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double)
2300 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2301 x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2302 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double)
2303 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2304 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double)
2305 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2306 x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2307 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double)
2308 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2309 z_map[i].z=(MagickRealType) 0.0000000;
2316 Linear conversion tables.
2318 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2319 #pragma omp parallel for schedule(static,4) \
2320 magick_threads(image,image,1,1)
2322 for (i=0; i <= (ssize_t) MaxMap; i++)
2324 x_map[i].x=(MagickRealType) (1.0*(double) i);
2325 y_map[i].x=(MagickRealType) 0.0;
2326 z_map[i].x=(MagickRealType) 0.0;
2327 x_map[i].y=(MagickRealType) 0.0;
2328 y_map[i].y=(MagickRealType) (1.0*(double) i);
2329 z_map[i].y=(MagickRealType) 0.0;
2330 x_map[i].z=(MagickRealType) 0.0;
2331 y_map[i].z=(MagickRealType) 0.0;
2332 z_map[i].z=(MagickRealType) (1.0*(double) i);
2340 switch (image->storage_class)
2346 Convert DirectClass image.
2348 image_view=AcquireAuthenticCacheView(image,exception);
2349 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2350 #pragma omp parallel for schedule(static,4) shared(status) \
2351 magick_threads(image,image,image->rows,1)
2353 for (y=0; y < (ssize_t) image->rows; y++)
2367 if (status == MagickFalse)
2369 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2371 if (q == (Quantum *) NULL)
2376 for (x=0; x < (ssize_t) image->columns; x++)
2383 red=ScaleQuantumToMap(GetPixelRed(image,q));
2384 green=ScaleQuantumToMap(GetPixelGreen(image,q));
2385 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
2386 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2387 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2388 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2389 if (image->colorspace == YCCColorspace)
2391 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2393 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2395 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2400 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2401 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2402 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2404 SetPixelRed(image,ClampToQuantum(pixel.red),q);
2405 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
2406 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
2407 q+=GetPixelChannels(image);
2409 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2410 if (sync == MagickFalse)
2412 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2417 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2418 #pragma omp critical (MagickCore_TransformsRGBImage)
2420 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
2422 if (proceed == MagickFalse)
2426 image_view=DestroyCacheView(image_view);
2432 Convert PseudoClass image.
2434 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2435 #pragma omp parallel for schedule(static,4) shared(status) \
2436 magick_threads(image,image,1,1)
2438 for (i=0; i < (ssize_t) image->colors; i++)
2448 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
2449 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
2450 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
2451 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2452 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2453 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2454 if (image->colorspace == YCCColorspace)
2456 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2458 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2460 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2465 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2466 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2467 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2469 image->colormap[i].red=(double) ClampToQuantum(pixel.red);
2470 image->colormap[i].green=(double) ClampToQuantum(pixel.green);
2471 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue);
2473 (void) SyncImage(image,exception);
2478 Relinquish resources.
2480 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2481 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2482 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2483 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2484 return(MagickFalse);