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-2014 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 ConvertRGBToCMY(const double red,const double green,
119 const double blue,double *cyan,double *magenta,double *yellow)
121 *cyan=QuantumScale*(QuantumRange-red);
122 *magenta=QuantumScale*(QuantumRange-green);
123 *yellow=QuantumScale*(QuantumRange-blue);
126 static inline void ConvertXYZToLMS(const double x,const double y,
127 const double z,double *L,double *M,double *S)
129 *L=0.7328*x+0.4296*y-0.1624*z;
130 *M=(-0.7036*x+1.6975*y+0.0061*z);
131 *S=0.0030*x+0.0136*y+0.9834*z;
134 static void ConvertRGBToLMS(const double red,const double green,
135 const double blue,double *L,double *M,double *S)
142 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
143 ConvertXYZToLMS(X,Y,Z,L,M,S);
146 static void ConvertRGBToLab(const double red,const double green,
147 const double blue,double *L,double *a,double *b)
154 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
155 ConvertXYZToLab(X,Y,Z,L,a,b);
158 static void ConvertRGBToLuv(const double red,const double green,
159 const double blue,double *L,double *u,double *v)
166 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
167 ConvertXYZToLuv(X,Y,Z,L,u,v);
170 static void ConvertRGBToYDbDr(const double red,const double green,
171 const double blue,double *Y,double *Db,double *Dr)
173 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
174 *Db=QuantumScale*(-0.450*red-0.883*green+1.333*blue)+0.5;
175 *Dr=QuantumScale*(-1.333*red+1.116*green+0.217*blue)+0.5;
178 static void ConvertRGBToYIQ(const double red,const double green,
179 const double blue,double *Y,double *I,double *Q)
181 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
182 *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5;
183 *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5;
186 static void ConvertRGBToYPbPr(const double red,const double green,
187 const double blue,double *Y,double *Pb,double *Pr)
189 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
190 *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5;
191 *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5;
194 static void ConvertRGBToYCbCr(const double red,const double green,
195 const double blue,double *Y,double *Cb,double *Cr)
197 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
200 static void ConvertRGBToYUV(const double red,const double green,
201 const double blue,double *Y,double *U,double *V)
203 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
204 *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5;
205 *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5;
208 static MagickBooleanType sRGBTransformImage(Image *image,
209 const ColorspaceType colorspace,ExceptionInfo *exception)
211 #define sRGBTransformImageTag "RGBTransform/Image"
236 assert(image != (Image *) NULL);
237 assert(image->signature == MagickSignature);
238 if (image->debug != MagickFalse)
239 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
240 assert(colorspace != sRGBColorspace);
241 assert(colorspace != TransparentColorspace);
242 assert(colorspace != UndefinedColorspace);
253 Convert RGB to CMYK colorspace.
255 if (image->storage_class == PseudoClass)
257 if (SyncImage(image,exception) == MagickFalse)
259 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
262 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
264 GetPixelInfo(image,&zero);
265 image_view=AcquireAuthenticCacheView(image,exception);
266 #if defined(MAGICKCORE_OPENMP_SUPPORT)
267 #pragma omp parallel for schedule(static,4) shared(status) \
268 magick_threads(image,image,image->rows,1)
270 for (y=0; y < (ssize_t) image->rows; y++)
284 if (status == MagickFalse)
286 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
288 if (q == (Quantum *) NULL)
294 for (x=0; x < (ssize_t) image->columns; x++)
296 GetPixelInfoPixel(image,q,&pixel);
297 ConvertRGBToCMYK(&pixel);
298 SetPixelInfoPixel(image,&pixel,q);
299 q+=GetPixelChannels(image);
301 sync=SyncCacheViewAuthenticPixels(image_view,exception);
302 if (sync == MagickFalse)
305 image_view=DestroyCacheView(image_view);
306 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
307 ColorSeparationMatteType;
308 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
315 Transform image from sRGB to GRAY.
317 if (image->storage_class == PseudoClass)
319 if (SyncImage(image,exception) == MagickFalse)
321 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
324 image_view=AcquireAuthenticCacheView(image,exception);
325 #if defined(MAGICKCORE_OPENMP_SUPPORT)
326 #pragma omp parallel for schedule(static,4) shared(status) \
327 magick_threads(image,image,image->rows,1)
329 for (y=0; y < (ssize_t) image->rows; y++)
340 if (status == MagickFalse)
342 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
344 if (q == (Quantum *) NULL)
349 for (x=0; x < (ssize_t) image->columns; x++)
351 SetPixelGray(image,ClampToQuantum(GetPixelIntensity(image,q)),q);
352 q+=GetPixelChannels(image);
354 sync=SyncCacheViewAuthenticPixels(image_view,exception);
355 if (sync == MagickFalse)
358 image_view=DestroyCacheView(image_view);
359 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
361 image->type=GrayscaleType;
374 case LCHabColorspace:
375 case LCHuvColorspace:
379 case YCbCrColorspace:
380 case YDbDrColorspace:
382 case YPbPrColorspace:
386 Transform image from sRGB to target colorspace.
388 if (image->storage_class == PseudoClass)
390 if (SyncImage(image,exception) == MagickFalse)
392 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
395 image_view=AcquireAuthenticCacheView(image,exception);
396 #if defined(MAGICKCORE_OPENMP_SUPPORT)
397 #pragma omp parallel for schedule(static,4) shared(status) \
398 magick_threads(image,image,image->rows,1)
400 for (y=0; y < (ssize_t) image->rows; y++)
411 if (status == MagickFalse)
413 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
415 if (q == (Quantum *) NULL)
420 for (x=0; x < (ssize_t) image->columns; x++)
430 red=(double) GetPixelRed(image,q);
431 green=(double) GetPixelGreen(image,q);
432 blue=(double) GetPixelBlue(image,q);
437 ConvertRGBToCMY(red,green,blue,&X,&Y,&Z);
442 ConvertRGBToHCL(red,green,blue,&X,&Y,&Z);
447 ConvertRGBToHCLp(red,green,blue,&X,&Y,&Z);
452 ConvertRGBToHSB(red,green,blue,&X,&Y,&Z);
457 ConvertRGBToHSI(red,green,blue,&X,&Y,&Z);
462 ConvertRGBToHSL(red,green,blue,&X,&Y,&Z);
467 ConvertRGBToHSV(red,green,blue,&X,&Y,&Z);
472 ConvertRGBToHWB(red,green,blue,&X,&Y,&Z);
477 ConvertRGBToLab(red,green,blue,&X,&Y,&Z);
481 case LCHabColorspace:
483 ConvertRGBToLCHab(red,green,blue,&X,&Y,&Z);
486 case LCHuvColorspace:
488 ConvertRGBToLCHuv(red,green,blue,&X,&Y,&Z);
493 ConvertRGBToLMS(red,green,blue,&X,&Y,&Z);
498 ConvertRGBToLuv(red,green,blue,&X,&Y,&Z);
503 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
506 case YCbCrColorspace:
508 ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z);
511 case YDbDrColorspace:
513 ConvertRGBToYDbDr(red,green,blue,&X,&Y,&Z);
518 ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z);
521 case YPbPrColorspace:
523 ConvertRGBToYPbPr(red,green,blue,&X,&Y,&Z);
528 ConvertRGBToYUV(red,green,blue,&X,&Y,&Z);
534 Y=QuantumScale*green;
539 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
540 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
541 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q);
542 q+=GetPixelChannels(image);
544 sync=SyncCacheViewAuthenticPixels(image_view,exception);
545 if (sync == MagickFalse)
548 image_view=DestroyCacheView(image_view);
549 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
555 #define DisplayGamma (1.0/1.7)
556 #define FilmGamma 0.6
557 #define ReferenceBlack 95.0
558 #define ReferenceWhite 685.0
575 Transform RGB to Log colorspace.
577 density=DisplayGamma;
579 value=GetImageProperty(image,"gamma",exception);
580 if (value != (const char *) NULL)
581 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
582 film_gamma=FilmGamma;
583 value=GetImageProperty(image,"film-gamma",exception);
584 if (value != (const char *) NULL)
585 film_gamma=StringToDouble(value,(char **) NULL);
586 reference_black=ReferenceBlack;
587 value=GetImageProperty(image,"reference-black",exception);
588 if (value != (const char *) NULL)
589 reference_black=StringToDouble(value,(char **) NULL);
590 reference_white=ReferenceWhite;
591 value=GetImageProperty(image,"reference-white",exception);
592 if (value != (const char *) NULL)
593 reference_white=StringToDouble(value,(char **) NULL);
594 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
596 if (logmap == (Quantum *) NULL)
597 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
599 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
601 #if defined(MAGICKCORE_OPENMP_SUPPORT)
602 #pragma omp parallel for schedule(static,4) \
603 magick_threads(image,image,1,1)
605 for (i=0; i <= (ssize_t) MaxMap; i++)
606 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+
607 log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002/
608 film_gamma))/1024.0));
609 image_view=AcquireAuthenticCacheView(image,exception);
610 #if defined(MAGICKCORE_OPENMP_SUPPORT)
611 #pragma omp parallel for schedule(static,4) shared(status) \
612 magick_threads(image,image,image->rows,1)
614 for (y=0; y < (ssize_t) image->rows; y++)
625 if (status == MagickFalse)
627 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
629 if (q == (Quantum *) NULL)
634 for (x=(ssize_t) image->columns; x != 0; x--)
641 red=(double) DecodePixelGamma((MagickRealType)
642 GetPixelRed(image,q));
643 green=(double) DecodePixelGamma((MagickRealType)
644 GetPixelGreen(image,q));
645 blue=(double) DecodePixelGamma((MagickRealType)
646 GetPixelBlue(image,q));
647 SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q);
648 SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))],
650 SetPixelBlue(image,logmap[ScaleQuantumToMap(ClampToQuantum(blue))],q);
651 q+=GetPixelChannels(image);
653 sync=SyncCacheViewAuthenticPixels(image_view,exception);
654 if (sync == MagickFalse)
657 image_view=DestroyCacheView(image_view);
658 logmap=(Quantum *) RelinquishMagickMemory(logmap);
659 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
664 case scRGBColorspace:
667 Transform image from sRGB to linear RGB.
669 if (image->storage_class == PseudoClass)
671 if (SyncImage(image,exception) == MagickFalse)
673 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
676 image_view=AcquireAuthenticCacheView(image,exception);
677 #if defined(MAGICKCORE_OPENMP_SUPPORT)
678 #pragma omp parallel for schedule(static,4) shared(status) \
679 magick_threads(image,image,image->rows,1)
681 for (y=0; y < (ssize_t) image->rows; y++)
692 if (status == MagickFalse)
694 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
696 if (q == (Quantum *) NULL)
701 for (x=0; x < (ssize_t) image->columns; x++)
708 red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
709 green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
710 blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
711 SetPixelRed(image,ClampToQuantum(red),q);
712 SetPixelGreen(image,ClampToQuantum(green),q);
713 SetPixelBlue(image,ClampToQuantum(blue),q);
714 q+=GetPixelChannels(image);
716 sync=SyncCacheViewAuthenticPixels(image_view,exception);
717 if (sync == MagickFalse)
720 image_view=DestroyCacheView(image_view);
721 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
731 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
733 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
735 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
737 if ((x_map == (TransformPacket *) NULL) ||
738 (y_map == (TransformPacket *) NULL) ||
739 (z_map == (TransformPacket *) NULL))
740 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
742 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
748 Initialize OHTA tables:
750 I1 = 0.33333*R+0.33334*G+0.33333*B
751 I2 = 0.50000*R+0.00000*G-0.50000*B
752 I3 =-0.25000*R+0.50000*G-0.25000*B
754 I and Q, normally -0.5 through 0.5, are normalized to the range 0
755 through QuantumRange.
757 primary_info.y=(double) (MaxMap+1.0)/2.0;
758 primary_info.z=(double) (MaxMap+1.0)/2.0;
759 #if defined(MAGICKCORE_OPENMP_SUPPORT)
760 #pragma omp parallel for schedule(static,4) \
761 magick_threads(image,image,1,1)
763 for (i=0; i <= (ssize_t) MaxMap; i++)
765 x_map[i].x=(MagickRealType) (0.33333*(double) i);
766 y_map[i].x=(MagickRealType) (0.33334*(double) i);
767 z_map[i].x=(MagickRealType) (0.33333*(double) i);
768 x_map[i].y=(MagickRealType) (0.50000*(double) i);
769 y_map[i].y=(MagickRealType) (0.00000*(double) i);
770 z_map[i].y=(MagickRealType) (-0.50000*(double) i);
771 x_map[i].z=(MagickRealType) (-0.25000*(double) i);
772 y_map[i].z=(MagickRealType) (0.50000*(double) i);
773 z_map[i].z=(MagickRealType) (-0.25000*(double) i);
777 case Rec601YCbCrColorspace:
780 Initialize YCbCr tables (ITU-R BT.601):
782 Y = 0.2988390*R+0.5868110*G+0.1143500*B
783 Cb= -0.1687367*R-0.3312640*G+0.5000000*B
784 Cr= 0.5000000*R-0.4186880*G-0.0813120*B
786 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
787 through QuantumRange.
789 primary_info.y=(double) (MaxMap+1.0)/2.0;
790 primary_info.z=(double) (MaxMap+1.0)/2.0;
791 #if defined(MAGICKCORE_OPENMP_SUPPORT)
792 #pragma omp parallel for schedule(static,4) \
793 magick_threads(image,image,1,1)
795 for (i=0; i <= (ssize_t) MaxMap; i++)
797 x_map[i].x=(MagickRealType) (0.298839*(double) i);
798 y_map[i].x=(MagickRealType) (0.586811*(double) i);
799 z_map[i].x=(MagickRealType) (0.114350*(double) i);
800 x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
801 y_map[i].y=(MagickRealType) (-0.331264*(double) i);
802 z_map[i].y=(MagickRealType) (0.500000*(double) i);
803 x_map[i].z=(MagickRealType) (0.500000*(double) i);
804 y_map[i].z=(MagickRealType) (-0.418688*(double) i);
805 z_map[i].z=(MagickRealType) (-0.081312*(double) i);
809 case Rec709YCbCrColorspace:
812 Initialize YCbCr tables (ITU-R BT.709):
814 Y = 0.212656*R+0.715158*G+0.072186*B
815 Cb= -0.114572*R-0.385428*G+0.500000*B
816 Cr= 0.500000*R-0.454153*G-0.045847*B
818 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
819 through QuantumRange.
821 primary_info.y=(double) (MaxMap+1.0)/2.0;
822 primary_info.z=(double) (MaxMap+1.0)/2.0;
823 #if defined(MAGICKCORE_OPENMP_SUPPORT)
824 #pragma omp parallel for schedule(static,4) \
825 magick_threads(image,image,1,1)
827 for (i=0; i <= (ssize_t) MaxMap; i++)
829 x_map[i].x=(MagickRealType) (0.212656*(double) i);
830 y_map[i].x=(MagickRealType) (0.715158*(double) i);
831 z_map[i].x=(MagickRealType) (0.072186*(double) i);
832 x_map[i].y=(MagickRealType) (-0.114572*(double) i);
833 y_map[i].y=(MagickRealType) (-0.385428*(double) i);
834 z_map[i].y=(MagickRealType) (0.500000*(double) i);
835 x_map[i].z=(MagickRealType) (0.500000*(double) i);
836 y_map[i].z=(MagickRealType) (-0.454153*(double) i);
837 z_map[i].z=(MagickRealType) (-0.045847*(double) i);
844 Initialize YCC tables:
846 Y = 0.298839*R+0.586811*G+0.114350*B
847 C1= -0.298839*R-0.586811*G+0.88600*B
848 C2= 0.70100*R-0.586811*G-0.114350*B
850 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
852 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
853 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
854 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
856 x_map[i].x=0.003962014134275617*i;
857 y_map[i].x=0.007778268551236748*i;
858 z_map[i].x=0.001510600706713781*i;
859 x_map[i].y=(-0.002426619775463276)*i;
860 y_map[i].y=(-0.004763965913702149)*i;
861 z_map[i].y=0.007190585689165425*i;
862 x_map[i].z=0.006927257754597858*i;
863 y_map[i].z=(-0.005800713697502058)*i;
864 z_map[i].z=(-0.0011265440570958)*i;
866 for ( ; i <= (ssize_t) MaxMap; i++)
868 x_map[i].x=0.2201118963486454*(1.099*i-0.099);
869 y_map[i].x=0.4321260306242638*(1.099*i-0.099);
870 z_map[i].x=0.08392226148409894*(1.099*i-0.099);
871 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
872 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
873 z_map[i].y=0.3994769827314126*(1.099*i-0.099);
874 x_map[i].z=0.3848476530332144*(1.099*i-0.099);
875 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
876 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
883 Linear conversion tables.
885 #if defined(MAGICKCORE_OPENMP_SUPPORT)
886 #pragma omp parallel for schedule(static,4) \
887 magick_threads(image,image,1,1)
889 for (i=0; i <= (ssize_t) MaxMap; i++)
891 x_map[i].x=(MagickRealType) (1.0*(double) i);
892 y_map[i].x=(MagickRealType) 0.0;
893 z_map[i].x=(MagickRealType) 0.0;
894 x_map[i].y=(MagickRealType) 0.0;
895 y_map[i].y=(MagickRealType) (1.0*(double) i);
896 z_map[i].y=(MagickRealType) 0.0;
897 x_map[i].z=(MagickRealType) 0.0;
898 y_map[i].z=(MagickRealType) 0.0;
899 z_map[i].z=(MagickRealType) (1.0*(double) i);
907 switch (image->storage_class)
913 Convert DirectClass image.
915 image_view=AcquireAuthenticCacheView(image,exception);
916 #if defined(MAGICKCORE_OPENMP_SUPPORT)
917 #pragma omp parallel for schedule(static,4) shared(status) \
918 magick_threads(image,image,image->rows,1)
920 for (y=0; y < (ssize_t) image->rows; y++)
934 register unsigned int
939 if (status == MagickFalse)
941 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
943 if (q == (Quantum *) NULL)
948 for (x=0; x < (ssize_t) image->columns; x++)
950 red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
951 GetPixelRed(image,q)));
952 green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
953 GetPixelGreen(image,q)));
954 blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
955 GetPixelBlue(image,q)));
956 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
958 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
960 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
962 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
963 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
964 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
965 q+=GetPixelChannels(image);
967 sync=SyncCacheViewAuthenticPixels(image_view,exception);
968 if (sync == MagickFalse)
970 if (image->progress_monitor != (MagickProgressMonitor) NULL)
975 #if defined(MAGICKCORE_OPENMP_SUPPORT)
976 #pragma omp critical (MagickCore_sRGBTransformImage)
978 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
980 if (proceed == MagickFalse)
984 image_view=DestroyCacheView(image_view);
989 register unsigned int
995 Convert PseudoClass image.
997 for (i=0; i < (ssize_t) image->colors; i++)
1002 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
1003 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
1004 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
1005 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1006 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1007 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1008 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
1009 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
1010 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
1012 (void) SyncImage(image,exception);
1017 Relinquish resources.
1019 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1020 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1021 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1022 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1023 return(MagickFalse);
1028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032 % S e t I m a g e C o l o r s p a c e %
1036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038 % SetImageColorspace() sets the colorspace member of the Image structure.
1040 % The format of the SetImageColorspace method is:
1042 % MagickBooleanType SetImageColorspace(Image *image,
1043 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1045 % A description of each parameter follows:
1047 % o image: the image.
1049 % o colorspace: the colorspace.
1051 % o exception: return any errors or warnings in this structure.
1054 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1055 const ColorspaceType colorspace,ExceptionInfo *exception)
1063 if (image->colorspace == colorspace)
1065 image->colorspace=colorspace;
1066 image->rendering_intent=UndefinedIntent;
1067 image->gamma=1.000/2.200;
1068 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1070 if (IsGrayColorspace(colorspace) != MagickFalse)
1072 if ((image->intensity == Rec601LuminancePixelIntensityMethod) ||
1073 (image->intensity == Rec709LuminancePixelIntensityMethod))
1078 if ((IsRGBColorspace(colorspace) != MagickFalse) ||
1079 (colorspace == XYZColorspace))
1083 image->rendering_intent=PerceptualIntent;
1084 image->chromaticity.red_primary.x=0.6400;
1085 image->chromaticity.red_primary.y=0.3300;
1086 image->chromaticity.red_primary.z=0.0300;
1087 image->chromaticity.green_primary.x=0.3000;
1088 image->chromaticity.green_primary.y=0.6000;
1089 image->chromaticity.green_primary.z=0.1000;
1090 image->chromaticity.blue_primary.x=0.1500;
1091 image->chromaticity.blue_primary.y=0.0600;
1092 image->chromaticity.blue_primary.z=0.7900;
1093 image->chromaticity.white_point.x=0.3127;
1094 image->chromaticity.white_point.y=0.3290;
1095 image->chromaticity.white_point.z=0.3583;
1097 status=SyncImagePixelCache(image,exception);
1103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1107 % T r a n s f o r m I m a g e C o l o r s p a c e %
1111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1113 % TransformImageColorspace() transforms an image colorspace, changing the
1114 % image data to reflect the new colorspace.
1116 % The format of the TransformImageColorspace method is:
1118 % MagickBooleanType TransformImageColorspace(Image *image,
1119 % const ColorspaceType colorspace,ExceptionInfo *exception)
1121 % A description of each parameter follows:
1123 % o image: the image.
1125 % o colorspace: the colorspace.
1127 % o exception: return any errors or warnings in this structure.
1130 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1131 const ColorspaceType colorspace,ExceptionInfo *exception)
1136 assert(image != (Image *) NULL);
1137 assert(image->signature == MagickSignature);
1138 if (image->debug != MagickFalse)
1139 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1140 if (colorspace == UndefinedColorspace)
1141 return(SetImageColorspace(image,colorspace,exception));
1142 if (image->colorspace == colorspace)
1145 Convert the reference image from an alternate colorspace to sRGB.
1147 (void) DeleteImageProfile(image,"icc");
1148 (void) DeleteImageProfile(image,"icm");
1149 if (IssRGBColorspace(colorspace) != MagickFalse)
1150 return(TransformsRGBImage(image,exception));
1152 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1153 status=TransformsRGBImage(image,exception);
1154 if (status == MagickFalse)
1157 Convert the reference image from sRGB to an alternate colorspace.
1159 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1169 + T r a n s f o r m s R G B I m a g e %
1173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1175 % TransformsRGBImage() converts the reference image from an alternate
1176 % colorspace to sRGB. The transformation matrices are not the standard ones:
1177 % the weights are rescaled to normalize the range of the transformed values
1178 % to be [0..QuantumRange].
1180 % The format of the TransformsRGBImage method is:
1182 % MagickBooleanType TransformsRGBImage(Image *image,
1183 % ExceptionInfo *exception)
1185 % A description of each parameter follows:
1187 % o image: the image.
1189 % o exception: return any errors or warnings in this structure.
1193 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1194 const double yellow,double *red,double *green,double *blue)
1196 *red=QuantumRange*(1.0-cyan);
1197 *green=QuantumRange*(1.0-magenta);
1198 *blue=QuantumRange*(1.0-yellow);
1201 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1202 double *X,double *Y,double *Z)
1204 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1205 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1206 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1209 static inline void ConvertLMSToRGB(const double L,const double M,
1210 const double S,double *red,double *green,double *blue)
1217 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1218 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1221 static inline void ConvertLuvToRGB(const double L,const double u,
1222 const double v,double *red,double *green,double *blue)
1229 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1230 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1233 static inline ssize_t RoundToYCC(const double value)
1237 if (value >= 1388.0)
1239 return((ssize_t) (value+0.5));
1242 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1244 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1245 (QuantumRange-pixel->black)+pixel->black)));
1246 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1247 (QuantumRange-pixel->black)+pixel->black)));
1248 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1249 (QuantumRange-pixel->black)+pixel->black)));
1252 static inline void ConvertLabToRGB(const double L,const double a,
1253 const double b,double *red,double *green,double *blue)
1260 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1261 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1264 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1265 double *red,double *green,double *blue)
1267 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
1268 1.4019995886561440468*(Pr-0.5));
1269 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
1270 0.71413649331646789076*(Pr-0.5));
1271 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
1272 2.1453384174593273e-06*(Pr-0.5));
1275 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1276 const double Cr,double *red,double *green,double *blue)
1278 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1281 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1282 double *red,double *green,double *blue)
1284 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
1286 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
1288 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
1292 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
1293 double *red,double *green,double *blue)
1295 *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-
1296 0.52591263066186533*(Dr-0.5));
1297 *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+
1298 0.26789932820759876*(Dr-0.5));
1299 *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)-
1300 7.9202543533108e-05*(Dr-0.5));
1303 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1304 double *red,double *green,double *blue)
1306 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
1308 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
1310 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
1314 static MagickBooleanType TransformsRGBImage(Image *image,
1315 ExceptionInfo *exception)
1317 #define TransformsRGBImageTag "Transform/Image"
1322 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1323 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1324 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1325 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1326 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1327 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1328 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1329 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1330 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1331 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1332 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1333 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1334 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1335 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1336 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1337 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1338 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1339 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1340 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1341 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1342 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1343 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1344 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1345 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1346 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1347 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1348 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1349 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1350 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1351 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1352 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1353 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1354 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1355 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1356 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1357 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1358 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1359 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1360 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1361 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1362 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1363 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1364 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1365 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1366 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1367 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1368 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1369 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1370 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1371 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1372 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1373 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1374 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1375 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1376 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1377 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1378 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1379 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1380 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1381 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1382 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1383 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1384 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1385 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1386 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1387 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1388 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1389 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1390 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1391 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1392 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1393 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1394 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1395 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1396 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1397 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1398 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1399 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1400 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1401 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1402 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1403 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1404 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1405 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1406 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1407 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1408 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1409 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1410 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1411 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1412 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1413 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1414 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1415 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1416 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1417 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1418 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1419 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1420 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1421 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1422 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1423 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1424 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1425 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1426 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1427 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1428 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1429 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1430 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1431 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1432 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1433 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1434 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1435 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1436 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1437 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1438 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1439 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1440 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1441 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1442 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1443 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1444 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1445 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1446 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1447 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1448 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1449 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1450 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1451 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1452 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1453 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1454 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1455 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1456 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1457 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1458 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1459 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1460 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1461 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1462 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1463 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1464 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1465 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1466 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1467 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1468 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1469 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1470 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1471 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1472 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1473 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1474 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1475 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1476 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1477 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1478 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1479 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1480 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1481 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1482 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1483 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1484 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1485 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1486 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1487 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1488 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1489 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1490 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1491 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1492 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1493 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1494 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1495 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1496 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1497 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1498 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1499 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1500 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1501 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1502 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1503 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1504 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1505 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1506 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1507 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1508 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1509 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1510 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1511 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1512 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1513 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1514 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1515 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1516 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1517 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1518 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1519 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1520 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1521 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1522 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1523 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1524 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1525 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1526 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1527 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1528 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1529 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1530 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1531 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1532 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1533 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1534 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1535 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1536 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1537 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1538 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1539 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1540 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1541 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1542 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1543 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1544 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1545 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1546 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1547 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1548 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1549 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1550 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1551 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1552 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1553 0.998559f, 0.999280f, 1.000000f
1576 assert(image != (Image *) NULL);
1577 assert(image->signature == MagickSignature);
1578 if (image->debug != MagickFalse)
1579 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1582 switch (image->colorspace)
1584 case CMYKColorspace:
1590 Transform image from CMYK to sRGB.
1592 if (image->storage_class == PseudoClass)
1594 if (SyncImage(image,exception) == MagickFalse)
1595 return(MagickFalse);
1596 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1597 return(MagickFalse);
1599 GetPixelInfo(image,&zero);
1600 image_view=AcquireAuthenticCacheView(image,exception);
1601 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1602 #pragma omp parallel for schedule(static,4) shared(status) \
1603 magick_threads(image,image,image->rows,1)
1605 for (y=0; y < (ssize_t) image->rows; y++)
1619 if (status == MagickFalse)
1621 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1623 if (q == (Quantum *) NULL)
1629 for (x=0; x < (ssize_t) image->columns; x++)
1631 GetPixelInfoPixel(image,q,&pixel);
1632 ConvertCMYKToRGB(&pixel);
1633 SetPixelInfoPixel(image,&pixel,q);
1634 q+=GetPixelChannels(image);
1636 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1637 if (sync == MagickFalse)
1640 image_view=DestroyCacheView(image_view);
1641 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1642 return(MagickFalse);
1645 case GRAYColorspace:
1648 Transform linear GRAY to sRGB colorspace.
1650 if (image->storage_class == PseudoClass)
1652 if (SyncImage(image,exception) == MagickFalse)
1653 return(MagickFalse);
1654 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1655 return(MagickFalse);
1657 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1658 return(MagickFalse);
1659 image_view=AcquireAuthenticCacheView(image,exception);
1660 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1661 #pragma omp parallel for schedule(static,4) shared(status) \
1662 magick_threads(image,image,image->rows,1)
1664 for (y=0; y < (ssize_t) image->rows; y++)
1675 if (status == MagickFalse)
1677 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1679 if (q == (Quantum *) NULL)
1684 for (x=(ssize_t) image->columns; x != 0; x--)
1689 gray=(MagickRealType) GetPixelGray(image,q);
1690 if ((image->intensity == Rec601LuminancePixelIntensityMethod) ||
1691 (image->intensity == Rec709LuminancePixelIntensityMethod))
1692 gray=EncodePixelGamma(gray);
1693 SetPixelRed(image,ClampToQuantum(gray),q);
1694 SetPixelGreen(image,ClampToQuantum(gray),q);
1695 SetPixelBlue(image,ClampToQuantum(gray),q);
1696 q+=GetPixelChannels(image);
1698 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1699 if (sync == MagickFalse)
1702 image_view=DestroyCacheView(image_view);
1703 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1704 return(MagickFalse);
1709 case HCLpColorspace:
1717 case LCHabColorspace:
1718 case LCHuvColorspace:
1722 case YCbCrColorspace:
1723 case YDbDrColorspace:
1725 case YPbPrColorspace:
1729 Transform image from source colorspace to sRGB.
1731 if (image->storage_class == PseudoClass)
1733 if (SyncImage(image,exception) == MagickFalse)
1734 return(MagickFalse);
1735 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1736 return(MagickFalse);
1738 image_view=AcquireAuthenticCacheView(image,exception);
1739 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1740 #pragma omp parallel for schedule(static,4) shared(status) \
1741 magick_threads(image,image,image->rows,1)
1743 for (y=0; y < (ssize_t) image->rows; y++)
1754 if (status == MagickFalse)
1756 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1758 if (q == (Quantum *) NULL)
1763 for (x=0; x < (ssize_t) image->columns; x++)
1773 X=QuantumScale*GetPixelRed(image,q);
1774 Y=QuantumScale*GetPixelGreen(image,q);
1775 Z=QuantumScale*GetPixelBlue(image,q);
1776 switch (image->colorspace)
1780 ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
1785 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
1788 case HCLpColorspace:
1790 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
1795 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
1800 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
1805 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
1810 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
1815 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
1820 ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
1824 case LCHabColorspace:
1826 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
1829 case LCHuvColorspace:
1831 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
1836 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
1841 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
1846 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
1849 case YCbCrColorspace:
1851 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
1854 case YDbDrColorspace:
1856 ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
1861 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
1864 case YPbPrColorspace:
1866 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
1871 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
1877 green=QuantumRange*Y;
1878 blue=QuantumRange*Z;
1882 SetPixelRed(image,ClampToQuantum(red),q);
1883 SetPixelGreen(image,ClampToQuantum(green),q);
1884 SetPixelBlue(image,ClampToQuantum(blue),q);
1885 q+=GetPixelChannels(image);
1887 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1888 if (sync == MagickFalse)
1891 image_view=DestroyCacheView(image_view);
1892 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1893 return(MagickFalse);
1913 Transform Log to sRGB colorspace.
1915 density=DisplayGamma;
1917 value=GetImageProperty(image,"gamma",exception);
1918 if (value != (const char *) NULL)
1919 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
1920 film_gamma=FilmGamma;
1921 value=GetImageProperty(image,"film-gamma",exception);
1922 if (value != (const char *) NULL)
1923 film_gamma=StringToDouble(value,(char **) NULL);
1924 reference_black=ReferenceBlack;
1925 value=GetImageProperty(image,"reference-black",exception);
1926 if (value != (const char *) NULL)
1927 reference_black=StringToDouble(value,(char **) NULL);
1928 reference_white=ReferenceWhite;
1929 value=GetImageProperty(image,"reference-white",exception);
1930 if (value != (const char *) NULL)
1931 reference_white=StringToDouble(value,(char **) NULL);
1932 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1934 if (logmap == (Quantum *) NULL)
1935 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1937 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
1939 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
1940 logmap[i]=(Quantum) 0;
1941 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
1942 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
1943 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/
1944 film_gamma)-black));
1945 for ( ; i <= (ssize_t) MaxMap; i++)
1946 logmap[i]=QuantumRange;
1947 if (image->storage_class == PseudoClass)
1949 if (SyncImage(image,exception) == MagickFalse)
1950 return(MagickFalse);
1951 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1952 return(MagickFalse);
1954 image_view=AcquireAuthenticCacheView(image,exception);
1955 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1956 #pragma omp parallel for schedule(static,4) shared(status) \
1957 magick_threads(image,image,image->rows,1)
1959 for (y=0; y < (ssize_t) image->rows; y++)
1970 if (status == MagickFalse)
1972 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1974 if (q == (Quantum *) NULL)
1979 for (x=(ssize_t) image->columns; x != 0; x--)
1986 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
1987 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
1988 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
1989 SetPixelRed(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
1991 SetPixelGreen(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
1993 SetPixelBlue(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
1995 q+=GetPixelChannels(image);
1997 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1998 if (sync == MagickFalse)
2001 image_view=DestroyCacheView(image_view);
2002 logmap=(Quantum *) RelinquishMagickMemory(logmap);
2003 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2004 return(MagickFalse);
2008 case scRGBColorspace:
2011 Transform linear RGB to sRGB colorspace.
2013 if (image->storage_class == PseudoClass)
2015 if (SyncImage(image,exception) == MagickFalse)
2016 return(MagickFalse);
2017 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2018 return(MagickFalse);
2020 image_view=AcquireAuthenticCacheView(image,exception);
2021 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2022 #pragma omp parallel for schedule(static,4) shared(status) \
2023 magick_threads(image,image,image->rows,1)
2025 for (y=0; y < (ssize_t) image->rows; y++)
2036 if (status == MagickFalse)
2038 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2040 if (q == (Quantum *) NULL)
2045 for (x=(ssize_t) image->columns; x != 0; x--)
2052 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q));
2053 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q));
2054 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q));
2055 SetPixelRed(image,ClampToQuantum(red),q);
2056 SetPixelGreen(image,ClampToQuantum(green),q);
2057 SetPixelBlue(image,ClampToQuantum(blue),q);
2058 q+=GetPixelChannels(image);
2060 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2061 if (sync == MagickFalse)
2064 image_view=DestroyCacheView(image_view);
2065 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2066 return(MagickFalse);
2073 Allocate the tables.
2075 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2077 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2079 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2081 if ((x_map == (TransformPacket *) NULL) ||
2082 (y_map == (TransformPacket *) NULL) ||
2083 (z_map == (TransformPacket *) NULL))
2085 if (z_map != (TransformPacket *) NULL)
2086 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2087 if (y_map != (TransformPacket *) NULL)
2088 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2089 if (x_map != (TransformPacket *) NULL)
2090 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2091 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2094 switch (image->colorspace)
2096 case OHTAColorspace:
2099 Initialize OHTA tables:
2101 I1 = 0.33333*R+0.33334*G+0.33333*B
2102 I2 = 0.50000*R+0.00000*G-0.50000*B
2103 I3 =-0.25000*R+0.50000*G-0.25000*B
2104 R = I1+1.00000*I2-0.66668*I3
2105 G = I1+0.00000*I2+1.33333*I3
2106 B = I1-1.00000*I2-0.66668*I3
2108 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2109 through QuantumRange.
2111 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2112 #pragma omp parallel for schedule(static,4) \
2113 magick_threads(image,image,1,1)
2115 for (i=0; i <= (ssize_t) MaxMap; i++)
2117 x_map[i].x=(MagickRealType) (1.0*(double) i);
2118 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap));
2119 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2120 x_map[i].y=(MagickRealType) (1.0*(double) i);
2121 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap));
2122 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap));
2123 x_map[i].z=(MagickRealType) (1.0*(double) i);
2124 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap));
2125 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2129 case Rec601YCbCrColorspace:
2132 Initialize YCbCr tables:
2135 G = Y-0.344136*Cb-0.714136*Cr
2138 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2139 through QuantumRange.
2141 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2142 #pragma omp parallel for schedule(static,4) \
2143 magick_threads(image,image,1,1)
2145 for (i=0; i <= (ssize_t) MaxMap; i++)
2147 x_map[i].x=0.99999999999914679361*(double) i;
2148 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2149 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2150 x_map[i].y=0.99999975910502514331*(double) i;
2151 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2152 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2153 x_map[i].z=1.00000124040004623180*(double) i;
2154 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2155 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2159 case Rec709YCbCrColorspace:
2162 Initialize YCbCr tables:
2165 G = Y-0.187324*Cb-0.468124*Cr
2168 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2169 through QuantumRange.
2171 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2172 #pragma omp parallel for schedule(static,4) \
2173 magick_threads(image,image,1,1)
2175 for (i=0; i <= (ssize_t) MaxMap; i++)
2177 x_map[i].x=(MagickRealType) (1.0*i);
2178 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2179 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap));
2180 x_map[i].y=(MagickRealType) (1.0*i);
2181 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap));
2182 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap));
2183 x_map[i].z=(MagickRealType) (1.0*i);
2184 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap));
2185 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2192 Initialize YCC tables:
2195 G = Y-0.317038*C1-0.682243*C2
2198 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2200 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2201 #pragma omp parallel for schedule(static,4) \
2202 magick_threads(image,image,1,1)
2204 for (i=0; i <= (ssize_t) MaxMap; i++)
2206 x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2207 y_map[i].x=(MagickRealType) 0.0000000;
2208 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double)
2209 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2210 x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2211 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double)
2212 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2213 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double)
2214 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2215 x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2216 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double)
2217 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2218 z_map[i].z=(MagickRealType) 0.0000000;
2225 Linear conversion tables.
2227 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2228 #pragma omp parallel for schedule(static,4) \
2229 magick_threads(image,image,1,1)
2231 for (i=0; i <= (ssize_t) MaxMap; i++)
2233 x_map[i].x=(MagickRealType) (1.0*(double) i);
2234 y_map[i].x=(MagickRealType) 0.0;
2235 z_map[i].x=(MagickRealType) 0.0;
2236 x_map[i].y=(MagickRealType) 0.0;
2237 y_map[i].y=(MagickRealType) (1.0*(double) i);
2238 z_map[i].y=(MagickRealType) 0.0;
2239 x_map[i].z=(MagickRealType) 0.0;
2240 y_map[i].z=(MagickRealType) 0.0;
2241 z_map[i].z=(MagickRealType) (1.0*(double) i);
2249 switch (image->storage_class)
2255 Convert DirectClass image.
2257 image_view=AcquireAuthenticCacheView(image,exception);
2258 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2259 #pragma omp parallel for schedule(static,4) shared(status) \
2260 magick_threads(image,image,image->rows,1)
2262 for (y=0; y < (ssize_t) image->rows; y++)
2276 if (status == MagickFalse)
2278 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2280 if (q == (Quantum *) NULL)
2285 for (x=0; x < (ssize_t) image->columns; x++)
2292 red=ScaleQuantumToMap(GetPixelRed(image,q));
2293 green=ScaleQuantumToMap(GetPixelGreen(image,q));
2294 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
2295 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2296 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2297 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2298 if (image->colorspace == YCCColorspace)
2300 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2302 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2304 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2309 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2310 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2311 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2313 SetPixelRed(image,ClampToQuantum(pixel.red),q);
2314 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
2315 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
2316 q+=GetPixelChannels(image);
2318 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2319 if (sync == MagickFalse)
2321 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2326 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2327 #pragma omp critical (MagickCore_TransformsRGBImage)
2329 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
2331 if (proceed == MagickFalse)
2335 image_view=DestroyCacheView(image_view);
2341 Convert PseudoClass image.
2343 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2344 #pragma omp parallel for schedule(static,4) shared(status) \
2345 magick_threads(image,image,1,1)
2347 for (i=0; i < (ssize_t) image->colors; i++)
2357 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
2358 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
2359 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
2360 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2361 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2362 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2363 if (image->colorspace == YCCColorspace)
2365 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2367 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2369 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2374 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2375 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2376 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2378 image->colormap[i].red=(double) ClampToQuantum(pixel.red);
2379 image->colormap[i].green=(double) ClampToQuantum(pixel.green);
2380 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue);
2382 (void) SyncImage(image,exception);
2387 Relinquish resources.
2389 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2390 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2391 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2392 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2393 return(MagickFalse);