2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % CCCC OOO L OOO RRRR SSSSS PPPP AAA CCCC EEEEE %
7 % C O O L O O R R SS P P A A C E %
8 % C O O L O O RRRR SSS PPPP AAAAA C EEE %
9 % C O O L O O R R SS P A A C E %
10 % CCCC OOO LLLLL OOO R R SSSSS P A A CCCC EEEEE %
13 % MagickCore Image Colorspace Methods %
20 % Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/property.h"
44 #include "MagickCore/cache.h"
45 #include "MagickCore/cache-private.h"
46 #include "MagickCore/cache-view.h"
47 #include "MagickCore/color.h"
48 #include "MagickCore/color-private.h"
49 #include "MagickCore/colorspace.h"
50 #include "MagickCore/colorspace-private.h"
51 #include "MagickCore/exception.h"
52 #include "MagickCore/exception-private.h"
53 #include "MagickCore/image.h"
54 #include "MagickCore/image-private.h"
55 #include "MagickCore/gem.h"
56 #include "MagickCore/gem-private.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/monitor.h"
59 #include "MagickCore/monitor-private.h"
60 #include "MagickCore/pixel-accessor.h"
61 #include "MagickCore/pixel-private.h"
62 #include "MagickCore/quantize.h"
63 #include "MagickCore/quantum.h"
64 #include "MagickCore/quantum-private.h"
65 #include "MagickCore/resource_.h"
66 #include "MagickCore/string_.h"
67 #include "MagickCore/string-private.h"
68 #include "MagickCore/utility.h"
73 typedef struct _TransformPacket
84 static MagickBooleanType
85 TransformsRGBImage(Image *,ExceptionInfo *);
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 + s R G B T r a n s f o r m I m a g e %
96 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98 % sRGBTransformImage() converts the reference image from sRGB to an alternate
99 % colorspace. The transformation matrices are not the standard ones: the
100 % weights are rescaled to normalized the range of the transformed values to
101 % be [0..QuantumRange].
103 % The format of the sRGBTransformImage method is:
105 % MagickBooleanType sRGBTransformImage(Image *image,
106 % const ColorspaceType colorspace,EsceptionInfo *exception)
108 % A description of each parameter follows:
110 % o image: the image.
112 % o colorspace: the colorspace to transform the image to.
114 % o exception: return any errors or warnings in this structure.
118 static inline void ConvertRGBToCMY(const double red,const double green,
119 const double blue,double *cyan,double *magenta,double *yellow)
122 Convert RGB to CMY colorspace.
124 *cyan=QuantumScale*(QuantumRange-red);
125 *magenta=QuantumScale*(QuantumRange-green);
126 *yellow=QuantumScale*(QuantumRange-blue);
129 static inline void ConvertXYZToLMS(const double x,const double y,
130 const double z,double *L,double *M,double *S)
133 Convert XYZ to LMS colorspace.
135 *L=0.7328*x+0.4296*y-0.1624*z;
136 *M=(-0.7036*x+1.6975*y+0.0061*z);
137 *S=0.0030*x+0.0136*y+0.9834*z;
140 static void ConvertRGBToLMS(const double red,const double green,
141 const double blue,double *L,double *M,double *S)
148 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
149 ConvertXYZToLMS(X,Y,Z,L,M,S);
152 static void ConvertRGBToLab(const double red,const double green,
153 const double blue,double *L,double *a,double *b)
160 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
161 ConvertXYZToLab(X,Y,Z,L,a,b);
164 static void ConvertRGBToLuv(const double red,const double green,
165 const double blue,double *L,double *u,double *v)
172 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
173 ConvertXYZToLuv(X,Y,Z,L,u,v);
176 static void ConvertRGBToYIQ(const double red,const double green,
177 const double blue,double *Y,double *I,double *Q)
180 Convert RGB to YIQ colorspace.
182 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
183 *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5;
184 *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5;
187 static void ConvertRGBToYPbPr(const double red,const double green,
188 const double blue,double *Y,double *Pb,double *Pr)
191 Convert RGB to YPbPr colorspace.
193 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
194 *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5;
195 *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5;
198 static void ConvertRGBToYCbCr(const double red,const double green,
199 const double blue,double *Y,double *Cb,double *Cr)
202 Convert RGB to YCbCr colorspace.
204 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
207 static void ConvertRGBToYUV(const double red,const double green,
208 const double blue,double *Y,double *U,double *V)
211 Convert RGB to YUV colorspace.
213 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
214 *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5;
215 *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5;
218 static MagickBooleanType sRGBTransformImage(Image *image,
219 const ColorspaceType colorspace,ExceptionInfo *exception)
221 #define sRGBTransformImageTag "RGBTransform/Image"
246 assert(image != (Image *) NULL);
247 assert(image->signature == MagickSignature);
248 if (image->debug != MagickFalse)
249 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
250 assert(colorspace != sRGBColorspace);
251 assert(colorspace != TransparentColorspace);
252 assert(colorspace != UndefinedColorspace);
263 Convert RGB to CMYK colorspace.
265 if (image->storage_class == PseudoClass)
267 if (SyncImage(image,exception) == MagickFalse)
269 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
272 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
274 GetPixelInfo(image,&zero);
275 image_view=AcquireAuthenticCacheView(image,exception);
276 #if defined(MAGICKCORE_OPENMP_SUPPORT)
277 #pragma omp parallel for schedule(static,4) shared(status) \
278 magick_threads(image,image,image->rows,1)
280 for (y=0; y < (ssize_t) image->rows; y++)
294 if (status == MagickFalse)
296 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
298 if (q == (Quantum *) NULL)
304 for (x=0; x < (ssize_t) image->columns; x++)
306 GetPixelInfoPixel(image,q,&pixel);
307 ConvertRGBToCMYK(&pixel);
308 SetPixelInfoPixel(image,&pixel,q);
309 q+=GetPixelChannels(image);
311 sync=SyncCacheViewAuthenticPixels(image_view,exception);
312 if (sync == MagickFalse)
315 image_view=DestroyCacheView(image_view);
316 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
317 ColorSeparationMatteType;
318 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
325 Transform image from sRGB to GRAY.
327 if (image->storage_class == PseudoClass)
329 if (SyncImage(image,exception) == MagickFalse)
331 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
334 image_view=AcquireAuthenticCacheView(image,exception);
335 #if defined(MAGICKCORE_OPENMP_SUPPORT)
336 #pragma omp parallel for schedule(static,4) shared(status) \
337 magick_threads(image,image,image->rows,1)
339 for (y=0; y < (ssize_t) image->rows; y++)
350 if (status == MagickFalse)
352 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
354 if (q == (Quantum *) NULL)
359 for (x=0; x < (ssize_t) image->columns; x++)
361 SetPixelGray(image,ClampToQuantum(GetPixelIntensity(image,q)),q);
362 q+=GetPixelChannels(image);
364 sync=SyncCacheViewAuthenticPixels(image_view,exception);
365 if (sync == MagickFalse)
368 image_view=DestroyCacheView(image_view);
369 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
371 image->type=GrayscaleType;
384 case LCHabColorspace:
385 case LCHuvColorspace:
389 case YCbCrColorspace:
391 case YPbPrColorspace:
395 Transform image from sRGB to target colorspace.
397 if (image->storage_class == PseudoClass)
399 if (SyncImage(image,exception) == MagickFalse)
401 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
404 image_view=AcquireAuthenticCacheView(image,exception);
405 #if defined(MAGICKCORE_OPENMP_SUPPORT)
406 #pragma omp parallel for schedule(static,4) shared(status) \
407 magick_threads(image,image,image->rows,1)
409 for (y=0; y < (ssize_t) image->rows; y++)
420 if (status == MagickFalse)
422 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
424 if (q == (Quantum *) NULL)
429 for (x=0; x < (ssize_t) image->columns; x++)
439 red=(double) GetPixelRed(image,q);
440 green=(double) GetPixelGreen(image,q);
441 blue=(double) GetPixelBlue(image,q);
446 ConvertRGBToCMY(red,green,blue,&X,&Y,&Z);
451 ConvertRGBToHCL(red,green,blue,&X,&Y,&Z);
456 ConvertRGBToHCLp(red,green,blue,&X,&Y,&Z);
461 ConvertRGBToHSB(red,green,blue,&X,&Y,&Z);
466 ConvertRGBToHSI(red,green,blue,&X,&Y,&Z);
471 ConvertRGBToHSL(red,green,blue,&X,&Y,&Z);
476 ConvertRGBToHSV(red,green,blue,&X,&Y,&Z);
481 ConvertRGBToHWB(red,green,blue,&X,&Y,&Z);
486 ConvertRGBToLab(red,green,blue,&X,&Y,&Z);
490 case LCHabColorspace:
492 ConvertRGBToLCHab(red,green,blue,&X,&Y,&Z);
495 case LCHuvColorspace:
497 ConvertRGBToLCHuv(red,green,blue,&X,&Y,&Z);
502 ConvertRGBToLMS(red,green,blue,&X,&Y,&Z);
507 ConvertRGBToLuv(red,green,blue,&X,&Y,&Z);
512 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
515 case YCbCrColorspace:
517 ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z);
522 ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z);
525 case YPbPrColorspace:
527 ConvertRGBToYPbPr(red,green,blue,&X,&Y,&Z);
532 ConvertRGBToYUV(red,green,blue,&X,&Y,&Z);
538 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
539 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
540 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q);
541 q+=GetPixelChannels(image);
543 sync=SyncCacheViewAuthenticPixels(image_view,exception);
544 if (sync == MagickFalse)
547 image_view=DestroyCacheView(image_view);
548 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
554 #define DisplayGamma (1.0/1.7)
555 #define FilmGamma 0.6
556 #define ReferenceBlack 95.0
557 #define ReferenceWhite 685.0
574 Transform RGB to Log colorspace.
576 density=DisplayGamma;
578 value=GetImageProperty(image,"gamma",exception);
579 if (value != (const char *) NULL)
580 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
581 film_gamma=FilmGamma;
582 value=GetImageProperty(image,"film-gamma",exception);
583 if (value != (const char *) NULL)
584 film_gamma=StringToDouble(value,(char **) NULL);
585 reference_black=ReferenceBlack;
586 value=GetImageProperty(image,"reference-black",exception);
587 if (value != (const char *) NULL)
588 reference_black=StringToDouble(value,(char **) NULL);
589 reference_white=ReferenceWhite;
590 value=GetImageProperty(image,"reference-white",exception);
591 if (value != (const char *) NULL)
592 reference_white=StringToDouble(value,(char **) NULL);
593 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
595 if (logmap == (Quantum *) NULL)
596 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
598 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
600 #if defined(MAGICKCORE_OPENMP_SUPPORT)
601 #pragma omp parallel for schedule(static,4) \
602 magick_threads(image,image,1,1)
604 for (i=0; i <= (ssize_t) MaxMap; i++)
605 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+
606 log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002/
607 film_gamma))/1024.0));
608 image_view=AcquireAuthenticCacheView(image,exception);
609 #if defined(MAGICKCORE_OPENMP_SUPPORT)
610 #pragma omp parallel for schedule(static,4) shared(status) \
611 magick_threads(image,image,image->rows,1)
613 for (y=0; y < (ssize_t) image->rows; y++)
624 if (status == MagickFalse)
626 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
628 if (q == (Quantum *) NULL)
633 for (x=(ssize_t) image->columns; x != 0; x--)
640 red=(double) GetPixelRed(image,q);
641 green=(double) GetPixelGreen(image,q);
642 blue=(double) GetPixelBlue(image,q);
643 SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q);
644 SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))],
646 SetPixelBlue(image,logmap[ScaleQuantumToMap(ClampToQuantum(blue))],q);
647 q+=GetPixelChannels(image);
649 sync=SyncCacheViewAuthenticPixels(image_view,exception);
650 if (sync == MagickFalse)
653 image_view=DestroyCacheView(image_view);
654 logmap=(Quantum *) RelinquishMagickMemory(logmap);
655 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
660 case scRGBColorspace:
663 Transform image from sRGB to linear RGB.
665 if (image->storage_class == PseudoClass)
667 if (SyncImage(image,exception) == MagickFalse)
669 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
672 image_view=AcquireAuthenticCacheView(image,exception);
673 #if defined(MAGICKCORE_OPENMP_SUPPORT)
674 #pragma omp parallel for schedule(static,4) shared(status) \
675 magick_threads(image,image,image->rows,1)
677 for (y=0; y < (ssize_t) image->rows; y++)
688 if (status == MagickFalse)
690 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
692 if (q == (Quantum *) NULL)
697 for (x=0; x < (ssize_t) image->columns; x++)
704 red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
705 green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
706 blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
707 SetPixelRed(image,ClampToQuantum(red),q);
708 SetPixelGreen(image,ClampToQuantum(green),q);
709 SetPixelBlue(image,ClampToQuantum(blue),q);
710 q+=GetPixelChannels(image);
712 sync=SyncCacheViewAuthenticPixels(image_view,exception);
713 if (sync == MagickFalse)
716 image_view=DestroyCacheView(image_view);
717 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
727 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
729 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
731 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
733 if ((x_map == (TransformPacket *) NULL) ||
734 (y_map == (TransformPacket *) NULL) ||
735 (z_map == (TransformPacket *) NULL))
736 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
738 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
744 Initialize OHTA tables:
746 I1 = 0.33333*R+0.33334*G+0.33333*B
747 I2 = 0.50000*R+0.00000*G-0.50000*B
748 I3 =-0.25000*R+0.50000*G-0.25000*B
750 I and Q, normally -0.5 through 0.5, are normalized to the range 0
751 through QuantumRange.
753 primary_info.y=(double) (MaxMap+1.0)/2.0;
754 primary_info.z=(double) (MaxMap+1.0)/2.0;
755 #if defined(MAGICKCORE_OPENMP_SUPPORT)
756 #pragma omp parallel for schedule(static,4) \
757 magick_threads(image,image,1,1)
759 for (i=0; i <= (ssize_t) MaxMap; i++)
761 x_map[i].x=(MagickRealType) (0.33333*(double) i);
762 y_map[i].x=(MagickRealType) (0.33334*(double) i);
763 z_map[i].x=(MagickRealType) (0.33333*(double) i);
764 x_map[i].y=(MagickRealType) (0.50000*(double) i);
765 y_map[i].y=(MagickRealType) (0.00000*(double) i);
766 z_map[i].y=(MagickRealType) (-0.50000*(double) i);
767 x_map[i].z=(MagickRealType) (-0.25000*(double) i);
768 y_map[i].z=(MagickRealType) (0.50000*(double) i);
769 z_map[i].z=(MagickRealType) (-0.25000*(double) i);
773 case Rec601YCbCrColorspace:
776 Initialize YCbCr tables (ITU-R BT.601):
778 Y = 0.2988390*R+0.5868110*G+0.1143500*B
779 Cb= -0.1687367*R-0.3312640*G+0.5000000*B
780 Cr= 0.5000000*R-0.4186880*G-0.0813120*B
782 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
783 through QuantumRange.
785 primary_info.y=(double) (MaxMap+1.0)/2.0;
786 primary_info.z=(double) (MaxMap+1.0)/2.0;
787 #if defined(MAGICKCORE_OPENMP_SUPPORT)
788 #pragma omp parallel for schedule(static,4) \
789 magick_threads(image,image,1,1)
791 for (i=0; i <= (ssize_t) MaxMap; i++)
793 x_map[i].x=(MagickRealType) (0.298839*(double) i);
794 y_map[i].x=(MagickRealType) (0.586811*(double) i);
795 z_map[i].x=(MagickRealType) (0.114350*(double) i);
796 x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
797 y_map[i].y=(MagickRealType) (-0.331264*(double) i);
798 z_map[i].y=(MagickRealType) (0.500000*(double) i);
799 x_map[i].z=(MagickRealType) (0.500000*(double) i);
800 y_map[i].z=(MagickRealType) (-0.418688*(double) i);
801 z_map[i].z=(MagickRealType) (-0.081312*(double) i);
805 case Rec709YCbCrColorspace:
808 Initialize YCbCr tables (ITU-R BT.709):
810 Y = 0.212600*R+0.715200*G+0.072200*B
811 Cb= -0.114572*R-0.385428*G+0.500000*B
812 Cr= 0.500000*R-0.454153*G-0.045847*B
814 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
815 through QuantumRange.
817 primary_info.y=(double) (MaxMap+1.0)/2.0;
818 primary_info.z=(double) (MaxMap+1.0)/2.0;
819 #if defined(MAGICKCORE_OPENMP_SUPPORT)
820 #pragma omp parallel for schedule(static,4) \
821 magick_threads(image,image,1,1)
823 for (i=0; i <= (ssize_t) MaxMap; i++)
825 x_map[i].x=(MagickRealType) (0.212600*(double) i);
826 y_map[i].x=(MagickRealType) (0.715200*(double) i);
827 z_map[i].x=(MagickRealType) (0.072200*(double) i);
828 x_map[i].y=(MagickRealType) (-0.114572*(double) i);
829 y_map[i].y=(MagickRealType) (-0.385428*(double) i);
830 z_map[i].y=(MagickRealType) (0.500000*(double) i);
831 x_map[i].z=(MagickRealType) (0.500000*(double) i);
832 y_map[i].z=(MagickRealType) (-0.454153*(double) i);
833 z_map[i].z=(MagickRealType) (-0.045847*(double) i);
840 Initialize YCC tables:
842 Y = 0.298839*R+0.586811*G+0.114350*B
843 C1= -0.298839*R-0.586811*G+0.88600*B
844 C2= 0.70100*R-0.586811*G-0.114350*B
846 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
848 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
849 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
850 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
852 x_map[i].x=0.003962014134275617*i;
853 y_map[i].x=0.007778268551236748*i;
854 z_map[i].x=0.001510600706713781*i;
855 x_map[i].y=(-0.002426619775463276)*i;
856 y_map[i].y=(-0.004763965913702149)*i;
857 z_map[i].y=0.007190585689165425*i;
858 x_map[i].z=0.006927257754597858*i;
859 y_map[i].z=(-0.005800713697502058)*i;
860 z_map[i].z=(-0.0011265440570958)*i;
862 for ( ; i <= (ssize_t) MaxMap; i++)
864 x_map[i].x=0.2201118963486454*(1.099*i-0.099);
865 y_map[i].x=0.4321260306242638*(1.099*i-0.099);
866 z_map[i].x=0.08392226148409894*(1.099*i-0.099);
867 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
868 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
869 z_map[i].y=0.3994769827314126*(1.099*i-0.099);
870 x_map[i].z=0.3848476530332144*(1.099*i-0.099);
871 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
872 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
879 Linear conversion tables.
881 #if defined(MAGICKCORE_OPENMP_SUPPORT)
882 #pragma omp parallel for schedule(static,4) \
883 magick_threads(image,image,1,1)
885 for (i=0; i <= (ssize_t) MaxMap; i++)
887 x_map[i].x=(MagickRealType) (1.0*(double) i);
888 y_map[i].x=(MagickRealType) 0.0;
889 z_map[i].x=(MagickRealType) 0.0;
890 x_map[i].y=(MagickRealType) 0.0;
891 y_map[i].y=(MagickRealType) (1.0*(double) i);
892 z_map[i].y=(MagickRealType) 0.0;
893 x_map[i].z=(MagickRealType) 0.0;
894 y_map[i].z=(MagickRealType) 0.0;
895 z_map[i].z=(MagickRealType) (1.0*(double) i);
903 switch (image->storage_class)
909 Convert DirectClass image.
911 image_view=AcquireAuthenticCacheView(image,exception);
912 #if defined(MAGICKCORE_OPENMP_SUPPORT)
913 #pragma omp parallel for schedule(static,4) shared(status) \
914 magick_threads(image,image,image->rows,1)
916 for (y=0; y < (ssize_t) image->rows; y++)
930 register unsigned int
935 if (status == MagickFalse)
937 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
939 if (q == (Quantum *) NULL)
944 for (x=0; x < (ssize_t) image->columns; x++)
946 red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
947 GetPixelRed(image,q)));
948 green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
949 GetPixelGreen(image,q)));
950 blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
951 GetPixelBlue(image,q)));
952 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
954 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
956 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
958 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
959 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
960 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
961 q+=GetPixelChannels(image);
963 sync=SyncCacheViewAuthenticPixels(image_view,exception);
964 if (sync == MagickFalse)
966 if (image->progress_monitor != (MagickProgressMonitor) NULL)
971 #if defined(MAGICKCORE_OPENMP_SUPPORT)
972 #pragma omp critical (MagickCore_sRGBTransformImage)
974 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
976 if (proceed == MagickFalse)
980 image_view=DestroyCacheView(image_view);
985 register unsigned int
991 Convert PseudoClass image.
993 for (i=0; i < (ssize_t) image->colors; i++)
998 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
999 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
1000 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
1001 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1002 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1003 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1004 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
1005 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
1006 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
1008 (void) SyncImage(image,exception);
1013 Relinquish resources.
1015 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1016 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1017 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1018 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1019 return(MagickFalse);
1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1028 % S e t I m a g e C o l o r s p a c e %
1032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034 % SetImageColorspace() sets the colorspace member of the Image structure.
1036 % The format of the SetImageColorspace method is:
1038 % MagickBooleanType SetImageColorspace(Image *image,
1039 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1041 % A description of each parameter follows:
1043 % o image: the image.
1045 % o colorspace: the colorspace.
1047 % o exception: return any errors or warnings in this structure.
1050 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1051 const ColorspaceType colorspace,ExceptionInfo *exception)
1053 if (image->colorspace == colorspace)
1055 image->colorspace=colorspace;
1056 image->rendering_intent=UndefinedIntent;
1058 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1059 if (IsGrayColorspace(colorspace) != MagickFalse)
1061 if ((image->intensity != Rec601LuminancePixelIntensityMethod) &&
1062 (image->intensity != Rec709LuminancePixelIntensityMethod) &&
1063 (image->intensity != UndefinedPixelIntensityMethod))
1064 image->gamma=1.000/2.200;
1065 image->type=GrayscaleType;
1068 if (IssRGBColorspace(colorspace) != MagickFalse)
1069 image->gamma=1.000/2.200;
1070 if (image->gamma == (1.000/2.200))
1072 image->rendering_intent=PerceptualIntent;
1073 image->gamma=1.000/2.200;
1074 image->chromaticity.red_primary.x=0.6400;
1075 image->chromaticity.red_primary.y=0.3300;
1076 image->chromaticity.red_primary.z=0.0300;
1077 image->chromaticity.green_primary.x=0.3000;
1078 image->chromaticity.green_primary.y=0.6000;
1079 image->chromaticity.green_primary.z=0.1000;
1080 image->chromaticity.blue_primary.x=0.1500;
1081 image->chromaticity.blue_primary.y=0.0600;
1082 image->chromaticity.blue_primary.z=0.7900;
1083 image->chromaticity.white_point.x=0.3127;
1084 image->chromaticity.white_point.y=0.3290;
1085 image->chromaticity.white_point.z=0.3583;
1087 if (IsGrayColorspace(colorspace) != MagickFalse)
1088 image->type=GrayscaleType;
1089 return(SyncImagePixelCache(image,exception));
1093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1097 % T r a n s f o r m I m a g e C o l o r s p a c e %
1101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 % TransformImageColorspace() transforms an image colorspace, changing the
1104 % image data to reflect the new colorspace.
1106 % The format of the TransformImageColorspace method is:
1108 % MagickBooleanType TransformImageColorspace(Image *image,
1109 % const ColorspaceType colorspace,ExceptionInfo *exception)
1111 % A description of each parameter follows:
1113 % o image: the image.
1115 % o colorspace: the colorspace.
1117 % o exception: return any errors or warnings in this structure.
1120 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1121 const ColorspaceType colorspace,ExceptionInfo *exception)
1126 assert(image != (Image *) NULL);
1127 assert(image->signature == MagickSignature);
1128 if (image->debug != MagickFalse)
1129 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1130 if (colorspace == UndefinedColorspace)
1131 return(SetImageColorspace(image,colorspace,exception));
1132 if (image->colorspace == colorspace)
1133 return(MagickTrue); /* same colorspace: no op */
1135 Convert the reference image from an alternate colorspace to sRGB.
1137 (void) DeleteImageProfile(image,"icc");
1138 (void) DeleteImageProfile(image,"icm");
1139 if (IssRGBColorspace(colorspace) != MagickFalse)
1140 return(TransformsRGBImage(image,exception));
1142 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1143 status=TransformsRGBImage(image,exception);
1144 if (status == MagickFalse)
1147 Convert the reference image from sRGB to an alternate colorspace.
1149 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1159 + T r a n s f o r m s R G B I m a g e %
1163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1165 % TransformsRGBImage() converts the reference image from an alternate
1166 % colorspace to sRGB. The transformation matrices are not the standard ones:
1167 % the weights are rescaled to normalize the range of the transformed values
1168 % to be [0..QuantumRange].
1170 % The format of the TransformsRGBImage method is:
1172 % MagickBooleanType TransformsRGBImage(Image *image,
1173 % ExceptionInfo *exception)
1175 % A description of each parameter follows:
1177 % o image: the image.
1179 % o exception: return any errors or warnings in this structure.
1183 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1184 const double yellow,double *red,double *green,double *blue)
1187 Convert CMY to RGB colorspace.
1189 *red=QuantumRange*(1.0-cyan);
1190 *green=QuantumRange*(1.0-magenta);
1191 *blue=QuantumRange*(1.0-yellow);
1194 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1195 double *X,double *Y,double *Z)
1197 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1198 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1199 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1202 static inline void ConvertLMSToRGB(const double L,const double M,
1203 const double S,double *red,double *green,double *blue)
1210 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1211 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1214 static inline void ConvertLuvToRGB(const double L,const double u,
1215 const double v,double *red,double *green,double *blue)
1222 ConvertLuvToXYZ(100.0*L,(354.0*u-134.0),262.0*v-140.0,&X,&Y,&Z);
1223 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1226 static inline ssize_t RoundToYCC(const double value)
1230 if (value >= 1388.0)
1232 return((ssize_t) (value+0.5));
1235 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1237 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1238 (QuantumRange-pixel->black)+pixel->black)));
1239 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1240 (QuantumRange-pixel->black)+pixel->black)));
1241 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1242 (QuantumRange-pixel->black)+pixel->black)));
1245 static inline void ConvertLabToRGB(const double L,const double a,
1246 const double b,double *red,double *green,double *blue)
1253 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1254 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1257 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1258 double *red,double *green,double *blue)
1261 Convert YPbPr to RGB colorspace.
1263 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
1264 1.4019995886561440468*(Pr-0.5));
1265 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
1266 0.71413649331646789076*(Pr-0.5));
1267 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
1268 2.1453384174593273e-06*(Pr-0.5));
1271 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1272 const double Cr,double *red,double *green,double *blue)
1275 Convert YCbCr to RGB colorspace.
1277 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1280 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1281 double *red,double *green,double *blue)
1284 Convert YIQ to RGB colorspace.
1286 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
1288 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
1290 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
1294 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1295 double *red,double *green,double *blue)
1298 Convert YUV to RGB colorspace.
1300 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
1302 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
1304 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
1308 static MagickBooleanType TransformsRGBImage(Image *image,
1309 ExceptionInfo *exception)
1311 #define TransformsRGBImageTag "Transform/Image"
1316 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1317 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1318 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1319 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1320 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1321 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1322 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1323 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1324 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1325 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1326 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1327 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1328 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1329 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1330 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1331 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1332 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1333 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1334 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1335 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1336 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1337 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1338 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1339 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1340 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1341 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1342 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1343 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1344 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1345 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1346 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1347 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1348 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1349 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1350 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1351 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1352 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1353 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1354 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1355 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1356 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1357 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1358 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1359 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1360 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1361 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1362 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1363 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1364 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1365 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1366 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1367 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1368 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1369 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1370 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1371 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1372 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1373 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1374 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1375 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1376 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1377 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1378 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1379 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1380 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1381 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1382 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1383 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1384 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1385 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1386 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1387 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1388 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1389 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1390 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1391 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1392 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1393 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1394 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1395 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1396 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1397 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1398 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1399 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1400 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1401 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1402 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1403 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1404 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1405 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1406 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1407 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1408 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1409 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1410 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1411 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1412 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1413 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1414 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1415 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1416 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1417 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1418 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1419 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1420 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1421 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1422 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1423 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1424 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1425 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1426 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1427 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1428 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1429 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1430 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1431 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1432 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1433 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1434 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1435 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1436 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1437 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1438 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1439 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1440 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1441 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1442 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1443 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1444 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1445 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1446 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1447 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1448 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1449 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1450 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1451 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1452 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1453 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1454 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1455 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1456 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1457 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1458 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1459 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1460 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1461 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1462 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1463 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1464 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1465 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1466 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1467 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1468 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1469 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1470 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1471 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1472 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1473 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1474 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1475 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1476 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1477 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1478 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1479 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1480 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1481 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1482 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1483 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1484 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1485 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1486 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1487 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1488 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1489 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1490 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1491 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1492 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1493 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1494 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1495 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1496 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1497 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1498 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1499 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1500 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1501 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1502 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1503 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1504 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1505 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1506 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1507 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1508 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1509 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1510 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1511 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1512 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1513 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1514 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1515 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1516 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1517 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1518 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1519 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1520 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1521 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1522 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1523 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1524 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1525 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1526 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1527 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1528 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1529 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1530 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1531 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1532 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1533 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1534 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1535 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1536 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1537 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1538 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1539 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1540 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1541 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1542 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1543 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1544 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1545 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1546 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1547 0.998559f, 0.999280f, 1.000000f
1570 assert(image != (Image *) NULL);
1571 assert(image->signature == MagickSignature);
1572 if (image->debug != MagickFalse)
1573 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1576 switch (image->colorspace)
1578 case CMYKColorspace:
1584 Transform image from CMYK to sRGB.
1586 if (image->storage_class == PseudoClass)
1588 if (SyncImage(image,exception) == MagickFalse)
1589 return(MagickFalse);
1590 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1591 return(MagickFalse);
1593 GetPixelInfo(image,&zero);
1594 image_view=AcquireAuthenticCacheView(image,exception);
1595 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1596 #pragma omp parallel for schedule(static,4) shared(status) \
1597 magick_threads(image,image,image->rows,1)
1599 for (y=0; y < (ssize_t) image->rows; y++)
1613 if (status == MagickFalse)
1615 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1617 if (q == (Quantum *) NULL)
1623 for (x=0; x < (ssize_t) image->columns; x++)
1625 GetPixelInfoPixel(image,q,&pixel);
1626 ConvertCMYKToRGB(&pixel);
1627 SetPixelInfoPixel(image,&pixel,q);
1628 q+=GetPixelChannels(image);
1630 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1631 if (sync == MagickFalse)
1634 image_view=DestroyCacheView(image_view);
1635 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1636 return(MagickFalse);
1639 case GRAYColorspace:
1642 Transform linear GRAY to sRGB colorspace.
1644 if (image->storage_class == PseudoClass)
1646 if (SyncImage(image,exception) == MagickFalse)
1647 return(MagickFalse);
1648 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1649 return(MagickFalse);
1651 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1652 return(MagickFalse);
1653 image_view=AcquireAuthenticCacheView(image,exception);
1654 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1655 #pragma omp parallel for schedule(static,4) shared(status) \
1656 magick_threads(image,image,image->rows,1)
1658 for (y=0; y < (ssize_t) image->rows; y++)
1669 if (status == MagickFalse)
1671 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1673 if (q == (Quantum *) NULL)
1678 for (x=(ssize_t) image->columns; x != 0; x--)
1683 gray=EncodePixelGamma((MagickRealType) GetPixelGray(image,q));
1684 SetPixelRed(image,ClampToQuantum(gray),q);
1685 SetPixelGreen(image,ClampToQuantum(gray),q);
1686 SetPixelBlue(image,ClampToQuantum(gray),q);
1687 q+=GetPixelChannels(image);
1689 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1690 if (sync == MagickFalse)
1693 image_view=DestroyCacheView(image_view);
1694 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1695 return(MagickFalse);
1700 case HCLpColorspace:
1708 case LCHabColorspace:
1709 case LCHuvColorspace:
1713 case YCbCrColorspace:
1715 case YPbPrColorspace:
1719 Transform image from source colorspace to sRGB.
1721 if (image->storage_class == PseudoClass)
1723 if (SyncImage(image,exception) == MagickFalse)
1724 return(MagickFalse);
1725 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1726 return(MagickFalse);
1728 image_view=AcquireAuthenticCacheView(image,exception);
1729 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1730 #pragma omp parallel for schedule(static,4) shared(status) \
1731 magick_threads(image,image,image->rows,1)
1733 for (y=0; y < (ssize_t) image->rows; y++)
1744 if (status == MagickFalse)
1746 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1748 if (q == (Quantum *) NULL)
1753 for (x=0; x < (ssize_t) image->columns; x++)
1763 X=QuantumScale*GetPixelRed(image,q);
1764 Y=QuantumScale*GetPixelGreen(image,q);
1765 Z=QuantumScale*GetPixelBlue(image,q);
1766 switch (image->colorspace)
1770 ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
1775 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
1778 case HCLpColorspace:
1780 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
1785 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
1790 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
1795 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
1800 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
1805 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
1810 ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
1814 case LCHabColorspace:
1816 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
1819 case LCHuvColorspace:
1821 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
1826 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
1831 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
1836 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
1839 case YCbCrColorspace:
1841 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
1846 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
1849 case YPbPrColorspace:
1851 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
1856 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
1862 SetPixelRed(image,ClampToQuantum(red),q);
1863 SetPixelGreen(image,ClampToQuantum(green),q);
1864 SetPixelBlue(image,ClampToQuantum(blue),q);
1865 q+=GetPixelChannels(image);
1867 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1868 if (sync == MagickFalse)
1871 image_view=DestroyCacheView(image_view);
1872 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1873 return(MagickFalse);
1893 Transform Log to sRGB colorspace.
1895 density=DisplayGamma;
1897 value=GetImageProperty(image,"gamma",exception);
1898 if (value != (const char *) NULL)
1899 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
1900 film_gamma=FilmGamma;
1901 value=GetImageProperty(image,"film-gamma",exception);
1902 if (value != (const char *) NULL)
1903 film_gamma=StringToDouble(value,(char **) NULL);
1904 reference_black=ReferenceBlack;
1905 value=GetImageProperty(image,"reference-black",exception);
1906 if (value != (const char *) NULL)
1907 reference_black=StringToDouble(value,(char **) NULL);
1908 reference_white=ReferenceWhite;
1909 value=GetImageProperty(image,"reference-white",exception);
1910 if (value != (const char *) NULL)
1911 reference_white=StringToDouble(value,(char **) NULL);
1912 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1914 if (logmap == (Quantum *) NULL)
1915 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1917 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
1919 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
1920 logmap[i]=(Quantum) 0;
1921 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
1922 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
1923 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/
1924 film_gamma)-black));
1925 for ( ; i <= (ssize_t) MaxMap; i++)
1926 logmap[i]=QuantumRange;
1927 if (image->storage_class == PseudoClass)
1929 if (SyncImage(image,exception) == MagickFalse)
1930 return(MagickFalse);
1931 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1932 return(MagickFalse);
1934 image_view=AcquireAuthenticCacheView(image,exception);
1935 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1936 #pragma omp parallel for schedule(static,4) shared(status) \
1937 magick_threads(image,image,image->rows,1)
1939 for (y=0; y < (ssize_t) image->rows; y++)
1950 if (status == MagickFalse)
1952 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1954 if (q == (Quantum *) NULL)
1959 for (x=(ssize_t) image->columns; x != 0; x--)
1966 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
1967 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
1968 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
1969 SetPixelRed(image,ClampToQuantum(red),q);
1970 SetPixelGreen(image,ClampToQuantum(green),q);
1971 SetPixelBlue(image,ClampToQuantum(blue),q);
1972 q+=GetPixelChannels(image);
1974 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1975 if (sync == MagickFalse)
1978 image_view=DestroyCacheView(image_view);
1979 logmap=(Quantum *) RelinquishMagickMemory(logmap);
1980 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1981 return(MagickFalse);
1985 case scRGBColorspace:
1988 Transform linear RGB to sRGB colorspace.
1990 if (image->storage_class == PseudoClass)
1992 if (SyncImage(image,exception) == MagickFalse)
1993 return(MagickFalse);
1994 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1995 return(MagickFalse);
1997 image_view=AcquireAuthenticCacheView(image,exception);
1998 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1999 #pragma omp parallel for schedule(static,4) shared(status) \
2000 magick_threads(image,image,image->rows,1)
2002 for (y=0; y < (ssize_t) image->rows; y++)
2013 if (status == MagickFalse)
2015 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2017 if (q == (Quantum *) NULL)
2022 for (x=(ssize_t) image->columns; x != 0; x--)
2029 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q));
2030 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q));
2031 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q));
2032 SetPixelRed(image,ClampToQuantum(red),q);
2033 SetPixelGreen(image,ClampToQuantum(green),q);
2034 SetPixelBlue(image,ClampToQuantum(blue),q);
2035 q+=GetPixelChannels(image);
2037 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2038 if (sync == MagickFalse)
2041 image_view=DestroyCacheView(image_view);
2042 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2043 return(MagickFalse);
2050 Allocate the tables.
2052 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2054 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2056 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2058 if ((x_map == (TransformPacket *) NULL) ||
2059 (y_map == (TransformPacket *) NULL) ||
2060 (z_map == (TransformPacket *) NULL))
2062 if (z_map != (TransformPacket *) NULL)
2063 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2064 if (y_map != (TransformPacket *) NULL)
2065 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2066 if (x_map != (TransformPacket *) NULL)
2067 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2068 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2071 switch (image->colorspace)
2073 case OHTAColorspace:
2076 Initialize OHTA tables:
2078 I1 = 0.33333*R+0.33334*G+0.33333*B
2079 I2 = 0.50000*R+0.00000*G-0.50000*B
2080 I3 =-0.25000*R+0.50000*G-0.25000*B
2081 R = I1+1.00000*I2-0.66668*I3
2082 G = I1+0.00000*I2+1.33333*I3
2083 B = I1-1.00000*I2-0.66668*I3
2085 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2086 through QuantumRange.
2088 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2089 #pragma omp parallel for schedule(static,4) \
2090 magick_threads(image,image,1,1)
2092 for (i=0; i <= (ssize_t) MaxMap; i++)
2094 x_map[i].x=(MagickRealType) (1.0*(double) i);
2095 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap));
2096 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2097 x_map[i].y=(MagickRealType) (1.0*(double) i);
2098 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap));
2099 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap));
2100 x_map[i].z=(MagickRealType) (1.0*(double) i);
2101 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap));
2102 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2106 case Rec601YCbCrColorspace:
2109 Initialize YCbCr tables:
2112 G = Y-0.344136*Cb-0.714136*Cr
2115 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2116 through QuantumRange.
2118 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2119 #pragma omp parallel for schedule(static,4) \
2120 magick_threads(image,image,1,1)
2122 for (i=0; i <= (ssize_t) MaxMap; i++)
2124 x_map[i].x=0.99999999999914679361*(double) i;
2125 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2126 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2127 x_map[i].y=0.99999975910502514331*(double) i;
2128 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2129 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2130 x_map[i].z=1.00000124040004623180*(double) i;
2131 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2132 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2136 case Rec709YCbCrColorspace:
2139 Initialize YCbCr tables:
2142 G = Y-0.187324*Cb-0.468124*Cr
2145 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2146 through QuantumRange.
2148 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2149 #pragma omp parallel for schedule(static,4) \
2150 magick_threads(image,image,1,1)
2152 for (i=0; i <= (ssize_t) MaxMap; i++)
2154 x_map[i].x=(MagickRealType) (1.0*i);
2155 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2156 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap));
2157 x_map[i].y=(MagickRealType) (1.0*i);
2158 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap));
2159 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap));
2160 x_map[i].z=(MagickRealType) (1.0*i);
2161 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap));
2162 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2169 Initialize YCC tables:
2172 G = Y-0.317038*C1-0.682243*C2
2175 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2177 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2178 #pragma omp parallel for schedule(static,4) \
2179 magick_threads(image,image,1,1)
2181 for (i=0; i <= (ssize_t) MaxMap; i++)
2183 x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2184 y_map[i].x=(MagickRealType) 0.0000000;
2185 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double)
2186 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2187 x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2188 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double)
2189 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2190 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double)
2191 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2192 x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2193 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double)
2194 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2195 z_map[i].z=(MagickRealType) 0.0000000;
2202 Linear conversion tables.
2204 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2205 #pragma omp parallel for schedule(static,4) \
2206 magick_threads(image,image,1,1)
2208 for (i=0; i <= (ssize_t) MaxMap; i++)
2210 x_map[i].x=(MagickRealType) (1.0*(double) i);
2211 y_map[i].x=(MagickRealType) 0.0;
2212 z_map[i].x=(MagickRealType) 0.0;
2213 x_map[i].y=(MagickRealType) 0.0;
2214 y_map[i].y=(MagickRealType) (1.0*(double) i);
2215 z_map[i].y=(MagickRealType) 0.0;
2216 x_map[i].z=(MagickRealType) 0.0;
2217 y_map[i].z=(MagickRealType) 0.0;
2218 z_map[i].z=(MagickRealType) (1.0*(double) i);
2226 switch (image->storage_class)
2232 Convert DirectClass image.
2234 image_view=AcquireAuthenticCacheView(image,exception);
2235 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2236 #pragma omp parallel for schedule(static,4) shared(status) \
2237 magick_threads(image,image,image->rows,1)
2239 for (y=0; y < (ssize_t) image->rows; y++)
2253 if (status == MagickFalse)
2255 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2257 if (q == (Quantum *) NULL)
2262 for (x=0; x < (ssize_t) image->columns; x++)
2269 red=ScaleQuantumToMap(GetPixelRed(image,q));
2270 green=ScaleQuantumToMap(GetPixelGreen(image,q));
2271 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
2272 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2273 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2274 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2275 if (image->colorspace == YCCColorspace)
2277 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2279 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2281 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2286 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2287 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2288 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2290 SetPixelRed(image,ClampToQuantum(pixel.red),q);
2291 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
2292 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
2293 q+=GetPixelChannels(image);
2295 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2296 if (sync == MagickFalse)
2298 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2303 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2304 #pragma omp critical (MagickCore_TransformsRGBImage)
2306 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
2308 if (proceed == MagickFalse)
2312 image_view=DestroyCacheView(image_view);
2318 Convert PseudoClass image.
2320 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2321 #pragma omp parallel for schedule(static,4) shared(status) \
2322 magick_threads(image,image,1,1)
2324 for (i=0; i < (ssize_t) image->colors; i++)
2334 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
2335 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
2336 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
2337 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2338 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2339 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2340 if (image->colorspace == YCCColorspace)
2342 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2344 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2346 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2351 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2352 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2353 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2355 image->colormap[i].red=(double) ClampToQuantum(pixel.red);
2356 image->colormap[i].green=(double) ClampToQuantum(pixel.green);
2357 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue);
2359 (void) SyncImage(image,exception);
2364 Relinquish resources.
2366 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2367 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2368 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2369 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2370 return(MagickFalse);