MagickCore  6.9.13-19
Convert, Edit, Or Compose Bitmap Images
colorspace.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
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 %
11 % %
12 % %
13 % MagickCore Image Colorspace Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % July 1992 %
18 % %
19 % %
20 % Copyright 1999 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % https://imagemagick.org/script/license.php %
27 % %
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. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 */
38 ␌
39 /*
40  Include declarations.
41 */
42 #include "magick/studio.h"
43 #include "magick/attribute.h"
44 #include "magick/cache.h"
45 #include "magick/cache-private.h"
46 #include "magick/cache-view.h"
47 #include "magick/color.h"
48 #include "magick/color-private.h"
49 #include "magick/colorspace.h"
50 #include "magick/colorspace-private.h"
51 #include "magick/exception.h"
52 #include "magick/exception-private.h"
53 #include "magick/enhance.h"
54 #include "magick/image.h"
55 #include "magick/image-private.h"
56 #include "magick/gem.h"
57 #include "magick/gem-private.h"
58 #include "magick/memory_.h"
59 #include "magick/monitor.h"
60 #include "magick/monitor-private.h"
61 #include "magick/pixel-private.h"
62 #include "magick/property.h"
63 #include "magick/quantize.h"
64 #include "magick/quantum.h"
65 #include "magick/resource_.h"
66 #include "magick/string_.h"
67 #include "magick/string-private.h"
68 #include "magick/utility.h"
69 ␌
70 /*
71  Typedef declarations.
72 */
73 typedef struct _TransformPacket
74 {
75  MagickRealType
76  x,
77  y,
78  z;
80 ␌
81 /*
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 % %
84 % %
85 % %
86 % G e t I m a g e C o l o r s p a c e T y p e %
87 % %
88 % %
89 % %
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 %
92 % GetImageColorspaceType() returns the potential colorspace of image:
93 % sRGBColorspaceType, RGBColorspaceType, GRAYColorspaceType, etc.
94 %
95 % To ensure the image type matches its potential, use SetImageColorspaceType():
96 %
97 % (void) SetImageColorspaceType(image,GetImageColorspaceType(image),
98 % exception);
99 %
100 % The format of the GetImageColorspaceType method is:
101 %
102 % ColorspaceType GetImageColorspaceType(const Image *image,
103 % ExceptionInfo *exception)
104 %
105 % A description of each parameter follows:
106 %
107 % o image: the image.
108 %
109 % o exception: return any errors or warnings in this structure.
110 %
111 */
112 MagickExport ColorspaceType GetImageColorspaceType(const Image *image,
113  ExceptionInfo *exception)
114 {
115  ColorspaceType
116  colorspace;
117 
118  ImageType
119  type;
120 
121  assert(image != (Image *) NULL);
122  assert(image->signature == MagickCoreSignature);
123  if (IsEventLogging() != MagickFalse)
124  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
125  colorspace=image->colorspace;
126  type=IdentifyImageType(image,exception);
127  if ((type == BilevelType) || (type == GrayscaleType) ||
128  (type == GrayscaleMatteType))
129  colorspace=GRAYColorspace;
130  return(colorspace);
131 }
132 ␌
133 /*
134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % %
136 % %
137 % %
138 + R G B T r a n s f o r m I m a g e %
139 % %
140 % %
141 % %
142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 %
144 % RGBTransformImage() converts the reference image from sRGB to an alternate
145 % colorspace. The transformation matrices are not the standard ones: the
146 % weights are rescaled to normalized the range of the transformed values to
147 % be [0..QuantumRange].
148 %
149 % The format of the RGBTransformImage method is:
150 %
151 % MagickBooleanType RGBTransformImage(Image *image,
152 % const ColorspaceType colorspace)
153 %
154 % A description of each parameter follows:
155 %
156 % o image: the image.
157 %
158 % o colorspace: the colorspace to transform the image to.
159 %
160 */
161 
162 static inline void ConvertRGBToCMY(const Quantum red,const Quantum green,
163  const Quantum blue,double *cyan,double *magenta,double *yellow)
164 {
165  *cyan=QuantumScale*((double) QuantumRange-(double) red);
166  *magenta=QuantumScale*((double) QuantumRange-(double) green);
167  *yellow=QuantumScale*((double) QuantumRange-(double) blue);
168 }
169 
170 static void ConvertRGBToLab(const Quantum red,const Quantum green,
171  const Quantum blue,double *L,double *a,double *b)
172 {
173  double
174  X,
175  Y,
176  Z;
177 
178  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
179  ConvertXYZToLab(X,Y,Z,L,a,b);
180 }
181 
182 static inline void ConvertXYZToLMS(const double x,const double y,
183  const double z,double *L,double *M,double *S)
184 {
185  *L=0.7328*x+0.4296*y-0.1624*z;
186  *M=(-0.7036*x+1.6975*y+0.0061*z);
187  *S=0.0030*x+0.0136*y+0.9834*z;
188 }
189 
190 static void ConvertRGBToLMS(const Quantum red,const Quantum green,
191  const Quantum blue,double *L,double *M,double *S)
192 {
193  double
194  X,
195  Y,
196  Z;
197 
198  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
199  ConvertXYZToLMS(X,Y,Z,L,M,S);
200 }
201 
202 static void ConvertRGBToLuv(const Quantum red,const Quantum green,
203  const Quantum blue,double *L,double *u,double *v)
204 {
205  double
206  X,
207  Y,
208  Z;
209 
210  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
211  ConvertXYZToLuv(X,Y,Z,L,u,v);
212 }
213 
214 static void ConvertRGBToxyY(const Quantum red,const Quantum green,
215  const Quantum blue,double *low_x,double *low_y,double *cap_Y)
216 {
217  double
218  gamma,
219  X,
220  Y,
221  Z;
222 
223  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
224  gamma=PerceptibleReciprocal(X+Y+Z);
225  *low_x=gamma*X;
226  *low_y=gamma*Y;
227  *cap_Y=Y;
228 }
229 
230 static void ConvertRGBToYPbPr(const Quantum red,const Quantum green,
231  const Quantum blue,double *Y,double *Pb,double *Pr)
232 {
233  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
234  (double) blue);
235  *Pb=QuantumScale*((-0.1687367)*(double) red-0.331264*(double) green+0.5*
236  (double) blue)+0.5;
237  *Pr=QuantumScale*(0.5*(double) red-0.418688*(double) green-0.081312*
238  (double) blue)+0.5;
239 }
240 
241 static void ConvertRGBToYCbCr(const Quantum red,const Quantum green,
242  const Quantum blue,double *Y,double *Cb,double *Cr)
243 {
244  ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
245 }
246 
247 static void ConvertRGBToYUV(const Quantum red,const Quantum green,
248  const Quantum blue,double *Y,double *U,double *V)
249 {
250  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
251  (double) blue);
252  *U=QuantumScale*((-0.147)*(double) red-0.289*(double) green+0.436*
253  (double) blue)+0.5;
254  *V=QuantumScale*(0.615*(double) red-0.515*(double) green-0.100*
255  (double) blue)+0.5;
256 }
257 
258 static void ConvertRGBToYDbDr(const Quantum red,const Quantum green,
259  const Quantum blue,double *Y,double *Db,double *Dr)
260 {
261  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
262  (double) blue);
263  *Db=QuantumScale*(-0.450*(double) red-0.883*(double) green+1.333*
264  (double) blue)+0.5;
265  *Dr=QuantumScale*(-1.333*(double) red+1.116*(double) green+0.217*
266  (double) blue)+0.5;
267 }
268 
269 static void ConvertRGBToYIQ(const Quantum red,const Quantum green,
270  const Quantum blue,double *Y,double *I,double *Q)
271 {
272  *Y=QuantumScale*(0.298839*(double) red+0.586811*(double) green+0.114350*
273  (double) blue);
274  *I=QuantumScale*(0.595716*(double) red-0.274453*(double) green-0.321263*
275  (double) blue)+0.5;
276  *Q=QuantumScale*(0.211456*(double) red-0.522591*(double) green+0.311135*
277  (double) blue)+0.5;
278 }
279 
280 MagickExport MagickBooleanType RGBTransformImage(Image *image,
281  const ColorspaceType colorspace)
282 {
283 #define RGBTransformImageTag "RGBTransform/Image"
284 
285  CacheView
286  *image_view;
287 
289  *exception;
290 
291  MagickBooleanType
292  status;
293 
294  MagickOffsetType
295  progress;
296 
298  primary_info;
299 
300  ssize_t
301  i;
302 
303  ssize_t
304  y;
305 
307  *x_map,
308  *y_map,
309  *z_map;
310 
311  assert(image != (Image *) NULL);
312  assert(image->signature == MagickCoreSignature);
313  assert(colorspace != sRGBColorspace);
314  assert(colorspace != TransparentColorspace);
315  assert(colorspace != UndefinedColorspace);
316  if (IsEventLogging() != MagickFalse)
317  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
318  status=MagickTrue;
319  progress=0;
320  exception=(&image->exception);
321  switch (colorspace)
322  {
323  case CMYKColorspace:
324  {
326  zero;
327 
328  /*
329  Convert RGB to CMYK colorspace.
330  */
331  if (image->storage_class == PseudoClass)
332  {
333  if (SyncImage(image) == MagickFalse)
334  return(MagickFalse);
335  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
336  return(MagickFalse);
337  }
338  if (SetImageColorspace(image,colorspace) == MagickFalse)
339  return(MagickFalse);
340  GetMagickPixelPacket(image,&zero);
341  image_view=AcquireAuthenticCacheView(image,exception);
342 #if defined(MAGICKCORE_OPENMP_SUPPORT)
343  #pragma omp parallel for schedule(static) shared(status) \
344  magick_number_threads(image,image,image->rows,2)
345 #endif
346  for (y=0; y < (ssize_t) image->rows; y++)
347  {
348  MagickBooleanType
349  sync;
350 
352  pixel;
353 
354  IndexPacket
355  *magick_restrict indexes;
356 
357  ssize_t
358  x;
359 
361  *magick_restrict q;
362 
363  if (status == MagickFalse)
364  continue;
365  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
366  exception);
367  if (q == (PixelPacket *) NULL)
368  {
369  status=MagickFalse;
370  continue;
371  }
372  indexes=GetCacheViewAuthenticIndexQueue(image_view);
373  pixel=zero;
374  for (x=0; x < (ssize_t) image->columns; x++)
375  {
376  SetMagickPixelPacket(image,q,indexes+x,&pixel);
377  pixel.red=(MagickRealType) pixel.red;
378  pixel.green=(MagickRealType) pixel.green;
379  pixel.blue=(MagickRealType) pixel.blue;
380  ConvertRGBToCMYK(&pixel);
381  SetPixelPacket(image,&pixel,q,indexes+x);
382  q++;
383  }
384  sync=SyncCacheViewAuthenticPixels(image_view,exception);
385  if (sync == MagickFalse)
386  status=MagickFalse;
387  }
388  image_view=DestroyCacheView(image_view);
389  image->type=image->matte == MagickFalse ? ColorSeparationType :
390  ColorSeparationMatteType;
391  if (SetImageColorspace(image,colorspace) == MagickFalse)
392  return(MagickFalse);
393  return(status);
394  }
395  case LinearGRAYColorspace:
396  {
397  /*
398  Transform image from sRGB to GRAY.
399  */
400  if (image->storage_class == PseudoClass)
401  {
402  if (SyncImage(image) == MagickFalse)
403  return(MagickFalse);
404  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
405  return(MagickFalse);
406  }
407  image_view=AcquireAuthenticCacheView(image,exception);
408 #if defined(MAGICKCORE_OPENMP_SUPPORT)
409  #pragma omp parallel for schedule(static) shared(status) \
410  magick_number_threads(image,image,image->rows,2)
411 #endif
412  for (y=0; y < (ssize_t) image->rows; y++)
413  {
414  MagickBooleanType
415  sync;
416 
417  ssize_t
418  x;
419 
421  *magick_restrict q;
422 
423  if (status == MagickFalse)
424  continue;
425  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
426  exception);
427  if (q == (PixelPacket *) NULL)
428  {
429  status=MagickFalse;
430  continue;
431  }
432  for (x=0; x < (ssize_t) image->columns; x++)
433  {
434  MagickRealType
435  gray;
436 
437  gray=0.212656*DecodePixelGamma(GetPixelRed(q))+0.715158*
438  DecodePixelGamma(GetPixelGreen(q))+0.072186*
439  DecodePixelGamma(GetPixelBlue(q));
440  SetPixelGray(q,ClampToQuantum(gray));
441  q++;
442  }
443  sync=SyncCacheViewAuthenticPixels(image_view,exception);
444  if (sync == MagickFalse)
445  status=MagickFalse;
446  }
447  image_view=DestroyCacheView(image_view);
448  if (SetImageColorspace(image,colorspace) == MagickFalse)
449  return(MagickFalse);
450  image->type=GrayscaleType;
451  return(status);
452  }
453  case GRAYColorspace:
454  {
455  /*
456  Transform image from sRGB to GRAY.
457  */
458  if (image->storage_class == PseudoClass)
459  {
460  if (SyncImage(image) == MagickFalse)
461  return(MagickFalse);
462  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
463  return(MagickFalse);
464  }
465  image_view=AcquireAuthenticCacheView(image,exception);
466 #if defined(MAGICKCORE_OPENMP_SUPPORT)
467  #pragma omp parallel for schedule(static) shared(status) \
468  magick_number_threads(image,image,image->rows,2)
469 #endif
470  for (y=0; y < (ssize_t) image->rows; y++)
471  {
472  MagickBooleanType
473  sync;
474 
475  ssize_t
476  x;
477 
479  *magick_restrict q;
480 
481  if (status == MagickFalse)
482  continue;
483  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
484  exception);
485  if (q == (PixelPacket *) NULL)
486  {
487  status=MagickFalse;
488  continue;
489  }
490  for (x=0; x < (ssize_t) image->columns; x++)
491  {
492  MagickRealType
493  gray;
494 
495  gray=0.212656*(double) GetPixelRed(q)+0.715158*(double)
496  GetPixelGreen(q)+0.072186*(double) GetPixelBlue(q);
497  SetPixelGray(q,ClampToQuantum(gray));
498  q++;
499  }
500  sync=SyncCacheViewAuthenticPixels(image_view,exception);
501  if (sync == MagickFalse)
502  status=MagickFalse;
503  }
504  image_view=DestroyCacheView(image_view);
505  if (SetImageColorspace(image,colorspace) == MagickFalse)
506  return(MagickFalse);
507  image->type=GrayscaleType;
508  return(status);
509  }
510  case CMYColorspace:
511  case HCLColorspace:
512  case HCLpColorspace:
513  case HSBColorspace:
514  case HSIColorspace:
515  case HSLColorspace:
516  case HSVColorspace:
517  case HWBColorspace:
518  case LabColorspace:
519  case LCHColorspace:
520  case LCHabColorspace:
521  case LCHuvColorspace:
522  case LMSColorspace:
523  case LuvColorspace:
524  case xyYColorspace:
525  case XYZColorspace:
526  case YCbCrColorspace:
527  case YDbDrColorspace:
528  case YIQColorspace:
529  case YPbPrColorspace:
530  case YUVColorspace:
531  {
532  /*
533  Transform image from sRGB to HSI.
534  */
535  if (image->storage_class == PseudoClass)
536  {
537  if (SyncImage(image) == MagickFalse)
538  return(MagickFalse);
539  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
540  return(MagickFalse);
541  }
542  image_view=AcquireAuthenticCacheView(image,exception);
543 #if defined(MAGICKCORE_OPENMP_SUPPORT)
544  #pragma omp parallel for schedule(static) shared(status) \
545  magick_number_threads(image,image,image->rows,2)
546 #endif
547  for (y=0; y < (ssize_t) image->rows; y++)
548  {
549  MagickBooleanType
550  sync;
551 
552  ssize_t
553  x;
554 
556  *magick_restrict q;
557 
558  if (status == MagickFalse)
559  continue;
560  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
561  exception);
562  if (q == (PixelPacket *) NULL)
563  {
564  status=MagickFalse;
565  continue;
566  }
567  for (x=0; x < (ssize_t) image->columns; x++)
568  {
569  double
570  X,
571  Y,
572  Z;
573 
574  Quantum
575  blue,
576  green,
577  red;
578 
579  red=ClampToQuantum((MagickRealType) GetPixelRed(q));
580  green=ClampToQuantum((MagickRealType) GetPixelGreen(q));
581  blue=ClampToQuantum((MagickRealType) GetPixelBlue(q));
582  switch (colorspace)
583  {
584  case CMYColorspace:
585  {
586  ConvertRGBToCMY(red,green,blue,&X,&Y,&Z);
587  break;
588  }
589  case HCLColorspace:
590  {
591  ConvertRGBToHCL(red,green,blue,&X,&Y,&Z);
592  break;
593  }
594  case HCLpColorspace:
595  {
596  ConvertRGBToHCLp(red,green,blue,&X,&Y,&Z);
597  break;
598  }
599  case HSBColorspace:
600  {
601  ConvertRGBToHSB(red,green,blue,&X,&Y,&Z);
602  break;
603  }
604  case HSIColorspace:
605  {
606  ConvertRGBToHSI(red,green,blue,&X,&Y,&Z);
607  break;
608  }
609  case HSLColorspace:
610  {
611  ConvertRGBToHSL(red,green,blue,&X,&Y,&Z);
612  break;
613  }
614  case HSVColorspace:
615  {
616  ConvertRGBToHSV(red,green,blue,&X,&Y,&Z);
617  break;
618  }
619  case HWBColorspace:
620  {
621  ConvertRGBToHWB(red,green,blue,&X,&Y,&Z);
622  break;
623  }
624  case LabColorspace:
625  {
626  ConvertRGBToLab(red,green,blue,&X,&Y,&Z);
627  break;
628  }
629  case LCHColorspace:
630  case LCHabColorspace:
631  {
632  ConvertRGBToLCHab(red,green,blue,&X,&Y,&Z);
633  break;
634  }
635  case LCHuvColorspace:
636  {
637  ConvertRGBToLCHuv(red,green,blue,&X,&Y,&Z);
638  break;
639  }
640  case LMSColorspace:
641  {
642  ConvertRGBToLMS(red,green,blue,&X,&Y,&Z);
643  break;
644  }
645  case LuvColorspace:
646  {
647  ConvertRGBToLuv(red,green,blue,&X,&Y,&Z);
648  break;
649  }
650  case xyYColorspace:
651  {
652  ConvertRGBToxyY(red,green,blue,&X,&Y,&Z);
653  break;
654  }
655  case XYZColorspace:
656  {
657  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
658  break;
659  }
660  case YCbCrColorspace:
661  {
662  ConvertRGBToYCbCr(red,green,blue,&X,&Y,&Z);
663  break;
664  }
665  case YDbDrColorspace:
666  {
667  ConvertRGBToYDbDr(red,green,blue,&X,&Y,&Z);
668  break;
669  }
670  case YIQColorspace:
671  {
672  ConvertRGBToYIQ(red,green,blue,&X,&Y,&Z);
673  break;
674  }
675  case YPbPrColorspace:
676  {
677  ConvertRGBToYPbPr(red,green,blue,&X,&Y,&Z);
678  break;
679  }
680  case YUVColorspace:
681  {
682  ConvertRGBToYUV(red,green,blue,&X,&Y,&Z);
683  break;
684  }
685  default:
686  {
687  X=QuantumScale*(double) red;
688  Y=QuantumScale*(double) green;
689  Z=QuantumScale*(double) blue;
690  break;
691  }
692  }
693  SetPixelRed(q,ClampToQuantum((MagickRealType) QuantumRange*X));
694  SetPixelGreen(q,ClampToQuantum((MagickRealType) QuantumRange*Y));
695  SetPixelBlue(q,ClampToQuantum((MagickRealType) QuantumRange*Z));
696  q++;
697  }
698  sync=SyncCacheViewAuthenticPixels(image_view,exception);
699  if (sync == MagickFalse)
700  status=MagickFalse;
701  }
702  image_view=DestroyCacheView(image_view);
703  if (SetImageColorspace(image,colorspace) == MagickFalse)
704  return(MagickFalse);
705  return(status);
706  }
707  case LogColorspace:
708  {
709 #define DisplayGamma (1.0/1.7)
710 #define FilmGamma 0.6
711 #define ReferenceBlack 95.0
712 #define ReferenceWhite 685.0
713 
714  const char
715  *value;
716 
717  double
718  black,
719  density,
720  film_gamma,
721  gamma,
722  reference_black,
723  reference_white;
724 
725  Quantum
726  *logmap;
727 
728  /*
729  Transform RGB to Log colorspace.
730  */
731  density=DisplayGamma;
732  gamma=DisplayGamma;
733  value=GetImageProperty(image,"gamma");
734  if (value != (const char *) NULL)
735  gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
736  film_gamma=FilmGamma;
737  value=GetImageProperty(image,"film-gamma");
738  if (value != (const char *) NULL)
739  film_gamma=StringToDouble(value,(char **) NULL);
740  reference_black=ReferenceBlack;
741  value=GetImageProperty(image,"reference-black");
742  if (value != (const char *) NULL)
743  reference_black=StringToDouble(value,(char **) NULL);
744  reference_white=ReferenceWhite;
745  value=GetImageProperty(image,"reference-white");
746  if (value != (const char *) NULL)
747  reference_white=StringToDouble(value,(char **) NULL);
748  logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
749  sizeof(*logmap));
750  if (logmap == (Quantum *) NULL)
751  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
752  image->filename);
753  black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002*
754  PerceptibleReciprocal(film_gamma));
755 #if defined(MAGICKCORE_OPENMP_SUPPORT)
756  #pragma omp parallel for schedule(static)
757 #endif
758  for (i=0; i <= (ssize_t) MaxMap; i++)
759  logmap[i]=ScaleMapToQuantum((MagickRealType) (MaxMap*(reference_white+
760  log10(black+(1.0*i/MaxMap)*(1.0-black))/((gamma/density)*0.002*
761  PerceptibleReciprocal(film_gamma)))/1024.0));
762  image_view=AcquireAuthenticCacheView(image,exception);
763 #if defined(MAGICKCORE_OPENMP_SUPPORT)
764  #pragma omp parallel for schedule(static) shared(status) \
765  magick_number_threads(image,image,image->rows,2)
766 #endif
767  for (y=0; y < (ssize_t) image->rows; y++)
768  {
769  MagickBooleanType
770  sync;
771 
772  ssize_t
773  x;
774 
776  *magick_restrict q;
777 
778  if (status == MagickFalse)
779  continue;
780  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
781  exception);
782  if (q == (PixelPacket *) NULL)
783  {
784  status=MagickFalse;
785  continue;
786  }
787  for (x=(ssize_t) image->columns; x != 0; x--)
788  {
789  Quantum
790  blue,
791  green,
792  red;
793 
794  red=ClampToQuantum(DecodePixelGamma((MagickRealType)
795  GetPixelRed(q)));
796  green=ClampToQuantum(DecodePixelGamma((MagickRealType)
797  GetPixelGreen(q)));
798  blue=ClampToQuantum(DecodePixelGamma((MagickRealType)
799  GetPixelBlue(q)));
800  SetPixelRed(q,logmap[ScaleQuantumToMap(red)]);
801  SetPixelGreen(q,logmap[ScaleQuantumToMap(green)]);
802  SetPixelBlue(q,logmap[ScaleQuantumToMap(blue)]);
803  q++;
804  }
805  sync=SyncCacheViewAuthenticPixels(image_view,exception);
806  if (sync == MagickFalse)
807  status=MagickFalse;
808  }
809  image_view=DestroyCacheView(image_view);
810  logmap=(Quantum *) RelinquishMagickMemory(logmap);
811  if (SetImageColorspace(image,colorspace) == MagickFalse)
812  return(MagickFalse);
813  return(status);
814  }
815  case RGBColorspace:
816  case scRGBColorspace:
817  {
818  /*
819  Transform image from sRGB to linear RGB.
820  */
821  if (image->storage_class == PseudoClass)
822  {
823  if (SyncImage(image) == MagickFalse)
824  return(MagickFalse);
825  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
826  return(MagickFalse);
827  }
828  image_view=AcquireAuthenticCacheView(image,exception);
829 #if defined(MAGICKCORE_OPENMP_SUPPORT)
830  #pragma omp parallel for schedule(static) shared(status) \
831  magick_number_threads(image,image,image->rows,2)
832 #endif
833  for (y=0; y < (ssize_t) image->rows; y++)
834  {
835  MagickBooleanType
836  sync;
837 
838  ssize_t
839  x;
840 
842  *magick_restrict q;
843 
844  if (status == MagickFalse)
845  continue;
846  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
847  exception);
848  if (q == (PixelPacket *) NULL)
849  {
850  status=MagickFalse;
851  continue;
852  }
853  for (x=0; x < (ssize_t) image->columns; x++)
854  {
855  Quantum
856  blue,
857  green,
858  red;
859 
860  red=ClampToQuantum(DecodePixelGamma((MagickRealType)
861  GetPixelRed(q)));
862  green=ClampToQuantum(DecodePixelGamma((MagickRealType)
863  GetPixelGreen(q)));
864  blue=ClampToQuantum(DecodePixelGamma((MagickRealType)
865  GetPixelBlue(q)));
866  SetPixelRed(q,red);
867  SetPixelGreen(q,green);
868  SetPixelBlue(q,blue);
869  q++;
870  }
871  sync=SyncCacheViewAuthenticPixels(image_view,exception);
872  if (sync == MagickFalse)
873  status=MagickFalse;
874  }
875  image_view=DestroyCacheView(image_view);
876  if (SetImageColorspace(image,colorspace) == MagickFalse)
877  return(MagickFalse);
878  return(status);
879  }
880  default:
881  break;
882  }
883  /*
884  Allocate the tables.
885  */
886  x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
887  sizeof(*x_map));
888  y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
889  sizeof(*y_map));
890  z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
891  sizeof(*z_map));
892  if ((x_map == (TransformPacket *) NULL) ||
893  (y_map == (TransformPacket *) NULL) ||
894  (z_map == (TransformPacket *) NULL))
895  {
896  if (x_map != (TransformPacket *) NULL)
897  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
898  if (y_map != (TransformPacket *) NULL)
899  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
900  if (z_map != (TransformPacket *) NULL)
901  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
902  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
903  image->filename);
904  }
905  (void) memset(&primary_info,0,sizeof(primary_info));
906  switch (colorspace)
907  {
908  case OHTAColorspace:
909  {
910  /*
911  Initialize OHTA tables:
912 
913  I1 = 0.33333*R+0.33334*G+0.33333*B
914  I2 = 0.50000*R+0.00000*G-0.50000*B
915  I3 =-0.25000*R+0.50000*G-0.25000*B
916 
917  I and Q, normally -0.5 through 0.5, are normalized to the range 0
918  through QuantumRange.
919  */
920  primary_info.y=(MagickRealType) ((MaxMap+1)/2);
921  primary_info.z=(MagickRealType) ((MaxMap+1)/2);
922 #if defined(MAGICKCORE_OPENMP_SUPPORT)
923  #pragma omp parallel for schedule(static)
924 #endif
925  for (i=0; i <= (ssize_t) MaxMap; i++)
926  {
927  x_map[i].x=(MagickRealType) (0.33333*(double) i);
928  x_map[i].y=(MagickRealType) (0.50000*(double) i);
929  x_map[i].z=(MagickRealType) (-0.25000*(double) i);
930  y_map[i].x=(MagickRealType) (0.33334*(double) i);
931  y_map[i].y=(MagickRealType) (0.00000*(double) i);
932  y_map[i].z=(MagickRealType) (0.50000*(double) i);
933  z_map[i].x=(MagickRealType) (0.33333*(double) i);
934  z_map[i].y=(MagickRealType) (-0.50000*(double) i);
935  z_map[i].z=(MagickRealType) (-0.25000*(double) i);
936  }
937  break;
938  }
939  case Rec601LumaColorspace:
940  {
941  /*
942  Initialize Rec601 luma tables:
943 
944  G = 0.298839*R+0.586811*G+0.114350*B
945  */
946 #if defined(MAGICKCORE_OPENMP_SUPPORT)
947  #pragma omp parallel for schedule(static)
948 #endif
949  for (i=0; i <= (ssize_t) MaxMap; i++)
950  {
951  x_map[i].x=(MagickRealType) (0.298839*(double) i);
952  x_map[i].y=(MagickRealType) (0.298839*(double) i);
953  x_map[i].z=(MagickRealType) (0.298839*(double) i);
954  y_map[i].x=(MagickRealType) (0.586811*(double) i);
955  y_map[i].y=(MagickRealType) (0.586811*(double) i);
956  y_map[i].z=(MagickRealType) (0.586811*(double) i);
957  z_map[i].x=(MagickRealType) (0.114350*(double) i);
958  z_map[i].y=(MagickRealType) (0.114350*(double) i);
959  z_map[i].z=(MagickRealType) (0.114350*(double) i);
960  }
961  break;
962  }
963  case Rec601YCbCrColorspace:
964  {
965  /*
966  Initialize YCbCr tables (ITU-R BT.601):
967 
968  Y = 0.2988390*R+0.5868110*G+0.1143500*B
969  Cb= -0.1687367*R-0.3312640*G+0.5000000*B
970  Cr= 0.5000000*R-0.4186880*G-0.0813120*B
971 
972  Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
973  through QuantumRange.
974  */
975  primary_info.y=(MagickRealType) ((MaxMap+1)/2);
976  primary_info.z=(MagickRealType) ((MaxMap+1)/2);
977 #if defined(MAGICKCORE_OPENMP_SUPPORT)
978  #pragma omp parallel for schedule(static)
979 #endif
980  for (i=0; i <= (ssize_t) MaxMap; i++)
981  {
982  x_map[i].x=(MagickRealType) (0.298839*(double) i);
983  x_map[i].y=(MagickRealType) (-0.1687367*(double) i);
984  x_map[i].z=(MagickRealType) (0.500000*(double) i);
985  y_map[i].x=(MagickRealType) (0.586811*(double) i);
986  y_map[i].y=(MagickRealType) (-0.331264*(double) i);
987  y_map[i].z=(MagickRealType) (-0.418688*(double) i);
988  z_map[i].x=(MagickRealType) (0.114350*(double) i);
989  z_map[i].y=(MagickRealType) (0.500000*(double) i);
990  z_map[i].z=(MagickRealType) (-0.081312*(double) i);
991  }
992  break;
993  }
994  case Rec709LumaColorspace:
995  {
996  /*
997  Initialize Rec709 luma tables:
998 
999  G = 0.212656*R+0.715158*G+0.072186*B
1000  */
1001 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1002  #pragma omp parallel for schedule(static)
1003 #endif
1004  for (i=0; i <= (ssize_t) MaxMap; i++)
1005  {
1006  x_map[i].x=(MagickRealType) (0.212656*(double) i);
1007  x_map[i].y=(MagickRealType) (0.212656*(double) i);
1008  x_map[i].z=(MagickRealType) (0.212656*(double) i);
1009  y_map[i].x=(MagickRealType) (0.715158*(double) i);
1010  y_map[i].y=(MagickRealType) (0.715158*(double) i);
1011  y_map[i].z=(MagickRealType) (0.715158*(double) i);
1012  z_map[i].x=(MagickRealType) (0.072186*(double) i);
1013  z_map[i].y=(MagickRealType) (0.072186*(double) i);
1014  z_map[i].z=(MagickRealType) (0.072186*(double) i);
1015  }
1016  break;
1017  }
1018  case Rec709YCbCrColorspace:
1019  {
1020  /*
1021  Initialize YCbCr tables (ITU-R BT.709):
1022 
1023  Y = 0.212656*R+0.715158*G+0.072186*B
1024  Cb= -0.114572*R-0.385428*G+0.500000*B
1025  Cr= 0.500000*R-0.454153*G-0.045847*B
1026 
1027  Cb and Cr, normally -0.5 through 0.5, are normalized to the range 0
1028  through QuantumRange.
1029  */
1030  primary_info.y=(MagickRealType) ((MaxMap+1)/2);
1031  primary_info.z=(MagickRealType) ((MaxMap+1)/2);
1032 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1033  #pragma omp parallel for schedule(static)
1034 #endif
1035  for (i=0; i <= (ssize_t) MaxMap; i++)
1036  {
1037  x_map[i].x=(MagickRealType) (0.212656*(double) i);
1038  x_map[i].y=(MagickRealType) (-0.114572*(double) i);
1039  x_map[i].z=(MagickRealType) (0.500000*(double) i);
1040  y_map[i].x=(MagickRealType) (0.715158*(double) i);
1041  y_map[i].y=(MagickRealType) (-0.385428*(double) i);
1042  y_map[i].z=(MagickRealType) (-0.454153*(double) i);
1043  z_map[i].x=(MagickRealType) (0.072186*(double) i);
1044  z_map[i].y=(MagickRealType) (0.500000*(double) i);
1045  z_map[i].z=(MagickRealType) (-0.045847*(double) i);
1046  }
1047  break;
1048  }
1049  case YCCColorspace:
1050  {
1051  /*
1052  Initialize YCC tables:
1053 
1054  Y = 0.298839*R+0.586811*G+0.114350*B
1055  C1= -0.298839*R-0.586811*G+0.88600*B
1056  C2= 0.70100*R-0.586811*G-0.114350*B
1057 
1058  YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
1059  */
1060  primary_info.y=(MagickRealType) ScaleQuantumToMap(
1061  ScaleCharToQuantum(156));
1062  primary_info.z=(MagickRealType) ScaleQuantumToMap(
1063  ScaleCharToQuantum(137));
1064  for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
1065  {
1066  x_map[i].x=0.005382*i;
1067  x_map[i].y=(-0.003296)*i;
1068  x_map[i].z=0.009410*i;
1069  y_map[i].x=0.010566*i;
1070  y_map[i].y=(-0.006471)*i;
1071  y_map[i].z=(-0.007880)*i;
1072  z_map[i].x=0.002052*i;
1073  z_map[i].y=0.009768*i;
1074  z_map[i].z=(-0.001530)*i;
1075  }
1076  for ( ; i <= (ssize_t) MaxMap; i++)
1077  {
1078  x_map[i].x=0.298839*(1.099*i-0.099);
1079  x_map[i].y=(-0.298839)*(1.099*i-0.099);
1080  x_map[i].z=0.70100*(1.099*i-0.099);
1081  y_map[i].x=0.586811*(1.099*i-0.099);
1082  y_map[i].y=(-0.586811)*(1.099*i-0.099);
1083  y_map[i].z=(-0.586811)*(1.099*i-0.099);
1084  z_map[i].x=0.114350*(1.099*i-0.099);
1085  z_map[i].y=0.88600*(1.099*i-0.099);
1086  z_map[i].z=(-0.114350)*(1.099*i-0.099);
1087  }
1088  break;
1089  }
1090  default:
1091  {
1092  /*
1093  Linear conversion tables.
1094  */
1095 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1096  #pragma omp parallel for schedule(static)
1097 #endif
1098  for (i=0; i <= (ssize_t) MaxMap; i++)
1099  {
1100  x_map[i].x=(MagickRealType) (1.0*(double) i);
1101  y_map[i].x=(MagickRealType) 0.0;
1102  z_map[i].x=(MagickRealType) 0.0;
1103  x_map[i].y=(MagickRealType) 0.0;
1104  y_map[i].y=(MagickRealType) (1.0*(double) i);
1105  z_map[i].y=(MagickRealType) 0.0;
1106  x_map[i].z=(MagickRealType) 0.0;
1107  y_map[i].z=(MagickRealType) 0.0;
1108  z_map[i].z=(MagickRealType) (1.0*(double) i);
1109  }
1110  break;
1111  }
1112  }
1113  /*
1114  Convert from sRGB.
1115  */
1116  switch (image->storage_class)
1117  {
1118  case DirectClass:
1119  default:
1120  {
1121  /*
1122  Convert DirectClass image.
1123  */
1124  image_view=AcquireAuthenticCacheView(image,exception);
1125 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1126  #pragma omp parallel for schedule(static) shared(status) \
1127  magick_number_threads(image,image,image->rows,2)
1128 #endif
1129  for (y=0; y < (ssize_t) image->rows; y++)
1130  {
1131  MagickBooleanType
1132  sync;
1133 
1135  pixel;
1136 
1137  ssize_t
1138  x;
1139 
1140  PixelPacket
1141  *magick_restrict q;
1142 
1143  size_t
1144  blue,
1145  green,
1146  red;
1147 
1148  if (status == MagickFalse)
1149  continue;
1150  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1151  exception);
1152  if (q == (PixelPacket *) NULL)
1153  {
1154  status=MagickFalse;
1155  continue;
1156  }
1157  for (x=0; x < (ssize_t) image->columns; x++)
1158  {
1159  red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1160  GetPixelRed(q)));
1161  green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1162  GetPixelGreen(q)));
1163  blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1164  GetPixelBlue(q)));
1165  pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
1166  (MagickRealType) primary_info.x;
1167  pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
1168  (MagickRealType) primary_info.y;
1169  pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
1170  (MagickRealType) primary_info.z;
1171  SetPixelRed(q,ScaleMapToQuantum(pixel.red));
1172  SetPixelGreen(q,ScaleMapToQuantum(pixel.green));
1173  SetPixelBlue(q,ScaleMapToQuantum(pixel.blue));
1174  q++;
1175  }
1176  sync=SyncCacheViewAuthenticPixels(image_view,exception);
1177  if (sync == MagickFalse)
1178  status=MagickFalse;
1179  if (image->progress_monitor != (MagickProgressMonitor) NULL)
1180  {
1181  MagickBooleanType
1182  proceed;
1183 
1184 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1185  #pragma omp atomic
1186 #endif
1187  progress++;
1188  proceed=SetImageProgress(image,RGBTransformImageTag,progress,
1189  image->rows);
1190  if (proceed == MagickFalse)
1191  status=MagickFalse;
1192  }
1193  }
1194  image_view=DestroyCacheView(image_view);
1195  break;
1196  }
1197  case PseudoClass:
1198  {
1199  size_t
1200  blue,
1201  green,
1202  red;
1203 
1204  /*
1205  Convert PseudoClass image.
1206  */
1207  for (i=0; i < (ssize_t) image->colors; i++)
1208  {
1210  pixel;
1211 
1212  red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1213  image->colormap[i].red));
1214  green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1215  image->colormap[i].green));
1216  blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1217  image->colormap[i].blue));
1218  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1219  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1220  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1221  image->colormap[i].red=ScaleMapToQuantum(pixel.red);
1222  image->colormap[i].green=ScaleMapToQuantum(pixel.green);
1223  image->colormap[i].blue=ScaleMapToQuantum(pixel.blue);
1224  }
1225  (void) SyncImage(image);
1226  break;
1227  }
1228  }
1229  /*
1230  Relinquish resources.
1231  */
1232  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1233  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1234  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1235  if (SetImageColorspace(image,colorspace) == MagickFalse)
1236  return(MagickFalse);
1237  return(status);
1238 }
1239 ␌
1240 /*
1241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1242 % %
1243 % %
1244 % %
1245 % S e t I m a g e C o l o r s p a c e %
1246 % %
1247 % %
1248 % %
1249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1250 %
1251 % SetImageColorspace() sets the colorspace member of the Image structure.
1252 %
1253 % The format of the SetImageColorspace method is:
1254 %
1255 % MagickBooleanType SetImageColorspace(Image *image,
1256 % const ColorspaceType colorspace)
1257 %
1258 % A description of each parameter follows:
1259 %
1260 % o image: the image.
1261 %
1262 % o colorspace: the colorspace.
1263 %
1264 */
1265 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1266  const ColorspaceType colorspace)
1267 {
1268  ImageType
1269  type;
1270 
1271  MagickBooleanType
1272  status;
1273 
1274  assert(image != (Image *) NULL);
1275  assert(image->signature == MagickCoreSignature);
1276  if (IsEventLogging() != MagickFalse)
1277  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1278  if (image->colorspace == colorspace)
1279  return(MagickTrue);
1280  image->colorspace=colorspace;
1281  image->rendering_intent=UndefinedIntent;
1282  image->gamma=1.000/2.200;
1283  (void) memset(&image->chromaticity,0,sizeof(image->chromaticity));
1284  type=image->type;
1285  if (IsGrayColorspace(colorspace) != MagickFalse)
1286  {
1287  if (colorspace == LinearGRAYColorspace)
1288  image->gamma=1.0;
1289  type=GrayscaleType;
1290  }
1291  else
1292  if ((IsRGBColorspace(colorspace) != MagickFalse) ||
1293  (colorspace == XYZColorspace) || (colorspace == xyYColorspace))
1294  image->gamma=1.0;
1295  else
1296  {
1297  image->rendering_intent=PerceptualIntent;
1298  image->chromaticity.red_primary.x=0.6400;
1299  image->chromaticity.red_primary.y=0.3300;
1300  image->chromaticity.red_primary.z=0.0300;
1301  image->chromaticity.green_primary.x=0.3000;
1302  image->chromaticity.green_primary.y=0.6000;
1303  image->chromaticity.green_primary.z=0.1000;
1304  image->chromaticity.blue_primary.x=0.1500;
1305  image->chromaticity.blue_primary.y=0.0600;
1306  image->chromaticity.blue_primary.z=0.7900;
1307  image->chromaticity.white_point.x=0.3127;
1308  image->chromaticity.white_point.y=0.3290;
1309  image->chromaticity.white_point.z=0.3583;
1310  }
1311  status=SyncImagePixelCache(image,&image->exception);
1312  image->type=type;
1313  return(status);
1314 }
1315 ␌
1316 /*
1317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1318 % %
1319 % %
1320 % %
1321 % S e t I m a g e G r a y %
1322 % %
1323 % %
1324 % %
1325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326 %
1327 % SetImageGray() returns MagickTrue if all the pixels in the image have the
1328 % same red, green, and blue intensities and changes the type of the image to
1329 % bi-level or grayscale.
1330 %
1331 % The format of the SetImageGray method is:
1332 %
1333 % MagickBooleanType SetImageGray(const Image *image,
1334 % ExceptionInfo *exception)
1335 %
1336 % A description of each parameter follows:
1337 %
1338 % o image: the image.
1339 %
1340 % o exception: return any errors or warnings in this structure.
1341 %
1342 */
1343 MagickExport MagickBooleanType SetImageGray(Image *image,
1344  ExceptionInfo *exception)
1345 {
1346  CacheView
1347  *image_view;
1348 
1349  const char
1350  *value;
1351 
1352  ImageType
1353  type = BilevelType;
1354 
1355  ssize_t
1356  y;
1357 
1358  assert(image != (Image *) NULL);
1359  assert(image->signature == MagickCoreSignature);
1360  if (IsEventLogging() != MagickFalse)
1361  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1362  if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
1363  (image->type == GrayscaleMatteType))
1364  return(MagickTrue);
1365  if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
1366  (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
1367  return(MagickFalse);
1368  value=GetImageProperty(image,"colorspace:auto-grayscale");
1369  if (IsStringNotFalse(value) == MagickFalse)
1370  return(MagickFalse);
1371  image_view=AcquireVirtualCacheView(image,exception);
1372 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1373  #pragma omp parallel for schedule(static) shared(type) \
1374  magick_number_threads(image,image,image->rows,2)
1375 #endif
1376  for (y=0; y < (ssize_t) image->rows; y++)
1377  {
1378  const PixelPacket
1379  *p;
1380 
1381  ssize_t
1382  x;
1383 
1384  if (type == UndefinedType)
1385  continue;
1386  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1387  if (p == (const PixelPacket *) NULL)
1388  {
1389  type=UndefinedType;
1390  continue;
1391  }
1392  for (x=0; x < (ssize_t) image->columns; x++)
1393  {
1394  if (IsGrayPixel(p) == MagickFalse)
1395  {
1396  type=UndefinedType;
1397  break;
1398  }
1399  if ((type == BilevelType) && (IsMonochromePixel(p) == MagickFalse))
1400  type=GrayscaleType;
1401  p++;
1402  }
1403  }
1404  image_view=DestroyCacheView(image_view);
1405  if (type == UndefinedType)
1406  return(MagickFalse);
1407  image->colorspace=GRAYColorspace;
1408  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
1409  return(MagickFalse);
1410  image->type=type;
1411  if ((type == GrayscaleType) && (image->matte != MagickFalse))
1412  image->type=GrayscaleMatteType;
1413  return(MagickTrue);
1414 }
1415 ␌
1416 /*
1417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1418 % %
1419 % %
1420 % %
1421 % S e t I m a g e M o n o c h r o m e %
1422 % %
1423 % %
1424 % %
1425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1426 %
1427 % SetImageMonochrome() returns MagickTrue if all the pixels in the image have
1428 % the same red, green, and blue intensities and the intensity is either
1429 % 0 or QuantumRange and changes the type of the image to bi-level.
1430 %
1431 % The format of the SetImageMonochrome method is:
1432 %
1433 % MagickBooleanType SetImageMonochrome(const Image *image,
1434 % ExceptionInfo *exception)
1435 %
1436 % A description of each parameter follows:
1437 %
1438 % o image: the image.
1439 %
1440 % o exception: return any errors or warnings in this structure.
1441 %
1442 */
1443 MagickExport MagickBooleanType SetImageMonochrome(Image *image,
1444  ExceptionInfo *exception)
1445 {
1446  const char
1447  *value;
1448 
1449  CacheView
1450  *image_view;
1451 
1452  ImageType
1453  type = BilevelType;
1454 
1455  ssize_t
1456  y;
1457 
1458  assert(image != (Image *) NULL);
1459  assert(image->signature == MagickCoreSignature);
1460  if (IsEventLogging() != MagickFalse)
1461  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1462  if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1463  return(MagickTrue);
1464  if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
1465  (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
1466  return(MagickFalse);
1467  value=GetImageProperty(image,"colorspace:auto-grayscale");
1468  if (IsStringNotFalse(value) == MagickFalse)
1469  return(MagickFalse);
1470  image_view=AcquireVirtualCacheView(image,exception);
1471 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1472  #pragma omp parallel for schedule(static) shared(type) \
1473  magick_number_threads(image,image,image->rows,2)
1474 #endif
1475  for (y=0; y < (ssize_t) image->rows; y++)
1476  {
1477  const PixelPacket
1478  *p;
1479 
1480  ssize_t
1481  x;
1482 
1483  if (type == UndefinedType)
1484  continue;
1485  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1486  if (p == (const PixelPacket *) NULL)
1487  {
1488  type=UndefinedType;
1489  continue;
1490  }
1491  for (x=0; x < (ssize_t) image->columns; x++)
1492  {
1493  if (IsMonochromePixel(p) == MagickFalse)
1494  {
1495  type=UndefinedType;
1496  break;
1497  }
1498  p++;
1499  }
1500  }
1501  image_view=DestroyCacheView(image_view);
1502  if (type == UndefinedType)
1503  return(MagickFalse);
1504  image->colorspace=GRAYColorspace;
1505  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
1506  return(MagickFalse);
1507  image->type=type;
1508  return(MagickTrue);
1509 }
1510 ␌
1511 /*
1512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1513 % %
1514 % %
1515 % %
1516 % T r a n s f o r m I m a g e C o l o r s p a c e %
1517 % %
1518 % %
1519 % %
1520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1521 %
1522 % TransformImageColorspace() transforms an image colorspace.
1523 %
1524 % The format of the TransformImageColorspace method is:
1525 %
1526 % MagickBooleanType TransformImageColorspace(Image *image,
1527 % const ColorspaceType colorspace)
1528 %
1529 % A description of each parameter follows:
1530 %
1531 % o image: the image.
1532 %
1533 % o colorspace: the colorspace.
1534 %
1535 */
1536 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1537  const ColorspaceType colorspace)
1538 {
1539  MagickBooleanType
1540  status;
1541 
1542  assert(image != (Image *) NULL);
1543  assert(image->signature == MagickCoreSignature);
1544  if (IsEventLogging() != MagickFalse)
1545  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1546  if (image->colorspace == colorspace)
1547  return(MagickTrue);
1548  (void) DeleteImageProfile(image,"icc");
1549  (void) DeleteImageProfile(image,"icm");
1550  if (colorspace == UndefinedColorspace)
1551  return(SetImageColorspace(image,colorspace));
1552  /*
1553  Convert the reference image from an alternate colorspace to sRGB.
1554  */
1555  if (IssRGBColorspace(colorspace) != MagickFalse)
1556  return(TransformRGBImage(image,image->colorspace));
1557  status=MagickTrue;
1558  if (IssRGBColorspace(image->colorspace) == MagickFalse)
1559  status=TransformRGBImage(image,image->colorspace);
1560  if (status == MagickFalse)
1561  return(status);
1562  /*
1563  Convert the reference image from sRGB to an alternate colorspace.
1564  */
1565  if (RGBTransformImage(image,colorspace) == MagickFalse)
1566  status=MagickFalse;
1567  return(status);
1568 }
1569 ␌
1570 /*
1571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1572 % %
1573 % %
1574 % %
1575 + T r a n s f o r m R G B I m a g e %
1576 % %
1577 % %
1578 % %
1579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1580 %
1581 % TransformRGBImage() converts the reference image from an alternate
1582 % colorspace to sRGB. The transformation matrices are not the standard ones:
1583 % the weights are rescaled to normalize the range of the transformed values to
1584 % be [0..QuantumRange].
1585 %
1586 % The format of the TransformRGBImage method is:
1587 %
1588 % MagickBooleanType TransformRGBImage(Image *image,
1589 % const ColorspaceType colorspace)
1590 %
1591 % A description of each parameter follows:
1592 %
1593 % o image: the image.
1594 %
1595 % o colorspace: the colorspace to transform the image to.
1596 %
1597 */
1598 
1599 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1600  const double yellow,Quantum *red,Quantum *green,Quantum *blue)
1601 {
1602  *red=ClampToQuantum((MagickRealType) QuantumRange*(1.0-cyan));
1603  *green=ClampToQuantum((MagickRealType) QuantumRange*(1.0-magenta));
1604  *blue=ClampToQuantum((MagickRealType) QuantumRange*(1.0-yellow));
1605 }
1606 
1607 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1608  double *X,double *Y,double *Z)
1609 {
1610  *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1611  *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1612  *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1613 }
1614 
1615 static inline void ConvertLMSToRGB(const double L,const double M,
1616  const double S,Quantum *red,Quantum *green,Quantum *blue)
1617 {
1618  double
1619  X,
1620  Y,
1621  Z;
1622 
1623  ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1624  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1625 }
1626 
1627 static inline void ConvertLuvToRGB(const double L,const double u,
1628  const double v,Quantum *red,Quantum *green,Quantum *blue)
1629 {
1630  double
1631  X,
1632  Y,
1633  Z;
1634 
1635  ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1636  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1637 }
1638 
1639 static inline ssize_t RoundToYCC(const MagickRealType value)
1640 {
1641  if (value <= 0.0)
1642  return(0);
1643  if (value >= 1388.0)
1644  return(1388);
1645  return((ssize_t) (value+0.5));
1646 }
1647 
1648 static inline void ConvertLabToRGB(const double L,const double a,
1649  const double b,Quantum *red,Quantum *green,Quantum *blue)
1650 {
1651  double
1652  X,
1653  Y,
1654  Z;
1655 
1656  ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1657  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1658 }
1659 
1660 static inline void ConvertxyYToRGB(const double low_x,const double low_y,
1661  const double cap_Y,Quantum *red,Quantum *green,Quantum *blue)
1662 {
1663  double
1664  gamma,
1665  X,
1666  Y,
1667  Z;
1668 
1669  gamma=PerceptibleReciprocal(low_y);
1670  X=gamma*cap_Y*low_x;
1671  Y=cap_Y;
1672  Z=gamma*cap_Y*(1.0-low_x-low_y);
1673  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1674 }
1675 
1676 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1677  Quantum *red,Quantum *green,Quantum *blue)
1678 {
1679  *red=ClampToQuantum((MagickRealType) QuantumRange*(0.99999999999914679361*Y-
1680  1.2188941887145875e-06*(Pb-0.5)+1.4019995886561440468*(Pr-0.5)));
1681  *green=ClampToQuantum((MagickRealType) QuantumRange*(0.99999975910502514331*Y-
1682  0.34413567816504303521*(Pb-0.5)-0.71413649331646789076*(Pr-0.5)));
1683  *blue=ClampToQuantum((MagickRealType) QuantumRange*(1.00000124040004623180*Y+
1684  1.77200006607230409200*(Pb-0.5)+2.1453384174593273e-06*(Pr-0.5)));
1685 }
1686 
1687 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1688  const double Cr,Quantum *red,Quantum *green,Quantum *blue)
1689 {
1690  ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1691 }
1692 
1693 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
1694  Quantum *red,Quantum *green,Quantum *blue)
1695 {
1696  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y+9.2303716147657e-05*
1697  (Db-0.5)-0.52591263066186533*(Dr-0.5)));
1698  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.12913289889050927*
1699  (Db-0.5)+0.26789932820759876*(Dr-0.5)));
1700  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y+0.66467905997895482*
1701  (Db-0.5)-7.9202543533108e-05*(Dr-0.5)));
1702 }
1703 
1704 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1705  Quantum *red,Quantum *green,Quantum *blue)
1706 {
1707  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y+0.9562957197589482261*
1708  (I-0.5)+0.6210244164652610754*(Q-0.5)));
1709  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.2721220993185104464*
1710  (I-0.5)-0.6473805968256950427*(Q-0.5)));
1711  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y-1.1069890167364901945*
1712  (I-0.5)+1.7046149983646481374*(Q-0.5)));
1713 }
1714 
1715 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1716  Quantum *red,Quantum *green,Quantum *blue)
1717 {
1718  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y-3.945707070708279e-05*
1719  (U-0.5)+1.1398279671717170825*(V-0.5)));
1720  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.3946101641414141437*
1721  (U-0.5)-0.5805003156565656797*(V-0.5)));
1722  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y+2.0319996843434342537*
1723  (U-0.5)-4.813762626262513e-04*(V-0.5)));
1724 }
1725 
1726 MagickExport MagickBooleanType TransformRGBImage(Image *image,
1727  const ColorspaceType colorspace)
1728 {
1729 #define TransformRGBImageTag "Transform/Image"
1730 
1731  static const float
1732  YCCMap[1389] =
1733  {
1734  0.000000, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1735  0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1736  0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1737  0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1738  0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1739  0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1740  0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1741  0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1742  0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1743  0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1744  0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1745  0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1746  0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1747  0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1748  0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1749  0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1750  0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1751  0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1752  0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1753  0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1754  0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1755  0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1756  0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1757  0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1758  0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1759  0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1760  0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1761  0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1762  0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1763  0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1764  0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1765  0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1766  0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1767  0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1768  0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1769  0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1770  0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1771  0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1772  0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1773  0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1774  0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1775  0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1776  0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1777  0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1778  0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1779  0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1780  0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1781  0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1782  0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1783  0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1784  0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1785  0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1786  0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1787  0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1788  0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1789  0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1790  0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1791  0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1792  0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1793  0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1794  0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1795  0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1796  0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1797  0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1798  0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1799  0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1800  0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1801  0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1802  0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1803  0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1804  0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1805  0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1806  0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1807  0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1808  0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1809  0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1810  0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1811  0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1812  0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1813  0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1814  0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1815  0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1816  0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1817  0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1818  0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1819  0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1820  0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1821  0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1822  0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1823  0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1824  0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1825  0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1826  0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1827  0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1828  0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1829  0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1830  0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1831  0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1832  0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1833  0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1834  0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1835  0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1836  0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1837  0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1838  0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1839  0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1840  0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1841  0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1842  0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1843  0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1844  0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1845  0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1846  0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1847  0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1848  0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1849  0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1850  0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1851  0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1852  0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1853  0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1854  0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1855  0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1856  0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1857  0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1858  0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1859  0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1860  0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1861  0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1862  0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1863  0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1864  0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1865  0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1866  0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1867  0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1868  0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1869  0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1870  0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1871  0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1872  0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1873  0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1874  0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1875  0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1876  0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1877  0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1878  0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1879  0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1880  0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1881  0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1882  0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1883  0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1884  0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1885  0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1886  0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1887  0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1888  0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1889  0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1890  0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1891  0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1892  0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1893  0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1894  0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1895  0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1896  0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1897  0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1898  0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1899  0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1900  0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1901  0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1902  0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1903  0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1904  0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1905  0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1906  0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1907  0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1908  0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1909  0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1910  0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1911  0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1912  0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1913  0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1914  0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1915  0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1916  0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1917  0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1918  0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1919  0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1920  0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1921  0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1922  0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1923  0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1924  0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1925  0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1926  0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1927  0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1928  0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1929  0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1930  0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1931  0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1932  0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1933  0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1934  0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1935  0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1936  0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1937  0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1938  0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1939  0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1940  0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1941  0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1942  0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1943  0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1944  0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1945  0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1946  0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1947  0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1948  0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1949  0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1950  0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1951  0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1952  0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1953  0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1954  0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1955  0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1956  0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1957  0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1958  0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1959  0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1960  0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1961  0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1962  0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1963  0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1964  0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1965  0.998559f, 0.999280f, 1.000000
1966  };
1967 
1968  CacheView
1969  *image_view;
1970 
1972  *exception;
1973 
1974  MagickBooleanType
1975  status;
1976 
1977  MagickOffsetType
1978  progress;
1979 
1980  ssize_t
1981  i;
1982 
1983  ssize_t
1984  y;
1985 
1987  *y_map,
1988  *x_map,
1989  *z_map;
1990 
1991  assert(image != (Image *) NULL);
1992  assert(image->signature == MagickCoreSignature);
1993  if (IsEventLogging() != MagickFalse)
1994  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1995  status=MagickTrue;
1996  progress=0;
1997  exception=(&image->exception);
1998  switch (colorspace)
1999  {
2000  case CMYKColorspace:
2001  {
2003  zero;
2004 
2005  /*
2006  Transform image from CMYK to sRGB.
2007  */
2008  if (image->storage_class == PseudoClass)
2009  {
2010  if (SyncImage(image) == MagickFalse)
2011  return(MagickFalse);
2012  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2013  return(MagickFalse);
2014  }
2015  GetMagickPixelPacket(image,&zero);
2016  image_view=AcquireAuthenticCacheView(image,exception);
2017 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2018  #pragma omp parallel for schedule(static) shared(status) \
2019  magick_number_threads(image,image,image->rows,2)
2020 #endif
2021  for (y=0; y < (ssize_t) image->rows; y++)
2022  {
2023  MagickBooleanType
2024  sync;
2025 
2027  pixel;
2028 
2029  IndexPacket
2030  *magick_restrict indexes;
2031 
2032  ssize_t
2033  x;
2034 
2035  PixelPacket
2036  *magick_restrict q;
2037 
2038  if (status == MagickFalse)
2039  continue;
2040  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2041  exception);
2042  if (q == (PixelPacket *) NULL)
2043  {
2044  status=MagickFalse;
2045  continue;
2046  }
2047  indexes=GetCacheViewAuthenticIndexQueue(image_view);
2048  pixel=zero;
2049  for (x=0; x < (ssize_t) image->columns; x++)
2050  {
2051  SetMagickPixelPacket(image,q,indexes+x,&pixel);
2052  ConvertCMYKToRGB(&pixel);
2053  SetPixelPacket(image,&pixel,q,indexes+x);
2054  q++;
2055  }
2056  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2057  if (sync == MagickFalse)
2058  status=MagickFalse;
2059  }
2060  image_view=DestroyCacheView(image_view);
2061  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2062  return(MagickFalse);
2063  return(status);
2064  }
2065  case LinearGRAYColorspace:
2066  case Rec601LumaColorspace:
2067  {
2068  /*
2069  Transform linear RGB to sRGB colorspace.
2070  */
2071  if (image->storage_class == PseudoClass)
2072  {
2073  if (SyncImage(image) == MagickFalse)
2074  return(MagickFalse);
2075  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2076  return(MagickFalse);
2077  }
2078  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2079  return(MagickFalse);
2080  image_view=AcquireAuthenticCacheView(image,exception);
2081 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2082  #pragma omp parallel for schedule(static) shared(status) \
2083  magick_number_threads(image,image,image->rows,2)
2084 #endif
2085  for (y=0; y < (ssize_t) image->rows; y++)
2086  {
2087  MagickBooleanType
2088  sync;
2089 
2090  ssize_t
2091  x;
2092 
2093  PixelPacket
2094  *magick_restrict q;
2095 
2096  if (status == MagickFalse)
2097  continue;
2098  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2099  exception);
2100  if (q == (PixelPacket *) NULL)
2101  {
2102  status=MagickFalse;
2103  continue;
2104  }
2105  for (x=(ssize_t) image->columns; x != 0; x--)
2106  {
2107  MagickRealType
2108  gray;
2109 
2110  gray=0.212656*EncodePixelGamma(GetPixelRed(q))+0.715158*
2111  EncodePixelGamma(GetPixelGreen(q))+0.072186*
2112  EncodePixelGamma(GetPixelBlue(q));
2113  SetPixelRed(q,ClampToQuantum(gray));
2114  SetPixelGreen(q,ClampToQuantum(gray));
2115  SetPixelBlue(q,ClampToQuantum(gray));
2116  q++;
2117  }
2118  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2119  if (sync == MagickFalse)
2120  status=MagickFalse;
2121  }
2122  image_view=DestroyCacheView(image_view);
2123  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2124  return(MagickFalse);
2125  return(status);
2126  }
2127  case GRAYColorspace:
2128  case Rec709LumaColorspace:
2129  {
2130  /*
2131  Transform linear RGB to sRGB colorspace.
2132  */
2133  if (image->storage_class == PseudoClass)
2134  {
2135  if (SyncImage(image) == MagickFalse)
2136  return(MagickFalse);
2137  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2138  return(MagickFalse);
2139  }
2140  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2141  return(MagickFalse);
2142  image_view=AcquireAuthenticCacheView(image,exception);
2143 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2144  #pragma omp parallel for schedule(static) shared(status) \
2145  magick_number_threads(image,image,image->rows,2)
2146 #endif
2147  for (y=0; y < (ssize_t) image->rows; y++)
2148  {
2149  MagickBooleanType
2150  sync;
2151 
2152  ssize_t
2153  x;
2154 
2155  PixelPacket
2156  *magick_restrict q;
2157 
2158  if (status == MagickFalse)
2159  continue;
2160  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2161  exception);
2162  if (q == (PixelPacket *) NULL)
2163  {
2164  status=MagickFalse;
2165  continue;
2166  }
2167  for (x=(ssize_t) image->columns; x != 0; x--)
2168  {
2169  MagickRealType
2170  gray;
2171 
2172  gray=(MagickRealType) (0.212656*(double) GetPixelRed(q)+0.715158*
2173  (double) GetPixelGreen(q)+0.072186*(double) GetPixelBlue(q));
2174  SetPixelRed(q,ClampToQuantum(gray));
2175  SetPixelGreen(q,ClampToQuantum(gray));
2176  SetPixelBlue(q,ClampToQuantum(gray));
2177  q++;
2178  }
2179  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2180  if (sync == MagickFalse)
2181  status=MagickFalse;
2182  }
2183  image_view=DestroyCacheView(image_view);
2184  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2185  return(MagickFalse);
2186  return(status);
2187  }
2188  case CMYColorspace:
2189  case HCLColorspace:
2190  case HCLpColorspace:
2191  case HSBColorspace:
2192  case HSIColorspace:
2193  case HSLColorspace:
2194  case HSVColorspace:
2195  case HWBColorspace:
2196  case LabColorspace:
2197  case LCHColorspace:
2198  case LCHabColorspace:
2199  case LCHuvColorspace:
2200  case LMSColorspace:
2201  case LuvColorspace:
2202  case xyYColorspace:
2203  case XYZColorspace:
2204  case YCbCrColorspace:
2205  case YDbDrColorspace:
2206  case YIQColorspace:
2207  case YPbPrColorspace:
2208  case YUVColorspace:
2209  {
2210  /*
2211  Transform image from source colorspace to sRGB.
2212  */
2213  if (image->storage_class == PseudoClass)
2214  {
2215  if (SyncImage(image) == MagickFalse)
2216  return(MagickFalse);
2217  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2218  return(MagickFalse);
2219  }
2220  image_view=AcquireAuthenticCacheView(image,exception);
2221 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2222  #pragma omp parallel for schedule(static) shared(status) \
2223  magick_number_threads(image,image,image->rows,2)
2224 #endif
2225  for (y=0; y < (ssize_t) image->rows; y++)
2226  {
2227  MagickBooleanType
2228  sync;
2229 
2230  ssize_t
2231  x;
2232 
2233  PixelPacket
2234  *magick_restrict q;
2235 
2236  if (status == MagickFalse)
2237  continue;
2238  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2239  exception);
2240  if (q == (PixelPacket *) NULL)
2241  {
2242  status=MagickFalse;
2243  continue;
2244  }
2245  for (x=0; x < (ssize_t) image->columns; x++)
2246  {
2247  double
2248  X,
2249  Y,
2250  Z;
2251 
2252  Quantum
2253  blue,
2254  green,
2255  red;
2256 
2257  X=QuantumScale*(double) GetPixelRed(q);
2258  Y=QuantumScale*(double) GetPixelGreen(q);
2259  Z=QuantumScale*(double) GetPixelBlue(q);
2260  switch (colorspace)
2261  {
2262  case CMYColorspace:
2263  {
2264  ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
2265  break;
2266  }
2267  case HCLColorspace:
2268  {
2269  ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
2270  break;
2271  }
2272  case HCLpColorspace:
2273  {
2274  ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
2275  break;
2276  }
2277  case HSBColorspace:
2278  {
2279  ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
2280  break;
2281  }
2282  case HSIColorspace:
2283  {
2284  ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
2285  break;
2286  }
2287  case HSLColorspace:
2288  {
2289  ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
2290  break;
2291  }
2292  case HSVColorspace:
2293  {
2294  ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
2295  break;
2296  }
2297  case HWBColorspace:
2298  {
2299  ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
2300  break;
2301  }
2302  case LabColorspace:
2303  {
2304  ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
2305  break;
2306  }
2307  case LCHColorspace:
2308  case LCHabColorspace:
2309  {
2310  ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
2311  break;
2312  }
2313  case LCHuvColorspace:
2314  {
2315  ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
2316  break;
2317  }
2318  case LMSColorspace:
2319  {
2320  ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
2321  break;
2322  }
2323  case LuvColorspace:
2324  {
2325  ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
2326  break;
2327  }
2328  case xyYColorspace:
2329  {
2330  ConvertxyYToRGB(X,Y,Z,&red,&green,&blue);
2331  break;
2332  }
2333  case XYZColorspace:
2334  {
2335  ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2336  break;
2337  }
2338  case YCbCrColorspace:
2339  {
2340  ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
2341  break;
2342  }
2343  case YDbDrColorspace:
2344  {
2345  ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
2346  break;
2347  }
2348  case YIQColorspace:
2349  {
2350  ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
2351  break;
2352  }
2353  case YPbPrColorspace:
2354  {
2355  ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
2356  break;
2357  }
2358  case YUVColorspace:
2359  {
2360  ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
2361  break;
2362  }
2363  default:
2364  {
2365  red=ClampToQuantum((MagickRealType) QuantumRange*X);
2366  green=ClampToQuantum((MagickRealType) QuantumRange*Y);
2367  blue=ClampToQuantum((MagickRealType) QuantumRange*Z);
2368  break;
2369  }
2370  }
2371  SetPixelRed(q,ClampToQuantum((MagickRealType) red));
2372  SetPixelGreen(q,ClampToQuantum((MagickRealType) green));
2373  SetPixelBlue(q,ClampToQuantum((MagickRealType) blue));
2374  q++;
2375  }
2376  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2377  if (sync == MagickFalse)
2378  status=MagickFalse;
2379  }
2380  image_view=DestroyCacheView(image_view);
2381  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2382  return(MagickFalse);
2383  return(status);
2384  }
2385  case LogColorspace:
2386  {
2387  const char
2388  *value;
2389 
2390  double
2391  black,
2392  density,
2393  film_gamma,
2394  gamma,
2395  reference_black,
2396  reference_white;
2397 
2398  Quantum
2399  *logmap;
2400 
2401  /*
2402  Transform Log to sRGB colorspace.
2403  */
2404  density=DisplayGamma;
2405  gamma=DisplayGamma;
2406  value=GetImageProperty(image,"gamma");
2407  if (value != (const char *) NULL)
2408  gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
2409  film_gamma=FilmGamma;
2410  value=GetImageProperty(image,"film-gamma");
2411  if (value != (const char *) NULL)
2412  film_gamma=StringToDouble(value,(char **) NULL);
2413  reference_black=ReferenceBlack;
2414  value=GetImageProperty(image,"reference-black");
2415  if (value != (const char *) NULL)
2416  reference_black=StringToDouble(value,(char **) NULL);
2417  reference_white=ReferenceWhite;
2418  value=GetImageProperty(image,"reference-white");
2419  if (value != (const char *) NULL)
2420  reference_white=StringToDouble(value,(char **) NULL);
2421  logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2422  sizeof(*logmap));
2423  if (logmap == (Quantum *) NULL)
2424  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2425  image->filename);
2426  black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002*
2427  PerceptibleReciprocal(film_gamma));
2428  for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
2429  logmap[i]=(Quantum) 0;
2430  for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
2431  logmap[i]=ClampToQuantum((MagickRealType) QuantumRange/(1.0-black)*
2432  (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002*
2433  PerceptibleReciprocal(film_gamma))-black));
2434  for ( ; i <= (ssize_t) MaxMap; i++)
2435  logmap[i]=QuantumRange;
2436  if (image->storage_class == PseudoClass)
2437  {
2438  if (SyncImage(image) == MagickFalse)
2439  return(MagickFalse);
2440  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2441  return(MagickFalse);
2442  }
2443  image_view=AcquireAuthenticCacheView(image,exception);
2444 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2445  #pragma omp parallel for schedule(static) shared(status) \
2446  magick_number_threads(image,image,image->rows,2)
2447 #endif
2448  for (y=0; y < (ssize_t) image->rows; y++)
2449  {
2450  MagickBooleanType
2451  sync;
2452 
2453  ssize_t
2454  x;
2455 
2456  PixelPacket
2457  *magick_restrict q;
2458 
2459  if (status == MagickFalse)
2460  continue;
2461  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2462  exception);
2463  if (q == (PixelPacket *) NULL)
2464  {
2465  status=MagickFalse;
2466  continue;
2467  }
2468  for (x=(ssize_t) image->columns; x != 0; x--)
2469  {
2470  Quantum
2471  blue,
2472  green,
2473  red;
2474 
2475  red=ClampToQuantum(EncodePixelGamma((MagickRealType)
2476  logmap[ScaleQuantumToMap(GetPixelRed(q))]));
2477  green=ClampToQuantum(EncodePixelGamma((MagickRealType)
2478  logmap[ScaleQuantumToMap(GetPixelGreen(q))]));
2479  blue=ClampToQuantum(EncodePixelGamma((MagickRealType)
2480  logmap[ScaleQuantumToMap(GetPixelBlue(q))]));
2481  SetPixelRed(q,red);
2482  SetPixelGreen(q,green);
2483  SetPixelBlue(q,blue);
2484  q++;
2485  }
2486  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2487  if (sync == MagickFalse)
2488  status=MagickFalse;
2489  }
2490  image_view=DestroyCacheView(image_view);
2491  logmap=(Quantum *) RelinquishMagickMemory(logmap);
2492  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2493  return(MagickFalse);
2494  return(status);
2495  }
2496  case RGBColorspace:
2497  case scRGBColorspace:
2498  {
2499  /*
2500  Transform linear RGB to sRGB colorspace.
2501  */
2502  if (image->storage_class == PseudoClass)
2503  {
2504  if (SyncImage(image) == MagickFalse)
2505  return(MagickFalse);
2506  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2507  return(MagickFalse);
2508  }
2509  image_view=AcquireAuthenticCacheView(image,exception);
2510 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2511  #pragma omp parallel for schedule(static) shared(status) \
2512  magick_number_threads(image,image,image->rows,2)
2513 #endif
2514  for (y=0; y < (ssize_t) image->rows; y++)
2515  {
2516  MagickBooleanType
2517  sync;
2518 
2519  ssize_t
2520  x;
2521 
2522  PixelPacket
2523  *magick_restrict q;
2524 
2525  if (status == MagickFalse)
2526  continue;
2527  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2528  exception);
2529  if (q == (PixelPacket *) NULL)
2530  {
2531  status=MagickFalse;
2532  continue;
2533  }
2534  for (x=(ssize_t) image->columns; x != 0; x--)
2535  {
2536  Quantum
2537  blue,
2538  green,
2539  red;
2540 
2541  red=ClampToQuantum(EncodePixelGamma((MagickRealType) GetPixelRed(q)));
2542  green=ClampToQuantum(EncodePixelGamma((MagickRealType)
2543  GetPixelGreen(q)));
2544  blue=ClampToQuantum(EncodePixelGamma((MagickRealType)
2545  GetPixelBlue(q)));
2546  SetPixelRed(q,red);
2547  SetPixelGreen(q,green);
2548  SetPixelBlue(q,blue);
2549  q++;
2550  }
2551  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2552  if (sync == MagickFalse)
2553  status=MagickFalse;
2554  }
2555  image_view=DestroyCacheView(image_view);
2556  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2557  return(MagickFalse);
2558  return(status);
2559  }
2560  default:
2561  break;
2562  }
2563  /*
2564  Allocate the tables.
2565  */
2566  x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2567  sizeof(*x_map));
2568  y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2569  sizeof(*y_map));
2570  z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2571  sizeof(*z_map));
2572  if ((x_map == (TransformPacket *) NULL) ||
2573  (y_map == (TransformPacket *) NULL) ||
2574  (z_map == (TransformPacket *) NULL))
2575  {
2576  if (z_map != (TransformPacket *) NULL)
2577  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2578  if (y_map != (TransformPacket *) NULL)
2579  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2580  if (x_map != (TransformPacket *) NULL)
2581  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2582  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2583  image->filename);
2584  }
2585  switch (colorspace)
2586  {
2587  case OHTAColorspace:
2588  {
2589  /*
2590  Initialize OHTA tables:
2591 
2592  R = I1+1.00000*I2-0.66668*I3
2593  G = I1+0.00000*I2+1.33333*I3
2594  B = I1-1.00000*I2-0.66668*I3
2595 
2596  I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2597  through QuantumRange.
2598  */
2599 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2600  #pragma omp parallel for schedule(static)
2601 #endif
2602  for (i=0; i <= (ssize_t) MaxMap; i++)
2603  {
2604  x_map[i].x=(1.0*(double) i);
2605  y_map[i].x=(0.5*1.00000*(2.0*(double) i-MaxMap));
2606  z_map[i].x=(-0.5*0.66668*(2.0*(double) i-MaxMap));
2607  x_map[i].y=(1.0*(double) i);
2608  y_map[i].y=(0.5*0.00000*(2.0*(double) i-MaxMap));
2609  z_map[i].y=(0.5*1.33333*(2.0*(double) i-MaxMap));
2610  x_map[i].z=(1.0*(double) i);
2611  y_map[i].z=(-0.5*1.00000*(2.0*(double) i-MaxMap));
2612  z_map[i].z=(-0.5*0.66668*(2.0*(double) i-MaxMap));
2613  }
2614  break;
2615  }
2616  case Rec601YCbCrColorspace:
2617  {
2618  /*
2619  Initialize YCbCr tables:
2620 
2621  R = Y +1.402000*Cr
2622  G = Y-0.344136*Cb-0.714136*Cr
2623  B = Y+1.772000*Cb
2624 
2625  Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2626  through QuantumRange.
2627  */
2628 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2629  #pragma omp parallel for schedule(static)
2630 #endif
2631  for (i=0; i <= (ssize_t) MaxMap; i++)
2632  {
2633  x_map[i].x=0.99999999999914679361*(double) i;
2634  y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2635  z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2636  x_map[i].y=0.99999975910502514331*(double) i;
2637  y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2638  z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2639  x_map[i].z=1.00000124040004623180*(double) i;
2640  y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2641  z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2642  }
2643  break;
2644  }
2645  case Rec709YCbCrColorspace:
2646  {
2647  /*
2648  Initialize YCbCr tables:
2649 
2650  R = Y +1.574800*Cr
2651  G = Y-0.187324*Cb-0.468124*Cr
2652  B = Y+1.855600*Cb
2653 
2654  Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2655  through QuantumRange.
2656  */
2657 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2658  #pragma omp parallel for schedule(static)
2659 #endif
2660  for (i=0; i <= (ssize_t) MaxMap; i++)
2661  {
2662  x_map[i].x=(MagickRealType) (1.0*(double) i);
2663  y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*(double) i-MaxMap));
2664  z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*(double) i-MaxMap));
2665  x_map[i].y=(MagickRealType) (1.0*(double) i);
2666  y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*(double) i-MaxMap));
2667  z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*(double) i-MaxMap));
2668  x_map[i].z=(MagickRealType) (1.0*(double) i);
2669  y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*(double) i-MaxMap));
2670  z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*(double) i-MaxMap));
2671  }
2672  break;
2673  }
2674  case YCCColorspace:
2675  {
2676  /*
2677  Initialize YCC tables:
2678 
2679  R = Y +1.340762*C2
2680  G = Y-0.317038*C1-0.682243*C2
2681  B = Y+1.632639*C1
2682 
2683  YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2684  */
2685 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2686  #pragma omp parallel for schedule(static)
2687 #endif
2688  for (i=0; i <= (ssize_t) MaxMap; i++)
2689  {
2690  x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2691  y_map[i].x=(MagickRealType) (0.0000000);
2692  z_map[i].x=(MagickRealType) (1.8215000*((double) i-(MagickRealType)
2693  ScaleQuantumToMap(ScaleCharToQuantum(137))));
2694  x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2695  y_map[i].y=(MagickRealType) ((-0.4302726)*((double) i-(MagickRealType)
2696  ScaleQuantumToMap(ScaleCharToQuantum(156))));
2697  z_map[i].y=(MagickRealType) ((-0.9271435)*((double) i-(MagickRealType)
2698  ScaleQuantumToMap(ScaleCharToQuantum(137))));
2699  x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2700  y_map[i].z=(MagickRealType) (2.2179000*((double) i-(MagickRealType)
2701  ScaleQuantumToMap(ScaleCharToQuantum(156))));
2702  z_map[i].z=(MagickRealType) (0.0000000);
2703  }
2704  break;
2705  }
2706  default:
2707  {
2708  /*
2709  Linear conversion tables.
2710  */
2711 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2712  #pragma omp parallel for schedule(static)
2713 #endif
2714  for (i=0; i <= (ssize_t) MaxMap; i++)
2715  {
2716  x_map[i].x=(MagickRealType) (1.0*(double) i);
2717  y_map[i].x=(MagickRealType) 0.0;
2718  z_map[i].x=(MagickRealType) 0.0;
2719  x_map[i].y=(MagickRealType) 0.0;
2720  y_map[i].y=(MagickRealType) (1.0*(double) i);
2721  z_map[i].y=(MagickRealType) 0.0;
2722  x_map[i].z=(MagickRealType) 0.0;
2723  y_map[i].z=(MagickRealType) 0.0;
2724  z_map[i].z=(MagickRealType) (1.0*(double) i);
2725  }
2726  break;
2727  }
2728  }
2729  /*
2730  Convert to sRGB.
2731  */
2732  switch (image->storage_class)
2733  {
2734  case DirectClass:
2735  default:
2736  {
2737  /*
2738  Convert DirectClass image.
2739  */
2740  image_view=AcquireAuthenticCacheView(image,exception);
2741 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2742  #pragma omp parallel for schedule(static) shared(status) \
2743  magick_number_threads(image,image,image->rows,2)
2744 #endif
2745  for (y=0; y < (ssize_t) image->rows; y++)
2746  {
2747  MagickBooleanType
2748  sync;
2749 
2751  pixel;
2752 
2753  ssize_t
2754  x;
2755 
2756  PixelPacket
2757  *magick_restrict q;
2758 
2759  if (status == MagickFalse)
2760  continue;
2761  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2762  exception);
2763  if (q == (PixelPacket *) NULL)
2764  {
2765  status=MagickFalse;
2766  continue;
2767  }
2768  for (x=0; x < (ssize_t) image->columns; x++)
2769  {
2770  size_t
2771  blue,
2772  green,
2773  red;
2774 
2775  red=ScaleQuantumToMap(GetPixelRed(q));
2776  green=ScaleQuantumToMap(GetPixelGreen(q));
2777  blue=ScaleQuantumToMap(GetPixelBlue(q));
2778  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2779  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2780  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2781  if (colorspace == YCCColorspace)
2782  {
2783  pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2784  (double) MaxMap)];
2785  pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2786  (double) MaxMap)];
2787  pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2788  (double) MaxMap)];
2789  }
2790  else
2791  {
2792  pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2793  pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2794  pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2795  }
2796  SetPixelRed(q,ClampToQuantum(pixel.red));
2797  SetPixelGreen(q,ClampToQuantum(pixel.green));
2798  SetPixelBlue(q,ClampToQuantum(pixel.blue));
2799  q++;
2800  }
2801  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2802  if (sync == MagickFalse)
2803  status=MagickFalse;
2804  if (image->progress_monitor != (MagickProgressMonitor) NULL)
2805  {
2806  MagickBooleanType
2807  proceed;
2808 
2809 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2810  #pragma omp atomic
2811 #endif
2812  progress++;
2813  proceed=SetImageProgress(image,TransformRGBImageTag,progress,
2814  image->rows);
2815  if (proceed == MagickFalse)
2816  status=MagickFalse;
2817  }
2818  }
2819  image_view=DestroyCacheView(image_view);
2820  break;
2821  }
2822  case PseudoClass:
2823  {
2824  /*
2825  Convert PseudoClass image.
2826  */
2827 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2828  #pragma omp parallel for schedule(static) shared(status) \
2829  magick_number_threads(image,image,image->colors,1)
2830 #endif
2831  for (i=0; i < (ssize_t) image->colors; i++)
2832  {
2834  pixel;
2835 
2836  size_t
2837  blue,
2838  green,
2839  red;
2840 
2841  red=ScaleQuantumToMap(image->colormap[i].red);
2842  green=ScaleQuantumToMap(image->colormap[i].green);
2843  blue=ScaleQuantumToMap(image->colormap[i].blue);
2844  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2845  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2846  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2847  if (colorspace == YCCColorspace)
2848  {
2849  pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2850  (double) MaxMap)];
2851  pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2852  (double) MaxMap)];
2853  pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2854  (double) MaxMap)];
2855  }
2856  else
2857  {
2858  pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2859  pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2860  pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2861  }
2862  image->colormap[i].red=ClampToQuantum(pixel.red);
2863  image->colormap[i].green=ClampToQuantum(pixel.green);
2864  image->colormap[i].blue=ClampToQuantum(pixel.blue);
2865  }
2866  (void) SyncImage(image);
2867  break;
2868  }
2869  }
2870  /*
2871  Relinquish resources.
2872  */
2873  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2874  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2875  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2876  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2877  return(MagickFalse);
2878  return(MagickTrue);
2879 }
Definition: image.h:134