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->matte == MagickFalse ? 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->matte == MagickFalse ? 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 (void) DeleteImageProfile(image,"icc"); /* remove color profile */
1578 (void) DeleteImageProfile(image,"icm");
1579 return(SyncImagePixelCache(image,exception));
1583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1587 % T r a n s f o r m I m a g e C o l o r s p a c e %
1591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1593 % TransformImageColorspace() transforms an image colorspace, changing the
1594 % image data to reflect the new colorspace.
1596 % The format of the TransformImageColorspace method is:
1598 % MagickBooleanType TransformImageColorspace(Image *image,
1599 % const ColorspaceType colorspace,ExceptionInfo *exception)
1601 % A description of each parameter follows:
1603 % o image: the image.
1605 % o colorspace: the colorspace.
1607 % o exception: return any errors or warnings in this structure.
1610 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1611 const ColorspaceType colorspace,ExceptionInfo *exception)
1616 assert(image != (Image *) NULL);
1617 assert(image->signature == MagickSignature);
1618 if (image->debug != MagickFalse)
1619 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1620 if (colorspace == UndefinedColorspace)
1621 return(SetImageColorspace(image,colorspace,exception));
1622 if (image->colorspace == colorspace)
1623 return(MagickTrue); /* same colorspace: no op */
1625 Convert the reference image from an alternate colorspace to sRGB.
1627 if (IssRGBColorspace(colorspace) != MagickFalse)
1628 return(TransformsRGBImage(image,colorspace,exception));
1630 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1631 status=TransformsRGBImage(image,image->colorspace,exception);
1632 if (status == MagickFalse)
1635 Convert the reference image from sRGB to an alternate colorspace.
1637 if (sRGBTransformImage(image,colorspace,exception) == MagickFalse)
1643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1647 + T r a n s f o r m s R G B I m a g e %
1651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1653 % TransformsRGBImage() converts the reference image from an alternate
1654 % colorspace to sRGB. The transformation matrices are not the standard ones:
1655 % the weights are rescaled to normalize the range of the transformed values
1656 % to be [0..QuantumRange].
1658 % The format of the TransformsRGBImage method is:
1660 % MagickBooleanType TransformsRGBImage(Image *image,
1661 % const ColorspaceType colorspace,ExceptionInfo *exception)
1663 % A description of each parameter follows:
1665 % o image: the image.
1667 % o colorspace: the colorspace to transform the image to.
1669 % o exception: return any errors or warnings in this structure.
1673 static inline void ConvertLabToXYZ(const double L,const double a,const double b,
1674 double *X,double *Y,double *Z)
1681 assert(X != (double *) NULL);
1682 assert(Y != (double *) NULL);
1683 assert(Z != (double *) NULL);
1684 y=(100.0*L+16.0)/116.0;
1685 x=y+255.0*(a-0.5)/500.0;
1686 z=y-255.0*(b-0.5)/200.0;
1687 if (pow(x,3.0) > CIEEpsilon)
1690 x=(116.0*x-16.0)/CIEK;
1691 if (pow(y,3.0) > CIEEpsilon)
1695 if (pow(z,3.0) > CIEEpsilon)
1698 z=(116*z-16.0)/CIEK;
1704 static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
1705 double *X,double *Y,double *Z)
1707 assert(X != (double *) NULL);
1708 assert(Y != (double *) NULL);
1709 assert(Z != (double *) NULL);
1710 if ((100.0*L) > (CIEK*CIEEpsilon))
1711 *Y=(double) pow(((100.0*L)+16.0)/116.0,3.0);
1714 *X=((*Y*((39.0*(100.0*L)/((262.0*v-140.0)+13.0*(100.0*L)*(9.0*D65Y/(D65X+
1715 15.0*D65Y+3.0*D65Z))))-5.0))+5.0*(*Y))/((((52.0*(100.0*L)/((354.0*u-134.0)+
1716 13.0*(100.0*L)*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0)-(-1.0/3.0));
1717 *Z=(*X*(((52.0*(100.0*L)/((354.0*u-134.0)+13.0*(100.0*L)*(4.0*D65X/(D65X+
1718 15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-5.0*(*Y);
1721 static inline ssize_t RoundToYCC(const double value)
1725 if (value >= 1388.0)
1727 return((ssize_t) (value+0.5));
1730 static inline void ConvertXYZToRGB(const double x,const double y,
1731 const double z,double *red,double *green,double *blue)
1739 Convert XYZ to sRGB colorspace.
1741 assert(red != (double *) NULL);
1742 assert(green != (double *) NULL);
1743 assert(blue != (double *) NULL);
1744 r=3.2404542*x-1.5371385*y-0.4985314*z;
1745 g=(-0.9692660*x+1.8760108*y+0.0415560*z);
1746 b=0.0556434*x-0.2040259*y+1.0572252*z;
1747 *red=QuantumRange*r;
1748 *green=QuantumRange*g;
1749 *blue=QuantumRange*b;
1752 static inline void ConvertCMYKToRGB(PixelInfo *pixel)
1754 pixel->red=((QuantumRange-(QuantumScale*pixel->red*
1755 (QuantumRange-pixel->black)+pixel->black)));
1756 pixel->green=((QuantumRange-(QuantumScale*pixel->green*
1757 (QuantumRange-pixel->black)+pixel->black)));
1758 pixel->blue=((QuantumRange-(QuantumScale*pixel->blue*
1759 (QuantumRange-pixel->black)+pixel->black)));
1762 static MagickBooleanType TransformsRGBImage(Image *image,
1763 const ColorspaceType colorspace,ExceptionInfo *exception)
1765 #define TransformsRGBImageTag "Transform/Image"
1767 #if !defined(MAGICKCORE_HDRI_SUPPORT)
1771 0.000000f, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1772 0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1773 0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1774 0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1775 0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1776 0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1777 0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1778 0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1779 0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1780 0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1781 0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1782 0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1783 0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1784 0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1785 0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1786 0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1787 0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1788 0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1789 0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1790 0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1791 0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1792 0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1793 0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1794 0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1795 0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1796 0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1797 0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1798 0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1799 0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1800 0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1801 0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1802 0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1803 0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1804 0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1805 0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1806 0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1807 0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1808 0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1809 0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1810 0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1811 0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1812 0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1813 0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1814 0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1815 0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1816 0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1817 0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1818 0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1819 0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1820 0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1821 0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1822 0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1823 0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1824 0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1825 0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1826 0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1827 0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1828 0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1829 0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1830 0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1831 0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1832 0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1833 0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1834 0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1835 0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1836 0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1837 0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1838 0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1839 0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1840 0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1841 0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1842 0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1843 0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1844 0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1845 0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1846 0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1847 0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1848 0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1849 0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1850 0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1851 0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1852 0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1853 0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1854 0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1855 0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1856 0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1857 0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1858 0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1859 0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1860 0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1861 0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1862 0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1863 0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1864 0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1865 0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1866 0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1867 0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1868 0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1869 0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1870 0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1871 0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1872 0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1873 0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1874 0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1875 0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1876 0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1877 0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1878 0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1879 0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1880 0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1881 0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1882 0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1883 0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1884 0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1885 0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1886 0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1887 0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1888 0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1889 0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1890 0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1891 0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1892 0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1893 0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1894 0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1895 0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1896 0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1897 0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1898 0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1899 0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1900 0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1901 0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1902 0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1903 0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1904 0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1905 0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1906 0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1907 0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1908 0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1909 0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1910 0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1911 0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1912 0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1913 0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1914 0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1915 0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1916 0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1917 0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1918 0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1919 0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1920 0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1921 0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1922 0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1923 0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1924 0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1925 0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1926 0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1927 0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1928 0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1929 0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1930 0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1931 0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1932 0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1933 0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1934 0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1935 0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1936 0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1937 0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1938 0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1939 0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1940 0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1941 0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1942 0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1943 0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1944 0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1945 0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1946 0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1947 0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1948 0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1949 0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1950 0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1951 0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1952 0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1953 0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1954 0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1955 0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1956 0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1957 0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1958 0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1959 0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1960 0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1961 0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1962 0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1963 0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1964 0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1965 0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1966 0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1967 0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1968 0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1969 0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1970 0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1971 0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1972 0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1973 0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1974 0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1975 0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1976 0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1977 0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1978 0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1979 0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1980 0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1981 0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1982 0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1983 0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1984 0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1985 0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1986 0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1987 0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1988 0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1989 0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1990 0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1991 0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1992 0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1993 0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1994 0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1995 0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1996 0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1997 0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1998 0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1999 0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
2000 0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
2001 0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
2002 0.998559f, 0.999280f, 1.000000f
2026 assert(image != (Image *) NULL);
2027 assert(image->signature == MagickSignature);
2028 if (image->debug != MagickFalse)
2029 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2032 switch (image->colorspace)
2037 Transform image from CMY to sRGB.
2039 if (image->storage_class == PseudoClass)
2041 if (SyncImage(image,exception) == MagickFalse)
2042 return(MagickFalse);
2043 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2044 return(MagickFalse);
2046 image_view=AcquireAuthenticCacheView(image,exception);
2047 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2048 #pragma omp parallel for schedule(static,4) shared(status) \
2049 dynamic_number_threads(image,image->columns,image->rows,1)
2051 for (y=0; y < (ssize_t) image->rows; y++)
2062 if (status == MagickFalse)
2064 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2066 if (q == (Quantum *) NULL)
2071 for (x=0; x < (ssize_t) image->columns; x++)
2078 cyan=sRGBCompandor((double) (QuantumRange-
2079 GetPixelCyan(image,q)));
2080 magenta=sRGBCompandor((double) (QuantumRange-
2081 GetPixelMagenta(image,q)));
2082 yellow=sRGBCompandor((double) (QuantumRange-
2083 GetPixelYellow(image,q)));
2084 SetPixelCyan(image,ClampToQuantum(cyan),q);
2085 SetPixelMagenta(image,ClampToQuantum(magenta),q);
2086 SetPixelYellow(image,ClampToQuantum(yellow),q);
2087 q+=GetPixelChannels(image);
2089 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2090 if (sync == MagickFalse)
2093 image_view=DestroyCacheView(image_view);
2094 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2095 return(MagickFalse);
2098 case CMYKColorspace:
2104 Transform image from CMYK to sRGB.
2106 if (image->storage_class == PseudoClass)
2108 if (SyncImage(image,exception) == MagickFalse)
2109 return(MagickFalse);
2110 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2111 return(MagickFalse);
2113 GetPixelInfo(image,&zero);
2114 image_view=AcquireAuthenticCacheView(image,exception);
2115 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2116 #pragma omp parallel for schedule(static,4) shared(status) \
2117 dynamic_number_threads(image,image->columns,image->rows,1)
2119 for (y=0; y < (ssize_t) image->rows; y++)
2133 if (status == MagickFalse)
2135 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2137 if (q == (Quantum *) NULL)
2143 for (x=0; x < (ssize_t) image->columns; x++)
2145 GetPixelInfoPixel(image,q,&pixel);
2146 ConvertCMYKToRGB(&pixel);
2147 pixel.red=sRGBCompandor(pixel.red);
2148 pixel.green=sRGBCompandor(pixel.green);
2149 pixel.blue=sRGBCompandor(pixel.blue);
2150 SetPixelInfoPixel(image,&pixel,q);
2151 q+=GetPixelChannels(image);
2153 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2154 if (sync == MagickFalse)
2157 image_view=DestroyCacheView(image_view);
2158 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2159 return(MagickFalse);
2162 case GRAYColorspace:
2163 case Rec601LumaColorspace:
2164 case Rec709LumaColorspace:
2167 Transform linear GRAY to sRGB colorspace.
2169 if (image->storage_class == PseudoClass)
2171 if (SyncImage(image,exception) == MagickFalse)
2172 return(MagickFalse);
2173 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2174 return(MagickFalse);
2176 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2177 return(MagickFalse);
2178 image_view=AcquireAuthenticCacheView(image,exception);
2179 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2180 #pragma omp parallel for schedule(static,4) shared(status) \
2181 dynamic_number_threads(image,image->columns,image->rows,1)
2183 for (y=0; y < (ssize_t) image->rows; y++)
2194 if (status == MagickFalse)
2196 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2198 if (q == (Quantum *) NULL)
2203 for (x=(ssize_t) image->columns; x != 0; x--)
2208 gray=sRGBCompandor((double) GetPixelGray(image,q));
2209 SetPixelRed(image,ClampToQuantum(gray),q);
2210 SetPixelGreen(image,ClampToQuantum(gray),q);
2211 SetPixelBlue(image,ClampToQuantum(gray),q);
2212 q+=GetPixelChannels(image);
2214 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2215 if (sync == MagickFalse)
2218 image_view=DestroyCacheView(image_view);
2219 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2220 return(MagickFalse);
2226 Transform image from HCL to sRGB.
2228 if (image->storage_class == PseudoClass)
2230 if (SyncImage(image,exception) == MagickFalse)
2231 return(MagickFalse);
2232 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2233 return(MagickFalse);
2235 image_view=AcquireAuthenticCacheView(image,exception);
2236 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2237 #pragma omp parallel for schedule(static,4) shared(status) \
2238 dynamic_number_threads(image,image->columns,image->rows,1)
2240 for (y=0; y < (ssize_t) image->rows; y++)
2251 if (status == MagickFalse)
2253 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2255 if (q == (Quantum *) NULL)
2260 for (x=0; x < (ssize_t) image->columns; x++)
2270 hue=(double) (QuantumScale*GetPixelRed(image,q));
2271 chroma=(double) (QuantumScale*GetPixelGreen(image,q));
2272 luma=(double) (QuantumScale*GetPixelBlue(image,q));
2273 ConvertHCLToRGB(hue,chroma,luma,&red,&green,&blue);
2274 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2275 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2276 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2277 q+=GetPixelChannels(image);
2279 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2280 if (sync == MagickFalse)
2283 image_view=DestroyCacheView(image_view);
2284 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2285 return(MagickFalse);
2291 Transform image from HSB to sRGB.
2293 if (image->storage_class == PseudoClass)
2295 if (SyncImage(image,exception) == MagickFalse)
2296 return(MagickFalse);
2297 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2298 return(MagickFalse);
2300 image_view=AcquireAuthenticCacheView(image,exception);
2301 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2302 #pragma omp parallel for schedule(static,4) shared(status) \
2303 dynamic_number_threads(image,image->columns,image->rows,1)
2305 for (y=0; y < (ssize_t) image->rows; y++)
2316 if (status == MagickFalse)
2318 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2320 if (q == (Quantum *) NULL)
2325 for (x=0; x < (ssize_t) image->columns; x++)
2335 hue=(double) (QuantumScale*GetPixelRed(image,q));
2336 saturation=(double) (QuantumScale*GetPixelGreen(image,q));
2337 brightness=(double) (QuantumScale*GetPixelBlue(image,q));
2338 ConvertHSBToRGB(hue,saturation,brightness,&red,&green,&blue);
2339 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2340 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2341 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2342 q+=GetPixelChannels(image);
2344 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2345 if (sync == MagickFalse)
2348 image_view=DestroyCacheView(image_view);
2349 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2350 return(MagickFalse);
2356 Transform image from HSL to sRGB.
2358 if (image->storage_class == PseudoClass)
2360 if (SyncImage(image,exception) == MagickFalse)
2361 return(MagickFalse);
2362 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2363 return(MagickFalse);
2365 image_view=AcquireAuthenticCacheView(image,exception);
2366 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2367 #pragma omp parallel for schedule(static,4) shared(status) \
2368 dynamic_number_threads(image,image->columns,image->rows,1)
2370 for (y=0; y < (ssize_t) image->rows; y++)
2381 if (status == MagickFalse)
2383 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2385 if (q == (Quantum *) NULL)
2390 for (x=0; x < (ssize_t) image->columns; x++)
2400 hue=(double) (QuantumScale*GetPixelRed(image,q));
2401 saturation=(double) (QuantumScale*GetPixelGreen(image,q));
2402 lightness=(double) (QuantumScale*GetPixelBlue(image,q));
2403 ConvertHSLToRGB(hue,saturation,lightness,&red,&green,&blue);
2404 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2405 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2406 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2407 q+=GetPixelChannels(image);
2409 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2410 if (sync == MagickFalse)
2413 image_view=DestroyCacheView(image_view);
2414 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2415 return(MagickFalse);
2421 Transform image from HWB to sRGB.
2423 if (image->storage_class == PseudoClass)
2425 if (SyncImage(image,exception) == MagickFalse)
2426 return(MagickFalse);
2427 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2428 return(MagickFalse);
2430 image_view=AcquireAuthenticCacheView(image,exception);
2431 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2432 #pragma omp parallel for schedule(static,4) shared(status) \
2433 dynamic_number_threads(image,image->columns,image->rows,1)
2435 for (y=0; y < (ssize_t) image->rows; y++)
2446 if (status == MagickFalse)
2448 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2450 if (q == (Quantum *) NULL)
2455 for (x=0; x < (ssize_t) image->columns; x++)
2465 hue=(double) (QuantumScale*GetPixelRed(image,q));
2466 whiteness=(double) (QuantumScale*GetPixelGreen(image,q));
2467 blackness=(double) (QuantumScale*GetPixelBlue(image,q));
2468 ConvertHWBToRGB(hue,whiteness,blackness,&red,&green,&blue);
2469 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2470 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2471 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2472 q+=GetPixelChannels(image);
2474 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2475 if (sync == MagickFalse)
2478 image_view=DestroyCacheView(image_view);
2479 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2480 return(MagickFalse);
2486 Transform image from Lab to sRGB.
2488 if (image->storage_class == PseudoClass)
2490 if (SyncImage(image,exception) == MagickFalse)
2491 return(MagickFalse);
2492 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2493 return(MagickFalse);
2495 image_view=AcquireAuthenticCacheView(image,exception);
2496 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2497 #pragma omp parallel for schedule(static,4) shared(status) \
2498 dynamic_number_threads(image,image->columns,image->rows,1)
2500 for (y=0; y < (ssize_t) image->rows; y++)
2511 if (status == MagickFalse)
2513 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2515 if (q == (Quantum *) NULL)
2520 for (x=0; x < (ssize_t) image->columns; x++)
2533 L=QuantumScale*GetPixelRed(image,q);
2534 a=QuantumScale*GetPixelGreen(image,q);
2535 b=QuantumScale*GetPixelBlue(image,q);
2536 ConvertLabToXYZ(L,a,b,&X,&Y,&Z);
2537 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2538 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2539 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2540 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2541 q+=GetPixelChannels(image);
2543 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2544 if (sync == MagickFalse)
2547 image_view=DestroyCacheView(image_view);
2548 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2549 return(MagickFalse);
2569 Transform Log to sRGB colorspace.
2571 density=DisplayGamma;
2573 value=GetImageProperty(image,"gamma",exception);
2574 if (value != (const char *) NULL)
2575 gamma=MagickEpsilonReciprocal(StringToDouble(value,(char **) NULL));
2576 film_gamma=FilmGamma;
2577 value=GetImageProperty(image,"film-gamma",exception);
2578 if (value != (const char *) NULL)
2579 film_gamma=StringToDouble(value,(char **) NULL);
2580 reference_black=ReferenceBlack;
2581 value=GetImageProperty(image,"reference-black",exception);
2582 if (value != (const char *) NULL)
2583 reference_black=StringToDouble(value,(char **) NULL);
2584 reference_white=ReferenceWhite;
2585 value=GetImageProperty(image,"reference-white",exception);
2586 if (value != (const char *) NULL)
2587 reference_white=StringToDouble(value,(char **) NULL);
2588 logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2590 if (logmap == (Quantum *) NULL)
2591 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2593 black=pow(10.0,(reference_black-reference_white)*(gamma/density)*
2595 for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
2596 logmap[i]=(Quantum) 0;
2597 for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
2598 logmap[i]=ClampToQuantum(QuantumRange/(1.0-black)*
2599 (pow(10.0,(1024.0*i/MaxMap-reference_white)*
2600 (gamma/density)*0.002/film_gamma)-black));
2601 for ( ; i <= (ssize_t) MaxMap; i++)
2602 logmap[i]=QuantumRange;
2603 if (image->storage_class == PseudoClass)
2605 if (SyncImage(image,exception) == MagickFalse)
2606 return(MagickFalse);
2607 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2608 return(MagickFalse);
2610 image_view=AcquireAuthenticCacheView(image,exception);
2611 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2612 #pragma omp parallel for schedule(static,4) shared(status) \
2613 dynamic_number_threads(image,image->columns,image->rows,1)
2615 for (y=0; y < (ssize_t) image->rows; y++)
2626 if (status == MagickFalse)
2628 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2630 if (q == (Quantum *) NULL)
2635 for (x=(ssize_t) image->columns; x != 0; x--)
2642 red=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2643 GetPixelRed(image,q))]);
2644 green=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2645 GetPixelGreen(image,q))]);
2646 blue=sRGBCompandor((double) logmap[ScaleQuantumToMap(
2647 GetPixelBlue(image,q))]);
2648 SetPixelRed(image,ClampToQuantum(red),q);
2649 SetPixelGreen(image,ClampToQuantum(green),q);
2650 SetPixelBlue(image,ClampToQuantum(blue),q);
2651 q+=GetPixelChannels(image);
2653 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2654 if (sync == MagickFalse)
2657 image_view=DestroyCacheView(image_view);
2658 logmap=(Quantum *) RelinquishMagickMemory(logmap);
2659 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2660 return(MagickFalse);
2666 Transform image from Luv to sRGB.
2668 if (image->storage_class == PseudoClass)
2670 if (SyncImage(image,exception) == MagickFalse)
2671 return(MagickFalse);
2672 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2673 return(MagickFalse);
2675 image_view=AcquireAuthenticCacheView(image,exception);
2676 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2677 #pragma omp parallel for schedule(static,4) shared(status) \
2678 dynamic_number_threads(image,image->columns,image->rows,1)
2680 for (y=0; y < (ssize_t) image->rows; y++)
2691 if (status == MagickFalse)
2693 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2695 if (q == (Quantum *) NULL)
2700 for (x=0; x < (ssize_t) image->columns; x++)
2713 L=QuantumScale*GetPixelRed(image,q);
2714 u=QuantumScale*GetPixelGreen(image,q);
2715 v=QuantumScale*GetPixelBlue(image,q);
2716 ConvertLuvToXYZ(L,u,v,&X,&Y,&Z);
2717 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2718 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2719 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2720 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2721 q+=GetPixelChannels(image);
2723 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2724 if (sync == MagickFalse)
2727 image_view=DestroyCacheView(image_view);
2728 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2729 return(MagickFalse);
2735 Transform linear RGB to sRGB colorspace.
2737 if (image->storage_class == PseudoClass)
2739 if (SyncImage(image,exception) == MagickFalse)
2740 return(MagickFalse);
2741 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2742 return(MagickFalse);
2744 image_view=AcquireAuthenticCacheView(image,exception);
2745 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2746 #pragma omp parallel for schedule(static,4) shared(status) \
2747 dynamic_number_threads(image,image->columns,image->rows,1)
2749 for (y=0; y < (ssize_t) image->rows; y++)
2760 if (status == MagickFalse)
2762 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2764 if (q == (Quantum *) NULL)
2769 for (x=(ssize_t) image->columns; x != 0; x--)
2776 red=sRGBCompandor((double) GetPixelRed(image,q));
2777 green=sRGBCompandor((double) GetPixelGreen(image,q));
2778 blue=sRGBCompandor((double) GetPixelBlue(image,q));
2779 SetPixelRed(image,ClampToQuantum(red),q);
2780 SetPixelGreen(image,ClampToQuantum(green),q);
2781 SetPixelBlue(image,ClampToQuantum(blue),q);
2782 q+=GetPixelChannels(image);
2784 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2785 if (sync == MagickFalse)
2788 image_view=DestroyCacheView(image_view);
2789 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2790 return(MagickFalse);
2796 Transform image from XYZ to sRGB.
2798 if (image->storage_class == PseudoClass)
2800 if (SyncImage(image,exception) == MagickFalse)
2801 return(MagickFalse);
2802 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
2803 return(MagickFalse);
2805 image_view=AcquireAuthenticCacheView(image,exception);
2806 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2807 #pragma omp parallel for schedule(static,4) shared(status) \
2808 dynamic_number_threads(image,image->columns,image->rows,1)
2810 for (y=0; y < (ssize_t) image->rows; y++)
2821 if (status == MagickFalse)
2823 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2825 if (q == (Quantum *) NULL)
2830 for (x=0; x < (ssize_t) image->columns; x++)
2840 X=QuantumScale*GetPixelRed(image,q);
2841 Y=QuantumScale*GetPixelGreen(image,q);
2842 Z=QuantumScale*GetPixelBlue(image,q);
2843 ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2844 SetPixelRed(image,ClampToQuantum(sRGBCompandor(red)),q);
2845 SetPixelGreen(image,ClampToQuantum(sRGBCompandor(green)),q);
2846 SetPixelBlue(image,ClampToQuantum(sRGBCompandor(blue)),q);
2847 q+=GetPixelChannels(image);
2849 sync=SyncCacheViewAuthenticPixels(image_view,exception);
2850 if (sync == MagickFalse)
2853 image_view=DestroyCacheView(image_view);
2854 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
2855 return(MagickFalse);
2862 Allocate the tables.
2864 x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2866 y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2868 z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2870 if ((x_map == (TransformPacket *) NULL) ||
2871 (y_map == (TransformPacket *) NULL) ||
2872 (z_map == (TransformPacket *) NULL))
2874 if (z_map != (TransformPacket *) NULL)
2875 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2876 if (y_map != (TransformPacket *) NULL)
2877 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2878 if (x_map != (TransformPacket *) NULL)
2879 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2880 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2883 switch (image->colorspace)
2885 case OHTAColorspace:
2888 Initialize OHTA tables:
2890 R = I1+1.00000*I2-0.66668*I3
2891 G = I1+0.00000*I2+1.33333*I3
2892 B = I1-1.00000*I2-0.66668*I3
2894 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2895 through QuantumRange.
2897 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2898 #pragma omp parallel for schedule(static) \
2899 dynamic_number_threads(image,image->columns,1,1)
2901 for (i=0; i <= (ssize_t) MaxMap; i++)
2903 x_map[i].x=(double) i;
2904 y_map[i].x=0.500000*(2.000000*(double) i-(double)
2906 z_map[i].x=(-0.333340)*(2.000000*(double) i-(double)
2908 x_map[i].y=(double) i;
2909 y_map[i].y=0.000000;
2910 z_map[i].y=0.666665*(2.000000*(double) i-(double)
2912 x_map[i].z=(double) i;
2913 y_map[i].z=(-0.500000)*(2.000000*(double) i-(double)
2915 z_map[i].z=(-0.333340)*(2.000000*(double) i-(double)
2920 case Rec601YCbCrColorspace:
2921 case YCbCrColorspace:
2924 Initialize YCbCr tables:
2927 G = Y-0.344136*Cb-0.714136*Cr
2930 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2931 through QuantumRange.
2933 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2934 #pragma omp parallel for schedule(static) \
2935 dynamic_number_threads(image,image->columns,1,1)
2937 for (i=0; i <= (ssize_t) MaxMap; i++)
2939 x_map[i].x=(double) i;
2940 y_map[i].x=0.000000;
2941 z_map[i].x=(1.402000*0.500000)*(2.000000*(double) i-
2943 x_map[i].y=(double) i;
2944 y_map[i].y=(-0.344136*0.500000)*(2.000000*(double) i-
2946 z_map[i].y=(-0.714136*0.500000)*(2.000000*(double) i-
2948 x_map[i].z=(double) i;
2949 y_map[i].z=(1.772000*0.500000)*(2.000000*(double) i-
2951 z_map[i].z=0.000000;
2955 case Rec709YCbCrColorspace:
2958 Initialize YCbCr tables:
2961 G = Y-0.187324*Cb-0.468124*Cr
2964 Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2965 through QuantumRange.
2967 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2968 #pragma omp parallel for schedule(static) \
2969 dynamic_number_threads(image,image->columns,1,1)
2971 for (i=0; i <= (ssize_t) MaxMap; i++)
2973 x_map[i].x=(double) i;
2974 y_map[i].x=0.000000;
2975 z_map[i].x=(1.574800*0.50000)*(2.00000*(double) i-
2977 x_map[i].y=(double) i;
2978 y_map[i].y=(-0.187324*0.50000)*(2.00000*(double) i-
2980 z_map[i].y=(-0.468124*0.50000)*(2.00000*(double) i-
2982 x_map[i].z=(double) i;
2983 y_map[i].z=(1.855600*0.50000)*(2.00000*(double) i-
2992 Initialize YCC tables:
2995 G = Y-0.317038*C1-0.682243*C2
2998 YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
3000 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3001 #pragma omp parallel for schedule(static) \
3002 dynamic_number_threads(image,image->columns,1,1)
3004 for (i=0; i <= (ssize_t) MaxMap; i++)
3006 x_map[i].x=1.3584000*(double) i;
3007 y_map[i].x=0.0000000;
3008 z_map[i].x=1.8215000*((double) i-(double)
3009 ScaleQuantumToMap(ScaleCharToQuantum(137)));
3010 x_map[i].y=1.3584000*(double) i;
3011 y_map[i].y=(-0.4302726)*((double) i-(double)
3012 ScaleQuantumToMap(ScaleCharToQuantum(156)));
3013 z_map[i].y=(-0.9271435)*((double) i-(double)
3014 ScaleQuantumToMap(ScaleCharToQuantum(137)));
3015 x_map[i].z=1.3584000*(double) i;
3016 y_map[i].z=2.2179000*((double) i-(double)
3017 ScaleQuantumToMap(ScaleCharToQuantum(156)));
3018 z_map[i].z=0.0000000;
3025 Initialize YIQ tables:
3027 R = Y+0.95620*I+0.62140*Q
3028 G = Y-0.27270*I-0.64680*Q
3029 B = Y-1.10370*I+1.70060*Q
3031 I and Q, normally -0.5 through 0.5, must be normalized to the range 0
3032 through QuantumRange.
3034 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3035 #pragma omp parallel for schedule(static) \
3036 dynamic_number_threads(image,image->columns,1,1)
3038 for (i=0; i <= (ssize_t) MaxMap; i++)
3040 x_map[i].x=(double) i;
3041 y_map[i].x=0.47810*(2.00000*(double) i-(double)
3043 z_map[i].x=0.31070*(2.00000*(double) i-(double)
3045 x_map[i].y=(double) i;
3046 y_map[i].y=(-0.13635)*(2.00000*(double) i-(double)
3048 z_map[i].y=(-0.32340)*(2.00000*(double) i-(double)
3050 x_map[i].z=(double) i;
3051 y_map[i].z=(-0.55185)*(2.00000*(double) i-(double)
3053 z_map[i].z=0.85030*(2.00000*(double) i-(double)
3058 case YPbPrColorspace:
3061 Initialize YPbPr tables:
3064 G = Y-0.344136*C1+0.714136*C2
3067 Pb and Pr, normally -0.5 through 0.5, must be normalized to the range 0
3068 through QuantumRange.
3070 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3071 #pragma omp parallel for schedule(static) \
3072 dynamic_number_threads(image,image->columns,1,1)
3074 for (i=0; i <= (ssize_t) MaxMap; i++)
3076 x_map[i].x=(double) i;
3077 y_map[i].x=0.000000;
3078 z_map[i].x=0.701000*(2.00000*(double) i-(double)
3080 x_map[i].y=(double) i;
3081 y_map[i].y=(-0.172068)*(2.00000*(double) i-(double)
3083 z_map[i].y=0.357068*(2.00000*(double) i-(double)
3085 x_map[i].z=(double) i;
3086 y_map[i].z=0.88600*(2.00000*(double) i-(double)
3095 Initialize YUV tables:
3098 G = Y-0.3455*U-0.7169*V
3101 U and V, normally -0.5 through 0.5, must be normalized to the range 0
3102 through QuantumRange.
3104 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3105 #pragma omp parallel for schedule(static) \
3106 dynamic_number_threads(image,image->columns,1,1)
3108 for (i=0; i <= (ssize_t) MaxMap; i++)
3110 x_map[i].x=(double) i;
3112 z_map[i].x=0.70375*(2.0000*(double) i-(double) MaxMap);
3113 x_map[i].y=(double) i;
3114 y_map[i].y=(-0.17275)*(2.00000*(double) i-(double)
3116 z_map[i].y=(-0.35845)*(2.00000*(double) i-(double)
3118 x_map[i].z=(double) i;
3119 y_map[i].z=0.8895*(2.00000*(double) i-(double) MaxMap);
3127 Linear conversion tables.
3129 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3130 #pragma omp parallel for schedule(static) \
3131 dynamic_number_threads(image,image->columns,1,1)
3133 for (i=0; i <= (ssize_t) MaxMap; i++)
3135 x_map[i].x=(double) i;
3139 y_map[i].y=(double) i;
3143 z_map[i].z=(double) i;
3151 switch (image->storage_class)
3157 Convert DirectClass image.
3159 image_view=AcquireAuthenticCacheView(image,exception);
3160 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3161 #pragma omp parallel for schedule(static,4) shared(status) \
3162 dynamic_number_threads(image,image->columns,image->rows,1)
3164 for (y=0; y < (ssize_t) image->rows; y++)
3178 if (status == MagickFalse)
3180 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
3182 if (q == (Quantum *) NULL)
3187 for (x=0; x < (ssize_t) image->columns; x++)
3194 red=ScaleQuantumToMap(GetPixelRed(image,q));
3195 green=ScaleQuantumToMap(GetPixelGreen(image,q));
3196 blue=ScaleQuantumToMap(GetPixelBlue(image,q));
3197 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
3198 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
3199 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
3200 if (colorspace == YCCColorspace)
3202 #if !defined(MAGICKCORE_HDRI_SUPPORT)
3203 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3205 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3207 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3211 SetPixelRed(image,ClampToQuantum(sRGBCompandor((double)
3212 ScaleMapToQuantum(pixel.red))),q);
3213 SetPixelGreen(image,ClampToQuantum(sRGBCompandor((double)
3214 ScaleMapToQuantum(pixel.green))),q);
3215 SetPixelBlue(image,ClampToQuantum(sRGBCompandor((double)
3216 ScaleMapToQuantum(pixel.blue))),q);
3217 q+=GetPixelChannels(image);
3219 sync=SyncCacheViewAuthenticPixels(image_view,exception);
3220 if (sync == MagickFalse)
3222 if (image->progress_monitor != (MagickProgressMonitor) NULL)
3227 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3228 #pragma omp critical (MagickCore_TransformsRGBImage)
3230 proceed=SetImageProgress(image,TransformsRGBImageTag,progress++,
3232 if (proceed == MagickFalse)
3236 image_view=DestroyCacheView(image_view);
3242 Convert PseudoClass image.
3244 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3245 #pragma omp parallel for schedule(static,4) shared(status) \
3246 dynamic_number_threads(image,image->columns,1,1)
3248 for (i=0; i < (ssize_t) image->colors; i++)
3258 red=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red));
3259 green=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green));
3260 blue=ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue));
3261 pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
3262 pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
3263 pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
3264 if (colorspace == YCCColorspace)
3266 #if !defined(MAGICKCORE_HDRI_SUPPORT)
3267 pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3269 pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3271 pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*QuantumScale*
3275 image->colormap[i].red=(double) ClampToQuantum(
3276 sRGBCompandor((double) ScaleMapToQuantum(pixel.red)));
3277 image->colormap[i].green=(double) ClampToQuantum(
3278 sRGBCompandor((double) ScaleMapToQuantum(pixel.green)));
3279 image->colormap[i].blue=(double) ClampToQuantum(
3280 sRGBCompandor((double) ScaleMapToQuantum(pixel.blue)));
3282 (void) SyncImage(image,exception);
3287 Relinquish resources.
3289 z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
3290 y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
3291 x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
3292 if (SetImageColorspace(image,sRGBColorspace,exception) == MagickFalse)
3293 return(MagickFalse);