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) GetPixelRed(image,q);
642 green=(double) GetPixelGreen(image,q);
643 blue=(double) GetPixelBlue(image,q);
644 SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q);
645 SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))],
647 SetPixelBlue(image,logmap[ScaleQuantumToMap(ClampToQuantum(blue))],q);
648 q+=GetPixelChannels(image);
650 sync=SyncCacheViewAuthenticPixels(image_view,exception);
651 if (sync == MagickFalse)
654 image_view=DestroyCacheView(image_view);
655 logmap=(Quantum *) RelinquishMagickMemory(logmap);
656 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
661 case scRGBColorspace:
664 Transform image from sRGB to linear RGB.
666 if (image->storage_class == PseudoClass)
668 if (SyncImage(image,exception) == MagickFalse)
670 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
673 image_view=AcquireAuthenticCacheView(image,exception);
674 #if defined(MAGICKCORE_OPENMP_SUPPORT)
675 #pragma omp parallel for schedule(static,4) shared(status) \
676 magick_threads(image,image,image->rows,1)
678 for (y=0; y < (ssize_t) image->rows; y++)
689 if (status == MagickFalse)
691 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
693 if (q == (Quantum *) NULL)
698 for (x=0; x < (ssize_t) image->columns; x++)
705 red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
706 green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
707 blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
708 SetPixelRed(image,ClampToQuantum(red),q);
709 SetPixelGreen(image,ClampToQuantum(green),q);
710 SetPixelBlue(image,ClampToQuantum(blue),q);
711 q+=GetPixelChannels(image);
713 sync=SyncCacheViewAuthenticPixels(image_view,exception);
714 if (sync == MagickFalse)
717 image_view=DestroyCacheView(image_view);
718 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
728 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
730 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
732 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
734 if ((x_map == (TransformPacket *) NULL) ||
735 (y_map == (TransformPacket *) NULL) ||
736 (z_map == (TransformPacket *) NULL))
737 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
739 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
745 Initialize OHTA tables:
747 I1 = 0.33333*R+0.33334*G+0.33333*B
748 I2 = 0.50000*R+0.00000*G-0.50000*B
749 I3 =-0.25000*R+0.50000*G-0.25000*B
751 I and Q, normally -0.5 through 0.5, are normalized to the range 0
752 through QuantumRange.
754 primary_info.y=(double) (MaxMap+1.0)/2.0;
755 primary_info.z=(double) (MaxMap+1.0)/2.0;
756 #if defined(MAGICKCORE_OPENMP_SUPPORT)
757 #pragma omp parallel for schedule(static,4) \
758 magick_threads(image,image,1,1)
760 for (i=0; i <= (ssize_t) MaxMap; i++)
762 x_map[i].x=(MagickRealType) (0.33333*(double) i);
763 y_map[i].x=(MagickRealType) (0.33334*(double) i);
764 z_map[i].x=(MagickRealType) (0.33333*(double) i);
765 x_map[i].y=(MagickRealType) (0.50000*(double) i);
766 y_map[i].y=(MagickRealType) (0.00000*(double) i);
767 z_map[i].y=(MagickRealType) (-0.50000*(double) i);
768 x_map[i].z=(MagickRealType) (-0.25000*(double) i);
769 y_map[i].z=(MagickRealType) (0.50000*(double) i);
770 z_map[i].z=(MagickRealType) (-0.25000*(double) i);
774 case Rec601YCbCrColorspace:
777 Initialize YCbCr tables (ITU-R BT.601):
779 Y = 0.2988390*R+0.5868110*G+0.1143500*B
780 Cb= -0.1687367*R-0.3312640*G+0.5000000*B
781 Cr= 0.5000000*R-0.4186880*G-0.0813120*B
783 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
784 through QuantumRange.
786 primary_info.y=(double) (MaxMap+1.0)/2.0;
787 primary_info.z=(double) (MaxMap+1.0)/2.0;
788 #if defined(MAGICKCORE_OPENMP_SUPPORT)
789 #pragma omp parallel for schedule(static,4) \
790 magick_threads(image,image,1,1)
792 for (i=0; i <= (ssize_t) MaxMap; i++)
794 x_map[i].x=(MagickRealType) (0.298839*(double) i);
795 y_map[i].x=(MagickRealType) (0.586811*(double) i);
796 z_map[i].x=(MagickRealType) (0.114350*(double) i);
797 x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
798 y_map[i].y=(MagickRealType) (-0.331264*(double) i);
799 z_map[i].y=(MagickRealType) (0.500000*(double) i);
800 x_map[i].z=(MagickRealType) (0.500000*(double) i);
801 y_map[i].z=(MagickRealType) (-0.418688*(double) i);
802 z_map[i].z=(MagickRealType) (-0.081312*(double) i);
806 case Rec709YCbCrColorspace:
809 Initialize YCbCr tables (ITU-R BT.709):
811 Y = 0.212656*R+0.715158*G+0.072186*B
812 Cb= -0.114572*R-0.385428*G+0.500000*B
813 Cr= 0.500000*R-0.454153*G-0.045847*B
815 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
816 through QuantumRange.
818 primary_info.y=(double) (MaxMap+1.0)/2.0;
819 primary_info.z=(double) (MaxMap+1.0)/2.0;
820 #if defined(MAGICKCORE_OPENMP_SUPPORT)
821 #pragma omp parallel for schedule(static,4) \
822 magick_threads(image,image,1,1)
824 for (i=0; i <= (ssize_t) MaxMap; i++)
826 x_map[i].x=(MagickRealType) (0.212656*(double) i);
827 y_map[i].x=(MagickRealType) (0.715158*(double) i);
828 z_map[i].x=(MagickRealType) (0.072186*(double) i);
829 x_map[i].y=(MagickRealType) (-0.114572*(double) i);
830 y_map[i].y=(MagickRealType) (-0.385428*(double) i);
831 z_map[i].y=(MagickRealType) (0.500000*(double) i);
832 x_map[i].z=(MagickRealType) (0.500000*(double) i);
833 y_map[i].z=(MagickRealType) (-0.454153*(double) i);
834 z_map[i].z=(MagickRealType) (-0.045847*(double) i);
841 Initialize YCC tables:
843 Y = 0.298839*R+0.586811*G+0.114350*B
844 C1= -0.298839*R-0.586811*G+0.88600*B
845 C2= 0.70100*R-0.586811*G-0.114350*B
847 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
849 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
850 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
851 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
853 x_map[i].x=0.003962014134275617*i;
854 y_map[i].x=0.007778268551236748*i;
855 z_map[i].x=0.001510600706713781*i;
856 x_map[i].y=(-0.002426619775463276)*i;
857 y_map[i].y=(-0.004763965913702149)*i;
858 z_map[i].y=0.007190585689165425*i;
859 x_map[i].z=0.006927257754597858*i;
860 y_map[i].z=(-0.005800713697502058)*i;
861 z_map[i].z=(-0.0011265440570958)*i;
863 for ( ; i <= (ssize_t) MaxMap; i++)
865 x_map[i].x=0.2201118963486454*(1.099*i-0.099);
866 y_map[i].x=0.4321260306242638*(1.099*i-0.099);
867 z_map[i].x=0.08392226148409894*(1.099*i-0.099);
868 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
869 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
870 z_map[i].y=0.3994769827314126*(1.099*i-0.099);
871 x_map[i].z=0.3848476530332144*(1.099*i-0.099);
872 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
873 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
880 Linear conversion tables.
882 #if defined(MAGICKCORE_OPENMP_SUPPORT)
883 #pragma omp parallel for schedule(static,4) \
884 magick_threads(image,image,1,1)
886 for (i=0; i <= (ssize_t) MaxMap; i++)
888 x_map[i].x=(MagickRealType) (1.0*(double) i);
889 y_map[i].x=(MagickRealType) 0.0;
890 z_map[i].x=(MagickRealType) 0.0;
891 x_map[i].y=(MagickRealType) 0.0;
892 y_map[i].y=(MagickRealType) (1.0*(double) i);
893 z_map[i].y=(MagickRealType) 0.0;
894 x_map[i].z=(MagickRealType) 0.0;
895 y_map[i].z=(MagickRealType) 0.0;
896 z_map[i].z=(MagickRealType) (1.0*(double) i);
904 switch (image->storage_class)
910 Convert DirectClass image.
912 image_view=AcquireAuthenticCacheView(image,exception);
913 #if defined(MAGICKCORE_OPENMP_SUPPORT)
914 #pragma omp parallel for schedule(static,4) shared(status) \
915 magick_threads(image,image,image->rows,1)
917 for (y=0; y < (ssize_t) image->rows; y++)
931 register unsigned int
936 if (status == MagickFalse)
938 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
940 if (q == (Quantum *) NULL)
945 for (x=0; x < (ssize_t) image->columns; x++)
947 red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
948 GetPixelRed(image,q)));
949 green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
950 GetPixelGreen(image,q)));
951 blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
952 GetPixelBlue(image,q)));
953 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
955 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
957 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
959 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
960 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
961 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
962 q+=GetPixelChannels(image);
964 sync=SyncCacheViewAuthenticPixels(image_view,exception);
965 if (sync == MagickFalse)
967 if (image->progress_monitor != (MagickProgressMonitor) NULL)
972 #if defined(MAGICKCORE_OPENMP_SUPPORT)
973 #pragma omp critical (MagickCore_sRGBTransformImage)
975 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
977 if (proceed == MagickFalse)
981 image_view=DestroyCacheView(image_view);
986 register unsigned int
992 Convert PseudoClass image.
994 for (i=0; i < (ssize_t) image->colors; i++)
999 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
1000 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
1001 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
1002 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1003 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1004 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1005 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
1006 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
1007 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
1009 (void) SyncImage(image,exception);
1014 Relinquish resources.
1016 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1017 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1018 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1019 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1020 return(MagickFalse);
1025 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029 % S e t I m a g e C o l o r s p a c e %
1033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035 % SetImageColorspace() sets the colorspace member of the Image structure.
1037 % The format of the SetImageColorspace method is:
1039 % MagickBooleanType SetImageColorspace(Image *image,
1040 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1042 % A description of each parameter follows:
1044 % o image: the image.
1046 % o colorspace: the colorspace.
1048 % o exception: return any errors or warnings in this structure.
1051 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1052 const ColorspaceType colorspace,ExceptionInfo *exception)
1060 if (image->colorspace == colorspace)
1062 image->colorspace=colorspace;
1063 image->rendering_intent=UndefinedIntent;
1064 image->gamma=1.000/2.200;
1065 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1067 if (IsGrayColorspace(colorspace) != MagickFalse)
1069 if ((image->intensity == Rec601LuminancePixelIntensityMethod) ||
1070 (image->intensity == Rec709LuminancePixelIntensityMethod))
1075 if ((IsRGBColorspace(colorspace) != MagickFalse) ||
1076 (colorspace == XYZColorspace))
1080 image->rendering_intent=PerceptualIntent;
1081 image->chromaticity.red_primary.x=0.6400;
1082 image->chromaticity.red_primary.y=0.3300;
1083 image->chromaticity.red_primary.z=0.0300;
1084 image->chromaticity.green_primary.x=0.3000;
1085 image->chromaticity.green_primary.y=0.6000;
1086 image->chromaticity.green_primary.z=0.1000;
1087 image->chromaticity.blue_primary.x=0.1500;
1088 image->chromaticity.blue_primary.y=0.0600;
1089 image->chromaticity.blue_primary.z=0.7900;
1090 image->chromaticity.white_point.x=0.3127;
1091 image->chromaticity.white_point.y=0.3290;
1092 image->chromaticity.white_point.z=0.3583;
1094 status=SyncImagePixelCache(image,exception);
1100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1104 % T r a n s f o r m I m a g e C o l o r s p a c e %
1108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110 % TransformImageColorspace() transforms an image colorspace, changing the
1111 % image data to reflect the new colorspace.
1113 % The format of the TransformImageColorspace method is:
1115 % MagickBooleanType TransformImageColorspace(Image *image,
1116 % const ColorspaceType colorspace,ExceptionInfo *exception)
1118 % A description of each parameter follows:
1120 % o image: the image.
1122 % o colorspace: the colorspace.
1124 % o exception: return any errors or warnings in this structure.
1127 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1128 const ColorspaceType colorspace,ExceptionInfo *exception)
1133 assert(image != (Image *) NULL);
1134 assert(image->signature == MagickSignature);
1135 if (image->debug != MagickFalse)
1136 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1137 if (colorspace == UndefinedColorspace)
1138 return(SetImageColorspace(image,colorspace,exception));
1140 Convert the reference image from an alternate colorspace to sRGB.
1142 (void) DeleteImageProfile(image,"icc");
1143 (void) DeleteImageProfile(image,"icm");
1144 if (IssRGBColorspace(colorspace) != MagickFalse)
1145 return(TransformsRGBImage(image,exception));
1147 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1148 status=TransformsRGBImage(image,exception);
1149 if (status == MagickFalse)
1152 Convert the reference image from sRGB to an alternate colorspace.
1154 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1164 + T r a n s f o r m s R G B I m a g e %
1168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1170 % TransformsRGBImage() converts the reference image from an alternate
1171 % colorspace to sRGB. The transformation matrices are not the standard ones:
1172 % the weights are rescaled to normalize the range of the transformed values
1173 % to be [0..QuantumRange].
1175 % The format of the TransformsRGBImage method is:
1177 % MagickBooleanType TransformsRGBImage(Image *image,
1178 % ExceptionInfo *exception)
1180 % A description of each parameter follows:
1182 % o image: the image.
1184 % o exception: return any errors or warnings in this structure.
1188 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1189 const double yellow,double *red,double *green,double *blue)
1191 *red=QuantumRange*(1.0-cyan);
1192 *green=QuantumRange*(1.0-magenta);
1193 *blue=QuantumRange*(1.0-yellow);
1196 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1197 double *X,double *Y,double *Z)
1199 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1200 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1201 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1204 static inline void ConvertLMSToRGB(const double L,const double M,
1205 const double S,double *red,double *green,double *blue)
1212 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1213 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1216 static inline void ConvertLuvToRGB(const double L,const double u,
1217 const double v,double *red,double *green,double *blue)
1224 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1225 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1228 static inline ssize_t RoundToYCC(const double value)
1232 if (value >= 1388.0)
1234 return((ssize_t) (value+0.5));
1237 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1239 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1240 (QuantumRange-pixel->black)+pixel->black)));
1241 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1242 (QuantumRange-pixel->black)+pixel->black)));
1243 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1244 (QuantumRange-pixel->black)+pixel->black)));
1247 static inline void ConvertLabToRGB(const double L,const double a,
1248 const double b,double *red,double *green,double *blue)
1255 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1256 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1259 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1260 double *red,double *green,double *blue)
1262 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
1263 1.4019995886561440468*(Pr-0.5));
1264 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
1265 0.71413649331646789076*(Pr-0.5));
1266 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
1267 2.1453384174593273e-06*(Pr-0.5));
1270 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1271 const double Cr,double *red,double *green,double *blue)
1273 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1276 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1277 double *red,double *green,double *blue)
1279 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
1281 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
1283 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
1287 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
1288 double *red,double *green,double *blue)
1290 *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-
1291 0.52591263066186533*(Dr-0.5));
1292 *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+
1293 0.26789932820759876*(Dr-0.5));
1294 *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)-
1295 7.9202543533108e-05*(Dr-0.5));
1298 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1299 double *red,double *green,double *blue)
1301 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
1303 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
1305 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
1309 static MagickBooleanType TransformsRGBImage(Image *image,
1310 ExceptionInfo *exception)
1312 #define TransformsRGBImageTag "Transform/Image"
1317 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1318 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1319 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1320 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1321 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1322 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1323 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1324 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1325 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1326 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1327 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1328 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1329 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1330 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1331 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1332 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1333 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1334 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1335 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1336 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1337 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1338 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1339 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1340 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1341 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1342 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1343 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1344 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1345 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1346 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1347 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1348 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1349 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1350 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1351 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1352 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1353 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1354 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1355 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1356 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1357 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1358 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1359 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1360 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1361 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1362 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1363 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1364 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1365 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1366 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1367 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1368 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1369 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1370 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1371 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1372 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1373 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1374 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1375 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1376 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1377 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1378 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1379 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1380 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1381 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1382 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1383 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1384 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1385 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1386 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1387 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1388 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1389 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1390 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1391 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1392 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1393 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1394 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1395 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1396 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1397 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1398 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1399 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1400 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1401 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1402 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1403 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1404 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1405 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1406 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1407 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1408 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1409 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1410 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1411 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1412 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1413 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1414 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1415 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1416 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1417 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1418 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1419 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1420 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1421 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1422 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1423 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1424 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1425 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1426 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1427 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1428 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1429 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1430 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1431 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1432 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1433 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1434 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1435 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1436 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1437 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1438 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1439 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1440 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1441 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1442 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1443 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1444 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1445 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1446 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1447 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1448 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1449 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1450 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1451 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1452 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1453 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1454 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1455 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1456 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1457 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1458 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1459 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1460 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1461 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1462 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1463 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1464 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1465 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1466 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1467 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1468 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1469 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1470 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1471 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1472 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1473 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1474 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1475 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1476 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1477 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1478 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1479 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1480 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1481 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1482 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1483 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1484 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1485 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1486 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1487 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1488 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1489 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1490 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1491 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1492 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1493 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1494 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1495 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1496 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1497 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1498 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1499 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1500 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1501 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1502 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1503 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1504 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1505 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1506 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1507 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1508 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1509 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1510 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1511 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1512 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1513 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1514 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1515 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1516 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1517 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1518 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1519 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1520 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1521 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1522 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1523 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1524 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1525 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1526 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1527 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1528 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1529 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1530 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1531 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1532 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1533 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1534 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1535 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1536 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1537 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1538 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1539 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1540 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1541 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1542 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1543 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1544 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1545 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1546 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1547 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1548 0.998559f, 0.999280f, 1.000000f
1571 assert(image != (Image *) NULL);
1572 assert(image->signature == MagickSignature);
1573 if (image->debug != MagickFalse)
1574 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1577 switch (image->colorspace)
1579 case CMYKColorspace:
1585 Transform image from CMYK to sRGB.
1587 if (image->storage_class == PseudoClass)
1589 if (SyncImage(image,exception) == MagickFalse)
1590 return(MagickFalse);
1591 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1592 return(MagickFalse);
1594 GetPixelInfo(image,&zero);
1595 image_view=AcquireAuthenticCacheView(image,exception);
1596 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1597 #pragma omp parallel for schedule(static,4) shared(status) \
1598 magick_threads(image,image,image->rows,1)
1600 for (y=0; y < (ssize_t) image->rows; y++)
1614 if (status == MagickFalse)
1616 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1618 if (q == (Quantum *) NULL)
1624 for (x=0; x < (ssize_t) image->columns; x++)
1626 GetPixelInfoPixel(image,q,&pixel);
1627 ConvertCMYKToRGB(&pixel);
1628 SetPixelInfoPixel(image,&pixel,q);
1629 q+=GetPixelChannels(image);
1631 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1632 if (sync == MagickFalse)
1635 image_view=DestroyCacheView(image_view);
1636 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1637 return(MagickFalse);
1640 case GRAYColorspace:
1643 Transform linear GRAY to sRGB colorspace.
1645 if (image->storage_class == PseudoClass)
1647 if (SyncImage(image,exception) == MagickFalse)
1648 return(MagickFalse);
1649 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1650 return(MagickFalse);
1652 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1653 return(MagickFalse);
1654 image_view=AcquireAuthenticCacheView(image,exception);
1655 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1656 #pragma omp parallel for schedule(static,4) shared(status) \
1657 magick_threads(image,image,image->rows,1)
1659 for (y=0; y < (ssize_t) image->rows; y++)
1670 if (status == MagickFalse)
1672 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1674 if (q == (Quantum *) NULL)
1679 for (x=(ssize_t) image->columns; x != 0; x--)
1684 gray=(MagickRealType) GetPixelGray(image,q);
1685 if ((image->intensity == Rec601LuminancePixelIntensityMethod) ||
1686 (image->intensity == Rec709LuminancePixelIntensityMethod))
1687 gray=EncodePixelGamma(gray);
1688 SetPixelRed(image,ClampToQuantum(gray),q);
1689 SetPixelGreen(image,ClampToQuantum(gray),q);
1690 SetPixelBlue(image,ClampToQuantum(gray),q);
1691 q+=GetPixelChannels(image);
1693 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1694 if (sync == MagickFalse)
1697 image_view=DestroyCacheView(image_view);
1698 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1699 return(MagickFalse);
1704 case HCLpColorspace:
1712 case LCHabColorspace:
1713 case LCHuvColorspace:
1717 case YCbCrColorspace:
1718 case YDbDrColorspace:
1720 case YPbPrColorspace:
1724 Transform image from source colorspace to sRGB.
1726 if (image->storage_class == PseudoClass)
1728 if (SyncImage(image,exception) == MagickFalse)
1729 return(MagickFalse);
1730 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1731 return(MagickFalse);
1733 image_view=AcquireAuthenticCacheView(image,exception);
1734 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1735 #pragma omp parallel for schedule(static,4) shared(status) \
1736 magick_threads(image,image,image->rows,1)
1738 for (y=0; y < (ssize_t) image->rows; y++)
1749 if (status == MagickFalse)
1751 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1753 if (q == (Quantum *) NULL)
1758 for (x=0; x < (ssize_t) image->columns; x++)
1768 X=QuantumScale*GetPixelRed(image,q);
1769 Y=QuantumScale*GetPixelGreen(image,q);
1770 Z=QuantumScale*GetPixelBlue(image,q);
1771 switch (image->colorspace)
1775 ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
1780 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
1783 case HCLpColorspace:
1785 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
1790 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
1795 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
1800 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
1805 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
1810 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
1815 ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
1819 case LCHabColorspace:
1821 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
1824 case LCHuvColorspace:
1826 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
1831 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
1836 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
1841 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
1844 case YCbCrColorspace:
1846 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
1849 case YDbDrColorspace:
1851 ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
1856 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
1859 case YPbPrColorspace:
1861 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
1866 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
1872 green=QuantumRange*Y;
1873 blue=QuantumRange*Z;
1877 SetPixelRed(image,ClampToQuantum(red),q);
1878 SetPixelGreen(image,ClampToQuantum(green),q);
1879 SetPixelBlue(image,ClampToQuantum(blue),q);
1880 q+=GetPixelChannels(image);
1882 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1883 if (sync == MagickFalse)
1886 image_view=DestroyCacheView(image_view);
1887 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1888 return(MagickFalse);
1908 Transform Log to sRGB colorspace.
1910 density=DisplayGamma;
1912 value=GetImageProperty(image,"gamma",exception);
1913 if (value != (const char *) NULL)
1914 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
1915 film_gamma=FilmGamma;
1916 value=GetImageProperty(image,"film-gamma",exception);
1917 if (value != (const char *) NULL)
1918 film_gamma=StringToDouble(value,(char **) NULL);
1919 reference_black=ReferenceBlack;
1920 value=GetImageProperty(image,"reference-black",exception);
1921 if (value != (const char *) NULL)
1922 reference_black=StringToDouble(value,(char **) NULL);
1923 reference_white=ReferenceWhite;
1924 value=GetImageProperty(image,"reference-white",exception);
1925 if (value != (const char *) NULL)
1926 reference_white=StringToDouble(value,(char **) NULL);
1927 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1929 if (logmap == (Quantum *) NULL)
1930 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1932 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
1934 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
1935 logmap[i]=(Quantum) 0;
1936 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
1937 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
1938 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/
1939 film_gamma)-black));
1940 for ( ; i <= (ssize_t) MaxMap; i++)
1941 logmap[i]=QuantumRange;
1942 if (image->storage_class == PseudoClass)
1944 if (SyncImage(image,exception) == MagickFalse)
1945 return(MagickFalse);
1946 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1947 return(MagickFalse);
1949 image_view=AcquireAuthenticCacheView(image,exception);
1950 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1951 #pragma omp parallel for schedule(static,4) shared(status) \
1952 magick_threads(image,image,image->rows,1)
1954 for (y=0; y < (ssize_t) image->rows; y++)
1965 if (status == MagickFalse)
1967 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1969 if (q == (Quantum *) NULL)
1974 for (x=(ssize_t) image->columns; x != 0; x--)
1981 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
1982 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
1983 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
1984 SetPixelRed(image,ClampToQuantum(red),q);
1985 SetPixelGreen(image,ClampToQuantum(green),q);
1986 SetPixelBlue(image,ClampToQuantum(blue),q);
1987 q+=GetPixelChannels(image);
1989 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1990 if (sync == MagickFalse)
1993 image_view=DestroyCacheView(image_view);
1994 logmap=(Quantum *) RelinquishMagickMemory(logmap);
1995 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1996 return(MagickFalse);
2000 case scRGBColorspace:
2003 Transform linear RGB to sRGB colorspace.
2005 if (image->storage_class == PseudoClass)
2007 if (SyncImage(image,exception) == MagickFalse)
2008 return(MagickFalse);
2009 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2010 return(MagickFalse);
2012 image_view=AcquireAuthenticCacheView(image,exception);
2013 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2014 #pragma omp parallel for schedule(static,4) shared(status) \
2015 magick_threads(image,image,image->rows,1)
2017 for (y=0; y < (ssize_t) image->rows; y++)
2028 if (status == MagickFalse)
2030 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2032 if (q == (Quantum *) NULL)
2037 for (x=(ssize_t) image->columns; x != 0; x--)
2044 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q));
2045 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q));
2046 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q));
2047 SetPixelRed(image,ClampToQuantum(red),q);
2048 SetPixelGreen(image,ClampToQuantum(green),q);
2049 SetPixelBlue(image,ClampToQuantum(blue),q);
2050 q+=GetPixelChannels(image);
2052 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2053 if (sync == MagickFalse)
2056 image_view=DestroyCacheView(image_view);
2057 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2058 return(MagickFalse);
2065 Allocate the tables.
2067 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2069 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2071 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2073 if ((x_map == (TransformPacket *) NULL) ||
2074 (y_map == (TransformPacket *) NULL) ||
2075 (z_map == (TransformPacket *) NULL))
2077 if (z_map != (TransformPacket *) NULL)
2078 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2079 if (y_map != (TransformPacket *) NULL)
2080 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2081 if (x_map != (TransformPacket *) NULL)
2082 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2083 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2086 switch (image->colorspace)
2088 case OHTAColorspace:
2091 Initialize OHTA tables:
2093 I1 = 0.33333*R+0.33334*G+0.33333*B
2094 I2 = 0.50000*R+0.00000*G-0.50000*B
2095 I3 =-0.25000*R+0.50000*G-0.25000*B
2096 R = I1+1.00000*I2-0.66668*I3
2097 G = I1+0.00000*I2+1.33333*I3
2098 B = I1-1.00000*I2-0.66668*I3
2100 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2101 through QuantumRange.
2103 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2104 #pragma omp parallel for schedule(static,4) \
2105 magick_threads(image,image,1,1)
2107 for (i=0; i <= (ssize_t) MaxMap; i++)
2109 x_map[i].x=(MagickRealType) (1.0*(double) i);
2110 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap));
2111 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2112 x_map[i].y=(MagickRealType) (1.0*(double) i);
2113 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap));
2114 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap));
2115 x_map[i].z=(MagickRealType) (1.0*(double) i);
2116 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap));
2117 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2121 case Rec601YCbCrColorspace:
2124 Initialize YCbCr tables:
2127 G = Y-0.344136*Cb-0.714136*Cr
2130 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2131 through QuantumRange.
2133 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2134 #pragma omp parallel for schedule(static,4) \
2135 magick_threads(image,image,1,1)
2137 for (i=0; i <= (ssize_t) MaxMap; i++)
2139 x_map[i].x=0.99999999999914679361*(double) i;
2140 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2141 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2142 x_map[i].y=0.99999975910502514331*(double) i;
2143 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2144 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2145 x_map[i].z=1.00000124040004623180*(double) i;
2146 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2147 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2151 case Rec709YCbCrColorspace:
2154 Initialize YCbCr tables:
2157 G = Y-0.187324*Cb-0.468124*Cr
2160 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2161 through QuantumRange.
2163 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2164 #pragma omp parallel for schedule(static,4) \
2165 magick_threads(image,image,1,1)
2167 for (i=0; i <= (ssize_t) MaxMap; i++)
2169 x_map[i].x=(MagickRealType) (1.0*i);
2170 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2171 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap));
2172 x_map[i].y=(MagickRealType) (1.0*i);
2173 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap));
2174 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap));
2175 x_map[i].z=(MagickRealType) (1.0*i);
2176 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap));
2177 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2184 Initialize YCC tables:
2187 G = Y-0.317038*C1-0.682243*C2
2190 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2192 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2193 #pragma omp parallel for schedule(static,4) \
2194 magick_threads(image,image,1,1)
2196 for (i=0; i <= (ssize_t) MaxMap; i++)
2198 x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2199 y_map[i].x=(MagickRealType) 0.0000000;
2200 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double)
2201 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2202 x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2203 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double)
2204 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2205 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double)
2206 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2207 x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2208 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double)
2209 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2210 z_map[i].z=(MagickRealType) 0.0000000;
2217 Linear conversion tables.
2219 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2220 #pragma omp parallel for schedule(static,4) \
2221 magick_threads(image,image,1,1)
2223 for (i=0; i <= (ssize_t) MaxMap; i++)
2225 x_map[i].x=(MagickRealType) (1.0*(double) i);
2226 y_map[i].x=(MagickRealType) 0.0;
2227 z_map[i].x=(MagickRealType) 0.0;
2228 x_map[i].y=(MagickRealType) 0.0;
2229 y_map[i].y=(MagickRealType) (1.0*(double) i);
2230 z_map[i].y=(MagickRealType) 0.0;
2231 x_map[i].z=(MagickRealType) 0.0;
2232 y_map[i].z=(MagickRealType) 0.0;
2233 z_map[i].z=(MagickRealType) (1.0*(double) i);
2241 switch (image->storage_class)
2247 Convert DirectClass image.
2249 image_view=AcquireAuthenticCacheView(image,exception);
2250 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2251 #pragma omp parallel for schedule(static,4) shared(status) \
2252 magick_threads(image,image,image->rows,1)
2254 for (y=0; y < (ssize_t) image->rows; y++)
2268 if (status == MagickFalse)
2270 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2272 if (q == (Quantum *) NULL)
2277 for (x=0; x < (ssize_t) image->columns; x++)
2284 red=ScaleQuantumToMap(GetPixelRed(image,q));
2285 green=ScaleQuantumToMap(GetPixelGreen(image,q));
2286 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
2287 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2288 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2289 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2290 if (image->colorspace == YCCColorspace)
2292 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2294 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2296 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2301 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2302 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2303 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2305 SetPixelRed(image,ClampToQuantum(pixel.red),q);
2306 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
2307 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
2308 q+=GetPixelChannels(image);
2310 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2311 if (sync == MagickFalse)
2313 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2318 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2319 #pragma omp critical (MagickCore_TransformsRGBImage)
2321 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
2323 if (proceed == MagickFalse)
2327 image_view=DestroyCacheView(image_view);
2333 Convert PseudoClass image.
2335 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2336 #pragma omp parallel for schedule(static,4) shared(status) \
2337 magick_threads(image,image,1,1)
2339 for (i=0; i < (ssize_t) image->colors; i++)
2349 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
2350 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
2351 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
2352 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2353 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2354 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2355 if (image->colorspace == YCCColorspace)
2357 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2359 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2361 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2366 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2367 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2368 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2370 image->colormap[i].red=(double) ClampToQuantum(pixel.red);
2371 image->colormap[i].green=(double) ClampToQuantum(pixel.green);
2372 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue);
2374 (void) SyncImage(image,exception);
2379 Relinquish resources.
2381 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2382 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2383 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2384 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2385 return(MagickFalse);