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-2012 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 *,const ColorspaceType,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 ConvertRGBToXYZ(const double red,const double green,
119 const double blue,double *X,double *Y,double *Z)
126 assert(X != (double *) NULL);
127 assert(Y != (double *) NULL);
128 assert(Z != (double *) NULL);
130 g=QuantumScale*green;
132 *X=0.4124564*r+0.3575761*g+0.1804375*b;
133 *Y=0.2126729*r+0.7151522*g+0.0721750*b;
134 *Z=0.0193339*r+0.1191920*g+0.9503041*b;
137 static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
138 double *L,double *a,double *b)
140 #define D65X (0.950470)
142 #define D65Z (1.088830)
143 #define CIEEpsilon (216.0/24389.0)
144 #define CIEK (24389.0/27.0)
151 assert(L != (double *) NULL);
152 assert(a != (double *) NULL);
153 assert(b != (double *) NULL);
154 if ((X/D65X) > CIEEpsilon)
155 x=pow(X/D65X,1.0/3.0);
157 x=(CIEK*X/D65X+16.0)/116.0;
158 if ((Y/D65Y) > CIEEpsilon)
159 y=pow(Y/D65Y,1.0/3.0);
161 y=(CIEK*Y/D65Y+16.0)/116.0;
162 if ((Z/D65Z) > CIEEpsilon)
163 z=pow(Z/D65Z,1.0/3.0);
165 z=(CIEK*Z/D65Z+16.0)/116.0;
166 *L=((116.0*y)-16.0)/100.0;
167 *a=(500.0*(x-y))/255.0+0.5;
168 *b=(200.0*(y-z))/255.0+0.5;
171 static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
172 double *L,double *u,double *v)
177 assert(L != (double *) NULL);
178 assert(u != (double *) NULL);
179 assert(v != (double *) NULL);
180 if ((Y/D65Y) > CIEEpsilon)
181 *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
184 alpha=MagickEpsilonReciprocal(X+15.0*Y+3.0*Z);
185 *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
186 *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
192 static MagickBooleanType sRGBTransformImage(Image *image,
193 const ColorspaceType colorspace,ExceptionInfo *exception)
195 #define sRGBTransformImageTag "RGBTransform/Image"
220 assert(image != (Image *) NULL);
221 assert(image->signature == MagickSignature);
222 if (image->debug != MagickFalse)
223 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
224 assert(colorspace != sRGBColorspace);
225 assert(colorspace != TransparentColorspace);
226 assert(colorspace != UndefinedColorspace);
234 Convert RGB to CMY colorspace.
236 if (image->storage_class == PseudoClass)
238 if (SyncImage(image,exception) == MagickFalse)
240 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
243 image_view=AcquireAuthenticCacheView(image,exception);
244 #if defined(MAGICKCORE_OPENMP_SUPPORT)
245 #pragma omp parallel for schedule(static,4) shared(status) \
246 dynamic_number_threads(image,image->columns,image->rows,1)
248 for (y=0; y < (ssize_t) image->rows; y++)
259 if (status == MagickFalse)
261 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
263 if (q == (Quantum *) NULL)
268 for (x=0; x < (ssize_t) image->columns; x++)
275 cyan=InversesRGBCompandor((double) GetPixelCyan(image,q));
276 magenta=InversesRGBCompandor((double) GetPixelMagenta(image,q));
277 yellow=InversesRGBCompandor((double) GetPixelYellow(image,q));
278 SetPixelCyan(image,ClampToQuantum(QuantumRange-cyan),q);
279 SetPixelMagenta(image,ClampToQuantum(QuantumRange-magenta),q);
280 SetPixelYellow(image,ClampToQuantum(QuantumRange-yellow),q);
281 q+=GetPixelChannels(image);
283 sync=SyncCacheViewAuthenticPixels(image_view,exception);
284 if (sync == MagickFalse)
287 image_view=DestroyCacheView(image_view);
288 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
289 ColorSeparationMatteType;
290 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
300 Convert RGB to CMYK colorspace.
302 if (image->storage_class == PseudoClass)
304 if (SyncImage(image,exception) == MagickFalse)
306 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
309 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
311 GetPixelInfo(image,&zero);
312 image_view=AcquireAuthenticCacheView(image,exception);
313 #if defined(MAGICKCORE_OPENMP_SUPPORT)
314 #pragma omp parallel for schedule(static,4) shared(status) \
315 dynamic_number_threads(image,image->columns,image->rows,1)
317 for (y=0; y < (ssize_t) image->rows; y++)
331 if (status == MagickFalse)
333 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
335 if (q == (Quantum *) NULL)
341 for (x=0; x < (ssize_t) image->columns; x++)
343 GetPixelInfoPixel(image,q,&pixel);
344 pixel.red=InversesRGBCompandor(pixel.red);
345 pixel.green=InversesRGBCompandor(pixel.green);
346 pixel.blue=InversesRGBCompandor(pixel.blue);
347 ConvertRGBToCMYK(&pixel);
348 SetPixelInfoPixel(image,&pixel,q);
349 q+=GetPixelChannels(image);
351 sync=SyncCacheViewAuthenticPixels(image_view,exception);
352 if (sync == MagickFalse)
355 image_view=DestroyCacheView(image_view);
356 image->type=image->alpha_trait != BlendPixelTrait ? ColorSeparationType :
357 ColorSeparationMatteType;
358 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
363 case Rec601LumaColorspace:
366 Transform image from sRGB to GRAY.
368 if (image->storage_class == PseudoClass)
370 if (SyncImage(image,exception) == MagickFalse)
372 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
375 image_view=AcquireAuthenticCacheView(image,exception);
376 #if defined(MAGICKCORE_OPENMP_SUPPORT)
377 #pragma omp parallel for schedule(static,4) shared(status) \
378 dynamic_number_threads(image,image->columns,image->rows,1)
380 for (y=0; y < (ssize_t) image->rows; y++)
391 if (status == MagickFalse)
393 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
395 if (q == (Quantum *) NULL)
400 for (x=0; x < (ssize_t) image->columns; x++)
408 red=InversesRGBCompandor((double) GetPixelRed(image,q));
409 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
410 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
411 gray=0.298839*red+0.586811*green+0.114350*blue;
412 SetPixelGray(image,ClampToQuantum(gray),q);
413 q+=GetPixelChannels(image);
415 sync=SyncCacheViewAuthenticPixels(image_view,exception);
416 if (sync == MagickFalse)
419 image_view=DestroyCacheView(image_view);
420 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
422 image->type=GrayscaleType;
428 Transform image from sRGB to HCL.
430 if (image->storage_class == PseudoClass)
432 if (SyncImage(image,exception) == MagickFalse)
434 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
437 image_view=AcquireAuthenticCacheView(image,exception);
438 #if defined(MAGICKCORE_OPENMP_SUPPORT)
439 #pragma omp parallel for schedule(static,4) shared(status) \
440 dynamic_number_threads(image,image->columns,image->rows,1)
442 for (y=0; y < (ssize_t) image->rows; y++)
453 if (status == MagickFalse)
455 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
457 if (q == (Quantum *) NULL)
462 for (x=0; x < (ssize_t) image->columns; x++)
472 red=InversesRGBCompandor((double) GetPixelRed(image,q));
473 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
474 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
475 ConvertRGBToHCL(red,green,blue,&hue,&chroma,&luma);
476 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
477 SetPixelGreen(image,ClampToQuantum(QuantumRange*chroma),q);
478 SetPixelBlue(image,ClampToQuantum(QuantumRange*luma),q);
479 q+=GetPixelChannels(image);
481 sync=SyncCacheViewAuthenticPixels(image_view,exception);
482 if (sync == MagickFalse)
485 image_view=DestroyCacheView(image_view);
486 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
493 Transform image from sRGB to HSB.
495 if (image->storage_class == PseudoClass)
497 if (SyncImage(image,exception) == MagickFalse)
499 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
502 image_view=AcquireAuthenticCacheView(image,exception);
503 #if defined(MAGICKCORE_OPENMP_SUPPORT)
504 #pragma omp parallel for schedule(static,4) shared(status) \
505 dynamic_number_threads(image,image->columns,image->rows,1)
507 for (y=0; y < (ssize_t) image->rows; y++)
518 if (status == MagickFalse)
520 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
522 if (q == (Quantum *) NULL)
527 for (x=0; x < (ssize_t) image->columns; x++)
537 red=InversesRGBCompandor((double) GetPixelRed(image,q));
538 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
539 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
540 ConvertRGBToHSB(red,green,blue,&hue,&saturation,&brightness);
541 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
542 SetPixelGreen(image,ClampToQuantum(QuantumRange*saturation),q);
543 SetPixelBlue(image,ClampToQuantum(QuantumRange*brightness),q);
544 q+=GetPixelChannels(image);
546 sync=SyncCacheViewAuthenticPixels(image_view,exception);
547 if (sync == MagickFalse)
550 image_view=DestroyCacheView(image_view);
551 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
558 Transform image from sRGB to HSL.
560 if (image->storage_class == PseudoClass)
562 if (SyncImage(image,exception) == MagickFalse)
564 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
567 image_view=AcquireAuthenticCacheView(image,exception);
568 #if defined(MAGICKCORE_OPENMP_SUPPORT)
569 #pragma omp parallel for schedule(static,4) shared(status) \
570 dynamic_number_threads(image,image->columns,image->rows,1)
572 for (y=0; y < (ssize_t) image->rows; y++)
583 if (status == MagickFalse)
585 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
587 if (q == (Quantum *) NULL)
592 for (x=0; x < (ssize_t) image->columns; x++)
602 red=InversesRGBCompandor((double) GetPixelRed(image,q));
603 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
604 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
605 ConvertRGBToHSL(red,green,blue,&hue,&saturation,&lightness);
606 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
607 SetPixelGreen(image,ClampToQuantum(QuantumRange*saturation),q);
608 SetPixelBlue(image,ClampToQuantum(QuantumRange*lightness),q);
609 q+=GetPixelChannels(image);
611 sync=SyncCacheViewAuthenticPixels(image_view,exception);
612 if (sync == MagickFalse)
615 image_view=DestroyCacheView(image_view);
616 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
623 Transform image from sRGB to HWB.
625 if (image->storage_class == PseudoClass)
627 if (SyncImage(image,exception) == MagickFalse)
629 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
632 image_view=AcquireAuthenticCacheView(image,exception);
633 #if defined(MAGICKCORE_OPENMP_SUPPORT)
634 #pragma omp parallel for schedule(static,4) shared(status) \
635 dynamic_number_threads(image,image->columns,image->rows,1)
637 for (y=0; y < (ssize_t) image->rows; y++)
648 if (status == MagickFalse)
650 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
652 if (q == (Quantum *) NULL)
657 for (x=0; x < (ssize_t) image->columns; x++)
667 red=InversesRGBCompandor((double) GetPixelRed(image,q));
668 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
669 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
670 ConvertRGBToHWB(red,green,blue,&hue,&whiteness,&blackness);
671 SetPixelRed(image,ClampToQuantum(QuantumRange*hue),q);
672 SetPixelGreen(image,ClampToQuantum(QuantumRange*whiteness),q);
673 SetPixelBlue(image,ClampToQuantum(QuantumRange*blackness),q);
674 q+=GetPixelChannels(image);
676 sync=SyncCacheViewAuthenticPixels(image_view,exception);
677 if (sync == MagickFalse)
680 image_view=DestroyCacheView(image_view);
681 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
688 Transform image from sRGB to Lab.
690 if (image->storage_class == PseudoClass)
692 if (SyncImage(image,exception) == MagickFalse)
694 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
697 image_view=AcquireAuthenticCacheView(image,exception);
698 #if defined(MAGICKCORE_OPENMP_SUPPORT)
699 #pragma omp parallel for schedule(static,4) shared(status) \
700 dynamic_number_threads(image,image->columns,image->rows,1)
702 for (y=0; y < (ssize_t) image->rows; y++)
713 if (status == MagickFalse)
715 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
717 if (q == (Quantum *) NULL)
722 for (x=0; x < (ssize_t) image->columns; x++)
735 red=InversesRGBCompandor((double) GetPixelRed(image,q));
736 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
737 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
738 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
739 ConvertXYZToLab(X,Y,Z,&L,&a,&b);
740 SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
741 SetPixelGreen(image,ClampToQuantum(QuantumRange*a),q);
742 SetPixelBlue(image,ClampToQuantum(QuantumRange*b),q);
743 q+=GetPixelChannels(image);
745 sync=SyncCacheViewAuthenticPixels(image_view,exception);
746 if (sync == MagickFalse)
749 image_view=DestroyCacheView(image_view);
750 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
756 #define DisplayGamma (1.0/1.7)
757 #define FilmGamma 0.6
758 #define ReferenceBlack 95.0
759 #define ReferenceWhite 685.0
776 Transform RGB to Log colorspace.
778 density=DisplayGamma;
780 value=GetImageProperty(image,"gamma",exception);
781 if (value != (const char *) NULL)
782 gamma=MagickEpsilonReciprocal(StringToDouble(value,(char **) NULL));
783 film_gamma=FilmGamma;
784 value=GetImageProperty(image,"film-gamma",exception);
785 if (value != (const char *) NULL)
786 film_gamma=StringToDouble(value,(char **) NULL);
787 reference_black=ReferenceBlack;
788 value=GetImageProperty(image,"reference-black",exception);
789 if (value != (const char *) NULL)
790 reference_black=StringToDouble(value,(char **) NULL);
791 reference_white=ReferenceWhite;
792 value=GetImageProperty(image,"reference-white",exception);
793 if (value != (const char *) NULL)
794 reference_white=StringToDouble(value,(char **) NULL);
795 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
797 if (logmap == (Quantum *) NULL)
798 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
800 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*
802 #if defined(MAGICKCORE_OPENMP_SUPPORT)
803 #pragma omp parallel for schedule(static) \
804 dynamic_number_threads(image,image->columns,1,1)
806 for (i=0; i <= (ssize_t) MaxMap; i++)
807 logmap[i]=ScaleMapToQuantum((double) (MaxMap*(reference_white+
808 log10(black+((double) i/MaxMap)*(1.0-black))/((gamma/density)*
809 0.002/film_gamma))/1024.0));
810 image_view=AcquireAuthenticCacheView(image,exception);
811 #if defined(MAGICKCORE_OPENMP_SUPPORT)
812 #pragma omp parallel for schedule(static,4) shared(status) \
813 dynamic_number_threads(image,image->columns,image->rows,1)
815 for (y=0; y < (ssize_t) image->rows; y++)
826 if (status == MagickFalse)
828 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
830 if (q == (Quantum *) NULL)
835 for (x=(ssize_t) image->columns; x != 0; x--)
842 red=InversesRGBCompandor((double) GetPixelRed(image,q));
843 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
844 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
845 SetPixelRed(image,logmap[ScaleQuantumToMap(
846 ClampToQuantum(red))],q);
847 SetPixelGreen(image,logmap[ScaleQuantumToMap(
848 ClampToQuantum(green))],q);
849 SetPixelBlue(image,logmap[ScaleQuantumToMap(
850 ClampToQuantum(blue))],q);
851 q+=GetPixelChannels(image);
853 sync=SyncCacheViewAuthenticPixels(image_view,exception);
854 if (sync == MagickFalse)
857 image_view=DestroyCacheView(image_view);
858 logmap=(Quantum *) RelinquishMagickMemory(logmap);
859 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
866 Transform image from sRGB to Luv.
868 if (image->storage_class == PseudoClass)
870 if (SyncImage(image,exception) == MagickFalse)
872 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
875 image_view=AcquireAuthenticCacheView(image,exception);
876 #if defined(MAGICKCORE_OPENMP_SUPPORT)
877 #pragma omp parallel for schedule(static,4) shared(status) \
878 dynamic_number_threads(image,image->columns,image->rows,1)
880 for (y=0; y < (ssize_t) image->rows; y++)
891 if (status == MagickFalse)
893 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
895 if (q == (Quantum *) NULL)
900 for (x=0; x < (ssize_t) image->columns; x++)
913 red=InversesRGBCompandor((double) GetPixelRed(image,q));
914 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
915 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
916 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
917 ConvertXYZToLuv(X,Y,Z,&L,&u,&v);
918 SetPixelRed(image,ClampToQuantum(QuantumRange*L),q);
919 SetPixelGreen(image,ClampToQuantum(QuantumRange*u),q);
920 SetPixelBlue(image,ClampToQuantum(QuantumRange*v),q);
921 q+=GetPixelChannels(image);
923 sync=SyncCacheViewAuthenticPixels(image_view,exception);
924 if (sync == MagickFalse)
927 image_view=DestroyCacheView(image_view);
928 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
932 case Rec709LumaColorspace:
935 Transform image from sRGB to Rec709Luma.
937 if (image->storage_class == PseudoClass)
939 if (SyncImage(image,exception) == MagickFalse)
941 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
944 image_view=AcquireAuthenticCacheView(image,exception);
945 #if defined(MAGICKCORE_OPENMP_SUPPORT)
946 #pragma omp parallel for schedule(static,4) shared(status) \
947 dynamic_number_threads(image,image->columns,image->rows,1)
949 for (y=0; y < (ssize_t) image->rows; y++)
960 if (status == MagickFalse)
962 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
964 if (q == (Quantum *) NULL)
969 for (x=0; x < (ssize_t) image->columns; x++)
977 red=InversesRGBCompandor((double) GetPixelRed(image,q));
978 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
979 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
980 gray=0.212600*red+0.715200*green+0.072200*blue;
981 SetPixelGray(image,ClampToQuantum(gray),q);
982 q+=GetPixelChannels(image);
984 sync=SyncCacheViewAuthenticPixels(image_view,exception);
985 if (sync == MagickFalse)
988 image_view=DestroyCacheView(image_view);
989 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
991 image->type=GrayscaleType;
997 Transform image from sRGB to linear RGB.
999 if (image->storage_class == PseudoClass)
1001 if (SyncImage(image,exception) == MagickFalse)
1002 return(MagickFalse);
1003 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1004 return(MagickFalse);
1006 image_view=AcquireAuthenticCacheView(image,exception);
1007 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1008 #pragma omp parallel for schedule(static,4) shared(status) \
1009 dynamic_number_threads(image,image->columns,image->rows,1)
1011 for (y=0; y < (ssize_t) image->rows; y++)
1022 if (status == MagickFalse)
1024 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1026 if (q == (Quantum *) NULL)
1031 for (x=0; x < (ssize_t) image->columns; x++)
1038 red=InversesRGBCompandor((double) GetPixelRed(image,q));
1039 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
1040 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
1041 SetPixelRed(image,ClampToQuantum(red),q);
1042 SetPixelGreen(image,ClampToQuantum(green),q);
1043 SetPixelBlue(image,ClampToQuantum(blue),q);
1044 q+=GetPixelChannels(image);
1046 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1047 if (sync == MagickFalse)
1050 image_view=DestroyCacheView(image_view);
1051 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1052 return(MagickFalse);
1058 Transform image from sRGB to XYZ.
1060 if (image->storage_class == PseudoClass)
1062 if (SyncImage(image,exception) == MagickFalse)
1063 return(MagickFalse);
1064 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1065 return(MagickFalse);
1067 image_view=AcquireAuthenticCacheView(image,exception);
1068 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1069 #pragma omp parallel for schedule(static,4) shared(status) \
1070 dynamic_number_threads(image,image->columns,image->rows,1)
1072 for (y=0; y < (ssize_t) image->rows; y++)
1083 if (status == MagickFalse)
1085 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1087 if (q == (Quantum *) NULL)
1092 for (x=0; x < (ssize_t) image->columns; x++)
1102 red=InversesRGBCompandor((double) GetPixelRed(image,q));
1103 green=InversesRGBCompandor((double) GetPixelGreen(image,q));
1104 blue=InversesRGBCompandor((double) GetPixelBlue(image,q));
1105 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
1106 SetPixelRed(image,ClampToQuantum(QuantumRange*X),q);
1107 SetPixelGreen(image,ClampToQuantum(QuantumRange*Y),q);
1108 SetPixelBlue(image,ClampToQuantum(QuantumRange*Z),q);
1109 q+=GetPixelChannels(image);
1111 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1112 if (sync == MagickFalse)
1115 image_view=DestroyCacheView(image_view);
1116 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1117 return(MagickFalse);
1124 Allocate the tables.
1126 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1128 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1130 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
1132 if ((x_map == (TransformPacket *) NULL) ||
1133 (y_map == (TransformPacket *) NULL) ||
1134 (z_map == (TransformPacket *) NULL))
1135 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1137 (void) ResetMagickMemory(&primary_info,0,sizeof(primary_info));
1140 case OHTAColorspace:
1143 Initialize OHTA tables:
1145 I1 = 0.33333*R+0.33334*G+0.33333*B
1146 I2 = 0.50000*R+0.00000*G-0.50000*B
1147 I3 =-0.25000*R+0.50000*G-0.25000*B
1149 I and Q, normally -0.5 through 0.5, are normalized to the range 0
1150 through QuantumRange.
1152 primary_info.y=(double) (MaxMap+1.0)/2.0;
1153 primary_info.z=(double) (MaxMap+1.0)/2.0;
1154 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1155 #pragma omp parallel for schedule(static) \
1156 dynamic_number_threads(image,image->columns,1,1)
1158 for (i=0; i <= (ssize_t) MaxMap; i++)
1160 x_map[i].x=0.33333*(double) i;
1161 y_map[i].x=0.33334*(double) i;
1162 z_map[i].x=0.33333*(double) i;
1163 x_map[i].y=0.50000*(double) i;
1164 y_map[i].y=0.00000*(double) i;
1165 z_map[i].y=(-0.50000)*(double) i;
1166 x_map[i].z=(-0.25000)*(double) i;
1167 y_map[i].z=0.50000*(double) i;
1168 z_map[i].z=(-0.25000)*(double) i;
1172 case Rec601YCbCrColorspace:
1173 case YCbCrColorspace:
1176 Initialize YCbCr tables (ITU-R BT.601):
1178 Y = 0.298839*R+0.586811*G+0.114350*B
1179 Cb= -0.168736*R-0.331264*G+0.500000*B
1180 Cr= 0.500000*R-0.418688*G-0.081312*B
1182 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
1183 through QuantumRange.
1185 primary_info.y=(double) (MaxMap+1.0)/2.0;
1186 primary_info.z=(double) (MaxMap+1.0)/2.0;
1187 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1188 #pragma omp parallel for schedule(static) \
1189 dynamic_number_threads(image,image->columns,1,1)
1191 for (i=0; i <= (ssize_t) MaxMap; i++)
1193 x_map[i].x=0.298839*(double) i;
1194 y_map[i].x=0.586811*(double) i;
1195 z_map[i].x=0.114350*(double) i;
1196 x_map[i].y=(-0.168730)*(double) i;
1197 y_map[i].y=(-0.331264)*(double) i;
1198 z_map[i].y=0.500000*(double) i;
1199 x_map[i].z=0.500000*(double) i;
1200 y_map[i].z=(-0.418688)*(double) i;
1201 z_map[i].z=(-0.081312)*(double) i;
1205 case Rec709YCbCrColorspace:
1208 Initialize YCbCr tables (ITU-R BT.709):
1210 Y = 0.212600*R+0.715200*G+0.072200*B
1211 Cb= -0.114572*R-0.385428*G+0.500000*B
1212 Cr= 0.500000*R-0.454153*G-0.045847*B
1214 Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
1215 through QuantumRange.
1217 primary_info.y=(double) (MaxMap+1.0)/2.0;
1218 primary_info.z=(double) (MaxMap+1.0)/2.0;
1219 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1220 #pragma omp parallel for schedule(static) \
1221 dynamic_number_threads(image,image->columns,1,1)
1223 for (i=0; i <= (ssize_t) MaxMap; i++)
1225 x_map[i].x=0.212600*(double) i;
1226 y_map[i].x=0.715200*(double) i;
1227 z_map[i].x=0.072200*(double) i;
1228 x_map[i].y=(-0.114572)*(double) i;
1229 y_map[i].y=(-0.385428)*(double) i;
1230 z_map[i].y=0.500000*(double) i;
1231 x_map[i].z=0.500000*(double) i;
1232 y_map[i].z=(-0.454153)*(double) i;
1233 z_map[i].z=(-0.045847)*(double) i;
1240 Initialize YCC tables:
1242 Y = 0.298839*R+0.586811*G+0.114350*B
1243 C1= -0.298839*R-0.586811*G+0.88600*B
1244 C2= 0.70100*R-0.586811*G-0.114350*B
1246 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
1248 primary_info.y=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
1249 primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
1250 for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
1252 x_map[i].x=0.003962014134275617*(double) i;
1253 y_map[i].x=0.007778268551236748*(double) i;
1254 z_map[i].x=0.001510600706713781*(double) i;
1255 x_map[i].y=(-0.002426619775463276)*(double) i;
1256 y_map[i].y=(-0.004763965913702149)*(double) i;
1257 z_map[i].y=0.007190585689165425*(double) i;
1258 x_map[i].z=0.006927257754597858*(double) i;
1259 y_map[i].z=(-0.005800713697502058)*(double) i;
1260 z_map[i].z=(-0.0011265440570958)*(double) i;
1262 for ( ; i <= (ssize_t) MaxMap; i++)
1264 x_map[i].x=0.2201118963486454*(1.099*(double) i-0.099);
1265 y_map[i].x=0.4321260306242638*(1.099*(double) i-0.099);
1266 z_map[i].x=0.08392226148409894*(1.099*(double) i-0.099);
1267 x_map[i].y=(-0.1348122097479598)*(1.099*(double) i-0.099);
1268 y_map[i].y=(-0.2646647729834528)*(1.099*(double) i-0.099);
1269 z_map[i].y=0.3994769827314126*(1.099*(double) i-0.099);
1270 x_map[i].z=0.3848476530332144*(1.099*(double) i-0.099);
1271 y_map[i].z=(-0.3222618720834477)*(1.099*(double) i-0.099);
1272 z_map[i].z=(-0.06258578094976668)*(1.099*(double) i-0.099);
1279 Initialize YIQ tables:
1281 Y = 0.298839*R+0.586811*G+0.114350*B
1282 I = 0.59600*R-0.27400*G-0.32200*B
1283 Q = 0.21100*R-0.52300*G+0.31200*B
1285 I and Q, normally -0.5 through 0.5, are normalized to the range 0
1286 through QuantumRange.
1288 primary_info.y=(double) (MaxMap+1.0)/2.0;
1289 primary_info.z=(double) (MaxMap+1.0)/2.0;
1290 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1291 #pragma omp parallel for schedule(static) \
1292 dynamic_number_threads(image,image->columns,1,1)
1294 for (i=0; i <= (ssize_t) MaxMap; i++)
1296 x_map[i].x=0.298839*(double) i;
1297 y_map[i].x=0.586811*(double) i;
1298 z_map[i].x=0.114350*(double) i;
1299 x_map[i].y=0.59600*(double) i;
1300 y_map[i].y=(-0.27400)*(double) i;
1301 z_map[i].y=(-0.32200)*(double) i;
1302 x_map[i].z=0.21100*(double) i;
1303 y_map[i].z=(-0.52300)*(double) i;
1304 z_map[i].z=0.31200*(double) i;
1308 case YPbPrColorspace:
1311 Initialize YPbPr tables (ITU-R BT.601):
1313 Y = 0.298839*R+0.586811*G+0.114350*B
1314 Pb= -0.168736*R-0.331264*G+0.500000*B
1315 Pr= 0.500000*R-0.418688*G-0.081312*B
1317 Pb and Pr, normally -0.5 through 0.5, are normalized to the range 0
1318 through QuantumRange.
1320 primary_info.y=(double) (MaxMap+1.0)/2.0;
1321 primary_info.z=(double) (MaxMap+1.0)/2.0;
1322 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1323 #pragma omp parallel for schedule(static) \
1324 dynamic_number_threads(image,image->columns,1,1)
1326 for (i=0; i <= (ssize_t) MaxMap; i++)
1328 x_map[i].x=0.298839*(double) i;
1329 y_map[i].x=0.586811*(double) i;
1330 z_map[i].x=0.114350*(double) i;
1331 x_map[i].y=(-0.168736)*(double) i;
1332 y_map[i].y=(-0.331264)*(double) i;
1333 z_map[i].y=0.500000*(double) i;
1334 x_map[i].z=0.500000*(double) i;
1335 y_map[i].z=(-0.418688)*(double) i;
1336 z_map[i].z=(-0.081312)*(double) i;
1343 Initialize YUV tables:
1345 Y = 0.298839*R+0.586811*G+0.114350*B
1346 U = -0.168736*R-0.331264*G+0.500000*B
1347 V = 0.500000*R-0.418688*G-0.081312*B
1349 U and V, normally -0.5 through 0.5, are normalized to the range 0
1350 through QuantumRange. Note that U = 0.493*(B-Y), V = 0.877*(R-Y).
1352 primary_info.y=(double) (MaxMap+1.0)/2.0;
1353 primary_info.z=(double) (MaxMap+1.0)/2.0;
1354 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1355 #pragma omp parallel for schedule(static) \
1356 dynamic_number_threads(image,image->columns,1,1)
1358 for (i=0; i <= (ssize_t) MaxMap; i++)
1360 x_map[i].x=0.298839*(double) i;
1361 y_map[i].x=0.586811*(double) i;
1362 z_map[i].x=0.114350*(double) i;
1363 x_map[i].y=(-0.168736)*(double) i;
1364 y_map[i].y=(-0.331264)*(double) i;
1365 z_map[i].y=0.500000*(double) i;
1366 x_map[i].z=0.500000*(double) i;
1367 y_map[i].z=(-0.418688)*(double) i;
1368 z_map[i].z=(-0.081312)*(double) i;
1375 Linear conversion tables.
1377 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1378 #pragma omp parallel for schedule(static) \
1379 dynamic_number_threads(image,image->columns,1,1)
1381 for (i=0; i <= (ssize_t) MaxMap; i++)
1383 x_map[i].x=(double) i;
1387 y_map[i].y=(double) i;
1391 z_map[i].z=(double) i;
1399 switch (image->storage_class)
1405 Convert DirectClass image.
1407 image_view=AcquireAuthenticCacheView(image,exception);
1408 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1409 #pragma omp parallel for schedule(static,4) shared(status) \
1410 dynamic_number_threads(image,image->columns,image->rows,1)
1412 for (y=0; y < (ssize_t) image->rows; y++)
1426 register unsigned int
1431 if (status == MagickFalse)
1433 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1435 if (q == (Quantum *) NULL)
1440 for (x=0; x < (ssize_t) image->columns; x++)
1442 red=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor((double)
1443 GetPixelRed(image,q))));
1444 green=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor((double)
1445 GetPixelGreen(image,q))));
1446 blue=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor((double)
1447 GetPixelBlue(image,q))));
1448 pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
1450 pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
1452 pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
1454 SetPixelRed(image,ScaleMapToQuantum(pixel.red),q);
1455 SetPixelGreen(image,ScaleMapToQuantum(pixel.green),q);
1456 SetPixelBlue(image,ScaleMapToQuantum(pixel.blue),q);
1457 q+=GetPixelChannels(image);
1459 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1460 if (sync == MagickFalse)
1462 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1467 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1468 #pragma omp critical (MagickCore_sRGBTransformImage)
1470 proceed=SetImageProgress(image,sRGBTransformImageTag,progress++,
1472 if (proceed == MagickFalse)
1476 image_view=DestroyCacheView(image_view);
1481 register unsigned int
1487 Convert PseudoClass image.
1489 for (i=0; i < (ssize_t) image->colors; i++)
1494 red=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor(
1495 image->colormap[i].red)));
1496 green=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor(
1497 image->colormap[i].green)));
1498 blue=ScaleQuantumToMap(ClampToQuantum(InversesRGBCompandor(
1499 image->colormap[i].blue)));
1500 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1501 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1502 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1503 image->colormap[i].red=(double) ScaleMapToQuantum(pixel.red);
1504 image->colormap[i].green=(double) ScaleMapToQuantum(pixel.green);
1505 image->colormap[i].blue=(double) ScaleMapToQuantum(pixel.blue);
1507 (void) SyncImage(image,exception);
1512 Relinquish resources.
1514 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1515 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1516 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1517 if (SetImageColorspace(image,colorspace,exception) == MagickFalse)
1518 return(MagickFalse);
1523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1527 % S e t I m a g e C o l o r s p a c e %
1531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1533 % SetImageColorspace() sets the colorspace member of the Image structure.
1535 % The format of the SetImageColorspace method is:
1537 % MagickBooleanType SetImageColorspace(Image *image,
1538 % const ColorspaceType colorspace,ExceptiionInfo *exception)
1540 % A description of each parameter follows:
1542 % o image: the image.
1544 % o colorspace: the colorspace.
1546 % o exception: return any errors or warnings in this structure.
1549 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1550 const ColorspaceType colorspace,ExceptionInfo *exception)
1552 if (image->colorspace == colorspace)
1554 image->colorspace=colorspace;
1555 image->rendering_intent=UndefinedIntent;
1557 (void) ResetMagickMemory(&image->chromaticity,0,sizeof(image->chromaticity));
1558 if (IssRGBColorspace(colorspace) != MagickFalse)
1560 image->rendering_intent=PerceptualIntent;
1561 image->gamma=1.000/2.200;
1562 image->chromaticity.red_primary.x=0.6400;
1563 image->chromaticity.red_primary.y=0.3300;
1564 image->chromaticity.red_primary.z=0.0300;
1565 image->chromaticity.green_primary.x=0.3000;
1566 image->chromaticity.green_primary.y=0.6000;
1567 image->chromaticity.green_primary.z=0.1000;
1568 image->chromaticity.blue_primary.x=0.1500;
1569 image->chromaticity.blue_primary.y=0.0600;
1570 image->chromaticity.blue_primary.z=0.7900;
1571 image->chromaticity.white_point.x=0.3127;
1572 image->chromaticity.white_point.y=0.3290;
1573 image->chromaticity.white_point.z=0.3583f;
1575 if (IsGrayColorspace(colorspace) != MagickFalse)
1576 image->type=GrayscaleType;
1577 return(SyncImagePixelCache(image,exception));
1581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1585 % T r a n s f o r m I m a g e C o l o r s p a c e %
1589 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1591 % TransformImageColorspace() transforms an image colorspace, changing the
1592 % image data to reflect the new colorspace.
1594 % The format of the TransformImageColorspace method is:
1596 % MagickBooleanType TransformImageColorspace(Image *image,
1597 % const ColorspaceType colorspace,ExceptionInfo *exception)
1599 % A description of each parameter follows:
1601 % o image: the image.
1603 % o colorspace: the colorspace.
1605 % o exception: return any errors or warnings in this structure.
1608 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1609 const ColorspaceType colorspace,ExceptionInfo *exception)
1614 assert(image != (Image *) NULL);
1615 assert(image->signature == MagickSignature);
1616 if (image->debug != MagickFalse)
1617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1618 if (colorspace == UndefinedColorspace)
1619 return(SetImageColorspace(image,colorspace,exception));
1620 if (image->colorspace == colorspace)
1621 return(MagickTrue); /* same colorspace: no op */
1623 Convert the reference image from an alternate colorspace to sRGB.
1625 if (IssRGBColorspace(colorspace) != MagickFalse)
1626 return(TransformsRGBImage(image,colorspace,exception));
1628 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1629 status=TransformsRGBImage(image,image->colorspace,exception);
1630 if (status == MagickFalse)
1633 Convert the reference image from sRGB to an alternate colorspace.
1635 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1645 + T r a n s f o r m s R G B I m a g e %
1649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1651 % TransformsRGBImage() converts the reference image from an alternate
1652 % colorspace to sRGB. The transformation matrices are not the standard ones:
1653 % the weights are rescaled to normalize the range of the transformed values
1654 % to be [0..QuantumRange].
1656 % The format of the TransformsRGBImage method is:
1658 % MagickBooleanType TransformsRGBImage(Image *image,
1659 % const ColorspaceType colorspace,ExceptionInfo *exception)
1661 % A description of each parameter follows:
1663 % o image: the image.
1665 % o colorspace: the colorspace to transform the image to.
1667 % o exception: return any errors or warnings in this structure.
1671 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
1672 double *X,double *Y,double *Z)
1679 assert(X != (double *) NULL);
1680 assert(Y != (double *) NULL);
1681 assert(Z != (double *) NULL);
1682 y=(100.0*L+16.0)/116.0;
1683 x=y+255.0*(a-0.5)/500.0;
1684 z=y-255.0*(b-0.5)/200.0;
1685 if (pow(x,3.0) > CIEEpsilon)
1688 x=(116.0*x-16.0)/CIEK;
1689 if (pow(y,3.0) > CIEEpsilon)
1693 if (pow(z,3.0) > CIEEpsilon)
1696 z=(116*z-16.0)/CIEK;
1702 static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
1703 double *X,double *Y,double *Z)
1705 assert(X != (double *) NULL);
1706 assert(Y != (double *) NULL);
1707 assert(Z != (double *) NULL);
1708 if ((100.0*L) > (CIEK*CIEEpsilon))
1709 *Y=(double) pow(((100.0*L)+16.0)/116.0,3.0);
1712 *X=((*Y*((39.0*(100.0*L)/((262.0*v-140.0)+13.0*(100.0*L)*(9.0*D65Y/(D65X+
1713 15.0*D65Y+3.0*D65Z))))-5.0))+5.0*(*Y))/((((52.0*(100.0*L)/((354.0*u-134.0)+
1714 13.0*(100.0*L)*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
1715 *Z=(*X*(((52.0*(100.0*L)/((354.0*u-134.0)+13.0*(100.0*L)*(4.0*D65X/(D65X+
1716 15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-5.0*(*Y);
1719 static inline ssize_t RoundToYCC(const double value)
1723 if (value >= 1388.0)
1725 return((ssize_t) (value+0.5));
1728 static inline void ConvertXYZToRGB(const double x,const double y,
1729 const double z,double *red,double *green,double *blue)
1737 Convert XYZ to sRGB colorspace.
1739 assert(red != (double *) NULL);
1740 assert(green != (double *) NULL);
1741 assert(blue != (double *) NULL);
1742 r=3.2404542*x-1.5371385*y-0.4985314*z;
1743 g=(-0.9692660*x+1.8760108*y+0.0415560*z);
1744 b=0.0556434*x-0.2040259*y+1.0572252*z;
1745 *red=QuantumRange*r;
1746 *green=QuantumRange*g;
1747 *blue=QuantumRange*b;
1750 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1752 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1753 (QuantumRange-pixel->black)+pixel->black)));
1754 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1755 (QuantumRange-pixel->black)+pixel->black)));
1756 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1757 (QuantumRange-pixel->black)+pixel->black)));
1760 static MagickBooleanType TransformsRGBImage(Image *image,
1761 const ColorspaceType colorspace,ExceptionInfo *exception)
1763 #define TransformsRGBImageTag "Transform/Image"
1765 #if !defined(MAGICKCORE_HDRI_SUPPORT)
1769 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1770 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1771 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1772 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1773 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1774 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1775 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1776 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1777 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1778 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1779 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1780 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1781 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1782 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1783 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1784 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1785 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1786 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1787 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1788 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1789 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1790 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1791 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1792 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1793 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1794 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1795 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1796 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1797 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1798 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1799 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1800 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1801 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1802 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1803 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1804 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1805 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1806 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1807 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1808 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1809 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1810 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1811 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1812 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1813 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1814 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1815 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1816 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1817 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1818 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1819 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1820 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1821 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1822 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1823 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1824 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1825 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1826 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1827 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1828 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1829 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1830 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1831 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1832 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1833 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1834 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1835 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1836 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1837 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1838 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1839 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1840 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1841 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1842 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1843 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1844 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1845 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1846 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1847 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1848 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1849 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1850 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1851 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1852 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1853 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1854 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1855 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1856 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1857 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1858 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1859 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1860 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1861 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1862 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1863 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1864 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1865 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1866 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1867 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1868 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1869 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1870 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1871 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1872 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1873 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1874 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1875 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1876 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1877 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1878 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1879 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1880 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1881 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1882 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1883 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1884 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1885 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1886 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1887 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1888 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1889 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1890 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1891 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1892 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1893 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1894 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1895 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1896 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1897 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1898 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1899 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1900 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1901 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1902 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1903 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1904 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1905 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1906 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1907 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1908 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1909 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1910 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1911 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1912 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1913 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1914 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1915 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1916 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1917 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1918 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1919 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1920 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1921 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1922 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1923 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1924 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1925 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1926 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1927 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1928 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1929 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1930 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1931 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1932 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1933 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1934 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1935 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1936 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1937 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1938 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1939 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1940 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1941 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1942 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1943 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1944 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1945 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1946 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1947 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1948 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1949 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1950 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1951 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1952 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1953 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1954 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1955 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1956 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1957 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1958 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1959 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1960 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1961 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1962 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1963 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1964 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1965 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1966 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1967 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1968 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1969 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1970 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1971 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1972 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1973 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1974 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1975 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1976 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1977 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1978 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1979 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1980 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1981 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1982 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1983 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1984 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1985 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1986 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1987 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1988 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1989 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1990 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1991 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1992 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1993 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1994 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1995 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1996 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1997 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1998 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1999 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
2000 0.998559f, 0.999280f, 1.000000f
2024 assert(image != (Image *) NULL);
2025 assert(image->signature == MagickSignature);
2026 if (image->debug != MagickFalse)
2027 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2030 switch (image->colorspace)
2035 Transform image from CMY to sRGB.
2037 if (image->storage_class == PseudoClass)
2039 if (SyncImage(image,exception) == MagickFalse)
2040 return(MagickFalse);
2041 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2042 return(MagickFalse);
2044 image_view=AcquireAuthenticCacheView(image,exception);
2045 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2046 #pragma omp parallel for schedule(static,4) shared(status) \
2047 dynamic_number_threads(image,image->columns,image->rows,1)
2049 for (y=0; y < (ssize_t) image->rows; y++)
2060 if (status == MagickFalse)
2062 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2064 if (q == (Quantum *) NULL)
2069 for (x=0; x < (ssize_t) image->columns; x++)
2076 cyan=sRGBCompandor((double) (QuantumRange-
2077 GetPixelCyan(image,q)));
2078 magenta=sRGBCompandor((double) (QuantumRange-
2079 GetPixelMagenta(image,q)));
2080 yellow=sRGBCompandor((double) (QuantumRange-
2081 GetPixelYellow(image,q)));
2082 SetPixelCyan(image,ClampToQuantum(cyan),q);
2083 SetPixelMagenta(image,ClampToQuantum(magenta),q);
2084 SetPixelYellow(image,ClampToQuantum(yellow),q);
2085 q+=GetPixelChannels(image);
2087 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2088 if (sync == MagickFalse)
2091 image_view=DestroyCacheView(image_view);
2092 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2093 return(MagickFalse);
2096 case CMYKColorspace:
2102 Transform image from CMYK to sRGB.
2104 if (image->storage_class == PseudoClass)
2106 if (SyncImage(image,exception) == MagickFalse)
2107 return(MagickFalse);
2108 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2109 return(MagickFalse);
2111 GetPixelInfo(image,&zero);
2112 image_view=AcquireAuthenticCacheView(image,exception);
2113 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2114 #pragma omp parallel for schedule(static,4) shared(status) \
2115 dynamic_number_threads(image,image->columns,image->rows,1)
2117 for (y=0; y < (ssize_t) image->rows; y++)
2131 if (status == MagickFalse)
2133 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2135 if (q == (Quantum *) NULL)
2141 for (x=0; x < (ssize_t) image->columns; x++)
2143 GetPixelInfoPixel(image,q,&pixel);
2144 ConvertCMYKToRGB(&pixel);
2145 pixel.red=sRGBCompandor(pixel.red);
2146 pixel.green=sRGBCompandor(pixel.green);
2147 pixel.blue=sRGBCompandor(pixel.blue);
2148 SetPixelInfoPixel(image,&pixel,q);
2149 q+=GetPixelChannels(image);
2151 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2152 if (sync == MagickFalse)
2155 image_view=DestroyCacheView(image_view);
2156 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2157 return(MagickFalse);
2160 case GRAYColorspace:
2161 case Rec601LumaColorspace:
2162 case Rec709LumaColorspace:
2165 Transform linear GRAY to sRGB colorspace.
2167 if (image->storage_class == PseudoClass)
2169 if (SyncImage(image,exception) == MagickFalse)
2170 return(MagickFalse);
2171 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2172 return(MagickFalse);
2174 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2175 return(MagickFalse);
2176 image_view=AcquireAuthenticCacheView(image,exception);
2177 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2178 #pragma omp parallel for schedule(static,4) shared(status) \
2179 dynamic_number_threads(image,image->columns,image->rows,1)
2181 for (y=0; y < (ssize_t) image->rows; y++)
2192 if (status == MagickFalse)
2194 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2196 if (q == (Quantum *) NULL)
2201 for (x=(ssize_t) image->columns; x != 0; x--)
2206 gray=sRGBCompandor((double) GetPixelGray(image,q));
2207 SetPixelRed(image,ClampToQuantum(gray),q);
2208 SetPixelGreen(image,ClampToQuantum(gray),q);
2209 SetPixelBlue(image,ClampToQuantum(gray),q);
2210 q+=GetPixelChannels(image);
2212 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2213 if (sync == MagickFalse)
2216 image_view=DestroyCacheView(image_view);
2217 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2218 return(MagickFalse);
2224 Transform image from HCL to sRGB.
2226 if (image->storage_class == PseudoClass)
2228 if (SyncImage(image,exception) == MagickFalse)
2229 return(MagickFalse);
2230 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2231 return(MagickFalse);
2233 image_view=AcquireAuthenticCacheView(image,exception);
2234 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2235 #pragma omp parallel for schedule(static,4) shared(status) \
2236 dynamic_number_threads(image,image->columns,image->rows,1)
2238 for (y=0; y < (ssize_t) image->rows; y++)
2249 if (status == MagickFalse)
2251 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2253 if (q == (Quantum *) NULL)
2258 for (x=0; x < (ssize_t) image->columns; x++)
2268 hue=(double) (QuantumScale*GetPixelRed(image,q));
2269 chroma=(double) (QuantumScale*GetPixelGreen(image,q));
2270 luma=(double) (QuantumScale*GetPixelBlue(image,q));
2271 ConvertHCLToRGB(hue,chroma,luma,&red,&green,&blue);
2272 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2273 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2274 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2275 q+=GetPixelChannels(image);
2277 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2278 if (sync == MagickFalse)
2281 image_view=DestroyCacheView(image_view);
2282 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2283 return(MagickFalse);
2289 Transform image from HSB to sRGB.
2291 if (image->storage_class == PseudoClass)
2293 if (SyncImage(image,exception) == MagickFalse)
2294 return(MagickFalse);
2295 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2296 return(MagickFalse);
2298 image_view=AcquireAuthenticCacheView(image,exception);
2299 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2300 #pragma omp parallel for schedule(static,4) shared(status) \
2301 dynamic_number_threads(image,image->columns,image->rows,1)
2303 for (y=0; y < (ssize_t) image->rows; y++)
2314 if (status == MagickFalse)
2316 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2318 if (q == (Quantum *) NULL)
2323 for (x=0; x < (ssize_t) image->columns; x++)
2333 hue=(double) (QuantumScale*GetPixelRed(image,q));
2334 saturation=(double) (QuantumScale*GetPixelGreen(image,q));
2335 brightness=(double) (QuantumScale*GetPixelBlue(image,q));
2336 ConvertHSBToRGB(hue,saturation,brightness,&red,&green,&blue);
2337 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2338 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2339 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2340 q+=GetPixelChannels(image);
2342 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2343 if (sync == MagickFalse)
2346 image_view=DestroyCacheView(image_view);
2347 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2348 return(MagickFalse);
2354 Transform image from HSL to sRGB.
2356 if (image->storage_class == PseudoClass)
2358 if (SyncImage(image,exception) == MagickFalse)
2359 return(MagickFalse);
2360 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2361 return(MagickFalse);
2363 image_view=AcquireAuthenticCacheView(image,exception);
2364 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2365 #pragma omp parallel for schedule(static,4) shared(status) \
2366 dynamic_number_threads(image,image->columns,image->rows,1)
2368 for (y=0; y < (ssize_t) image->rows; y++)
2379 if (status == MagickFalse)
2381 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2383 if (q == (Quantum *) NULL)
2388 for (x=0; x < (ssize_t) image->columns; x++)
2398 hue=(double) (QuantumScale*GetPixelRed(image,q));
2399 saturation=(double) (QuantumScale*GetPixelGreen(image,q));
2400 lightness=(double) (QuantumScale*GetPixelBlue(image,q));
2401 ConvertHSLToRGB(hue,saturation,lightness,&red,&green,&blue);
2402 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2403 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2404 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2405 q+=GetPixelChannels(image);
2407 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2408 if (sync == MagickFalse)
2411 image_view=DestroyCacheView(image_view);
2412 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2413 return(MagickFalse);
2419 Transform image from HWB to sRGB.
2421 if (image->storage_class == PseudoClass)
2423 if (SyncImage(image,exception) == MagickFalse)
2424 return(MagickFalse);
2425 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2426 return(MagickFalse);
2428 image_view=AcquireAuthenticCacheView(image,exception);
2429 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2430 #pragma omp parallel for schedule(static,4) shared(status) \
2431 dynamic_number_threads(image,image->columns,image->rows,1)
2433 for (y=0; y < (ssize_t) image->rows; y++)
2444 if (status == MagickFalse)
2446 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2448 if (q == (Quantum *) NULL)
2453 for (x=0; x < (ssize_t) image->columns; x++)
2463 hue=(double) (QuantumScale*GetPixelRed(image,q));
2464 whiteness=(double) (QuantumScale*GetPixelGreen(image,q));
2465 blackness=(double) (QuantumScale*GetPixelBlue(image,q));
2466 ConvertHWBToRGB(hue,whiteness,blackness,&red,&green,&blue);
2467 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2468 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2469 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2470 q+=GetPixelChannels(image);
2472 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2473 if (sync == MagickFalse)
2476 image_view=DestroyCacheView(image_view);
2477 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2478 return(MagickFalse);
2484 Transform image from Lab to sRGB.
2486 if (image->storage_class == PseudoClass)
2488 if (SyncImage(image,exception) == MagickFalse)
2489 return(MagickFalse);
2490 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2491 return(MagickFalse);
2493 image_view=AcquireAuthenticCacheView(image,exception);
2494 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2495 #pragma omp parallel for schedule(static,4) shared(status) \
2496 dynamic_number_threads(image,image->columns,image->rows,1)
2498 for (y=0; y < (ssize_t) image->rows; y++)
2509 if (status == MagickFalse)
2511 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2513 if (q == (Quantum *) NULL)
2518 for (x=0; x < (ssize_t) image->columns; x++)
2531 L=QuantumScale*GetPixelRed(image,q);
2532 a=QuantumScale*GetPixelGreen(image,q);
2533 b=QuantumScale*GetPixelBlue(image,q);
2534 ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
2535 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2536 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2537 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2538 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2539 q+=GetPixelChannels(image);
2541 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2542 if (sync == MagickFalse)
2545 image_view=DestroyCacheView(image_view);
2546 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2547 return(MagickFalse);
2567 Transform Log to sRGB colorspace.
2569 density=DisplayGamma;
2571 value=GetImageProperty(image,"gamma",exception);
2572 if (value != (const char *) NULL)
2573 gamma=MagickEpsilonReciprocal(StringToDouble(value,(char **) NULL));
2574 film_gamma=FilmGamma;
2575 value=GetImageProperty(image,"film-gamma",exception);
2576 if (value != (const char *) NULL)
2577 film_gamma=StringToDouble(value,(char **) NULL);
2578 reference_black=ReferenceBlack;
2579 value=GetImageProperty(image,"reference-black",exception);
2580 if (value != (const char *) NULL)
2581 reference_black=StringToDouble(value,(char **) NULL);
2582 reference_white=ReferenceWhite;
2583 value=GetImageProperty(image,"reference-white",exception);
2584 if (value != (const char *) NULL)
2585 reference_white=StringToDouble(value,(char **) NULL);
2586 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2588 if (logmap == (Quantum *) NULL)
2589 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2591 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*
2593 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
2594 logmap[i]=(Quantum) 0;
2595 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
2596 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
2597 (pow(10.0,(1024.0*i/MaxMap-reference_white)*
2598 (gamma/density)*0.002/film_gamma)-black));
2599 for ( ; i <= (ssize_t) MaxMap; i++)
2600 logmap[i]=QuantumRange;
2601 if (image->storage_class == PseudoClass)
2603 if (SyncImage(image,exception) == MagickFalse)
2604 return(MagickFalse);
2605 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2606 return(MagickFalse);
2608 image_view=AcquireAuthenticCacheView(image,exception);
2609 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2610 #pragma omp parallel for schedule(static,4) shared(status) \
2611 dynamic_number_threads(image,image->columns,image->rows,1)
2613 for (y=0; y < (ssize_t) image->rows; y++)
2624 if (status == MagickFalse)
2626 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2628 if (q == (Quantum *) NULL)
2633 for (x=(ssize_t) image->columns; x != 0; x--)
2640 red=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2641 GetPixelRed(image,q))]);
2642 green=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2643 GetPixelGreen(image,q))]);
2644 blue=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2645 GetPixelBlue(image,q))]);
2646 SetPixelRed(image,ClampToQuantum(red),q);
2647 SetPixelGreen(image,ClampToQuantum(green),q);
2648 SetPixelBlue(image,ClampToQuantum(blue),q);
2649 q+=GetPixelChannels(image);
2651 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2652 if (sync == MagickFalse)
2655 image_view=DestroyCacheView(image_view);
2656 logmap=(Quantum *) RelinquishMagickMemory(logmap);
2657 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2658 return(MagickFalse);
2664 Transform image from Luv to sRGB.
2666 if (image->storage_class == PseudoClass)
2668 if (SyncImage(image,exception) == MagickFalse)
2669 return(MagickFalse);
2670 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2671 return(MagickFalse);
2673 image_view=AcquireAuthenticCacheView(image,exception);
2674 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2675 #pragma omp parallel for schedule(static,4) shared(status) \
2676 dynamic_number_threads(image,image->columns,image->rows,1)
2678 for (y=0; y < (ssize_t) image->rows; y++)
2689 if (status == MagickFalse)
2691 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2693 if (q == (Quantum *) NULL)
2698 for (x=0; x < (ssize_t) image->columns; x++)
2711 L=QuantumScale*GetPixelRed(image,q);
2712 u=QuantumScale*GetPixelGreen(image,q);
2713 v=QuantumScale*GetPixelBlue(image,q);
2714 ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
2715 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2716 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2717 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2718 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2719 q+=GetPixelChannels(image);
2721 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2722 if (sync == MagickFalse)
2725 image_view=DestroyCacheView(image_view);
2726 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2727 return(MagickFalse);
2733 Transform linear RGB to sRGB colorspace.
2735 if (image->storage_class == PseudoClass)
2737 if (SyncImage(image,exception) == MagickFalse)
2738 return(MagickFalse);
2739 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2740 return(MagickFalse);
2742 image_view=AcquireAuthenticCacheView(image,exception);
2743 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2744 #pragma omp parallel for schedule(static,4) shared(status) \
2745 dynamic_number_threads(image,image->columns,image->rows,1)
2747 for (y=0; y < (ssize_t) image->rows; y++)
2758 if (status == MagickFalse)
2760 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2762 if (q == (Quantum *) NULL)
2767 for (x=(ssize_t) image->columns; x != 0; x--)
2774 red=sRGBCompandor((double) GetPixelRed(image,q));
2775 green=sRGBCompandor((double) GetPixelGreen(image,q));
2776 blue=sRGBCompandor((double) GetPixelBlue(image,q));
2777 SetPixelRed(image,ClampToQuantum(red),q);
2778 SetPixelGreen(image,ClampToQuantum(green),q);
2779 SetPixelBlue(image,ClampToQuantum(blue),q);
2780 q+=GetPixelChannels(image);
2782 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2783 if (sync == MagickFalse)
2786 image_view=DestroyCacheView(image_view);
2787 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2788 return(MagickFalse);
2794 Transform image from XYZ to sRGB.
2796 if (image->storage_class == PseudoClass)
2798 if (SyncImage(image,exception) == MagickFalse)
2799 return(MagickFalse);
2800 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2801 return(MagickFalse);
2803 image_view=AcquireAuthenticCacheView(image,exception);
2804 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2805 #pragma omp parallel for schedule(static,4) shared(status) \
2806 dynamic_number_threads(image,image->columns,image->rows,1)
2808 for (y=0; y < (ssize_t) image->rows; y++)
2819 if (status == MagickFalse)
2821 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2823 if (q == (Quantum *) NULL)
2828 for (x=0; x < (ssize_t) image->columns; x++)
2838 X=QuantumScale*GetPixelRed(image,q);
2839 Y=QuantumScale*GetPixelGreen(image,q);
2840 Z=QuantumScale*GetPixelBlue(image,q);
2841 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2842 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2843 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2844 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2845 q+=GetPixelChannels(image);
2847 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2848 if (sync == MagickFalse)
2851 image_view=DestroyCacheView(image_view);
2852 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2853 return(MagickFalse);
2860 Allocate the tables.
2862 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2864 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2866 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2868 if ((x_map == (TransformPacket *) NULL) ||
2869 (y_map == (TransformPacket *) NULL) ||
2870 (z_map == (TransformPacket *) NULL))
2872 if (z_map != (TransformPacket *) NULL)
2873 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2874 if (y_map != (TransformPacket *) NULL)
2875 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2876 if (x_map != (TransformPacket *) NULL)
2877 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2878 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2881 switch (image->colorspace)
2883 case OHTAColorspace:
2886 Initialize OHTA tables:
2888 R = I1+1.00000*I2-0.66668*I3
2889 G = I1+0.00000*I2+1.33333*I3
2890 B = I1-1.00000*I2-0.66668*I3
2892 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2893 through QuantumRange.
2895 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2896 #pragma omp parallel for schedule(static) \
2897 dynamic_number_threads(image,image->columns,1,1)
2899 for (i=0; i <= (ssize_t) MaxMap; i++)
2901 x_map[i].x=(double) i;
2902 y_map[i].x=0.500000*(2.000000*(double) i-(double)
2904 z_map[i].x=(-0.333340)*(2.000000*(double) i-(double)
2906 x_map[i].y=(double) i;
2907 y_map[i].y=0.000000;
2908 z_map[i].y=0.666665*(2.000000*(double) i-(double)
2910 x_map[i].z=(double) i;
2911 y_map[i].z=(-0.500000)*(2.000000*(double) i-(double)
2913 z_map[i].z=(-0.333340)*(2.000000*(double) i-(double)
2918 case Rec601YCbCrColorspace:
2919 case YCbCrColorspace:
2922 Initialize YCbCr tables:
2925 G = Y-0.344136*Cb-0.714136*Cr
2928 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2929 through QuantumRange.
2931 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2932 #pragma omp parallel for schedule(static) \
2933 dynamic_number_threads(image,image->columns,1,1)
2935 for (i=0; i <= (ssize_t) MaxMap; i++)
2937 x_map[i].x=(double) i;
2938 y_map[i].x=0.000000;
2939 z_map[i].x=(1.402000*0.500000)*(2.000000*(double) i-
2941 x_map[i].y=(double) i;
2942 y_map[i].y=(-0.344136*0.500000)*(2.000000*(double) i-
2944 z_map[i].y=(-0.714136*0.500000)*(2.000000*(double) i-
2946 x_map[i].z=(double) i;
2947 y_map[i].z=(1.772000*0.500000)*(2.000000*(double) i-
2949 z_map[i].z=0.000000;
2953 case Rec709YCbCrColorspace:
2956 Initialize YCbCr tables:
2959 G = Y-0.187324*Cb-0.468124*Cr
2962 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2963 through QuantumRange.
2965 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2966 #pragma omp parallel for schedule(static) \
2967 dynamic_number_threads(image,image->columns,1,1)
2969 for (i=0; i <= (ssize_t) MaxMap; i++)
2971 x_map[i].x=(double) i;
2972 y_map[i].x=0.000000;
2973 z_map[i].x=(1.574800*0.50000)*(2.00000*(double) i-
2975 x_map[i].y=(double) i;
2976 y_map[i].y=(-0.187324*0.50000)*(2.00000*(double) i-
2978 z_map[i].y=(-0.468124*0.50000)*(2.00000*(double) i-
2980 x_map[i].z=(double) i;
2981 y_map[i].z=(1.855600*0.50000)*(2.00000*(double) i-
2990 Initialize YCC tables:
2993 G = Y-0.317038*C1-0.682243*C2
2996 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2998 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2999 #pragma omp parallel for schedule(static) \
3000 dynamic_number_threads(image,image->columns,1,1)
3002 for (i=0; i <= (ssize_t) MaxMap; i++)
3004 x_map[i].x=1.3584000*(double) i;
3005 y_map[i].x=0.0000000;
3006 z_map[i].x=1.8215000*((double) i-(double)
3007 ScaleQuantumToMap(ScaleCharToQuantum(137)));
3008 x_map[i].y=1.3584000*(double) i;
3009 y_map[i].y=(-0.4302726)*((double) i-(double)
3010 ScaleQuantumToMap(ScaleCharToQuantum(156)));
3011 z_map[i].y=(-0.9271435)*((double) i-(double)
3012 ScaleQuantumToMap(ScaleCharToQuantum(137)));
3013 x_map[i].z=1.3584000*(double) i;
3014 y_map[i].z=2.2179000*((double) i-(double)
3015 ScaleQuantumToMap(ScaleCharToQuantum(156)));
3016 z_map[i].z=0.0000000;
3023 Initialize YIQ tables:
3025 R = Y+0.95620*I+0.62140*Q
3026 G = Y-0.27270*I-0.64680*Q
3027 B = Y-1.10370*I+1.70060*Q
3029 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
3030 through QuantumRange.
3032 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3033 #pragma omp parallel for schedule(static) \
3034 dynamic_number_threads(image,image->columns,1,1)
3036 for (i=0; i <= (ssize_t) MaxMap; i++)
3038 x_map[i].x=(double) i;
3039 y_map[i].x=0.47810*(2.00000*(double) i-(double)
3041 z_map[i].x=0.31070*(2.00000*(double) i-(double)
3043 x_map[i].y=(double) i;
3044 y_map[i].y=(-0.13635)*(2.00000*(double) i-(double)
3046 z_map[i].y=(-0.32340)*(2.00000*(double) i-(double)
3048 x_map[i].z=(double) i;
3049 y_map[i].z=(-0.55185)*(2.00000*(double) i-(double)
3051 z_map[i].z=0.85030*(2.00000*(double) i-(double)
3056 case YPbPrColorspace:
3059 Initialize YPbPr tables:
3062 G = Y-0.344136*C1+0.714136*C2
3065 Pb and Pr, normally -0.5 through 0.5, must be normalized to the range 0
3066 through QuantumRange.
3068 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3069 #pragma omp parallel for schedule(static) \
3070 dynamic_number_threads(image,image->columns,1,1)
3072 for (i=0; i <= (ssize_t) MaxMap; i++)
3074 x_map[i].x=(double) i;
3075 y_map[i].x=0.000000;
3076 z_map[i].x=0.701000*(2.00000*(double) i-(double)
3078 x_map[i].y=(double) i;
3079 y_map[i].y=(-0.172068)*(2.00000*(double) i-(double)
3081 z_map[i].y=0.357068*(2.00000*(double) i-(double)
3083 x_map[i].z=(double) i;
3084 y_map[i].z=0.88600*(2.00000*(double) i-(double)
3093 Initialize YUV tables:
3096 G = Y-0.3455*U-0.7169*V
3099 U and V, normally -0.5 through 0.5, must be normalized to the range 0
3100 through QuantumRange.
3102 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3103 #pragma omp parallel for schedule(static) \
3104 dynamic_number_threads(image,image->columns,1,1)
3106 for (i=0; i <= (ssize_t) MaxMap; i++)
3108 x_map[i].x=(double) i;
3110 z_map[i].x=0.70375*(2.0000*(double) i-(double) MaxMap);
3111 x_map[i].y=(double) i;
3112 y_map[i].y=(-0.17275)*(2.00000*(double) i-(double)
3114 z_map[i].y=(-0.35845)*(2.00000*(double) i-(double)
3116 x_map[i].z=(double) i;
3117 y_map[i].z=0.8895*(2.00000*(double) i-(double) MaxMap);
3125 Linear conversion tables.
3127 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3128 #pragma omp parallel for schedule(static) \
3129 dynamic_number_threads(image,image->columns,1,1)
3131 for (i=0; i <= (ssize_t) MaxMap; i++)
3133 x_map[i].x=(double) i;
3137 y_map[i].y=(double) i;
3141 z_map[i].z=(double) i;
3149 switch (image->storage_class)
3155 Convert DirectClass image.
3157 image_view=AcquireAuthenticCacheView(image,exception);
3158 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3159 #pragma omp parallel for schedule(static,4) shared(status) \
3160 dynamic_number_threads(image,image->columns,image->rows,1)
3162 for (y=0; y < (ssize_t) image->rows; y++)
3176 if (status == MagickFalse)
3178 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
3180 if (q == (Quantum *) NULL)
3185 for (x=0; x < (ssize_t) image->columns; x++)
3192 red=ScaleQuantumToMap(GetPixelRed(image,q));
3193 green=ScaleQuantumToMap(GetPixelGreen(image,q));
3194 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
3195 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
3196 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
3197 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
3198 if (colorspace == YCCColorspace)
3200 #if !defined(MAGICKCORE_HDRI_SUPPORT)
3201 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3203 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3205 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3209 SetPixelRed(image,ClampToQuantum(sRGBCompandor((double)
3210 ScaleMapToQuantum(pixel.red))),q);
3211 SetPixelGreen(image,ClampToQuantum(sRGBCompandor((double)
3212 ScaleMapToQuantum(pixel.green))),q);
3213 SetPixelBlue(image,ClampToQuantum(sRGBCompandor((double)
3214 ScaleMapToQuantum(pixel.blue))),q);
3215 q+=GetPixelChannels(image);
3217 sync=SyncCacheViewAuthenticPixels(image_view,exception);
3218 if (sync == MagickFalse)
3220 if (image->progress_monitor != (MagickProgressMonitor) NULL)
3225 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3226 #pragma omp critical (MagickCore_TransformsRGBImage)
3228 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
3230 if (proceed == MagickFalse)
3234 image_view=DestroyCacheView(image_view);
3240 Convert PseudoClass image.
3242 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3243 #pragma omp parallel for schedule(static,4) shared(status) \
3244 dynamic_number_threads(image,image->columns,1,1)
3246 for (i=0; i < (ssize_t) image->colors; i++)
3256 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
3257 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
3258 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
3259 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
3260 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
3261 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
3262 if (colorspace == YCCColorspace)
3264 #if !defined(MAGICKCORE_HDRI_SUPPORT)
3265 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3267 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3269 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3273 image->colormap[i].red=(double) ClampToQuantum(
3274 sRGBCompandor((double) ScaleMapToQuantum(pixel.red)));
3275 image->colormap[i].green=(double) ClampToQuantum(
3276 sRGBCompandor((double) ScaleMapToQuantum(pixel.green)));
3277 image->colormap[i].blue=(double) ClampToQuantum(
3278 sRGBCompandor((double) ScaleMapToQuantum(pixel.blue)));
3280 (void) SyncImage(image,exception);
3285 Relinquish resources.
3287 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
3288 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
3289 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
3290 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
3291 return(MagickFalse);