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 ConvertRGBToYIQ(const double red,const double green,
171 const double blue,double *Y,double *I,double *Q)
173 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
174 *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5;
175 *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5;
178 static void ConvertRGBToYPbPr(const double red,const double green,
179 const double blue,double *Y,double *Pb,double *Pr)
181 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
182 *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5;
183 *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5;
186 static void ConvertRGBToYCbCr(const double red,const double green,
187 const double blue,double *Y,double *Cb,double *Cr)
189 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
192 static void ConvertRGBToYUV(const double red,const double green,
193 const double blue,double *Y,double *U,double *V)
195 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
196 *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5;
197 *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5;
200 static MagickBooleanType sRGBTransformImage(Image *image,
201 const ColorspaceType colorspace,ExceptionInfo *exception)
203 #define sRGBTransformImageTag "RGBTransform/Image"
228 assert(image != (Image *) NULL);
229 assert(image->signature == MagickSignature);
230 if (image->debug != MagickFalse)
231 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
232 assert(colorspace != sRGBColorspace);
233 assert(colorspace != TransparentColorspace);
234 assert(colorspace != UndefinedColorspace);
245 Convert RGB to CMYK colorspace.
247 if (image->storage_class == PseudoClass)
249 if (SyncImage(image,exception) == MagickFalse)
251 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
254 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
256 GetPixelInfo(image,&zero);
257 image_view=AcquireAuthenticCacheView(image,exception);
258 #if defined(MAGICKCORE_OPENMP_SUPPORT)
259 #pragma omp parallel for schedule(static,4) shared(status) \
260 magick_threads(image,image,image->rows,1)
262 for (y=0; y < (ssize_t) image->rows; y++)
276 if (status == MagickFalse)
278 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
280 if (q == (Quantum *) NULL)
286 for (x=0; x < (ssize_t) image->columns; x++)
288 GetPixelInfoPixel(image,q,&pixel);
289 ConvertRGBToCMYK(&pixel);
290 SetPixelInfoPixel(image,&pixel,q);
291 q+=GetPixelChannels(image);
293 sync=SyncCacheViewAuthenticPixels(image_view,exception);
294 if (sync == MagickFalse)
297 image_view=DestroyCacheView(image_view);
298 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
299 ColorSeparationMatteType;
300 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
307 Transform image from sRGB to GRAY.
309 if (image->storage_class == PseudoClass)
311 if (SyncImage(image,exception) == MagickFalse)
313 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
316 image_view=AcquireAuthenticCacheView(image,exception);
317 #if defined(MAGICKCORE_OPENMP_SUPPORT)
318 #pragma omp parallel for schedule(static,4) shared(status) \
319 magick_threads(image,image,image->rows,1)
321 for (y=0; y < (ssize_t) image->rows; y++)
332 if (status == MagickFalse)
334 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
336 if (q == (Quantum *) NULL)
341 for (x=0; x < (ssize_t) image->columns; x++)
343 SetPixelGray(image,ClampToQuantum(GetPixelIntensity(image,q)),q);
344 q+=GetPixelChannels(image);
346 sync=SyncCacheViewAuthenticPixels(image_view,exception);
347 if (sync == MagickFalse)
350 image_view=DestroyCacheView(image_view);
351 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
353 image->type=GrayscaleType;
366 case LCHabColorspace:
367 case LCHuvColorspace:
371 case YCbCrColorspace:
373 case YPbPrColorspace:
377 Transform image from sRGB to target colorspace.
379 if (image->storage_class == PseudoClass)
381 if (SyncImage(image,exception) == MagickFalse)
383 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
386 image_view=AcquireAuthenticCacheView(image,exception);
387 #if defined(MAGICKCORE_OPENMP_SUPPORT)
388 #pragma omp parallel for schedule(static,4) shared(status) \
389 magick_threads(image,image,image->rows,1)
391 for (y=0; y < (ssize_t) image->rows; y++)
402 if (status == MagickFalse)
404 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
406 if (q == (Quantum *) NULL)
411 for (x=0; x < (ssize_t) image->columns; x++)
421 red=(double) GetPixelRed(image,q);
422 green=(double) GetPixelGreen(image,q);
423 blue=(double) GetPixelBlue(image,q);
428 ConvertRGBToCMY(red,green,blue,&X,&Y,&Z);
433 ConvertRGBToHCL(red,green,blue,&X,&Y,&Z);
438 ConvertRGBToHCLp(red,green,blue,&X,&Y,&Z);
443 ConvertRGBToHSB(red,green,blue,&X,&Y,&Z);
448 ConvertRGBToHSI(red,green,blue,&X,&Y,&Z);
453 ConvertRGBToHSL(red,green,blue,&X,&Y,&Z);
458 ConvertRGBToHSV(red,green,blue,&X,&Y,&Z);
463 ConvertRGBToHWB(red,green,blue,&X,&Y,&Z);
468 ConvertRGBToLab(red,green,blue,&X,&Y,&Z);
472 case LCHabColorspace:
474 ConvertRGBToLCHab(red,green,blue,&X,&Y,&Z);
477 case LCHuvColorspace:
479 ConvertRGBToLCHuv(red,green,blue,&X,&Y,&Z);
484 ConvertRGBToLMS(red,green,blue,&X,&Y,&Z);
489 ConvertRGBToLuv(red,green,blue,&X,&Y,&Z);
494 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
497 case YCbCrColorspace:
499 ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z);
504 ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z);
507 case YPbPrColorspace:
509 ConvertRGBToYPbPr(red,green,blue,&X,&Y,&Z);
514 ConvertRGBToYUV(red,green,blue,&X,&Y,&Z);
520 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
521 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
522 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q);
523 q+=GetPixelChannels(image);
525 sync=SyncCacheViewAuthenticPixels(image_view,exception);
526 if (sync == MagickFalse)
529 image_view=DestroyCacheView(image_view);
530 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
536 #define DisplayGamma (1.0/1.7)
537 #define FilmGamma 0.6
538 #define ReferenceBlack 95.0
539 #define ReferenceWhite 685.0
556 Transform RGB to Log colorspace.
558 density=DisplayGamma;
560 value=GetImageProperty(image,"gamma",exception);
561 if (value != (const char *) NULL)
562 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
563 film_gamma=FilmGamma;
564 value=GetImageProperty(image,"film-gamma",exception);
565 if (value != (const char *) NULL)
566 film_gamma=StringToDouble(value,(char **) NULL);
567 reference_black=ReferenceBlack;
568 value=GetImageProperty(image,"reference-black",exception);
569 if (value != (const char *) NULL)
570 reference_black=StringToDouble(value,(char **) NULL);
571 reference_white=ReferenceWhite;
572 value=GetImageProperty(image,"reference-white",exception);
573 if (value != (const char *) NULL)
574 reference_white=StringToDouble(value,(char **) NULL);
575 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
577 if (logmap == (Quantum *) NULL)
578 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
580 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
582 #if defined(MAGICKCORE_OPENMP_SUPPORT)
583 #pragma omp parallel for schedule(static,4) \
584 magick_threads(image,image,1,1)
586 for (i=0; i <= (ssize_t) MaxMap; i++)
587 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+
588 log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002/
589 film_gamma))/1024.0));
590 image_view=AcquireAuthenticCacheView(image,exception);
591 #if defined(MAGICKCORE_OPENMP_SUPPORT)
592 #pragma omp parallel for schedule(static,4) shared(status) \
593 magick_threads(image,image,image->rows,1)
595 for (y=0; y < (ssize_t) image->rows; y++)
606 if (status == MagickFalse)
608 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
610 if (q == (Quantum *) NULL)
615 for (x=(ssize_t) image->columns; x != 0; x--)
622 red=(double) GetPixelRed(image,q);
623 green=(double) GetPixelGreen(image,q);
624 blue=(double) GetPixelBlue(image,q);
625 SetPixelRed(image,logmap[ScaleQuantumToMap(ClampToQuantum(red))],q);
626 SetPixelGreen(image,logmap[ScaleQuantumToMap(ClampToQuantum(green))],
628 SetPixelBlue(image,logmap[ScaleQuantumToMap(ClampToQuantum(blue))],q);
629 q+=GetPixelChannels(image);
631 sync=SyncCacheViewAuthenticPixels(image_view,exception);
632 if (sync == MagickFalse)
635 image_view=DestroyCacheView(image_view);
636 logmap=(Quantum *) RelinquishMagickMemory(logmap);
637 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
642 case scRGBColorspace:
645 Transform image from sRGB to linear RGB.
647 if (image->storage_class == PseudoClass)
649 if (SyncImage(image,exception) == MagickFalse)
651 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
654 image_view=AcquireAuthenticCacheView(image,exception);
655 #if defined(MAGICKCORE_OPENMP_SUPPORT)
656 #pragma omp parallel for schedule(static,4) shared(status) \
657 magick_threads(image,image,image->rows,1)
659 for (y=0; y < (ssize_t) image->rows; y++)
670 if (status == MagickFalse)
672 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
674 if (q == (Quantum *) NULL)
679 for (x=0; x < (ssize_t) image->columns; x++)
686 red=DecodePixelGamma((MagickRealType) GetPixelRed(image,q));
687 green=DecodePixelGamma((MagickRealType) GetPixelGreen(image,q));
688 blue=DecodePixelGamma((MagickRealType) GetPixelBlue(image,q));
689 SetPixelRed(image,ClampToQuantum(red),q);
690 SetPixelGreen(image,ClampToQuantum(green),q);
691 SetPixelBlue(image,ClampToQuantum(blue),q);
692 q+=GetPixelChannels(image);
694 sync=SyncCacheViewAuthenticPixels(image_view,exception);
695 if (sync == MagickFalse)
698 image_view=DestroyCacheView(image_view);
699 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
709 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
711 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
713 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
715 if ((x_map == (TransformPacket *) NULL) ||
716 (y_map == (TransformPacket *) NULL) ||
717 (z_map == (TransformPacket *) NULL))
718 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
720 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
726 Initialize OHTA tables:
728 I1 = 0.33333*R+0.33334*G+0.33333*B
729 I2 = 0.50000*R+0.00000*G-0.50000*B
730 I3 =-0.25000*R+0.50000*G-0.25000*B
732 I and Q, normally -0.5 through 0.5, are normalized to the range 0
733 through QuantumRange.
735 primary_info.y=(double) (MaxMap+1.0)/2.0;
736 primary_info.z=(double) (MaxMap+1.0)/2.0;
737 #if defined(MAGICKCORE_OPENMP_SUPPORT)
738 #pragma omp parallel for schedule(static,4) \
739 magick_threads(image,image,1,1)
741 for (i=0; i <= (ssize_t) MaxMap; i++)
743 x_map[i].x=(MagickRealType) (0.33333*(double) i);
744 y_map[i].x=(MagickRealType) (0.33334*(double) i);
745 z_map[i].x=(MagickRealType) (0.33333*(double) i);
746 x_map[i].y=(MagickRealType) (0.50000*(double) i);
747 y_map[i].y=(MagickRealType) (0.00000*(double) i);
748 z_map[i].y=(MagickRealType) (-0.50000*(double) i);
749 x_map[i].z=(MagickRealType) (-0.25000*(double) i);
750 y_map[i].z=(MagickRealType) (0.50000*(double) i);
751 z_map[i].z=(MagickRealType) (-0.25000*(double) i);
755 case Rec601YCbCrColorspace:
758 Initialize YCbCr tables (ITU-R BT.601):
760 Y = 0.2988390*R+0.5868110*G+0.1143500*B
761 Cb= -0.1687367*R-0.3312640*G+0.5000000*B
762 Cr= 0.5000000*R-0.4186880*G-0.0813120*B
764 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
765 through QuantumRange.
767 primary_info.y=(double) (MaxMap+1.0)/2.0;
768 primary_info.z=(double) (MaxMap+1.0)/2.0;
769 #if defined(MAGICKCORE_OPENMP_SUPPORT)
770 #pragma omp parallel for schedule(static,4) \
771 magick_threads(image,image,1,1)
773 for (i=0; i <= (ssize_t) MaxMap; i++)
775 x_map[i].x=(MagickRealType) (0.298839*(double) i);
776 y_map[i].x=(MagickRealType) (0.586811*(double) i);
777 z_map[i].x=(MagickRealType) (0.114350*(double) i);
778 x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
779 y_map[i].y=(MagickRealType) (-0.331264*(double) i);
780 z_map[i].y=(MagickRealType) (0.500000*(double) i);
781 x_map[i].z=(MagickRealType) (0.500000*(double) i);
782 y_map[i].z=(MagickRealType) (-0.418688*(double) i);
783 z_map[i].z=(MagickRealType) (-0.081312*(double) i);
787 case Rec709YCbCrColorspace:
790 Initialize YCbCr tables (ITU-R BT.709):
792 Y = 0.212600*R+0.715200*G+0.072200*B
793 Cb= -0.114572*R-0.385428*G+0.500000*B
794 Cr= 0.500000*R-0.454153*G-0.045847*B
796 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
797 through QuantumRange.
799 primary_info.y=(double) (MaxMap+1.0)/2.0;
800 primary_info.z=(double) (MaxMap+1.0)/2.0;
801 #if defined(MAGICKCORE_OPENMP_SUPPORT)
802 #pragma omp parallel for schedule(static,4) \
803 magick_threads(image,image,1,1)
805 for (i=0; i <= (ssize_t) MaxMap; i++)
807 x_map[i].x=(MagickRealType) (0.212600*(double) i);
808 y_map[i].x=(MagickRealType) (0.715200*(double) i);
809 z_map[i].x=(MagickRealType) (0.072200*(double) i);
810 x_map[i].y=(MagickRealType) (-0.114572*(double) i);
811 y_map[i].y=(MagickRealType) (-0.385428*(double) i);
812 z_map[i].y=(MagickRealType) (0.500000*(double) i);
813 x_map[i].z=(MagickRealType) (0.500000*(double) i);
814 y_map[i].z=(MagickRealType) (-0.454153*(double) i);
815 z_map[i].z=(MagickRealType) (-0.045847*(double) i);
822 Initialize YCC tables:
824 Y = 0.298839*R+0.586811*G+0.114350*B
825 C1= -0.298839*R-0.586811*G+0.88600*B
826 C2= 0.70100*R-0.586811*G-0.114350*B
828 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
830 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
831 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
832 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
834 x_map[i].x=0.003962014134275617*i;
835 y_map[i].x=0.007778268551236748*i;
836 z_map[i].x=0.001510600706713781*i;
837 x_map[i].y=(-0.002426619775463276)*i;
838 y_map[i].y=(-0.004763965913702149)*i;
839 z_map[i].y=0.007190585689165425*i;
840 x_map[i].z=0.006927257754597858*i;
841 y_map[i].z=(-0.005800713697502058)*i;
842 z_map[i].z=(-0.0011265440570958)*i;
844 for ( ; i <= (ssize_t) MaxMap; i++)
846 x_map[i].x=0.2201118963486454*(1.099*i-0.099);
847 y_map[i].x=0.4321260306242638*(1.099*i-0.099);
848 z_map[i].x=0.08392226148409894*(1.099*i-0.099);
849 x_map[i].y=(-0.1348122097479598)*(1.099*i-0.099);
850 y_map[i].y=(-0.2646647729834528)*(1.099*i-0.099);
851 z_map[i].y=0.3994769827314126*(1.099*i-0.099);
852 x_map[i].z=0.3848476530332144*(1.099*i-0.099);
853 y_map[i].z=(-0.3222618720834477)*(1.099*i-0.099);
854 z_map[i].z=(-0.06258578094976668)*(1.099*i-0.099);
861 Linear conversion tables.
863 #if defined(MAGICKCORE_OPENMP_SUPPORT)
864 #pragma omp parallel for schedule(static,4) \
865 magick_threads(image,image,1,1)
867 for (i=0; i <= (ssize_t) MaxMap; i++)
869 x_map[i].x=(MagickRealType) (1.0*(double) i);
870 y_map[i].x=(MagickRealType) 0.0;
871 z_map[i].x=(MagickRealType) 0.0;
872 x_map[i].y=(MagickRealType) 0.0;
873 y_map[i].y=(MagickRealType) (1.0*(double) i);
874 z_map[i].y=(MagickRealType) 0.0;
875 x_map[i].z=(MagickRealType) 0.0;
876 y_map[i].z=(MagickRealType) 0.0;
877 z_map[i].z=(MagickRealType) (1.0*(double) i);
885 switch (image->storage_class)
891 Convert DirectClass image.
893 image_view=AcquireAuthenticCacheView(image,exception);
894 #if defined(MAGICKCORE_OPENMP_SUPPORT)
895 #pragma omp parallel for schedule(static,4) shared(status) \
896 magick_threads(image,image,image->rows,1)
898 for (y=0; y < (ssize_t) image->rows; y++)
912 register unsigned int
917 if (status == MagickFalse)
919 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
921 if (q == (Quantum *) NULL)
926 for (x=0; x < (ssize_t) image->columns; x++)
928 red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
929 GetPixelRed(image,q)));
930 green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
931 GetPixelGreen(image,q)));
932 blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
933 GetPixelBlue(image,q)));
934 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
936 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
938 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
940 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
941 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
942 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
943 q+=GetPixelChannels(image);
945 sync=SyncCacheViewAuthenticPixels(image_view,exception);
946 if (sync == MagickFalse)
948 if (image->progress_monitor != (MagickProgressMonitor) NULL)
953 #if defined(MAGICKCORE_OPENMP_SUPPORT)
954 #pragma omp critical (MagickCore_sRGBTransformImage)
956 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
958 if (proceed == MagickFalse)
962 image_view=DestroyCacheView(image_view);
967 register unsigned int
973 Convert PseudoClass image.
975 for (i=0; i < (ssize_t) image->colors; i++)
980 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
981 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
982 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
983 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
984 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
985 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
986 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
987 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
988 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
990 (void) SyncImage(image,exception);
995 Relinquish resources.
997 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
998 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
999 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1000 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1001 return(MagickFalse);
1006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1010 % S e t I m a g e C o l o r s p a c e %
1014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016 % SetImageColorspace() sets the colorspace member of the Image structure.
1018 % The format of the SetImageColorspace method is:
1020 % MagickBooleanType SetImageColorspace(Image *image,
1021 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1023 % A description of each parameter follows:
1025 % o image: the image.
1027 % o colorspace: the colorspace.
1029 % o exception: return any errors or warnings in this structure.
1032 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1033 const ColorspaceType colorspace,ExceptionInfo *exception)
1035 if (image->colorspace == colorspace)
1037 image->colorspace=colorspace;
1038 image->rendering_intent=UndefinedIntent;
1040 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1041 if (IsGrayColorspace(colorspace) != MagickFalse)
1043 if ((image->intensity != Rec601LuminancePixelIntensityMethod) &&
1044 (image->intensity != Rec709LuminancePixelIntensityMethod) &&
1045 (image->intensity != UndefinedPixelIntensityMethod))
1046 image->gamma=1.000/2.200;
1047 image->type=GrayscaleType;
1050 if (IssRGBColorspace(colorspace) != MagickFalse)
1051 image->gamma=1.000/2.200;
1052 if (image->gamma == (1.000/2.200))
1054 image->rendering_intent=PerceptualIntent;
1055 image->gamma=1.000/2.200;
1056 image->chromaticity.red_primary.x=0.6400;
1057 image->chromaticity.red_primary.y=0.3300;
1058 image->chromaticity.red_primary.z=0.0300;
1059 image->chromaticity.green_primary.x=0.3000;
1060 image->chromaticity.green_primary.y=0.6000;
1061 image->chromaticity.green_primary.z=0.1000;
1062 image->chromaticity.blue_primary.x=0.1500;
1063 image->chromaticity.blue_primary.y=0.0600;
1064 image->chromaticity.blue_primary.z=0.7900;
1065 image->chromaticity.white_point.x=0.3127;
1066 image->chromaticity.white_point.y=0.3290;
1067 image->chromaticity.white_point.z=0.3583;
1069 if (IsGrayColorspace(colorspace) != MagickFalse)
1070 image->type=GrayscaleType;
1071 return(SyncImagePixelCache(image,exception));
1075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 % T r a n s f o r m I m a g e C o l o r s p a c e %
1083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1085 % TransformImageColorspace() transforms an image colorspace, changing the
1086 % image data to reflect the new colorspace.
1088 % The format of the TransformImageColorspace method is:
1090 % MagickBooleanType TransformImageColorspace(Image *image,
1091 % const ColorspaceType colorspace,ExceptionInfo *exception)
1093 % A description of each parameter follows:
1095 % o image: the image.
1097 % o colorspace: the colorspace.
1099 % o exception: return any errors or warnings in this structure.
1102 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1103 const ColorspaceType colorspace,ExceptionInfo *exception)
1108 assert(image != (Image *) NULL);
1109 assert(image->signature == MagickSignature);
1110 if (image->debug != MagickFalse)
1111 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1112 if (colorspace == UndefinedColorspace)
1113 return(SetImageColorspace(image,colorspace,exception));
1114 if (image->colorspace == colorspace)
1115 return(MagickTrue); /* same colorspace: no op */
1117 Convert the reference image from an alternate colorspace to sRGB.
1119 (void) DeleteImageProfile(image,"icc");
1120 (void) DeleteImageProfile(image,"icm");
1121 if (IssRGBColorspace(colorspace) != MagickFalse)
1122 return(TransformsRGBImage(image,exception));
1124 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1125 status=TransformsRGBImage(image,exception);
1126 if (status == MagickFalse)
1129 Convert the reference image from sRGB to an alternate colorspace.
1131 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1141 + T r a n s f o r m s R G B I m a g e %
1145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147 % TransformsRGBImage() converts the reference image from an alternate
1148 % colorspace to sRGB. The transformation matrices are not the standard ones:
1149 % the weights are rescaled to normalize the range of the transformed values
1150 % to be [0..QuantumRange].
1152 % The format of the TransformsRGBImage method is:
1154 % MagickBooleanType TransformsRGBImage(Image *image,
1155 % ExceptionInfo *exception)
1157 % A description of each parameter follows:
1159 % o image: the image.
1161 % o exception: return any errors or warnings in this structure.
1165 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1166 const double yellow,double *red,double *green,double *blue)
1168 *red=QuantumRange*(1.0-cyan);
1169 *green=QuantumRange*(1.0-magenta);
1170 *blue=QuantumRange*(1.0-yellow);
1173 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1174 double *X,double *Y,double *Z)
1176 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1177 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1178 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1181 static inline void ConvertLMSToRGB(const double L,const double M,
1182 const double S,double *red,double *green,double *blue)
1189 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1190 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1193 static inline void ConvertLuvToRGB(const double L,const double u,
1194 const double v,double *red,double *green,double *blue)
1201 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1202 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1205 static inline ssize_t RoundToYCC(const double value)
1209 if (value >= 1388.0)
1211 return((ssize_t) (value+0.5));
1214 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1216 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1217 (QuantumRange-pixel->black)+pixel->black)));
1218 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1219 (QuantumRange-pixel->black)+pixel->black)));
1220 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1221 (QuantumRange-pixel->black)+pixel->black)));
1224 static inline void ConvertLabToRGB(const double L,const double a,
1225 const double b,double *red,double *green,double *blue)
1232 ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1233 ConvertXYZToRGB(X,Y,Z,red,green,blue);
1236 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1237 double *red,double *green,double *blue)
1239 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
1240 1.4019995886561440468*(Pr-0.5));
1241 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
1242 0.71413649331646789076*(Pr-0.5));
1243 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
1244 2.1453384174593273e-06*(Pr-0.5));
1247 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1248 const double Cr,double *red,double *green,double *blue)
1250 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1253 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1254 double *red,double *green,double *blue)
1256 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
1258 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
1260 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
1264 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1265 double *red,double *green,double *blue)
1267 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
1269 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
1271 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
1275 static MagickBooleanType TransformsRGBImage(Image *image,
1276 ExceptionInfo *exception)
1278 #define TransformsRGBImageTag "Transform/Image"
1283 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1284 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1285 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1286 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1287 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1288 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1289 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1290 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1291 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1292 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1293 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1294 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1295 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1296 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1297 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1298 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1299 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1300 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1301 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1302 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1303 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1304 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1305 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1306 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1307 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1308 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1309 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1310 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1311 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1312 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1313 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1314 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1315 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1316 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1317 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1318 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1319 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1320 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1321 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1322 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1323 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1324 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1325 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1326 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1327 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1328 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1329 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1330 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1331 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1332 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1333 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1334 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1335 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1336 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1337 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1338 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1339 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1340 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1341 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1342 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1343 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1344 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1345 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1346 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1347 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1348 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1349 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1350 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1351 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1352 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1353 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1354 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1355 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1356 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1357 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1358 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1359 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1360 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1361 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1362 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1363 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1364 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1365 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1366 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1367 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1368 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1369 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1370 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1371 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1372 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1373 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1374 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1375 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1376 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1377 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1378 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1379 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1380 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1381 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1382 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1383 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1384 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1385 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1386 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1387 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1388 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1389 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1390 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1391 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1392 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1393 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1394 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1395 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1396 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1397 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1398 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1399 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1400 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1401 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1402 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1403 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1404 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1405 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1406 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1407 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1408 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1409 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1410 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1411 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1412 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1413 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1414 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1415 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1416 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1417 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1418 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1419 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1420 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1421 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1422 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1423 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1424 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1425 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1426 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1427 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1428 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1429 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1430 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1431 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1432 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1433 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1434 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1435 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1436 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1437 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1438 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1439 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1440 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1441 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1442 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1443 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1444 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1445 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1446 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1447 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1448 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1449 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1450 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1451 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1452 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1453 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1454 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1455 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1456 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1457 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1458 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1459 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1460 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1461 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1462 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1463 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1464 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1465 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1466 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1467 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1468 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1469 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1470 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1471 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1472 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1473 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1474 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1475 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1476 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1477 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1478 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1479 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1480 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1481 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1482 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1483 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1484 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1485 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1486 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1487 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1488 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1489 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1490 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1491 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1492 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1493 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1494 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1495 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1496 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1497 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1498 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1499 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1500 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1501 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1502 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1503 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1504 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1505 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1506 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1507 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1508 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1509 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1510 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1511 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1512 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1513 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1514 0.998559f, 0.999280f, 1.000000f
1537 assert(image != (Image *) NULL);
1538 assert(image->signature == MagickSignature);
1539 if (image->debug != MagickFalse)
1540 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1543 switch (image->colorspace)
1545 case CMYKColorspace:
1551 Transform image from CMYK to sRGB.
1553 if (image->storage_class == PseudoClass)
1555 if (SyncImage(image,exception) == MagickFalse)
1556 return(MagickFalse);
1557 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1558 return(MagickFalse);
1560 GetPixelInfo(image,&zero);
1561 image_view=AcquireAuthenticCacheView(image,exception);
1562 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1563 #pragma omp parallel for schedule(static,4) shared(status) \
1564 magick_threads(image,image,image->rows,1)
1566 for (y=0; y < (ssize_t) image->rows; y++)
1580 if (status == MagickFalse)
1582 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1584 if (q == (Quantum *) NULL)
1590 for (x=0; x < (ssize_t) image->columns; x++)
1592 GetPixelInfoPixel(image,q,&pixel);
1593 ConvertCMYKToRGB(&pixel);
1594 SetPixelInfoPixel(image,&pixel,q);
1595 q+=GetPixelChannels(image);
1597 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1598 if (sync == MagickFalse)
1601 image_view=DestroyCacheView(image_view);
1602 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1603 return(MagickFalse);
1606 case GRAYColorspace:
1609 Transform linear GRAY to sRGB colorspace.
1611 if (image->storage_class == PseudoClass)
1613 if (SyncImage(image,exception) == MagickFalse)
1614 return(MagickFalse);
1615 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1616 return(MagickFalse);
1618 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1619 return(MagickFalse);
1620 image_view=AcquireAuthenticCacheView(image,exception);
1621 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1622 #pragma omp parallel for schedule(static,4) shared(status) \
1623 magick_threads(image,image,image->rows,1)
1625 for (y=0; y < (ssize_t) image->rows; y++)
1636 if (status == MagickFalse)
1638 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1640 if (q == (Quantum *) NULL)
1645 for (x=(ssize_t) image->columns; x != 0; x--)
1650 gray=EncodePixelGamma((MagickRealType) GetPixelGray(image,q));
1651 SetPixelRed(image,ClampToQuantum(gray),q);
1652 SetPixelGreen(image,ClampToQuantum(gray),q);
1653 SetPixelBlue(image,ClampToQuantum(gray),q);
1654 q+=GetPixelChannels(image);
1656 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1657 if (sync == MagickFalse)
1660 image_view=DestroyCacheView(image_view);
1661 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1662 return(MagickFalse);
1667 case HCLpColorspace:
1675 case LCHabColorspace:
1676 case LCHuvColorspace:
1680 case YCbCrColorspace:
1682 case YPbPrColorspace:
1686 Transform image from source colorspace to sRGB.
1688 if (image->storage_class == PseudoClass)
1690 if (SyncImage(image,exception) == MagickFalse)
1691 return(MagickFalse);
1692 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1693 return(MagickFalse);
1695 image_view=AcquireAuthenticCacheView(image,exception);
1696 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1697 #pragma omp parallel for schedule(static,4) shared(status) \
1698 magick_threads(image,image,image->rows,1)
1700 for (y=0; y < (ssize_t) image->rows; y++)
1711 if (status == MagickFalse)
1713 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1715 if (q == (Quantum *) NULL)
1720 for (x=0; x < (ssize_t) image->columns; x++)
1730 X=QuantumScale*GetPixelRed(image,q);
1731 Y=QuantumScale*GetPixelGreen(image,q);
1732 Z=QuantumScale*GetPixelBlue(image,q);
1733 switch (image->colorspace)
1737 ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
1742 ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
1745 case HCLpColorspace:
1747 ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
1752 ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
1757 ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
1762 ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
1767 ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
1772 ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
1777 ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
1781 case LCHabColorspace:
1783 ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
1786 case LCHuvColorspace:
1788 ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
1793 ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
1798 ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
1803 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
1806 case YCbCrColorspace:
1808 ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
1813 ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
1816 case YPbPrColorspace:
1818 ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
1823 ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
1829 SetPixelRed(image,ClampToQuantum(red),q);
1830 SetPixelGreen(image,ClampToQuantum(green),q);
1831 SetPixelBlue(image,ClampToQuantum(blue),q);
1832 q+=GetPixelChannels(image);
1834 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1835 if (sync == MagickFalse)
1838 image_view=DestroyCacheView(image_view);
1839 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1840 return(MagickFalse);
1860 Transform Log to sRGB colorspace.
1862 density=DisplayGamma;
1864 value=GetImageProperty(image,"gamma",exception);
1865 if (value != (const char *) NULL)
1866 gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
1867 film_gamma=FilmGamma;
1868 value=GetImageProperty(image,"film-gamma",exception);
1869 if (value != (const char *) NULL)
1870 film_gamma=StringToDouble(value,(char **) NULL);
1871 reference_black=ReferenceBlack;
1872 value=GetImageProperty(image,"reference-black",exception);
1873 if (value != (const char *) NULL)
1874 reference_black=StringToDouble(value,(char **) NULL);
1875 reference_white=ReferenceWhite;
1876 value=GetImageProperty(image,"reference-white",exception);
1877 if (value != (const char *) NULL)
1878 reference_white=StringToDouble(value,(char **) NULL);
1879 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1881 if (logmap == (Quantum *) NULL)
1882 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1884 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002/
1886 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
1887 logmap[i]=(Quantum) 0;
1888 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
1889 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
1890 (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002/
1891 film_gamma)-black));
1892 for ( ; i <= (ssize_t) MaxMap; i++)
1893 logmap[i]=QuantumRange;
1894 if (image->storage_class == PseudoClass)
1896 if (SyncImage(image,exception) == MagickFalse)
1897 return(MagickFalse);
1898 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1899 return(MagickFalse);
1901 image_view=AcquireAuthenticCacheView(image,exception);
1902 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1903 #pragma omp parallel for schedule(static,4) shared(status) \
1904 magick_threads(image,image,image->rows,1)
1906 for (y=0; y < (ssize_t) image->rows; y++)
1917 if (status == MagickFalse)
1919 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1921 if (q == (Quantum *) NULL)
1926 for (x=(ssize_t) image->columns; x != 0; x--)
1933 red=(double) logmap[ScaleQuantumToMap(GetPixelRed(image,q))];
1934 green=(double) logmap[ScaleQuantumToMap(GetPixelGreen(image,q))];
1935 blue=(double) logmap[ScaleQuantumToMap(GetPixelBlue(image,q))];
1936 SetPixelRed(image,ClampToQuantum(red),q);
1937 SetPixelGreen(image,ClampToQuantum(green),q);
1938 SetPixelBlue(image,ClampToQuantum(blue),q);
1939 q+=GetPixelChannels(image);
1941 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1942 if (sync == MagickFalse)
1945 image_view=DestroyCacheView(image_view);
1946 logmap=(Quantum *) RelinquishMagickMemory(logmap);
1947 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
1948 return(MagickFalse);
1952 case scRGBColorspace:
1955 Transform linear RGB to sRGB colorspace.
1957 if (image->storage_class == PseudoClass)
1959 if (SyncImage(image,exception) == MagickFalse)
1960 return(MagickFalse);
1961 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1962 return(MagickFalse);
1964 image_view=AcquireAuthenticCacheView(image,exception);
1965 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1966 #pragma omp parallel for schedule(static,4) shared(status) \
1967 magick_threads(image,image,image->rows,1)
1969 for (y=0; y < (ssize_t) image->rows; y++)
1980 if (status == MagickFalse)
1982 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1984 if (q == (Quantum *) NULL)
1989 for (x=(ssize_t) image->columns; x != 0; x--)
1996 red=EncodePixelGamma((MagickRealType) GetPixelRed(image,q));
1997 green=EncodePixelGamma((MagickRealType) GetPixelGreen(image,q));
1998 blue=EncodePixelGamma((MagickRealType) GetPixelBlue(image,q));
1999 SetPixelRed(image,ClampToQuantum(red),q);
2000 SetPixelGreen(image,ClampToQuantum(green),q);
2001 SetPixelBlue(image,ClampToQuantum(blue),q);
2002 q+=GetPixelChannels(image);
2004 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2005 if (sync == MagickFalse)
2008 image_view=DestroyCacheView(image_view);
2009 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2010 return(MagickFalse);
2017 Allocate the tables.
2019 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2021 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2023 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2025 if ((x_map == (TransformPacket *) NULL) ||
2026 (y_map == (TransformPacket *) NULL) ||
2027 (z_map == (TransformPacket *) NULL))
2029 if (z_map != (TransformPacket *) NULL)
2030 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2031 if (y_map != (TransformPacket *) NULL)
2032 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2033 if (x_map != (TransformPacket *) NULL)
2034 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2035 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2038 switch (image->colorspace)
2040 case OHTAColorspace:
2043 Initialize OHTA tables:
2045 I1 = 0.33333*R+0.33334*G+0.33333*B
2046 I2 = 0.50000*R+0.00000*G-0.50000*B
2047 I3 =-0.25000*R+0.50000*G-0.25000*B
2048 R = I1+1.00000*I2-0.66668*I3
2049 G = I1+0.00000*I2+1.33333*I3
2050 B = I1-1.00000*I2-0.66668*I3
2052 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2053 through QuantumRange.
2055 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2056 #pragma omp parallel for schedule(static,4) \
2057 magick_threads(image,image,1,1)
2059 for (i=0; i <= (ssize_t) MaxMap; i++)
2061 x_map[i].x=(MagickRealType) (1.0*(double) i);
2062 y_map[i].x=(MagickRealType) (0.5*1.00000*(2.0*(double) i-MaxMap));
2063 z_map[i].x=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2064 x_map[i].y=(MagickRealType) (1.0*(double) i);
2065 y_map[i].y=(MagickRealType) (0.5*0.00000*(2.0*(double) i-MaxMap));
2066 z_map[i].y=(MagickRealType) (0.5*1.33333*(2.0*(double) i-MaxMap));
2067 x_map[i].z=(MagickRealType) (1.0*(double) i);
2068 y_map[i].z=(MagickRealType) (-0.5*1.00000*(2.0*(double) i-MaxMap));
2069 z_map[i].z=(MagickRealType) (-0.5*0.66668*(2.0*(double) i-MaxMap));
2073 case Rec601YCbCrColorspace:
2076 Initialize YCbCr tables:
2079 G = Y-0.344136*Cb-0.714136*Cr
2082 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2083 through QuantumRange.
2085 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2086 #pragma omp parallel for schedule(static,4) \
2087 magick_threads(image,image,1,1)
2089 for (i=0; i <= (ssize_t) MaxMap; i++)
2091 x_map[i].x=0.99999999999914679361*(double) i;
2092 y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2093 z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2094 x_map[i].y=0.99999975910502514331*(double) i;
2095 y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2096 z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2097 x_map[i].z=1.00000124040004623180*(double) i;
2098 y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2099 z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2103 case Rec709YCbCrColorspace:
2106 Initialize YCbCr tables:
2109 G = Y-0.187324*Cb-0.468124*Cr
2112 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2113 through QuantumRange.
2115 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2116 #pragma omp parallel for schedule(static,4) \
2117 magick_threads(image,image,1,1)
2119 for (i=0; i <= (ssize_t) MaxMap; i++)
2121 x_map[i].x=(MagickRealType) (1.0*i);
2122 y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2123 z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*i-MaxMap));
2124 x_map[i].y=(MagickRealType) (1.0*i);
2125 y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*i-MaxMap));
2126 z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*i-MaxMap));
2127 x_map[i].z=(MagickRealType) (1.0*i);
2128 y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*i-MaxMap));
2129 z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*i-MaxMap));
2136 Initialize YCC tables:
2139 G = Y-0.317038*C1-0.682243*C2
2142 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2144 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2145 #pragma omp parallel for schedule(static,4) \
2146 magick_threads(image,image,1,1)
2148 for (i=0; i <= (ssize_t) MaxMap; i++)
2150 x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2151 y_map[i].x=(MagickRealType) 0.0000000;
2152 z_map[i].x=(MagickRealType) (1.8215000*(1.0*(double) i-(double)
2153 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2154 x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2155 y_map[i].y=(MagickRealType) (-0.4302726*(1.0*(double) i-(double)
2156 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2157 z_map[i].y=(MagickRealType) (-0.9271435*(1.0*(double) i-(double)
2158 ScaleQuantumToMap(ScaleCharToQuantum(137))));
2159 x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2160 y_map[i].z=(MagickRealType) (2.2179000*(1.0*(double) i-(double)
2161 ScaleQuantumToMap(ScaleCharToQuantum(156))));
2162 z_map[i].z=(MagickRealType) 0.0000000;
2169 Linear conversion tables.
2171 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2172 #pragma omp parallel for schedule(static,4) \
2173 magick_threads(image,image,1,1)
2175 for (i=0; i <= (ssize_t) MaxMap; i++)
2177 x_map[i].x=(MagickRealType) (1.0*(double) i);
2178 y_map[i].x=(MagickRealType) 0.0;
2179 z_map[i].x=(MagickRealType) 0.0;
2180 x_map[i].y=(MagickRealType) 0.0;
2181 y_map[i].y=(MagickRealType) (1.0*(double) i);
2182 z_map[i].y=(MagickRealType) 0.0;
2183 x_map[i].z=(MagickRealType) 0.0;
2184 y_map[i].z=(MagickRealType) 0.0;
2185 z_map[i].z=(MagickRealType) (1.0*(double) i);
2193 switch (image->storage_class)
2199 Convert DirectClass image.
2201 image_view=AcquireAuthenticCacheView(image,exception);
2202 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2203 #pragma omp parallel for schedule(static,4) shared(status) \
2204 magick_threads(image,image,image->rows,1)
2206 for (y=0; y < (ssize_t) image->rows; y++)
2220 if (status == MagickFalse)
2222 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2224 if (q == (Quantum *) NULL)
2229 for (x=0; x < (ssize_t) image->columns; x++)
2236 red=ScaleQuantumToMap(GetPixelRed(image,q));
2237 green=ScaleQuantumToMap(GetPixelGreen(image,q));
2238 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
2239 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2240 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2241 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2242 if (image->colorspace == YCCColorspace)
2244 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2246 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2248 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2253 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2254 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2255 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2257 SetPixelRed(image,ClampToQuantum(pixel.red),q);
2258 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
2259 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
2260 q+=GetPixelChannels(image);
2262 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2263 if (sync == MagickFalse)
2265 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2270 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2271 #pragma omp critical (MagickCore_TransformsRGBImage)
2273 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
2275 if (proceed == MagickFalse)
2279 image_view=DestroyCacheView(image_view);
2285 Convert PseudoClass image.
2287 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2288 #pragma omp parallel for schedule(static,4) shared(status) \
2289 magick_threads(image,image,1,1)
2291 for (i=0; i < (ssize_t) image->colors; i++)
2301 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
2302 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
2303 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
2304 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2305 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2306 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2307 if (image->colorspace == YCCColorspace)
2309 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2311 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2313 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2318 pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2319 pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2320 pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2322 image->colormap[i].red=(double) ClampToQuantum(pixel.red);
2323 image->colormap[i].green=(double) ClampToQuantum(pixel.green);
2324 image->colormap[i].blue=(double) ClampToQuantum(pixel.blue);
2326 (void) SyncImage(image,exception);
2331 Relinquish resources.
2333 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2334 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2335 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2336 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2337 return(MagickFalse);