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)
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 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
535 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
536 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q);
537 q+=GetPixelChannels(image);
539 sync=SyncCacheViewAuthenticPixels(image_view,exception);
540 if (sync == MagickFalse)
543 image_view=DestroyCacheView(image_view);
544 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
550 #define DisplayGamma (1.0/1.7)
551 #define FilmGamma 0.6
552 #define ReferenceBlack 95.0
553 #define ReferenceWhite 685.0
570 Transform RGB to Log colorspace.
572 density=DisplayGamma;
574 value=GetImageProperty(image,"gamma",exception);
575 if (value != (const char *) NULL)
576 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
577 film_gamma=FilmGamma;
578 value=GetImageProperty(image,"film-gamma",exception);
579 if (value != (const char *) NULL)
580 film_gamma=StringToDouble(value,(char **) NULL);
581 reference_black=ReferenceBlack;
582 value=GetImageProperty(image,"reference-black",exception);
583 if (value != (const char *) NULL)
584 reference_black=StringToDouble(value,(char **) NULL);
585 reference_white=ReferenceWhite;
586 value=GetImageProperty(image,"reference-white",exception);
587 if (value != (const char *) NULL)
588 reference_white=StringToDouble(value,(char **) NULL);
589 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
591 if (logmap == (Quantum *) NULL)
592 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
594 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
596 #if defined(MAGICKCORE_OPENMP_SUPPORT)
597 #pragma omp parallel for schedule(static,4) \
598 magick_threads(image,image,1,1)
600 for (i=0; i <= (ssize_t) MaxMap; i++)
601 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+
602 log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002/
603 film_gamma))/1024.0));
604 image_view=AcquireAuthenticCacheView(image,exception);
605 #if defined(MAGICKCORE_OPENMP_SUPPORT)
606 #pragma omp parallel for schedule(static,4) shared(status) \
607 magick_threads(image,image,image->rows,1)
609 for (y=0; y < (ssize_t) image->rows; y++)
620 if (status == MagickFalse)
622 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
624 if (q == (Quantum *) NULL)
629 for (x=(ssize_t) image->columns; x != 0; x--)
636 red=(double) GetPixelRed(image,q);
637 green=(double) GetPixelGreen(image,q);
638 blue=(double) GetPixelBlue(image,q);
639 SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q);
640 SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))],
642 SetPixelBlue(image,logmap[ScaleQuantumToMap(ClampToQuantum(blue))],q);
643 q+=GetPixelChannels(image);
645 sync=SyncCacheViewAuthenticPixels(image_view,exception);
646 if (sync == MagickFalse)
649 image_view=DestroyCacheView(image_view);
650 logmap=(Quantum *) RelinquishMagickMemory(logmap);
651 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
656 case scRGBColorspace:
659 Transform image from sRGB to linear RGB.
661 if (image->storage_class == PseudoClass)
663 if (SyncImage(image,exception) == MagickFalse)
665 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
668 image_view=AcquireAuthenticCacheView(image,exception);
669 #if defined(MAGICKCORE_OPENMP_SUPPORT)
670 #pragma omp parallel for schedule(static,4) shared(status) \
671 magick_threads(image,image,image->rows,1)
673 for (y=0; y < (ssize_t) image->rows; y++)
684 if (status == MagickFalse)
686 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
688 if (q == (Quantum *) NULL)
693 for (x=0; x < (ssize_t) image->columns; x++)
700 red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
701 green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
702 blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
703 SetPixelRed(image,ClampToQuantum(red),q);
704 SetPixelGreen(image,ClampToQuantum(green),q);
705 SetPixelBlue(image,ClampToQuantum(blue),q);
706 q+=GetPixelChannels(image);
708 sync=SyncCacheViewAuthenticPixels(image_view,exception);
709 if (sync == MagickFalse)
712 image_view=DestroyCacheView(image_view);
713 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
723 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
725 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
727 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
729 if ((x_map == (TransformPacket *) NULL) ||
730 (y_map == (TransformPacket *) NULL) ||
731 (z_map == (TransformPacket *) NULL))
732 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
734 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
740 Initialize OHTA tables:
742 I1 = 0.33333*R+0.33334*G+0.33333*B
743 I2 = 0.50000*R+0.00000*G-0.50000*B
744 I3 =-0.25000*R+0.50000*G-0.25000*B
746 I and Q, normally -0.5 through 0.5, are normalized to the range 0
747 through QuantumRange.
749 primary_info.y=(double) (MaxMap+1.0)/2.0;
750 primary_info.z=(double) (MaxMap+1.0)/2.0;
751 #if defined(MAGICKCORE_OPENMP_SUPPORT)
752 #pragma omp parallel for schedule(static,4) \
753 magick_threads(image,image,1,1)
755 for (i=0; i <= (ssize_t) MaxMap; i++)
757 x_map[i].x=(MagickRealType) (0.33333*(double) i);
758 y_map[i].x=(MagickRealType) (0.33334*(double) i);
759 z_map[i].x=(MagickRealType) (0.33333*(double) i);
760 x_map[i].y=(MagickRealType) (0.50000*(double) i);
761 y_map[i].y=(MagickRealType) (0.00000*(double) i);
762 z_map[i].y=(MagickRealType) (-0.50000*(double) i);
763 x_map[i].z=(MagickRealType) (-0.25000*(double) i);
764 y_map[i].z=(MagickRealType) (0.50000*(double) i);
765 z_map[i].z=(MagickRealType) (-0.25000*(double) i);
769 case Rec601YCbCrColorspace:
772 Initialize YCbCr tables (ITU-R BT.601):
774 Y = 0.2988390*R+0.5868110*G+0.1143500*B
775 Cb= -0.1687367*R-0.3312640*G+0.5000000*B
776 Cr= 0.5000000*R-0.4186880*G-0.0813120*B
778 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
779 through QuantumRange.
781 primary_info.y=(double) (MaxMap+1.0)/2.0;
782 primary_info.z=(double) (MaxMap+1.0)/2.0;
783 #if defined(MAGICKCORE_OPENMP_SUPPORT)
784 #pragma omp parallel for schedule(static,4) \
785 magick_threads(image,image,1,1)
787 for (i=0; i <= (ssize_t) MaxMap; i++)
789 x_map[i].x=(MagickRealType) (0.298839*(double) i);
790 y_map[i].x=(MagickRealType) (0.586811*(double) i);
791 z_map[i].x=(MagickRealType) (0.114350*(double) i);
792 x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
793 y_map[i].y=(MagickRealType) (-0.331264*(double) i);
794 z_map[i].y=(MagickRealType) (0.500000*(double) i);
795 x_map[i].z=(MagickRealType) (0.500000*(double) i);
796 y_map[i].z=(MagickRealType) (-0.418688*(double) i);
797 z_map[i].z=(MagickRealType) (-0.081312*(double) i);
801 case Rec709YCbCrColorspace:
804 Initialize YCbCr tables (ITU-R BT.709):
806 Y = 0.212600*R+0.715200*G+0.072200*B
807 Cb= -0.114572*R-0.385428*G+0.500000*B
808 Cr= 0.500000*R-0.454153*G-0.045847*B
810 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
811 through QuantumRange.
813 primary_info.y=(double) (MaxMap+1.0)/2.0;
814 primary_info.z=(double) (MaxMap+1.0)/2.0;
815 #if defined(MAGICKCORE_OPENMP_SUPPORT)
816 #pragma omp parallel for schedule(static,4) \
817 magick_threads(image,image,1,1)
819 for (i=0; i <= (ssize_t) MaxMap; i++)
821 x_map[i].x=(MagickRealType) (0.212600*(double) i);
822 y_map[i].x=(MagickRealType) (0.715200*(double) i);
823 z_map[i].x=(MagickRealType) (0.072200*(double) i);
824 x_map[i].y=(MagickRealType) (-0.114572*(double) i);
825 y_map[i].y=(MagickRealType) (-0.385428*(double) i);
826 z_map[i].y=(MagickRealType) (0.500000*(double) i);
827 x_map[i].z=(MagickRealType) (0.500000*(double) i);
828 y_map[i].z=(MagickRealType) (-0.454153*(double) i);
829 z_map[i].z=(MagickRealType) (-0.045847*(double) i);
836 Initialize YCC tables:
838 Y = 0.298839*R+0.586811*G+0.114350*B
839 C1= -0.298839*R-0.586811*G+0.88600*B
840 C2= 0.70100*R-0.586811*G-0.114350*B
842 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
844 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
845 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
846 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
848 x_map[i].x=0.003962014134275617*i;
849 y_map[i].x=0.007778268551236748*i;
850 z_map[i].x=0.001510600706713781*i;
851 x_map[i].y=(-0.002426619775463276)*i;
852 y_map[i].y=(-0.004763965913702149)*i;
853 z_map[i].y=0.007190585689165425*i;
854 x_map[i].z=0.006927257754597858*i;
855 y_map[i].z=(-0.005800713697502058)*i;
856 z_map[i].z=(-0.0011265440570958)*i;
858 for ( ; i <= (ssize_t) MaxMap; i++)
860 x_map[i].x=0.2201118963486454*(1.099*i-0.099);
861 y_map[i].x=0.4321260306242638*(1.099*i-0.099);
862 z_map[i].x=0.08392226148409894*(1.099*i-0.099);
863 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
864 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
865 z_map[i].y=0.3994769827314126*(1.099*i-0.099);
866 x_map[i].z=0.3848476530332144*(1.099*i-0.099);
867 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
868 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
875 Linear conversion tables.
877 #if defined(MAGICKCORE_OPENMP_SUPPORT)
878 #pragma omp parallel for schedule(static,4) \
879 magick_threads(image,image,1,1)
881 for (i=0; i <= (ssize_t) MaxMap; i++)
883 x_map[i].x=(MagickRealType) (1.0*(double) i);
884 y_map[i].x=(MagickRealType) 0.0;
885 z_map[i].x=(MagickRealType) 0.0;
886 x_map[i].y=(MagickRealType) 0.0;
887 y_map[i].y=(MagickRealType) (1.0*(double) i);
888 z_map[i].y=(MagickRealType) 0.0;
889 x_map[i].z=(MagickRealType) 0.0;
890 y_map[i].z=(MagickRealType) 0.0;
891 z_map[i].z=(MagickRealType) (1.0*(double) i);
899 switch (image->storage_class)
905 Convert DirectClass image.
907 image_view=AcquireAuthenticCacheView(image,exception);
908 #if defined(MAGICKCORE_OPENMP_SUPPORT)
909 #pragma omp parallel for schedule(static,4) shared(status) \
910 magick_threads(image,image,image->rows,1)
912 for (y=0; y < (ssize_t) image->rows; y++)
926 register unsigned int
931 if (status == MagickFalse)
933 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
935 if (q == (Quantum *) NULL)
940 for (x=0; x < (ssize_t) image->columns; x++)
942 red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
943 GetPixelRed(image,q)));
944 green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
945 GetPixelGreen(image,q)));
946 blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
947 GetPixelBlue(image,q)));
948 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
950 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
952 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
954 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
955 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
956 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
957 q+=GetPixelChannels(image);
959 sync=SyncCacheViewAuthenticPixels(image_view,exception);
960 if (sync == MagickFalse)
962 if (image->progress_monitor != (MagickProgressMonitor) NULL)
967 #if defined(MAGICKCORE_OPENMP_SUPPORT)
968 #pragma omp critical (MagickCore_sRGBTransformImage)
970 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
972 if (proceed == MagickFalse)
976 image_view=DestroyCacheView(image_view);
981 register unsigned int
987 Convert PseudoClass image.
989 for (i=0; i < (ssize_t) image->colors; i++)
994 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
995 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
996 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
997 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
998 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
999 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1000 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
1001 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
1002 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
1004 (void) SyncImage(image,exception);
1009 Relinquish resources.
1011 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1012 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1013 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1014 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1015 return(MagickFalse);
1020 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024 % S e t I m a g e C o l o r s p a c e %
1028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030 % SetImageColorspace() sets the colorspace member of the Image structure.
1032 % The format of the SetImageColorspace method is:
1034 % MagickBooleanType SetImageColorspace(Image *image,
1035 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1037 % A description of each parameter follows:
1039 % o image: the image.
1041 % o colorspace: the colorspace.
1043 % o exception: return any errors or warnings in this structure.
1046 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1047 const ColorspaceType colorspace,ExceptionInfo *exception)
1049 if (image->colorspace == colorspace)
1051 image->colorspace=colorspace;
1052 image->rendering_intent=UndefinedIntent;
1054 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1055 if (IsGrayColorspace(colorspace) != MagickFalse)
1057 if ((image->intensity != Rec601LuminancePixelIntensityMethod) &&
1058 (image->intensity != Rec709LuminancePixelIntensityMethod) &&
1059 (image->intensity != UndefinedPixelIntensityMethod))
1060 image->gamma=1.000/2.200;
1061 image->type=GrayscaleType;
1064 if (IssRGBColorspace(colorspace) != MagickFalse)
1065 image->gamma=1.000/2.200;
1066 if (image->gamma == (1.000/2.200))
1068 image->rendering_intent=PerceptualIntent;
1069 image->gamma=1.000/2.200;
1070 image->chromaticity.red_primary.x=0.6400;
1071 image->chromaticity.red_primary.y=0.3300;
1072 image->chromaticity.red_primary.z=0.0300;
1073 image->chromaticity.green_primary.x=0.3000;
1074 image->chromaticity.green_primary.y=0.6000;
1075 image->chromaticity.green_primary.z=0.1000;
1076 image->chromaticity.blue_primary.x=0.1500;
1077 image->chromaticity.blue_primary.y=0.0600;
1078 image->chromaticity.blue_primary.z=0.7900;
1079 image->chromaticity.white_point.x=0.3127;
1080 image->chromaticity.white_point.y=0.3290;
1081 image->chromaticity.white_point.z=0.3583;
1083 if (IsGrayColorspace(colorspace) != MagickFalse)
1084 image->type=GrayscaleType;
1085 return(SyncImagePixelCache(image,exception));
1089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1093 % T r a n s f o r m I m a g e C o l o r s p a c e %
1097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1099 % TransformImageColorspace() transforms an image colorspace, changing the
1100 % image data to reflect the new colorspace.
1102 % The format of the TransformImageColorspace method is:
1104 % MagickBooleanType TransformImageColorspace(Image *image,
1105 % const ColorspaceType colorspace,ExceptionInfo *exception)
1107 % A description of each parameter follows:
1109 % o image: the image.
1111 % o colorspace: the colorspace.
1113 % o exception: return any errors or warnings in this structure.
1116 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1117 const ColorspaceType colorspace,ExceptionInfo *exception)
1122 assert(image != (Image *) NULL);
1123 assert(image->signature == MagickSignature);
1124 if (image->debug != MagickFalse)
1125 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1126 if (colorspace == UndefinedColorspace)
1127 return(SetImageColorspace(image,colorspace,exception));
1128 if (image->colorspace == colorspace)
1129 return(MagickTrue); /* same colorspace: no op */
1131 Convert the reference image from an alternate colorspace to sRGB.
1133 (void) DeleteImageProfile(image,"icc");
1134 (void) DeleteImageProfile(image,"icm");
1135 if (IssRGBColorspace(colorspace) != MagickFalse)
1136 return(TransformsRGBImage(image,exception));
1138 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1139 status=TransformsRGBImage(image,exception);
1140 if (status == MagickFalse)
1143 Convert the reference image from sRGB to an alternate colorspace.
1145 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155 + T r a n s f o r m s R G B I m a g e %
1159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1161 % TransformsRGBImage() converts the reference image from an alternate
1162 % colorspace to sRGB. The transformation matrices are not the standard ones:
1163 % the weights are rescaled to normalize the range of the transformed values
1164 % to be [0..QuantumRange].
1166 % The format of the TransformsRGBImage method is:
1168 % MagickBooleanType TransformsRGBImage(Image *image,
1169 % ExceptionInfo *exception)
1171 % A description of each parameter follows:
1173 % o image: the image.
1175 % o exception: return any errors or warnings in this structure.
1179 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1180 const double yellow,double *red,double *green,double *blue)
1182 *red=QuantumRange*(1.0-cyan);
1183 *green=QuantumRange*(1.0-magenta);
1184 *blue=QuantumRange*(1.0-yellow);
1187 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1188 double *X,double *Y,double *Z)
1190 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1191 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1192 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1195 static inline void ConvertLMSToRGB(const double L,const double M,
1196 const double S,double *red,double *green,double *blue)
1203 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1204 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1207 static inline void ConvertLuvToRGB(const double L,const double u,
1208 const double v,double *red,double *green,double *blue)
1215 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1216 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1219 static inline ssize_t RoundToYCC(const double value)
1223 if (value >= 1388.0)
1225 return((ssize_t) (value+0.5));
1228 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1230 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1231 (QuantumRange-pixel->black)+pixel->black)));
1232 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1233 (QuantumRange-pixel->black)+pixel->black)));
1234 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1235 (QuantumRange-pixel->black)+pixel->black)));
1238 static inline void ConvertLabToRGB(const double L,const double a,
1239 const double b,double *red,double *green,double *blue)
1246 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1247 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1250 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1251 double *red,double *green,double *blue)
1253 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
1254 1.4019995886561440468*(Pr-0.5));
1255 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
1256 0.71413649331646789076*(Pr-0.5));
1257 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
1258 2.1453384174593273e-06*(Pr-0.5));
1261 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1262 const double Cr,double *red,double *green,double *blue)
1264 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1267 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1268 double *red,double *green,double *blue)
1270 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
1272 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
1274 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
1278 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
1279 double *red,double *green,double *blue)
1281 *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-
1282 0.52591263066186533*(Dr-0.5));
1283 *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+
1284 0.26789932820759876*(Dr-0.5));
1285 *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)-
1286 7.9202543533108e-05*(Dr-0.5));
1289 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1290 double *red,double *green,double *blue)
1292 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
1294 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
1296 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
1300 static MagickBooleanType TransformsRGBImage(Image *image,
1301 ExceptionInfo *exception)
1303 #define TransformsRGBImageTag "Transform/Image"
1308 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1309 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1310 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1311 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1312 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1313 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1314 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1315 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1316 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1317 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1318 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1319 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1320 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1321 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1322 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1323 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1324 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1325 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1326 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1327 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1328 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1329 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1330 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1331 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1332 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1333 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1334 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1335 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1336 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1337 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1338 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1339 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1340 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1341 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1342 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1343 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1344 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1345 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1346 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1347 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1348 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1349 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1350 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1351 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1352 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1353 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1354 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1355 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1356 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1357 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1358 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1359 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1360 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1361 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1362 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1363 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1364 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1365 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1366 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1367 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1368 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1369 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1370 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1371 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1372 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1373 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1374 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1375 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1376 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1377 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1378 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1379 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1380 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1381 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1382 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1383 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1384 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1385 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1386 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1387 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1388 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1389 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1390 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1391 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1392 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1393 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1394 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1395 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1396 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1397 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1398 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1399 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1400 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1401 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1402 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1403 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1404 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1405 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1406 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1407 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1408 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1409 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1410 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1411 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1412 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1413 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1414 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1415 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1416 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1417 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1418 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1419 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1420 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1421 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1422 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1423 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1424 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1425 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1426 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1427 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1428 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1429 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1430 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1431 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1432 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1433 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1434 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1435 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1436 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1437 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1438 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1439 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1440 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1441 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1442 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1443 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1444 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1445 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1446 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1447 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1448 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1449 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1450 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1451 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1452 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1453 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1454 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1455 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1456 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1457 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1458 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1459 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1460 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1461 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1462 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1463 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1464 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1465 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1466 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1467 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1468 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1469 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1470 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1471 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1472 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1473 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1474 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1475 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1476 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1477 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1478 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1479 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1480 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1481 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1482 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1483 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1484 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1485 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1486 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1487 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1488 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1489 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1490 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1491 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1492 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1493 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1494 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1495 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1496 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1497 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1498 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1499 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1500 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1501 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1502 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1503 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1504 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1505 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1506 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1507 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1508 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1509 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1510 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1511 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1512 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1513 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1514 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1515 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1516 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1517 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1518 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1519 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1520 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1521 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1522 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1523 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1524 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1525 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1526 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1527 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1528 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1529 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1530 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1531 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1532 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1533 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1534 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1535 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1536 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1537 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1538 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1539 0.998559f, 0.999280f, 1.000000f
1562 assert(image != (Image *) NULL);
1563 assert(image->signature == MagickSignature);
1564 if (image->debug != MagickFalse)
1565 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1568 switch (image->colorspace)
1570 case CMYKColorspace:
1576 Transform image from CMYK to sRGB.
1578 if (image->storage_class == PseudoClass)
1580 if (SyncImage(image,exception) == MagickFalse)
1581 return(MagickFalse);
1582 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1583 return(MagickFalse);
1585 GetPixelInfo(image,&zero);
1586 image_view=AcquireAuthenticCacheView(image,exception);
1587 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1588 #pragma omp parallel for schedule(static,4) shared(status) \
1589 magick_threads(image,image,image->rows,1)
1591 for (y=0; y < (ssize_t) image->rows; y++)
1605 if (status == MagickFalse)
1607 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1609 if (q == (Quantum *) NULL)
1615 for (x=0; x < (ssize_t) image->columns; x++)
1617 GetPixelInfoPixel(image,q,&pixel);
1618 ConvertCMYKToRGB(&pixel);
1619 SetPixelInfoPixel(image,&pixel,q);
1620 q+=GetPixelChannels(image);
1622 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1623 if (sync == MagickFalse)
1626 image_view=DestroyCacheView(image_view);
1627 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1628 return(MagickFalse);
1631 case GRAYColorspace:
1634 Transform linear GRAY to sRGB colorspace.
1636 if (image->storage_class == PseudoClass)
1638 if (SyncImage(image,exception) == MagickFalse)
1639 return(MagickFalse);
1640 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1641 return(MagickFalse);
1643 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1644 return(MagickFalse);
1645 image_view=AcquireAuthenticCacheView(image,exception);
1646 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1647 #pragma omp parallel for schedule(static,4) shared(status) \
1648 magick_threads(image,image,image->rows,1)
1650 for (y=0; y < (ssize_t) image->rows; y++)
1661 if (status == MagickFalse)
1663 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1665 if (q == (Quantum *) NULL)
1670 for (x=(ssize_t) image->columns; x != 0; x--)
1675 gray=EncodePixelGamma((MagickRealType) GetPixelGray(image,q));
1676 SetPixelRed(image,ClampToQuantum(gray),q);
1677 SetPixelGreen(image,ClampToQuantum(gray),q);
1678 SetPixelBlue(image,ClampToQuantum(gray),q);
1679 q+=GetPixelChannels(image);
1681 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1682 if (sync == MagickFalse)
1685 image_view=DestroyCacheView(image_view);
1686 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1687 return(MagickFalse);
1692 case HCLpColorspace:
1700 case LCHabColorspace:
1701 case LCHuvColorspace:
1705 case YCbCrColorspace:
1706 case YDbDrColorspace:
1708 case YPbPrColorspace:
1712 Transform image from source colorspace to sRGB.
1714 if (image->storage_class == PseudoClass)
1716 if (SyncImage(image,exception) == MagickFalse)
1717 return(MagickFalse);
1718 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1719 return(MagickFalse);
1721 image_view=AcquireAuthenticCacheView(image,exception);
1722 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1723 #pragma omp parallel for schedule(static,4) shared(status) \
1724 magick_threads(image,image,image->rows,1)
1726 for (y=0; y < (ssize_t) image->rows; y++)
1737 if (status == MagickFalse)
1739 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1741 if (q == (Quantum *) NULL)
1746 for (x=0; x < (ssize_t) image->columns; x++)
1756 X=QuantumScale*GetPixelRed(image,q);
1757 Y=QuantumScale*GetPixelGreen(image,q);
1758 Z=QuantumScale*GetPixelBlue(image,q);
1759 switch (image->colorspace)
1763 ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
1768 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
1771 case HCLpColorspace:
1773 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
1778 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
1783 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
1788 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
1793 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
1798 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
1803 ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
1807 case LCHabColorspace:
1809 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
1812 case LCHuvColorspace:
1814 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
1819 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
1824 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
1829 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
1832 case YCbCrColorspace:
1834 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
1837 case YDbDrColorspace:
1839 ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
1844 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
1847 case YPbPrColorspace:
1849 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
1854 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
1860 SetPixelRed(image,ClampToQuantum(red),q);
1861 SetPixelGreen(image,ClampToQuantum(green),q);
1862 SetPixelBlue(image,ClampToQuantum(blue),q);
1863 q+=GetPixelChannels(image);
1865 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1866 if (sync == MagickFalse)
1869 image_view=DestroyCacheView(image_view);
1870 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1871 return(MagickFalse);
1891 Transform Log to sRGB colorspace.
1893 density=DisplayGamma;
1895 value=GetImageProperty(image,"gamma",exception);
1896 if (value != (const char *) NULL)
1897 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
1898 film_gamma=FilmGamma;
1899 value=GetImageProperty(image,"film-gamma",exception);
1900 if (value != (const char *) NULL)
1901 film_gamma=StringToDouble(value,(char **) NULL);
1902 reference_black=ReferenceBlack;
1903 value=GetImageProperty(image,"reference-black",exception);
1904 if (value != (const char *) NULL)
1905 reference_black=StringToDouble(value,(char **) NULL);
1906 reference_white=ReferenceWhite;
1907 value=GetImageProperty(image,"reference-white",exception);
1908 if (value != (const char *) NULL)
1909 reference_white=StringToDouble(value,(char **) NULL);
1910 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1912 if (logmap == (Quantum *) NULL)
1913 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1915 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
1917 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
1918 logmap[i]=(Quantum) 0;
1919 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
1920 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
1921 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/
1922 film_gamma)-black));
1923 for ( ; i <= (ssize_t) MaxMap; i++)
1924 logmap[i]=QuantumRange;
1925 if (image->storage_class == PseudoClass)
1927 if (SyncImage(image,exception) == MagickFalse)
1928 return(MagickFalse);
1929 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1930 return(MagickFalse);
1932 image_view=AcquireAuthenticCacheView(image,exception);
1933 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1934 #pragma omp parallel for schedule(static,4) shared(status) \
1935 magick_threads(image,image,image->rows,1)
1937 for (y=0; y < (ssize_t) image->rows; y++)
1948 if (status == MagickFalse)
1950 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1952 if (q == (Quantum *) NULL)
1957 for (x=(ssize_t) image->columns; x != 0; x--)
1964 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
1965 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
1966 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
1967 SetPixelRed(image,ClampToQuantum(red),q);
1968 SetPixelGreen(image,ClampToQuantum(green),q);
1969 SetPixelBlue(image,ClampToQuantum(blue),q);
1970 q+=GetPixelChannels(image);
1972 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1973 if (sync == MagickFalse)
1976 image_view=DestroyCacheView(image_view);
1977 logmap=(Quantum *) RelinquishMagickMemory(logmap);
1978 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1979 return(MagickFalse);
1983 case scRGBColorspace:
1986 Transform linear RGB to sRGB colorspace.
1988 if (image->storage_class == PseudoClass)
1990 if (SyncImage(image,exception) == MagickFalse)
1991 return(MagickFalse);
1992 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1993 return(MagickFalse);
1995 image_view=AcquireAuthenticCacheView(image,exception);
1996 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1997 #pragma omp parallel for schedule(static,4) shared(status) \
1998 magick_threads(image,image,image->rows,1)
2000 for (y=0; y < (ssize_t) image->rows; y++)
2011 if (status == MagickFalse)
2013 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2015 if (q == (Quantum *) NULL)
2020 for (x=(ssize_t) image->columns; x != 0; x--)
2027 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q));
2028 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q));
2029 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q));
2030 SetPixelRed(image,ClampToQuantum(red),q);
2031 SetPixelGreen(image,ClampToQuantum(green),q);
2032 SetPixelBlue(image,ClampToQuantum(blue),q);
2033 q+=GetPixelChannels(image);
2035 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2036 if (sync == MagickFalse)
2039 image_view=DestroyCacheView(image_view);
2040 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2041 return(MagickFalse);
2048 Allocate the tables.
2050 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2052 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2054 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2056 if ((x_map == (TransformPacket *) NULL) ||
2057 (y_map == (TransformPacket *) NULL) ||
2058 (z_map == (TransformPacket *) NULL))
2060 if (z_map != (TransformPacket *) NULL)
2061 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2062 if (y_map != (TransformPacket *) NULL)
2063 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2064 if (x_map != (TransformPacket *) NULL)
2065 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2066 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2069 switch (image->colorspace)
2071 case OHTAColorspace:
2074 Initialize OHTA tables:
2076 I1 = 0.33333*R+0.33334*G+0.33333*B
2077 I2 = 0.50000*R+0.00000*G-0.50000*B
2078 I3 =-0.25000*R+0.50000*G-0.25000*B
2079 R = I1+1.00000*I2-0.66668*I3
2080 G = I1+0.00000*I2+1.33333*I3
2081 B = I1-1.00000*I2-0.66668*I3
2083 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2084 through QuantumRange.
2086 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2087 #pragma omp parallel for schedule(static,4) \
2088 magick_threads(image,image,1,1)
2090 for (i=0; i <= (ssize_t) MaxMap; i++)
2092 x_map[i].x=(MagickRealType) (1.0*(double) i);
2093 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap));
2094 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2095 x_map[i].y=(MagickRealType) (1.0*(double) i);
2096 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap));
2097 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap));
2098 x_map[i].z=(MagickRealType) (1.0*(double) i);
2099 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap));
2100 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2104 case Rec601YCbCrColorspace:
2107 Initialize YCbCr tables:
2110 G = Y-0.344136*Cb-0.714136*Cr
2113 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2114 through QuantumRange.
2116 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2117 #pragma omp parallel for schedule(static,4) \
2118 magick_threads(image,image,1,1)
2120 for (i=0; i <= (ssize_t) MaxMap; i++)
2122 x_map[i].x=0.99999999999914679361*(double) i;
2123 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2124 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2125 x_map[i].y=0.99999975910502514331*(double) i;
2126 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2127 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2128 x_map[i].z=1.00000124040004623180*(double) i;
2129 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2130 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2134 case Rec709YCbCrColorspace:
2137 Initialize YCbCr tables:
2140 G = Y-0.187324*Cb-0.468124*Cr
2143 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2144 through QuantumRange.
2146 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2147 #pragma omp parallel for schedule(static,4) \
2148 magick_threads(image,image,1,1)
2150 for (i=0; i <= (ssize_t) MaxMap; i++)
2152 x_map[i].x=(MagickRealType) (1.0*i);
2153 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2154 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap));
2155 x_map[i].y=(MagickRealType) (1.0*i);
2156 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap));
2157 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap));
2158 x_map[i].z=(MagickRealType) (1.0*i);
2159 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap));
2160 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2167 Initialize YCC tables:
2170 G = Y-0.317038*C1-0.682243*C2
2173 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2175 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2176 #pragma omp parallel for schedule(static,4) \
2177 magick_threads(image,image,1,1)
2179 for (i=0; i <= (ssize_t) MaxMap; i++)
2181 x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2182 y_map[i].x=(MagickRealType) 0.0000000;
2183 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double)
2184 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2185 x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2186 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double)
2187 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2188 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double)
2189 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2190 x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2191 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double)
2192 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2193 z_map[i].z=(MagickRealType) 0.0000000;
2200 Linear conversion tables.
2202 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2203 #pragma omp parallel for schedule(static,4) \
2204 magick_threads(image,image,1,1)
2206 for (i=0; i <= (ssize_t) MaxMap; i++)
2208 x_map[i].x=(MagickRealType) (1.0*(double) i);
2209 y_map[i].x=(MagickRealType) 0.0;
2210 z_map[i].x=(MagickRealType) 0.0;
2211 x_map[i].y=(MagickRealType) 0.0;
2212 y_map[i].y=(MagickRealType) (1.0*(double) i);
2213 z_map[i].y=(MagickRealType) 0.0;
2214 x_map[i].z=(MagickRealType) 0.0;
2215 y_map[i].z=(MagickRealType) 0.0;
2216 z_map[i].z=(MagickRealType) (1.0*(double) i);
2224 switch (image->storage_class)
2230 Convert DirectClass image.
2232 image_view=AcquireAuthenticCacheView(image,exception);
2233 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2234 #pragma omp parallel for schedule(static,4) shared(status) \
2235 magick_threads(image,image,image->rows,1)
2237 for (y=0; y < (ssize_t) image->rows; y++)
2251 if (status == MagickFalse)
2253 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2255 if (q == (Quantum *) NULL)
2260 for (x=0; x < (ssize_t) image->columns; x++)
2267 red=ScaleQuantumToMap(GetPixelRed(image,q));
2268 green=ScaleQuantumToMap(GetPixelGreen(image,q));
2269 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
2270 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2271 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2272 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2273 if (image->colorspace == YCCColorspace)
2275 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2277 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2279 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2284 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2285 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2286 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2288 SetPixelRed(image,ClampToQuantum(pixel.red),q);
2289 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
2290 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
2291 q+=GetPixelChannels(image);
2293 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2294 if (sync == MagickFalse)
2296 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2301 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2302 #pragma omp critical (MagickCore_TransformsRGBImage)
2304 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
2306 if (proceed == MagickFalse)
2310 image_view=DestroyCacheView(image_view);
2316 Convert PseudoClass image.
2318 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2319 #pragma omp parallel for schedule(static,4) shared(status) \
2320 magick_threads(image,image,1,1)
2322 for (i=0; i < (ssize_t) image->colors; i++)
2332 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
2333 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
2334 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
2335 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2336 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2337 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2338 if (image->colorspace == YCCColorspace)
2340 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2342 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2344 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2349 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2350 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2351 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2353 image->colormap[i].red=(double) ClampToQuantum(pixel.red);
2354 image->colormap[i].green=(double) ClampToQuantum(pixel.green);
2355 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue);
2357 (void) SyncImage(image,exception);
2362 Relinquish resources.
2364 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2365 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2366 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2367 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2368 return(MagickFalse);