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));
1143 Convert the reference image from an alternate colorspace to sRGB.
1145 (void) DeleteImageProfile(image,"icc");
1146 (void) DeleteImageProfile(image,"icm");
1147 if (IssRGBColorspace(colorspace) != MagickFalse)
1148 return(TransformsRGBImage(image,exception));
1150 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1151 status=TransformsRGBImage(image,exception);
1152 if (status == MagickFalse)
1155 Convert the reference image from sRGB to an alternate colorspace.
1157 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1167 + T r a n s f o r m s R G B I m a g e %
1171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1173 % TransformsRGBImage() converts the reference image from an alternate
1174 % colorspace to sRGB. The transformation matrices are not the standard ones:
1175 % the weights are rescaled to normalize the range of the transformed values
1176 % to be [0..QuantumRange].
1178 % The format of the TransformsRGBImage method is:
1180 % MagickBooleanType TransformsRGBImage(Image *image,
1181 % ExceptionInfo *exception)
1183 % A description of each parameter follows:
1185 % o image: the image.
1187 % o exception: return any errors or warnings in this structure.
1191 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1192 const double yellow,double *red,double *green,double *blue)
1194 *red=QuantumRange*(1.0-cyan);
1195 *green=QuantumRange*(1.0-magenta);
1196 *blue=QuantumRange*(1.0-yellow);
1199 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1200 double *X,double *Y,double *Z)
1202 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1203 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1204 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1207 static inline void ConvertLMSToRGB(const double L,const double M,
1208 const double S,double *red,double *green,double *blue)
1215 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1216 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1219 static inline void ConvertLuvToRGB(const double L,const double u,
1220 const double v,double *red,double *green,double *blue)
1227 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1228 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1231 static inline ssize_t RoundToYCC(const double value)
1235 if (value >= 1388.0)
1237 return((ssize_t) (value+0.5));
1240 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1242 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1243 (QuantumRange-pixel->black)+pixel->black)));
1244 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1245 (QuantumRange-pixel->black)+pixel->black)));
1246 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1247 (QuantumRange-pixel->black)+pixel->black)));
1250 static inline void ConvertLabToRGB(const double L,const double a,
1251 const double b,double *red,double *green,double *blue)
1258 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1259 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1262 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1263 double *red,double *green,double *blue)
1265 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
1266 1.4019995886561440468*(Pr-0.5));
1267 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
1268 0.71413649331646789076*(Pr-0.5));
1269 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
1270 2.1453384174593273e-06*(Pr-0.5));
1273 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1274 const double Cr,double *red,double *green,double *blue)
1276 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1279 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1280 double *red,double *green,double *blue)
1282 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
1284 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
1286 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
1290 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
1291 double *red,double *green,double *blue)
1293 *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-
1294 0.52591263066186533*(Dr-0.5));
1295 *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+
1296 0.26789932820759876*(Dr-0.5));
1297 *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)-
1298 7.9202543533108e-05*(Dr-0.5));
1301 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1302 double *red,double *green,double *blue)
1304 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
1306 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
1308 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
1312 static MagickBooleanType TransformsRGBImage(Image *image,
1313 ExceptionInfo *exception)
1315 #define TransformsRGBImageTag "Transform/Image"
1320 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1321 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1322 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1323 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1324 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1325 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1326 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1327 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1328 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1329 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1330 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1331 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1332 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1333 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1334 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1335 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1336 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1337 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1338 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1339 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1340 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1341 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1342 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1343 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1344 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1345 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1346 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1347 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1348 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1349 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1350 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1351 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1352 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1353 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1354 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1355 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1356 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1357 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1358 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1359 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1360 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1361 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1362 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1363 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1364 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1365 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1366 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1367 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1368 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1369 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1370 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1371 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1372 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1373 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1374 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1375 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1376 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1377 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1378 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1379 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1380 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1381 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1382 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1383 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1384 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1385 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1386 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1387 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1388 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1389 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1390 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1391 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1392 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1393 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1394 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1395 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1396 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1397 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1398 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1399 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1400 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1401 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1402 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1403 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1404 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1405 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1406 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1407 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1408 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1409 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1410 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1411 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1412 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1413 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1414 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1415 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1416 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1417 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1418 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1419 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1420 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1421 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1422 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1423 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1424 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1425 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1426 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1427 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1428 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1429 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1430 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1431 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1432 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1433 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1434 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1435 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1436 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1437 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1438 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1439 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1440 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1441 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1442 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1443 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1444 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1445 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1446 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1447 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1448 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1449 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1450 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1451 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1452 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1453 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1454 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1455 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1456 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1457 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1458 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1459 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1460 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1461 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1462 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1463 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1464 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1465 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1466 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1467 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1468 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1469 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1470 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1471 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1472 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1473 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1474 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1475 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1476 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1477 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1478 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1479 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1480 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1481 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1482 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1483 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1484 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1485 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1486 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1487 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1488 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1489 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1490 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1491 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1492 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1493 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1494 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1495 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1496 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1497 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1498 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1499 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1500 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1501 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1502 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1503 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1504 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1505 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1506 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1507 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1508 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1509 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1510 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1511 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1512 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1513 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1514 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1515 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1516 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1517 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1518 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1519 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1520 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1521 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1522 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1523 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1524 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1525 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1526 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1527 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1528 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1529 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1530 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1531 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1532 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1533 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1534 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1535 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1536 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1537 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1538 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1539 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1540 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1541 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1542 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1543 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1544 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1545 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1546 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1547 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1548 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1549 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1550 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1551 0.998559f, 0.999280f, 1.000000f
1574 assert(image != (Image *) NULL);
1575 assert(image->signature == MagickSignature);
1576 if (image->debug != MagickFalse)
1577 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1580 switch (image->colorspace)
1582 case CMYKColorspace:
1588 Transform image from CMYK to sRGB.
1590 if (image->storage_class == PseudoClass)
1592 if (SyncImage(image,exception) == MagickFalse)
1593 return(MagickFalse);
1594 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1595 return(MagickFalse);
1597 GetPixelInfo(image,&zero);
1598 image_view=AcquireAuthenticCacheView(image,exception);
1599 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1600 #pragma omp parallel for schedule(static,4) shared(status) \
1601 magick_threads(image,image,image->rows,1)
1603 for (y=0; y < (ssize_t) image->rows; y++)
1617 if (status == MagickFalse)
1619 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1621 if (q == (Quantum *) NULL)
1627 for (x=0; x < (ssize_t) image->columns; x++)
1629 GetPixelInfoPixel(image,q,&pixel);
1630 ConvertCMYKToRGB(&pixel);
1631 SetPixelInfoPixel(image,&pixel,q);
1632 q+=GetPixelChannels(image);
1634 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1635 if (sync == MagickFalse)
1638 image_view=DestroyCacheView(image_view);
1639 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1640 return(MagickFalse);
1643 case GRAYColorspace:
1646 Transform linear GRAY to sRGB colorspace.
1648 if (image->storage_class == PseudoClass)
1650 if (SyncImage(image,exception) == MagickFalse)
1651 return(MagickFalse);
1652 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1653 return(MagickFalse);
1655 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1656 return(MagickFalse);
1657 image_view=AcquireAuthenticCacheView(image,exception);
1658 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1659 #pragma omp parallel for schedule(static,4) shared(status) \
1660 magick_threads(image,image,image->rows,1)
1662 for (y=0; y < (ssize_t) image->rows; y++)
1673 if (status == MagickFalse)
1675 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1677 if (q == (Quantum *) NULL)
1682 for (x=(ssize_t) image->columns; x != 0; x--)
1687 gray=(MagickRealType) GetPixelGray(image,q);
1688 if ((image->intensity == Rec601LuminancePixelIntensityMethod) ||
1689 (image->intensity == Rec709LuminancePixelIntensityMethod))
1690 gray=EncodePixelGamma(gray);
1691 SetPixelRed(image,ClampToQuantum(gray),q);
1692 SetPixelGreen(image,ClampToQuantum(gray),q);
1693 SetPixelBlue(image,ClampToQuantum(gray),q);
1694 q+=GetPixelChannels(image);
1696 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1697 if (sync == MagickFalse)
1700 image_view=DestroyCacheView(image_view);
1701 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1702 return(MagickFalse);
1707 case HCLpColorspace:
1715 case LCHabColorspace:
1716 case LCHuvColorspace:
1720 case YCbCrColorspace:
1721 case YDbDrColorspace:
1723 case YPbPrColorspace:
1727 Transform image from source colorspace to sRGB.
1729 if (image->storage_class == PseudoClass)
1731 if (SyncImage(image,exception) == MagickFalse)
1732 return(MagickFalse);
1733 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1734 return(MagickFalse);
1736 image_view=AcquireAuthenticCacheView(image,exception);
1737 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1738 #pragma omp parallel for schedule(static,4) shared(status) \
1739 magick_threads(image,image,image->rows,1)
1741 for (y=0; y < (ssize_t) image->rows; y++)
1752 if (status == MagickFalse)
1754 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1756 if (q == (Quantum *) NULL)
1761 for (x=0; x < (ssize_t) image->columns; x++)
1771 X=QuantumScale*GetPixelRed(image,q);
1772 Y=QuantumScale*GetPixelGreen(image,q);
1773 Z=QuantumScale*GetPixelBlue(image,q);
1774 switch (image->colorspace)
1778 ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
1783 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
1786 case HCLpColorspace:
1788 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
1793 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
1798 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
1803 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
1808 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
1813 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
1818 ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
1822 case LCHabColorspace:
1824 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
1827 case LCHuvColorspace:
1829 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
1834 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
1839 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
1844 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
1847 case YCbCrColorspace:
1849 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
1852 case YDbDrColorspace:
1854 ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
1859 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
1862 case YPbPrColorspace:
1864 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
1869 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
1875 green=QuantumRange*Y;
1876 blue=QuantumRange*Z;
1880 SetPixelRed(image,ClampToQuantum(red),q);
1881 SetPixelGreen(image,ClampToQuantum(green),q);
1882 SetPixelBlue(image,ClampToQuantum(blue),q);
1883 q+=GetPixelChannels(image);
1885 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1886 if (sync == MagickFalse)
1889 image_view=DestroyCacheView(image_view);
1890 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1891 return(MagickFalse);
1911 Transform Log to sRGB colorspace.
1913 density=DisplayGamma;
1915 value=GetImageProperty(image,"gamma",exception);
1916 if (value != (const char *) NULL)
1917 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
1918 film_gamma=FilmGamma;
1919 value=GetImageProperty(image,"film-gamma",exception);
1920 if (value != (const char *) NULL)
1921 film_gamma=StringToDouble(value,(char **) NULL);
1922 reference_black=ReferenceBlack;
1923 value=GetImageProperty(image,"reference-black",exception);
1924 if (value != (const char *) NULL)
1925 reference_black=StringToDouble(value,(char **) NULL);
1926 reference_white=ReferenceWhite;
1927 value=GetImageProperty(image,"reference-white",exception);
1928 if (value != (const char *) NULL)
1929 reference_white=StringToDouble(value,(char **) NULL);
1930 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1932 if (logmap == (Quantum *) NULL)
1933 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1935 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
1937 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
1938 logmap[i]=(Quantum) 0;
1939 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
1940 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
1941 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/
1942 film_gamma)-black));
1943 for ( ; i <= (ssize_t) MaxMap; i++)
1944 logmap[i]=QuantumRange;
1945 if (image->storage_class == PseudoClass)
1947 if (SyncImage(image,exception) == MagickFalse)
1948 return(MagickFalse);
1949 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1950 return(MagickFalse);
1952 image_view=AcquireAuthenticCacheView(image,exception);
1953 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1954 #pragma omp parallel for schedule(static,4) shared(status) \
1955 magick_threads(image,image,image->rows,1)
1957 for (y=0; y < (ssize_t) image->rows; y++)
1968 if (status == MagickFalse)
1970 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1972 if (q == (Quantum *) NULL)
1977 for (x=(ssize_t) image->columns; x != 0; x--)
1984 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
1985 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
1986 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
1987 SetPixelRed(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
1989 SetPixelGreen(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
1991 SetPixelBlue(image,ClampToQuantum(EncodePixelGamma((MagickRealType)
1993 q+=GetPixelChannels(image);
1995 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1996 if (sync == MagickFalse)
1999 image_view=DestroyCacheView(image_view);
2000 logmap=(Quantum *) RelinquishMagickMemory(logmap);
2001 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2002 return(MagickFalse);
2006 case scRGBColorspace:
2009 Transform linear RGB to sRGB colorspace.
2011 if (image->storage_class == PseudoClass)
2013 if (SyncImage(image,exception) == MagickFalse)
2014 return(MagickFalse);
2015 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2016 return(MagickFalse);
2018 image_view=AcquireAuthenticCacheView(image,exception);
2019 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2020 #pragma omp parallel for schedule(static,4) shared(status) \
2021 magick_threads(image,image,image->rows,1)
2023 for (y=0; y < (ssize_t) image->rows; y++)
2034 if (status == MagickFalse)
2036 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2038 if (q == (Quantum *) NULL)
2043 for (x=(ssize_t) image->columns; x != 0; x--)
2050 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q));
2051 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q));
2052 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q));
2053 SetPixelRed(image,ClampToQuantum(red),q);
2054 SetPixelGreen(image,ClampToQuantum(green),q);
2055 SetPixelBlue(image,ClampToQuantum(blue),q);
2056 q+=GetPixelChannels(image);
2058 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2059 if (sync == MagickFalse)
2062 image_view=DestroyCacheView(image_view);
2063 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2064 return(MagickFalse);
2071 Allocate the tables.
2073 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2075 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2077 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2079 if ((x_map == (TransformPacket *) NULL) ||
2080 (y_map == (TransformPacket *) NULL) ||
2081 (z_map == (TransformPacket *) NULL))
2083 if (z_map != (TransformPacket *) NULL)
2084 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2085 if (y_map != (TransformPacket *) NULL)
2086 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2087 if (x_map != (TransformPacket *) NULL)
2088 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2089 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2092 switch (image->colorspace)
2094 case OHTAColorspace:
2097 Initialize OHTA tables:
2099 I1 = 0.33333*R+0.33334*G+0.33333*B
2100 I2 = 0.50000*R+0.00000*G-0.50000*B
2101 I3 =-0.25000*R+0.50000*G-0.25000*B
2102 R = I1+1.00000*I2-0.66668*I3
2103 G = I1+0.00000*I2+1.33333*I3
2104 B = I1-1.00000*I2-0.66668*I3
2106 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2107 through QuantumRange.
2109 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2110 #pragma omp parallel for schedule(static,4) \
2111 magick_threads(image,image,1,1)
2113 for (i=0; i <= (ssize_t) MaxMap; i++)
2115 x_map[i].x=(MagickRealType) (1.0*(double) i);
2116 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap));
2117 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2118 x_map[i].y=(MagickRealType) (1.0*(double) i);
2119 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap));
2120 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap));
2121 x_map[i].z=(MagickRealType) (1.0*(double) i);
2122 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap));
2123 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2127 case Rec601YCbCrColorspace:
2130 Initialize YCbCr tables:
2133 G = Y-0.344136*Cb-0.714136*Cr
2136 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2137 through QuantumRange.
2139 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2140 #pragma omp parallel for schedule(static,4) \
2141 magick_threads(image,image,1,1)
2143 for (i=0; i <= (ssize_t) MaxMap; i++)
2145 x_map[i].x=0.99999999999914679361*(double) i;
2146 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2147 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2148 x_map[i].y=0.99999975910502514331*(double) i;
2149 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2150 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2151 x_map[i].z=1.00000124040004623180*(double) i;
2152 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2153 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2157 case Rec709YCbCrColorspace:
2160 Initialize YCbCr tables:
2163 G = Y-0.187324*Cb-0.468124*Cr
2166 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2167 through QuantumRange.
2169 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2170 #pragma omp parallel for schedule(static,4) \
2171 magick_threads(image,image,1,1)
2173 for (i=0; i <= (ssize_t) MaxMap; i++)
2175 x_map[i].x=(MagickRealType) (1.0*i);
2176 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2177 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap));
2178 x_map[i].y=(MagickRealType) (1.0*i);
2179 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap));
2180 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap));
2181 x_map[i].z=(MagickRealType) (1.0*i);
2182 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap));
2183 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2190 Initialize YCC tables:
2193 G = Y-0.317038*C1-0.682243*C2
2196 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2198 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2199 #pragma omp parallel for schedule(static,4) \
2200 magick_threads(image,image,1,1)
2202 for (i=0; i <= (ssize_t) MaxMap; i++)
2204 x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2205 y_map[i].x=(MagickRealType) 0.0000000;
2206 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double)
2207 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2208 x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2209 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double)
2210 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2211 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double)
2212 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2213 x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2214 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double)
2215 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2216 z_map[i].z=(MagickRealType) 0.0000000;
2223 Linear conversion tables.
2225 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2226 #pragma omp parallel for schedule(static,4) \
2227 magick_threads(image,image,1,1)
2229 for (i=0; i <= (ssize_t) MaxMap; i++)
2231 x_map[i].x=(MagickRealType) (1.0*(double) i);
2232 y_map[i].x=(MagickRealType) 0.0;
2233 z_map[i].x=(MagickRealType) 0.0;
2234 x_map[i].y=(MagickRealType) 0.0;
2235 y_map[i].y=(MagickRealType) (1.0*(double) i);
2236 z_map[i].y=(MagickRealType) 0.0;
2237 x_map[i].z=(MagickRealType) 0.0;
2238 y_map[i].z=(MagickRealType) 0.0;
2239 z_map[i].z=(MagickRealType) (1.0*(double) i);
2247 switch (image->storage_class)
2253 Convert DirectClass image.
2255 image_view=AcquireAuthenticCacheView(image,exception);
2256 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2257 #pragma omp parallel for schedule(static,4) shared(status) \
2258 magick_threads(image,image,image->rows,1)
2260 for (y=0; y < (ssize_t) image->rows; y++)
2274 if (status == MagickFalse)
2276 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2278 if (q == (Quantum *) NULL)
2283 for (x=0; x < (ssize_t) image->columns; x++)
2290 red=ScaleQuantumToMap(GetPixelRed(image,q));
2291 green=ScaleQuantumToMap(GetPixelGreen(image,q));
2292 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
2293 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2294 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2295 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2296 if (image->colorspace == YCCColorspace)
2298 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2300 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2302 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2307 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2308 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2309 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2311 SetPixelRed(image,ClampToQuantum(pixel.red),q);
2312 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
2313 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
2314 q+=GetPixelChannels(image);
2316 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2317 if (sync == MagickFalse)
2319 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2324 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2325 #pragma omp critical (MagickCore_TransformsRGBImage)
2327 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
2329 if (proceed == MagickFalse)
2333 image_view=DestroyCacheView(image_view);
2339 Convert PseudoClass image.
2341 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2342 #pragma omp parallel for schedule(static,4) shared(status) \
2343 magick_threads(image,image,1,1)
2345 for (i=0; i < (ssize_t) image->colors; i++)
2355 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
2356 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
2357 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
2358 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2359 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2360 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2361 if (image->colorspace == YCCColorspace)
2363 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2365 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2367 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2372 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2373 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2374 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2376 image->colormap[i].red=(double) ClampToQuantum(pixel.red);
2377 image->colormap[i].green=(double) ClampToQuantum(pixel.green);
2378 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue);
2380 (void) SyncImage(image,exception);
2385 Relinquish resources.
2387 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2388 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2389 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2390 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2391 return(MagickFalse);