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