MagickCore  6.9.12-96
Convert, Edit, Or Compose Bitmap Images
 All Data Structures
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,1)
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,1)
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,1)
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,1)
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,1)
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,1)
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=(double) (MaxMap+1.0)/2.0;
921  primary_info.z=(double) (MaxMap+1.0)/2.0;
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=(double) (MaxMap+1.0)/2.0;
976  primary_info.z=(double) (MaxMap+1.0)/2.0;
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=(double) (MaxMap+1.0)/2.0;
1031  primary_info.z=(double) (MaxMap+1.0)/2.0;
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=(double) ScaleQuantumToMap(ScaleCharToQuantum(156));
1061  primary_info.z=(double) ScaleQuantumToMap(ScaleCharToQuantum(137));
1062  for (i=0; i <= (ssize_t) (0.018*MaxMap); i++)
1063  {
1064  x_map[i].x=0.005382*i;
1065  x_map[i].y=(-0.003296)*i;
1066  x_map[i].z=0.009410*i;
1067  y_map[i].x=0.010566*i;
1068  y_map[i].y=(-0.006471)*i;
1069  y_map[i].z=(-0.007880)*i;
1070  z_map[i].x=0.002052*i;
1071  z_map[i].y=0.009768*i;
1072  z_map[i].z=(-0.001530)*i;
1073  }
1074  for ( ; i <= (ssize_t) MaxMap; i++)
1075  {
1076  x_map[i].x=0.298839*(1.099*i-0.099);
1077  x_map[i].y=(-0.298839)*(1.099*i-0.099);
1078  x_map[i].z=0.70100*(1.099*i-0.099);
1079  y_map[i].x=0.586811*(1.099*i-0.099);
1080  y_map[i].y=(-0.586811)*(1.099*i-0.099);
1081  y_map[i].z=(-0.586811)*(1.099*i-0.099);
1082  z_map[i].x=0.114350*(1.099*i-0.099);
1083  z_map[i].y=0.88600*(1.099*i-0.099);
1084  z_map[i].z=(-0.114350)*(1.099*i-0.099);
1085  }
1086  break;
1087  }
1088  default:
1089  {
1090  /*
1091  Linear conversion tables.
1092  */
1093 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1094  #pragma omp parallel for schedule(static)
1095 #endif
1096  for (i=0; i <= (ssize_t) MaxMap; i++)
1097  {
1098  x_map[i].x=(MagickRealType) (1.0*(double) i);
1099  y_map[i].x=(MagickRealType) 0.0;
1100  z_map[i].x=(MagickRealType) 0.0;
1101  x_map[i].y=(MagickRealType) 0.0;
1102  y_map[i].y=(MagickRealType) (1.0*(double) i);
1103  z_map[i].y=(MagickRealType) 0.0;
1104  x_map[i].z=(MagickRealType) 0.0;
1105  y_map[i].z=(MagickRealType) 0.0;
1106  z_map[i].z=(MagickRealType) (1.0*(double) i);
1107  }
1108  break;
1109  }
1110  }
1111  /*
1112  Convert from sRGB.
1113  */
1114  switch (image->storage_class)
1115  {
1116  case DirectClass:
1117  default:
1118  {
1119  /*
1120  Convert DirectClass image.
1121  */
1122  image_view=AcquireAuthenticCacheView(image,exception);
1123 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1124  #pragma omp parallel for schedule(static) shared(status) \
1125  magick_number_threads(image,image,image->rows,1)
1126 #endif
1127  for (y=0; y < (ssize_t) image->rows; y++)
1128  {
1129  MagickBooleanType
1130  sync;
1131 
1133  pixel;
1134 
1135  ssize_t
1136  x;
1137 
1138  PixelPacket
1139  *magick_restrict q;
1140 
1141  size_t
1142  blue,
1143  green,
1144  red;
1145 
1146  if (status == MagickFalse)
1147  continue;
1148  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1149  exception);
1150  if (q == (PixelPacket *) NULL)
1151  {
1152  status=MagickFalse;
1153  continue;
1154  }
1155  for (x=0; x < (ssize_t) image->columns; x++)
1156  {
1157  red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1158  GetPixelRed(q)));
1159  green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1160  GetPixelGreen(q)));
1161  blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1162  GetPixelBlue(q)));
1163  pixel.red=(x_map[red].x+y_map[green].x+z_map[blue].x)+
1164  (MagickRealType) primary_info.x;
1165  pixel.green=(x_map[red].y+y_map[green].y+z_map[blue].y)+
1166  (MagickRealType) primary_info.y;
1167  pixel.blue=(x_map[red].z+y_map[green].z+z_map[blue].z)+
1168  (MagickRealType) primary_info.z;
1169  SetPixelRed(q,ScaleMapToQuantum(pixel.red));
1170  SetPixelGreen(q,ScaleMapToQuantum(pixel.green));
1171  SetPixelBlue(q,ScaleMapToQuantum(pixel.blue));
1172  q++;
1173  }
1174  sync=SyncCacheViewAuthenticPixels(image_view,exception);
1175  if (sync == MagickFalse)
1176  status=MagickFalse;
1177  if (image->progress_monitor != (MagickProgressMonitor) NULL)
1178  {
1179  MagickBooleanType
1180  proceed;
1181 
1182 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1183  #pragma omp atomic
1184 #endif
1185  progress++;
1186  proceed=SetImageProgress(image,RGBTransformImageTag,progress,
1187  image->rows);
1188  if (proceed == MagickFalse)
1189  status=MagickFalse;
1190  }
1191  }
1192  image_view=DestroyCacheView(image_view);
1193  break;
1194  }
1195  case PseudoClass:
1196  {
1197  size_t
1198  blue,
1199  green,
1200  red;
1201 
1202  /*
1203  Convert PseudoClass image.
1204  */
1205  for (i=0; i < (ssize_t) image->colors; i++)
1206  {
1208  pixel;
1209 
1210  red=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1211  image->colormap[i].red));
1212  green=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1213  image->colormap[i].green));
1214  blue=ScaleQuantumToMap(ClampToQuantum((MagickRealType)
1215  image->colormap[i].blue));
1216  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x+primary_info.x;
1217  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y+primary_info.y;
1218  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z+primary_info.z;
1219  image->colormap[i].red=ScaleMapToQuantum(pixel.red);
1220  image->colormap[i].green=ScaleMapToQuantum(pixel.green);
1221  image->colormap[i].blue=ScaleMapToQuantum(pixel.blue);
1222  }
1223  (void) SyncImage(image);
1224  break;
1225  }
1226  }
1227  /*
1228  Relinquish resources.
1229  */
1230  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
1231  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
1232  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
1233  if (SetImageColorspace(image,colorspace) == MagickFalse)
1234  return(MagickFalse);
1235  return(status);
1236 }
1237 
1238 /*
1239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1240 % %
1241 % %
1242 % %
1243 % S e t I m a g e C o l o r s p a c e %
1244 % %
1245 % %
1246 % %
1247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1248 %
1249 % SetImageColorspace() sets the colorspace member of the Image structure.
1250 %
1251 % The format of the SetImageColorspace method is:
1252 %
1253 % MagickBooleanType SetImageColorspace(Image *image,
1254 % const ColorspaceType colorspace)
1255 %
1256 % A description of each parameter follows:
1257 %
1258 % o image: the image.
1259 %
1260 % o colorspace: the colorspace.
1261 %
1262 */
1263 MagickExport MagickBooleanType SetImageColorspace(Image *image,
1264  const ColorspaceType colorspace)
1265 {
1266  ImageType
1267  type;
1268 
1269  MagickBooleanType
1270  status;
1271 
1272  assert(image != (Image *) NULL);
1273  assert(image->signature == MagickCoreSignature);
1274  if (IsEventLogging() != MagickFalse)
1275  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1276  if (image->colorspace == colorspace)
1277  return(MagickTrue);
1278  image->colorspace=colorspace;
1279  image->rendering_intent=UndefinedIntent;
1280  image->gamma=1.000/2.200;
1281  (void) memset(&image->chromaticity,0,sizeof(image->chromaticity));
1282  type=image->type;
1283  if (IsGrayColorspace(colorspace) != MagickFalse)
1284  {
1285  if (colorspace == LinearGRAYColorspace)
1286  image->gamma=1.0;
1287  type=GrayscaleType;
1288  }
1289  else
1290  if ((IsRGBColorspace(colorspace) != MagickFalse) ||
1291  (colorspace == XYZColorspace) || (colorspace == xyYColorspace))
1292  image->gamma=1.0;
1293  else
1294  {
1295  image->rendering_intent=PerceptualIntent;
1296  image->chromaticity.red_primary.x=0.6400;
1297  image->chromaticity.red_primary.y=0.3300;
1298  image->chromaticity.red_primary.z=0.0300;
1299  image->chromaticity.green_primary.x=0.3000;
1300  image->chromaticity.green_primary.y=0.6000;
1301  image->chromaticity.green_primary.z=0.1000;
1302  image->chromaticity.blue_primary.x=0.1500;
1303  image->chromaticity.blue_primary.y=0.0600;
1304  image->chromaticity.blue_primary.z=0.7900;
1305  image->chromaticity.white_point.x=0.3127;
1306  image->chromaticity.white_point.y=0.3290;
1307  image->chromaticity.white_point.z=0.3583;
1308  }
1309  status=SyncImagePixelCache(image,&image->exception);
1310  image->type=type;
1311  return(status);
1312 }
1313 
1314 /*
1315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1316 % %
1317 % %
1318 % %
1319 % S e t I m a g e G r a y %
1320 % %
1321 % %
1322 % %
1323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1324 %
1325 % SetImageGray() returns MagickTrue if all the pixels in the image have the
1326 % same red, green, and blue intensities and changes the type of the image to
1327 % bi-level or grayscale.
1328 %
1329 % The format of the SetImageGray method is:
1330 %
1331 % MagickBooleanType SetImageGray(const Image *image,
1332 % ExceptionInfo *exception)
1333 %
1334 % A description of each parameter follows:
1335 %
1336 % o image: the image.
1337 %
1338 % o exception: return any errors or warnings in this structure.
1339 %
1340 */
1341 MagickExport MagickBooleanType SetImageGray(Image *image,
1342  ExceptionInfo *exception)
1343 {
1344  const char
1345  *value;
1346 
1347  CacheView
1348  *image_view;
1349 
1350  ImageType
1351  type;
1352 
1353  const PixelPacket
1354  *p;
1355 
1356  ssize_t
1357  x;
1358 
1359  ssize_t
1360  y;
1361 
1362  assert(image != (Image *) NULL);
1363  assert(image->signature == MagickCoreSignature);
1364  if (IsEventLogging() != MagickFalse)
1365  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1366  if ((image->type == BilevelType) || (image->type == GrayscaleType) ||
1367  (image->type == GrayscaleMatteType))
1368  return(MagickTrue);
1369  if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
1370  (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
1371  return(MagickFalse);
1372  value=GetImageProperty(image,"colorspace:auto-grayscale");
1373  if (IsStringNotFalse(value) == MagickFalse)
1374  return(MagickFalse);
1375  type=BilevelType;
1376  image_view=AcquireVirtualCacheView(image,exception);
1377  for (y=0; y < (ssize_t) image->rows; y++)
1378  {
1379  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1380  if (p == (const PixelPacket *) NULL)
1381  break;
1382  for (x=0; x < (ssize_t) image->columns; x++)
1383  {
1384  if (IsGrayPixel(p) == MagickFalse)
1385  {
1386  type=UndefinedType;
1387  break;
1388  }
1389  if ((type == BilevelType) && (IsMonochromePixel(p) == MagickFalse))
1390  type=GrayscaleType;
1391  p++;
1392  }
1393  if (type == UndefinedType)
1394  break;
1395  }
1396  image_view=DestroyCacheView(image_view);
1397  if (type == UndefinedType)
1398  return(MagickFalse);
1399  image->colorspace=GRAYColorspace;
1400  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
1401  return(MagickFalse);
1402  image->type=type;
1403  if ((type == GrayscaleType) && (image->matte != MagickFalse))
1404  image->type=GrayscaleMatteType;
1405  return(MagickTrue);
1406 }
1407 
1408 /*
1409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410 % %
1411 % %
1412 % %
1413 % S e t I m a g e M o n o c h r o m e %
1414 % %
1415 % %
1416 % %
1417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1418 %
1419 % SetImageMonochrome() returns MagickTrue if all the pixels in the image have
1420 % the same red, green, and blue intensities and the intensity is either
1421 % 0 or QuantumRange and changes the type of the image to bi-level.
1422 %
1423 % The format of the SetImageMonochrome method is:
1424 %
1425 % MagickBooleanType SetImageMonochrome(const Image *image,
1426 % ExceptionInfo *exception)
1427 %
1428 % A description of each parameter follows:
1429 %
1430 % o image: the image.
1431 %
1432 % o exception: return any errors or warnings in this structure.
1433 %
1434 */
1435 MagickExport MagickBooleanType SetImageMonochrome(Image *image,
1436  ExceptionInfo *exception)
1437 {
1438  const char
1439  *value;
1440 
1441  CacheView
1442  *image_view;
1443 
1444  ImageType
1445  type;
1446 
1447  ssize_t
1448  x;
1449 
1450  const PixelPacket
1451  *p;
1452 
1453  ssize_t
1454  y;
1455 
1456  assert(image != (Image *) NULL);
1457  assert(image->signature == MagickCoreSignature);
1458  if (IsEventLogging() != MagickFalse)
1459  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1460  if (IsMonochromeImage(image,&image->exception) != MagickFalse)
1461  return(MagickTrue);
1462  if ((IsGrayColorspace(image->colorspace) == MagickFalse) &&
1463  (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse))
1464  return(MagickFalse);
1465  value=GetImageProperty(image,"colorspace:auto-grayscale");
1466  if (IsStringNotFalse(value) == MagickFalse)
1467  return(MagickFalse);
1468  type=BilevelType;
1469  image_view=AcquireVirtualCacheView(image,exception);
1470  for (y=0; y < (ssize_t) image->rows; y++)
1471  {
1472  p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1473  if (p == (const PixelPacket *) NULL)
1474  break;
1475  for (x=0; x < (ssize_t) image->columns; x++)
1476  {
1477  if (IsMonochromePixel(p) == MagickFalse)
1478  {
1479  type=UndefinedType;
1480  break;
1481  }
1482  p++;
1483  }
1484  if (type == UndefinedType)
1485  break;
1486  }
1487  image_view=DestroyCacheView(image_view);
1488  if (type == UndefinedType)
1489  return(MagickFalse);
1490  image->colorspace=GRAYColorspace;
1491  if (SyncImagePixelCache((Image *) image,exception) == MagickFalse)
1492  return(MagickFalse);
1493  image->type=type;
1494  return(MagickTrue);
1495 }
1496 
1497 /*
1498 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1499 % %
1500 % %
1501 % %
1502 % T r a n s f o r m I m a g e C o l o r s p a c e %
1503 % %
1504 % %
1505 % %
1506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1507 %
1508 % TransformImageColorspace() transforms an image colorspace.
1509 %
1510 % The format of the TransformImageColorspace method is:
1511 %
1512 % MagickBooleanType TransformImageColorspace(Image *image,
1513 % const ColorspaceType colorspace)
1514 %
1515 % A description of each parameter follows:
1516 %
1517 % o image: the image.
1518 %
1519 % o colorspace: the colorspace.
1520 %
1521 */
1522 MagickExport MagickBooleanType TransformImageColorspace(Image *image,
1523  const ColorspaceType colorspace)
1524 {
1525  MagickBooleanType
1526  status;
1527 
1528  assert(image != (Image *) NULL);
1529  assert(image->signature == MagickCoreSignature);
1530  if (IsEventLogging() != MagickFalse)
1531  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1532  if (image->colorspace == colorspace)
1533  return(MagickTrue);
1534  (void) DeleteImageProfile(image,"icc");
1535  (void) DeleteImageProfile(image,"icm");
1536  if (colorspace == UndefinedColorspace)
1537  return(SetImageColorspace(image,colorspace));
1538  /*
1539  Convert the reference image from an alternate colorspace to sRGB.
1540  */
1541  if (IssRGBColorspace(colorspace) != MagickFalse)
1542  return(TransformRGBImage(image,image->colorspace));
1543  status=MagickTrue;
1544  if (IssRGBColorspace(image->colorspace) == MagickFalse)
1545  status=TransformRGBImage(image,image->colorspace);
1546  if (status == MagickFalse)
1547  return(status);
1548  /*
1549  Convert the reference image from sRGB to an alternate colorspace.
1550  */
1551  if (RGBTransformImage(image,colorspace) == MagickFalse)
1552  status=MagickFalse;
1553  return(status);
1554 }
1555 
1556 /*
1557 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1558 % %
1559 % %
1560 % %
1561 + T r a n s f o r m R G B I m a g e %
1562 % %
1563 % %
1564 % %
1565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1566 %
1567 % TransformRGBImage() converts the reference image from an alternate
1568 % colorspace to sRGB. The transformation matrices are not the standard ones:
1569 % the weights are rescaled to normalize the range of the transformed values to
1570 % be [0..QuantumRange].
1571 %
1572 % The format of the TransformRGBImage method is:
1573 %
1574 % MagickBooleanType TransformRGBImage(Image *image,
1575 % const ColorspaceType colorspace)
1576 %
1577 % A description of each parameter follows:
1578 %
1579 % o image: the image.
1580 %
1581 % o colorspace: the colorspace to transform the image to.
1582 %
1583 */
1584 
1585 static inline void ConvertCMYToRGB(const double cyan,const double magenta,
1586  const double yellow,Quantum *red,Quantum *green,Quantum *blue)
1587 {
1588  *red=ClampToQuantum((MagickRealType) QuantumRange*(1.0-cyan));
1589  *green=ClampToQuantum((MagickRealType) QuantumRange*(1.0-magenta));
1590  *blue=ClampToQuantum((MagickRealType) QuantumRange*(1.0-yellow));
1591 }
1592 
1593 static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
1594  double *X,double *Y,double *Z)
1595 {
1596  *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
1597  *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
1598  *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
1599 }
1600 
1601 static inline void ConvertLMSToRGB(const double L,const double M,
1602  const double S,Quantum *red,Quantum *green,Quantum *blue)
1603 {
1604  double
1605  X,
1606  Y,
1607  Z;
1608 
1609  ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
1610  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1611 }
1612 
1613 static inline void ConvertLuvToRGB(const double L,const double u,
1614  const double v,Quantum *red,Quantum *green,Quantum *blue)
1615 {
1616  double
1617  X,
1618  Y,
1619  Z;
1620 
1621  ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
1622  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1623 }
1624 
1625 static inline ssize_t RoundToYCC(const MagickRealType value)
1626 {
1627  if (value <= 0.0)
1628  return(0);
1629  if (value >= 1388.0)
1630  return(1388);
1631  return((ssize_t) (value+0.5));
1632 }
1633 
1634 static inline void ConvertLabToRGB(const double L,const double a,
1635  const double b,Quantum *red,Quantum *green,Quantum *blue)
1636 {
1637  double
1638  X,
1639  Y,
1640  Z;
1641 
1642  ConvertLabToXYZ(100.0*L,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
1643  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1644 }
1645 
1646 static inline void ConvertxyYToRGB(const double low_x,const double low_y,
1647  const double cap_Y,Quantum *red,Quantum *green,Quantum *blue)
1648 {
1649  double
1650  gamma,
1651  X,
1652  Y,
1653  Z;
1654 
1655  gamma=PerceptibleReciprocal(low_y);
1656  X=gamma*cap_Y*low_x;
1657  Y=cap_Y;
1658  Z=gamma*cap_Y*(1.0-low_x-low_y);
1659  ConvertXYZToRGB(X,Y,Z,red,green,blue);
1660 }
1661 
1662 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
1663  Quantum *red,Quantum *green,Quantum *blue)
1664 {
1665  *red=ClampToQuantum((MagickRealType) QuantumRange*(0.99999999999914679361*Y-
1666  1.2188941887145875e-06*(Pb-0.5)+1.4019995886561440468*(Pr-0.5)));
1667  *green=ClampToQuantum((MagickRealType) QuantumRange*(0.99999975910502514331*Y-
1668  0.34413567816504303521*(Pb-0.5)-0.71413649331646789076*(Pr-0.5)));
1669  *blue=ClampToQuantum((MagickRealType) QuantumRange*(1.00000124040004623180*Y+
1670  1.77200006607230409200*(Pb-0.5)+2.1453384174593273e-06*(Pr-0.5)));
1671 }
1672 
1673 static void ConvertYCbCrToRGB(const double Y,const double Cb,
1674  const double Cr,Quantum *red,Quantum *green,Quantum *blue)
1675 {
1676  ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
1677 }
1678 
1679 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
1680  Quantum *red,Quantum *green,Quantum *blue)
1681 {
1682  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y+9.2303716147657e-05*
1683  (Db-0.5)-0.52591263066186533*(Dr-0.5)));
1684  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.12913289889050927*
1685  (Db-0.5)+0.26789932820759876*(Dr-0.5)));
1686  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y+0.66467905997895482*
1687  (Db-0.5)-7.9202543533108e-05*(Dr-0.5)));
1688 }
1689 
1690 static void ConvertYIQToRGB(const double Y,const double I,const double Q,
1691  Quantum *red,Quantum *green,Quantum *blue)
1692 {
1693  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y+0.9562957197589482261*
1694  (I-0.5)+0.6210244164652610754*(Q-0.5)));
1695  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.2721220993185104464*
1696  (I-0.5)-0.6473805968256950427*(Q-0.5)));
1697  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y-1.1069890167364901945*
1698  (I-0.5)+1.7046149983646481374*(Q-0.5)));
1699 }
1700 
1701 static void ConvertYUVToRGB(const double Y,const double U,const double V,
1702  Quantum *red,Quantum *green,Quantum *blue)
1703 {
1704  *red=ClampToQuantum((MagickRealType) QuantumRange*(Y-3.945707070708279e-05*
1705  (U-0.5)+1.1398279671717170825*(V-0.5)));
1706  *green=ClampToQuantum((MagickRealType) QuantumRange*(Y-0.3946101641414141437*
1707  (U-0.5)-0.5805003156565656797*(V-0.5)));
1708  *blue=ClampToQuantum((MagickRealType) QuantumRange*(Y+2.0319996843434342537*
1709  (U-0.5)-4.813762626262513e-04*(V-0.5)));
1710 }
1711 
1712 MagickExport MagickBooleanType TransformRGBImage(Image *image,
1713  const ColorspaceType colorspace)
1714 {
1715 #define TransformRGBImageTag "Transform/Image"
1716 
1717  static const float
1718  YCCMap[1389] =
1719  {
1720  0.000000, 0.000720f, 0.001441f, 0.002161f, 0.002882f, 0.003602f,
1721  0.004323f, 0.005043f, 0.005764f, 0.006484f, 0.007205f, 0.007925f,
1722  0.008646f, 0.009366f, 0.010086f, 0.010807f, 0.011527f, 0.012248f,
1723  0.012968f, 0.013689f, 0.014409f, 0.015130f, 0.015850f, 0.016571f,
1724  0.017291f, 0.018012f, 0.018732f, 0.019452f, 0.020173f, 0.020893f,
1725  0.021614f, 0.022334f, 0.023055f, 0.023775f, 0.024496f, 0.025216f,
1726  0.025937f, 0.026657f, 0.027378f, 0.028098f, 0.028818f, 0.029539f,
1727  0.030259f, 0.030980f, 0.031700f, 0.032421f, 0.033141f, 0.033862f,
1728  0.034582f, 0.035303f, 0.036023f, 0.036744f, 0.037464f, 0.038184f,
1729  0.038905f, 0.039625f, 0.040346f, 0.041066f, 0.041787f, 0.042507f,
1730  0.043228f, 0.043948f, 0.044669f, 0.045389f, 0.046110f, 0.046830f,
1731  0.047550f, 0.048271f, 0.048991f, 0.049712f, 0.050432f, 0.051153f,
1732  0.051873f, 0.052594f, 0.053314f, 0.054035f, 0.054755f, 0.055476f,
1733  0.056196f, 0.056916f, 0.057637f, 0.058357f, 0.059078f, 0.059798f,
1734  0.060519f, 0.061239f, 0.061960f, 0.062680f, 0.063401f, 0.064121f,
1735  0.064842f, 0.065562f, 0.066282f, 0.067003f, 0.067723f, 0.068444f,
1736  0.069164f, 0.069885f, 0.070605f, 0.071326f, 0.072046f, 0.072767f,
1737  0.073487f, 0.074207f, 0.074928f, 0.075648f, 0.076369f, 0.077089f,
1738  0.077810f, 0.078530f, 0.079251f, 0.079971f, 0.080692f, 0.081412f,
1739  0.082133f, 0.082853f, 0.083573f, 0.084294f, 0.085014f, 0.085735f,
1740  0.086455f, 0.087176f, 0.087896f, 0.088617f, 0.089337f, 0.090058f,
1741  0.090778f, 0.091499f, 0.092219f, 0.092939f, 0.093660f, 0.094380f,
1742  0.095101f, 0.095821f, 0.096542f, 0.097262f, 0.097983f, 0.098703f,
1743  0.099424f, 0.100144f, 0.100865f, 0.101585f, 0.102305f, 0.103026f,
1744  0.103746f, 0.104467f, 0.105187f, 0.105908f, 0.106628f, 0.107349f,
1745  0.108069f, 0.108790f, 0.109510f, 0.110231f, 0.110951f, 0.111671f,
1746  0.112392f, 0.113112f, 0.113833f, 0.114553f, 0.115274f, 0.115994f,
1747  0.116715f, 0.117435f, 0.118156f, 0.118876f, 0.119597f, 0.120317f,
1748  0.121037f, 0.121758f, 0.122478f, 0.123199f, 0.123919f, 0.124640f,
1749  0.125360f, 0.126081f, 0.126801f, 0.127522f, 0.128242f, 0.128963f,
1750  0.129683f, 0.130403f, 0.131124f, 0.131844f, 0.132565f, 0.133285f,
1751  0.134006f, 0.134726f, 0.135447f, 0.136167f, 0.136888f, 0.137608f,
1752  0.138329f, 0.139049f, 0.139769f, 0.140490f, 0.141210f, 0.141931f,
1753  0.142651f, 0.143372f, 0.144092f, 0.144813f, 0.145533f, 0.146254f,
1754  0.146974f, 0.147695f, 0.148415f, 0.149135f, 0.149856f, 0.150576f,
1755  0.151297f, 0.152017f, 0.152738f, 0.153458f, 0.154179f, 0.154899f,
1756  0.155620f, 0.156340f, 0.157061f, 0.157781f, 0.158501f, 0.159222f,
1757  0.159942f, 0.160663f, 0.161383f, 0.162104f, 0.162824f, 0.163545f,
1758  0.164265f, 0.164986f, 0.165706f, 0.166427f, 0.167147f, 0.167867f,
1759  0.168588f, 0.169308f, 0.170029f, 0.170749f, 0.171470f, 0.172190f,
1760  0.172911f, 0.173631f, 0.174352f, 0.175072f, 0.175793f, 0.176513f,
1761  0.177233f, 0.177954f, 0.178674f, 0.179395f, 0.180115f, 0.180836f,
1762  0.181556f, 0.182277f, 0.182997f, 0.183718f, 0.184438f, 0.185159f,
1763  0.185879f, 0.186599f, 0.187320f, 0.188040f, 0.188761f, 0.189481f,
1764  0.190202f, 0.190922f, 0.191643f, 0.192363f, 0.193084f, 0.193804f,
1765  0.194524f, 0.195245f, 0.195965f, 0.196686f, 0.197406f, 0.198127f,
1766  0.198847f, 0.199568f, 0.200288f, 0.201009f, 0.201729f, 0.202450f,
1767  0.203170f, 0.203890f, 0.204611f, 0.205331f, 0.206052f, 0.206772f,
1768  0.207493f, 0.208213f, 0.208934f, 0.209654f, 0.210375f, 0.211095f,
1769  0.211816f, 0.212536f, 0.213256f, 0.213977f, 0.214697f, 0.215418f,
1770  0.216138f, 0.216859f, 0.217579f, 0.218300f, 0.219020f, 0.219741f,
1771  0.220461f, 0.221182f, 0.221902f, 0.222622f, 0.223343f, 0.224063f,
1772  0.224784f, 0.225504f, 0.226225f, 0.226945f, 0.227666f, 0.228386f,
1773  0.229107f, 0.229827f, 0.230548f, 0.231268f, 0.231988f, 0.232709f,
1774  0.233429f, 0.234150f, 0.234870f, 0.235591f, 0.236311f, 0.237032f,
1775  0.237752f, 0.238473f, 0.239193f, 0.239914f, 0.240634f, 0.241354f,
1776  0.242075f, 0.242795f, 0.243516f, 0.244236f, 0.244957f, 0.245677f,
1777  0.246398f, 0.247118f, 0.247839f, 0.248559f, 0.249280f, 0.250000f,
1778  0.250720f, 0.251441f, 0.252161f, 0.252882f, 0.253602f, 0.254323f,
1779  0.255043f, 0.255764f, 0.256484f, 0.257205f, 0.257925f, 0.258646f,
1780  0.259366f, 0.260086f, 0.260807f, 0.261527f, 0.262248f, 0.262968f,
1781  0.263689f, 0.264409f, 0.265130f, 0.265850f, 0.266571f, 0.267291f,
1782  0.268012f, 0.268732f, 0.269452f, 0.270173f, 0.270893f, 0.271614f,
1783  0.272334f, 0.273055f, 0.273775f, 0.274496f, 0.275216f, 0.275937f,
1784  0.276657f, 0.277378f, 0.278098f, 0.278818f, 0.279539f, 0.280259f,
1785  0.280980f, 0.281700f, 0.282421f, 0.283141f, 0.283862f, 0.284582f,
1786  0.285303f, 0.286023f, 0.286744f, 0.287464f, 0.288184f, 0.288905f,
1787  0.289625f, 0.290346f, 0.291066f, 0.291787f, 0.292507f, 0.293228f,
1788  0.293948f, 0.294669f, 0.295389f, 0.296109f, 0.296830f, 0.297550f,
1789  0.298271f, 0.298991f, 0.299712f, 0.300432f, 0.301153f, 0.301873f,
1790  0.302594f, 0.303314f, 0.304035f, 0.304755f, 0.305476f, 0.306196f,
1791  0.306916f, 0.307637f, 0.308357f, 0.309078f, 0.309798f, 0.310519f,
1792  0.311239f, 0.311960f, 0.312680f, 0.313401f, 0.314121f, 0.314842f,
1793  0.315562f, 0.316282f, 0.317003f, 0.317723f, 0.318444f, 0.319164f,
1794  0.319885f, 0.320605f, 0.321326f, 0.322046f, 0.322767f, 0.323487f,
1795  0.324207f, 0.324928f, 0.325648f, 0.326369f, 0.327089f, 0.327810f,
1796  0.328530f, 0.329251f, 0.329971f, 0.330692f, 0.331412f, 0.332133f,
1797  0.332853f, 0.333573f, 0.334294f, 0.335014f, 0.335735f, 0.336455f,
1798  0.337176f, 0.337896f, 0.338617f, 0.339337f, 0.340058f, 0.340778f,
1799  0.341499f, 0.342219f, 0.342939f, 0.343660f, 0.344380f, 0.345101f,
1800  0.345821f, 0.346542f, 0.347262f, 0.347983f, 0.348703f, 0.349424f,
1801  0.350144f, 0.350865f, 0.351585f, 0.352305f, 0.353026f, 0.353746f,
1802  0.354467f, 0.355187f, 0.355908f, 0.356628f, 0.357349f, 0.358069f,
1803  0.358790f, 0.359510f, 0.360231f, 0.360951f, 0.361671f, 0.362392f,
1804  0.363112f, 0.363833f, 0.364553f, 0.365274f, 0.365994f, 0.366715f,
1805  0.367435f, 0.368156f, 0.368876f, 0.369597f, 0.370317f, 0.371037f,
1806  0.371758f, 0.372478f, 0.373199f, 0.373919f, 0.374640f, 0.375360f,
1807  0.376081f, 0.376801f, 0.377522f, 0.378242f, 0.378963f, 0.379683f,
1808  0.380403f, 0.381124f, 0.381844f, 0.382565f, 0.383285f, 0.384006f,
1809  0.384726f, 0.385447f, 0.386167f, 0.386888f, 0.387608f, 0.388329f,
1810  0.389049f, 0.389769f, 0.390490f, 0.391210f, 0.391931f, 0.392651f,
1811  0.393372f, 0.394092f, 0.394813f, 0.395533f, 0.396254f, 0.396974f,
1812  0.397695f, 0.398415f, 0.399135f, 0.399856f, 0.400576f, 0.401297f,
1813  0.402017f, 0.402738f, 0.403458f, 0.404179f, 0.404899f, 0.405620f,
1814  0.406340f, 0.407061f, 0.407781f, 0.408501f, 0.409222f, 0.409942f,
1815  0.410663f, 0.411383f, 0.412104f, 0.412824f, 0.413545f, 0.414265f,
1816  0.414986f, 0.415706f, 0.416427f, 0.417147f, 0.417867f, 0.418588f,
1817  0.419308f, 0.420029f, 0.420749f, 0.421470f, 0.422190f, 0.422911f,
1818  0.423631f, 0.424352f, 0.425072f, 0.425793f, 0.426513f, 0.427233f,
1819  0.427954f, 0.428674f, 0.429395f, 0.430115f, 0.430836f, 0.431556f,
1820  0.432277f, 0.432997f, 0.433718f, 0.434438f, 0.435158f, 0.435879f,
1821  0.436599f, 0.437320f, 0.438040f, 0.438761f, 0.439481f, 0.440202f,
1822  0.440922f, 0.441643f, 0.442363f, 0.443084f, 0.443804f, 0.444524f,
1823  0.445245f, 0.445965f, 0.446686f, 0.447406f, 0.448127f, 0.448847f,
1824  0.449568f, 0.450288f, 0.451009f, 0.451729f, 0.452450f, 0.453170f,
1825  0.453891f, 0.454611f, 0.455331f, 0.456052f, 0.456772f, 0.457493f,
1826  0.458213f, 0.458934f, 0.459654f, 0.460375f, 0.461095f, 0.461816f,
1827  0.462536f, 0.463256f, 0.463977f, 0.464697f, 0.465418f, 0.466138f,
1828  0.466859f, 0.467579f, 0.468300f, 0.469020f, 0.469741f, 0.470461f,
1829  0.471182f, 0.471902f, 0.472622f, 0.473343f, 0.474063f, 0.474784f,
1830  0.475504f, 0.476225f, 0.476945f, 0.477666f, 0.478386f, 0.479107f,
1831  0.479827f, 0.480548f, 0.481268f, 0.481988f, 0.482709f, 0.483429f,
1832  0.484150f, 0.484870f, 0.485591f, 0.486311f, 0.487032f, 0.487752f,
1833  0.488473f, 0.489193f, 0.489914f, 0.490634f, 0.491354f, 0.492075f,
1834  0.492795f, 0.493516f, 0.494236f, 0.494957f, 0.495677f, 0.496398f,
1835  0.497118f, 0.497839f, 0.498559f, 0.499280f, 0.500000f, 0.500720f,
1836  0.501441f, 0.502161f, 0.502882f, 0.503602f, 0.504323f, 0.505043f,
1837  0.505764f, 0.506484f, 0.507205f, 0.507925f, 0.508646f, 0.509366f,
1838  0.510086f, 0.510807f, 0.511527f, 0.512248f, 0.512968f, 0.513689f,
1839  0.514409f, 0.515130f, 0.515850f, 0.516571f, 0.517291f, 0.518012f,
1840  0.518732f, 0.519452f, 0.520173f, 0.520893f, 0.521614f, 0.522334f,
1841  0.523055f, 0.523775f, 0.524496f, 0.525216f, 0.525937f, 0.526657f,
1842  0.527378f, 0.528098f, 0.528818f, 0.529539f, 0.530259f, 0.530980f,
1843  0.531700f, 0.532421f, 0.533141f, 0.533862f, 0.534582f, 0.535303f,
1844  0.536023f, 0.536744f, 0.537464f, 0.538184f, 0.538905f, 0.539625f,
1845  0.540346f, 0.541066f, 0.541787f, 0.542507f, 0.543228f, 0.543948f,
1846  0.544669f, 0.545389f, 0.546109f, 0.546830f, 0.547550f, 0.548271f,
1847  0.548991f, 0.549712f, 0.550432f, 0.551153f, 0.551873f, 0.552594f,
1848  0.553314f, 0.554035f, 0.554755f, 0.555476f, 0.556196f, 0.556916f,
1849  0.557637f, 0.558357f, 0.559078f, 0.559798f, 0.560519f, 0.561239f,
1850  0.561960f, 0.562680f, 0.563401f, 0.564121f, 0.564842f, 0.565562f,
1851  0.566282f, 0.567003f, 0.567723f, 0.568444f, 0.569164f, 0.569885f,
1852  0.570605f, 0.571326f, 0.572046f, 0.572767f, 0.573487f, 0.574207f,
1853  0.574928f, 0.575648f, 0.576369f, 0.577089f, 0.577810f, 0.578530f,
1854  0.579251f, 0.579971f, 0.580692f, 0.581412f, 0.582133f, 0.582853f,
1855  0.583573f, 0.584294f, 0.585014f, 0.585735f, 0.586455f, 0.587176f,
1856  0.587896f, 0.588617f, 0.589337f, 0.590058f, 0.590778f, 0.591499f,
1857  0.592219f, 0.592939f, 0.593660f, 0.594380f, 0.595101f, 0.595821f,
1858  0.596542f, 0.597262f, 0.597983f, 0.598703f, 0.599424f, 0.600144f,
1859  0.600865f, 0.601585f, 0.602305f, 0.603026f, 0.603746f, 0.604467f,
1860  0.605187f, 0.605908f, 0.606628f, 0.607349f, 0.608069f, 0.608790f,
1861  0.609510f, 0.610231f, 0.610951f, 0.611671f, 0.612392f, 0.613112f,
1862  0.613833f, 0.614553f, 0.615274f, 0.615994f, 0.616715f, 0.617435f,
1863  0.618156f, 0.618876f, 0.619597f, 0.620317f, 0.621037f, 0.621758f,
1864  0.622478f, 0.623199f, 0.623919f, 0.624640f, 0.625360f, 0.626081f,
1865  0.626801f, 0.627522f, 0.628242f, 0.628963f, 0.629683f, 0.630403f,
1866  0.631124f, 0.631844f, 0.632565f, 0.633285f, 0.634006f, 0.634726f,
1867  0.635447f, 0.636167f, 0.636888f, 0.637608f, 0.638329f, 0.639049f,
1868  0.639769f, 0.640490f, 0.641210f, 0.641931f, 0.642651f, 0.643372f,
1869  0.644092f, 0.644813f, 0.645533f, 0.646254f, 0.646974f, 0.647695f,
1870  0.648415f, 0.649135f, 0.649856f, 0.650576f, 0.651297f, 0.652017f,
1871  0.652738f, 0.653458f, 0.654179f, 0.654899f, 0.655620f, 0.656340f,
1872  0.657061f, 0.657781f, 0.658501f, 0.659222f, 0.659942f, 0.660663f,
1873  0.661383f, 0.662104f, 0.662824f, 0.663545f, 0.664265f, 0.664986f,
1874  0.665706f, 0.666427f, 0.667147f, 0.667867f, 0.668588f, 0.669308f,
1875  0.670029f, 0.670749f, 0.671470f, 0.672190f, 0.672911f, 0.673631f,
1876  0.674352f, 0.675072f, 0.675793f, 0.676513f, 0.677233f, 0.677954f,
1877  0.678674f, 0.679395f, 0.680115f, 0.680836f, 0.681556f, 0.682277f,
1878  0.682997f, 0.683718f, 0.684438f, 0.685158f, 0.685879f, 0.686599f,
1879  0.687320f, 0.688040f, 0.688761f, 0.689481f, 0.690202f, 0.690922f,
1880  0.691643f, 0.692363f, 0.693084f, 0.693804f, 0.694524f, 0.695245f,
1881  0.695965f, 0.696686f, 0.697406f, 0.698127f, 0.698847f, 0.699568f,
1882  0.700288f, 0.701009f, 0.701729f, 0.702450f, 0.703170f, 0.703891f,
1883  0.704611f, 0.705331f, 0.706052f, 0.706772f, 0.707493f, 0.708213f,
1884  0.708934f, 0.709654f, 0.710375f, 0.711095f, 0.711816f, 0.712536f,
1885  0.713256f, 0.713977f, 0.714697f, 0.715418f, 0.716138f, 0.716859f,
1886  0.717579f, 0.718300f, 0.719020f, 0.719741f, 0.720461f, 0.721182f,
1887  0.721902f, 0.722622f, 0.723343f, 0.724063f, 0.724784f, 0.725504f,
1888  0.726225f, 0.726945f, 0.727666f, 0.728386f, 0.729107f, 0.729827f,
1889  0.730548f, 0.731268f, 0.731988f, 0.732709f, 0.733429f, 0.734150f,
1890  0.734870f, 0.735591f, 0.736311f, 0.737032f, 0.737752f, 0.738473f,
1891  0.739193f, 0.739914f, 0.740634f, 0.741354f, 0.742075f, 0.742795f,
1892  0.743516f, 0.744236f, 0.744957f, 0.745677f, 0.746398f, 0.747118f,
1893  0.747839f, 0.748559f, 0.749280f, 0.750000f, 0.750720f, 0.751441f,
1894  0.752161f, 0.752882f, 0.753602f, 0.754323f, 0.755043f, 0.755764f,
1895  0.756484f, 0.757205f, 0.757925f, 0.758646f, 0.759366f, 0.760086f,
1896  0.760807f, 0.761527f, 0.762248f, 0.762968f, 0.763689f, 0.764409f,
1897  0.765130f, 0.765850f, 0.766571f, 0.767291f, 0.768012f, 0.768732f,
1898  0.769452f, 0.770173f, 0.770893f, 0.771614f, 0.772334f, 0.773055f,
1899  0.773775f, 0.774496f, 0.775216f, 0.775937f, 0.776657f, 0.777378f,
1900  0.778098f, 0.778818f, 0.779539f, 0.780259f, 0.780980f, 0.781700f,
1901  0.782421f, 0.783141f, 0.783862f, 0.784582f, 0.785303f, 0.786023f,
1902  0.786744f, 0.787464f, 0.788184f, 0.788905f, 0.789625f, 0.790346f,
1903  0.791066f, 0.791787f, 0.792507f, 0.793228f, 0.793948f, 0.794669f,
1904  0.795389f, 0.796109f, 0.796830f, 0.797550f, 0.798271f, 0.798991f,
1905  0.799712f, 0.800432f, 0.801153f, 0.801873f, 0.802594f, 0.803314f,
1906  0.804035f, 0.804755f, 0.805476f, 0.806196f, 0.806916f, 0.807637f,
1907  0.808357f, 0.809078f, 0.809798f, 0.810519f, 0.811239f, 0.811960f,
1908  0.812680f, 0.813401f, 0.814121f, 0.814842f, 0.815562f, 0.816282f,
1909  0.817003f, 0.817723f, 0.818444f, 0.819164f, 0.819885f, 0.820605f,
1910  0.821326f, 0.822046f, 0.822767f, 0.823487f, 0.824207f, 0.824928f,
1911  0.825648f, 0.826369f, 0.827089f, 0.827810f, 0.828530f, 0.829251f,
1912  0.829971f, 0.830692f, 0.831412f, 0.832133f, 0.832853f, 0.833573f,
1913  0.834294f, 0.835014f, 0.835735f, 0.836455f, 0.837176f, 0.837896f,
1914  0.838617f, 0.839337f, 0.840058f, 0.840778f, 0.841499f, 0.842219f,
1915  0.842939f, 0.843660f, 0.844380f, 0.845101f, 0.845821f, 0.846542f,
1916  0.847262f, 0.847983f, 0.848703f, 0.849424f, 0.850144f, 0.850865f,
1917  0.851585f, 0.852305f, 0.853026f, 0.853746f, 0.854467f, 0.855187f,
1918  0.855908f, 0.856628f, 0.857349f, 0.858069f, 0.858790f, 0.859510f,
1919  0.860231f, 0.860951f, 0.861671f, 0.862392f, 0.863112f, 0.863833f,
1920  0.864553f, 0.865274f, 0.865994f, 0.866715f, 0.867435f, 0.868156f,
1921  0.868876f, 0.869597f, 0.870317f, 0.871037f, 0.871758f, 0.872478f,
1922  0.873199f, 0.873919f, 0.874640f, 0.875360f, 0.876081f, 0.876801f,
1923  0.877522f, 0.878242f, 0.878963f, 0.879683f, 0.880403f, 0.881124f,
1924  0.881844f, 0.882565f, 0.883285f, 0.884006f, 0.884726f, 0.885447f,
1925  0.886167f, 0.886888f, 0.887608f, 0.888329f, 0.889049f, 0.889769f,
1926  0.890490f, 0.891210f, 0.891931f, 0.892651f, 0.893372f, 0.894092f,
1927  0.894813f, 0.895533f, 0.896254f, 0.896974f, 0.897695f, 0.898415f,
1928  0.899135f, 0.899856f, 0.900576f, 0.901297f, 0.902017f, 0.902738f,
1929  0.903458f, 0.904179f, 0.904899f, 0.905620f, 0.906340f, 0.907061f,
1930  0.907781f, 0.908501f, 0.909222f, 0.909942f, 0.910663f, 0.911383f,
1931  0.912104f, 0.912824f, 0.913545f, 0.914265f, 0.914986f, 0.915706f,
1932  0.916427f, 0.917147f, 0.917867f, 0.918588f, 0.919308f, 0.920029f,
1933  0.920749f, 0.921470f, 0.922190f, 0.922911f, 0.923631f, 0.924352f,
1934  0.925072f, 0.925793f, 0.926513f, 0.927233f, 0.927954f, 0.928674f,
1935  0.929395f, 0.930115f, 0.930836f, 0.931556f, 0.932277f, 0.932997f,
1936  0.933718f, 0.934438f, 0.935158f, 0.935879f, 0.936599f, 0.937320f,
1937  0.938040f, 0.938761f, 0.939481f, 0.940202f, 0.940922f, 0.941643f,
1938  0.942363f, 0.943084f, 0.943804f, 0.944524f, 0.945245f, 0.945965f,
1939  0.946686f, 0.947406f, 0.948127f, 0.948847f, 0.949568f, 0.950288f,
1940  0.951009f, 0.951729f, 0.952450f, 0.953170f, 0.953891f, 0.954611f,
1941  0.955331f, 0.956052f, 0.956772f, 0.957493f, 0.958213f, 0.958934f,
1942  0.959654f, 0.960375f, 0.961095f, 0.961816f, 0.962536f, 0.963256f,
1943  0.963977f, 0.964697f, 0.965418f, 0.966138f, 0.966859f, 0.967579f,
1944  0.968300f, 0.969020f, 0.969741f, 0.970461f, 0.971182f, 0.971902f,
1945  0.972622f, 0.973343f, 0.974063f, 0.974784f, 0.975504f, 0.976225f,
1946  0.976945f, 0.977666f, 0.978386f, 0.979107f, 0.979827f, 0.980548f,
1947  0.981268f, 0.981988f, 0.982709f, 0.983429f, 0.984150f, 0.984870f,
1948  0.985591f, 0.986311f, 0.987032f, 0.987752f, 0.988473f, 0.989193f,
1949  0.989914f, 0.990634f, 0.991354f, 0.992075f, 0.992795f, 0.993516f,
1950  0.994236f, 0.994957f, 0.995677f, 0.996398f, 0.997118f, 0.997839f,
1951  0.998559f, 0.999280f, 1.000000
1952  };
1953 
1954  CacheView
1955  *image_view;
1956 
1958  *exception;
1959 
1960  MagickBooleanType
1961  status;
1962 
1963  MagickOffsetType
1964  progress;
1965 
1966  ssize_t
1967  i;
1968 
1969  ssize_t
1970  y;
1971 
1973  *y_map,
1974  *x_map,
1975  *z_map;
1976 
1977  assert(image != (Image *) NULL);
1978  assert(image->signature == MagickCoreSignature);
1979  if (IsEventLogging() != MagickFalse)
1980  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1981  status=MagickTrue;
1982  progress=0;
1983  exception=(&image->exception);
1984  switch (colorspace)
1985  {
1986  case CMYKColorspace:
1987  {
1989  zero;
1990 
1991  /*
1992  Transform image from CMYK to sRGB.
1993  */
1994  if (image->storage_class == PseudoClass)
1995  {
1996  if (SyncImage(image) == MagickFalse)
1997  return(MagickFalse);
1998  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1999  return(MagickFalse);
2000  }
2001  GetMagickPixelPacket(image,&zero);
2002  image_view=AcquireAuthenticCacheView(image,exception);
2003 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2004  #pragma omp parallel for schedule(static) shared(status) \
2005  magick_number_threads(image,image,image->rows,1)
2006 #endif
2007  for (y=0; y < (ssize_t) image->rows; y++)
2008  {
2009  MagickBooleanType
2010  sync;
2011 
2013  pixel;
2014 
2015  IndexPacket
2016  *magick_restrict indexes;
2017 
2018  ssize_t
2019  x;
2020 
2021  PixelPacket
2022  *magick_restrict q;
2023 
2024  if (status == MagickFalse)
2025  continue;
2026  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2027  exception);
2028  if (q == (PixelPacket *) NULL)
2029  {
2030  status=MagickFalse;
2031  continue;
2032  }
2033  indexes=GetCacheViewAuthenticIndexQueue(image_view);
2034  pixel=zero;
2035  for (x=0; x < (ssize_t) image->columns; x++)
2036  {
2037  SetMagickPixelPacket(image,q,indexes+x,&pixel);
2038  ConvertCMYKToRGB(&pixel);
2039  SetPixelPacket(image,&pixel,q,indexes+x);
2040  q++;
2041  }
2042  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2043  if (sync == MagickFalse)
2044  status=MagickFalse;
2045  }
2046  image_view=DestroyCacheView(image_view);
2047  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2048  return(MagickFalse);
2049  return(status);
2050  }
2051  case LinearGRAYColorspace:
2052  case Rec601LumaColorspace:
2053  {
2054  /*
2055  Transform linear RGB to sRGB colorspace.
2056  */
2057  if (image->storage_class == PseudoClass)
2058  {
2059  if (SyncImage(image) == MagickFalse)
2060  return(MagickFalse);
2061  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2062  return(MagickFalse);
2063  }
2064  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2065  return(MagickFalse);
2066  image_view=AcquireAuthenticCacheView(image,exception);
2067 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2068  #pragma omp parallel for schedule(static) shared(status) \
2069  magick_number_threads(image,image,image->rows,1)
2070 #endif
2071  for (y=0; y < (ssize_t) image->rows; y++)
2072  {
2073  MagickBooleanType
2074  sync;
2075 
2076  ssize_t
2077  x;
2078 
2079  PixelPacket
2080  *magick_restrict q;
2081 
2082  if (status == MagickFalse)
2083  continue;
2084  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2085  exception);
2086  if (q == (PixelPacket *) NULL)
2087  {
2088  status=MagickFalse;
2089  continue;
2090  }
2091  for (x=(ssize_t) image->columns; x != 0; x--)
2092  {
2093  MagickRealType
2094  gray;
2095 
2096  gray=0.212656*EncodePixelGamma(GetPixelRed(q))+0.715158*
2097  EncodePixelGamma(GetPixelGreen(q))+0.072186*
2098  EncodePixelGamma(GetPixelBlue(q));
2099  SetPixelRed(q,ClampToQuantum(gray));
2100  SetPixelGreen(q,ClampToQuantum(gray));
2101  SetPixelBlue(q,ClampToQuantum(gray));
2102  q++;
2103  }
2104  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2105  if (sync == MagickFalse)
2106  status=MagickFalse;
2107  }
2108  image_view=DestroyCacheView(image_view);
2109  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2110  return(MagickFalse);
2111  return(status);
2112  }
2113  case GRAYColorspace:
2114  case Rec709LumaColorspace:
2115  {
2116  /*
2117  Transform linear RGB to sRGB colorspace.
2118  */
2119  if (image->storage_class == PseudoClass)
2120  {
2121  if (SyncImage(image) == MagickFalse)
2122  return(MagickFalse);
2123  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2124  return(MagickFalse);
2125  }
2126  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2127  return(MagickFalse);
2128  image_view=AcquireAuthenticCacheView(image,exception);
2129 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2130  #pragma omp parallel for schedule(static) shared(status) \
2131  magick_number_threads(image,image,image->rows,1)
2132 #endif
2133  for (y=0; y < (ssize_t) image->rows; y++)
2134  {
2135  MagickBooleanType
2136  sync;
2137 
2138  ssize_t
2139  x;
2140 
2141  PixelPacket
2142  *magick_restrict q;
2143 
2144  if (status == MagickFalse)
2145  continue;
2146  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2147  exception);
2148  if (q == (PixelPacket *) NULL)
2149  {
2150  status=MagickFalse;
2151  continue;
2152  }
2153  for (x=(ssize_t) image->columns; x != 0; x--)
2154  {
2155  MagickRealType
2156  gray;
2157 
2158  gray=(MagickRealType) (0.212656*(double) GetPixelRed(q)+0.715158*
2159  (double) GetPixelGreen(q)+0.072186*(double) GetPixelBlue(q));
2160  SetPixelRed(q,ClampToQuantum(gray));
2161  SetPixelGreen(q,ClampToQuantum(gray));
2162  SetPixelBlue(q,ClampToQuantum(gray));
2163  q++;
2164  }
2165  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2166  if (sync == MagickFalse)
2167  status=MagickFalse;
2168  }
2169  image_view=DestroyCacheView(image_view);
2170  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2171  return(MagickFalse);
2172  return(status);
2173  }
2174  case CMYColorspace:
2175  case HCLColorspace:
2176  case HCLpColorspace:
2177  case HSBColorspace:
2178  case HSIColorspace:
2179  case HSLColorspace:
2180  case HSVColorspace:
2181  case HWBColorspace:
2182  case LabColorspace:
2183  case LCHColorspace:
2184  case LCHabColorspace:
2185  case LCHuvColorspace:
2186  case LMSColorspace:
2187  case LuvColorspace:
2188  case xyYColorspace:
2189  case XYZColorspace:
2190  case YCbCrColorspace:
2191  case YDbDrColorspace:
2192  case YIQColorspace:
2193  case YPbPrColorspace:
2194  case YUVColorspace:
2195  {
2196  /*
2197  Transform image from source colorspace to sRGB.
2198  */
2199  if (image->storage_class == PseudoClass)
2200  {
2201  if (SyncImage(image) == MagickFalse)
2202  return(MagickFalse);
2203  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2204  return(MagickFalse);
2205  }
2206  image_view=AcquireAuthenticCacheView(image,exception);
2207 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2208  #pragma omp parallel for schedule(static) shared(status) \
2209  magick_number_threads(image,image,image->rows,1)
2210 #endif
2211  for (y=0; y < (ssize_t) image->rows; y++)
2212  {
2213  MagickBooleanType
2214  sync;
2215 
2216  ssize_t
2217  x;
2218 
2219  PixelPacket
2220  *magick_restrict q;
2221 
2222  if (status == MagickFalse)
2223  continue;
2224  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2225  exception);
2226  if (q == (PixelPacket *) NULL)
2227  {
2228  status=MagickFalse;
2229  continue;
2230  }
2231  for (x=0; x < (ssize_t) image->columns; x++)
2232  {
2233  double
2234  X,
2235  Y,
2236  Z;
2237 
2238  Quantum
2239  blue,
2240  green,
2241  red;
2242 
2243  X=QuantumScale*(double) GetPixelRed(q);
2244  Y=QuantumScale*(double) GetPixelGreen(q);
2245  Z=QuantumScale*(double) GetPixelBlue(q);
2246  switch (colorspace)
2247  {
2248  case CMYColorspace:
2249  {
2250  ConvertCMYToRGB(X,Y,Z,&red,&green,&blue);
2251  break;
2252  }
2253  case HCLColorspace:
2254  {
2255  ConvertHCLToRGB(X,Y,Z,&red,&green,&blue);
2256  break;
2257  }
2258  case HCLpColorspace:
2259  {
2260  ConvertHCLpToRGB(X,Y,Z,&red,&green,&blue);
2261  break;
2262  }
2263  case HSBColorspace:
2264  {
2265  ConvertHSBToRGB(X,Y,Z,&red,&green,&blue);
2266  break;
2267  }
2268  case HSIColorspace:
2269  {
2270  ConvertHSIToRGB(X,Y,Z,&red,&green,&blue);
2271  break;
2272  }
2273  case HSLColorspace:
2274  {
2275  ConvertHSLToRGB(X,Y,Z,&red,&green,&blue);
2276  break;
2277  }
2278  case HSVColorspace:
2279  {
2280  ConvertHSVToRGB(X,Y,Z,&red,&green,&blue);
2281  break;
2282  }
2283  case HWBColorspace:
2284  {
2285  ConvertHWBToRGB(X,Y,Z,&red,&green,&blue);
2286  break;
2287  }
2288  case LabColorspace:
2289  {
2290  ConvertLabToRGB(X,Y,Z,&red,&green,&blue);
2291  break;
2292  }
2293  case LCHColorspace:
2294  case LCHabColorspace:
2295  {
2296  ConvertLCHabToRGB(X,Y,Z,&red,&green,&blue);
2297  break;
2298  }
2299  case LCHuvColorspace:
2300  {
2301  ConvertLCHuvToRGB(X,Y,Z,&red,&green,&blue);
2302  break;
2303  }
2304  case LMSColorspace:
2305  {
2306  ConvertLMSToRGB(X,Y,Z,&red,&green,&blue);
2307  break;
2308  }
2309  case LuvColorspace:
2310  {
2311  ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
2312  break;
2313  }
2314  case xyYColorspace:
2315  {
2316  ConvertxyYToRGB(X,Y,Z,&red,&green,&blue);
2317  break;
2318  }
2319  case XYZColorspace:
2320  {
2321  ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
2322  break;
2323  }
2324  case YCbCrColorspace:
2325  {
2326  ConvertYCbCrToRGB(X,Y,Z,&red,&green,&blue);
2327  break;
2328  }
2329  case YDbDrColorspace:
2330  {
2331  ConvertYDbDrToRGB(X,Y,Z,&red,&green,&blue);
2332  break;
2333  }
2334  case YIQColorspace:
2335  {
2336  ConvertYIQToRGB(X,Y,Z,&red,&green,&blue);
2337  break;
2338  }
2339  case YPbPrColorspace:
2340  {
2341  ConvertYPbPrToRGB(X,Y,Z,&red,&green,&blue);
2342  break;
2343  }
2344  case YUVColorspace:
2345  {
2346  ConvertYUVToRGB(X,Y,Z,&red,&green,&blue);
2347  break;
2348  }
2349  default:
2350  {
2351  red=ClampToQuantum((MagickRealType) QuantumRange*X);
2352  green=ClampToQuantum((MagickRealType) QuantumRange*Y);
2353  blue=ClampToQuantum((MagickRealType) QuantumRange*Z);
2354  break;
2355  }
2356  }
2357  SetPixelRed(q,ClampToQuantum((MagickRealType) red));
2358  SetPixelGreen(q,ClampToQuantum((MagickRealType) green));
2359  SetPixelBlue(q,ClampToQuantum((MagickRealType) blue));
2360  q++;
2361  }
2362  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2363  if (sync == MagickFalse)
2364  status=MagickFalse;
2365  }
2366  image_view=DestroyCacheView(image_view);
2367  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2368  return(MagickFalse);
2369  return(status);
2370  }
2371  case LogColorspace:
2372  {
2373  const char
2374  *value;
2375 
2376  double
2377  black,
2378  density,
2379  film_gamma,
2380  gamma,
2381  reference_black,
2382  reference_white;
2383 
2384  Quantum
2385  *logmap;
2386 
2387  /*
2388  Transform Log to sRGB colorspace.
2389  */
2390  density=DisplayGamma;
2391  gamma=DisplayGamma;
2392  value=GetImageProperty(image,"gamma");
2393  if (value != (const char *) NULL)
2394  gamma=PerceptibleReciprocal(StringToDouble(value,(char **) NULL));
2395  film_gamma=FilmGamma;
2396  value=GetImageProperty(image,"film-gamma");
2397  if (value != (const char *) NULL)
2398  film_gamma=StringToDouble(value,(char **) NULL);
2399  reference_black=ReferenceBlack;
2400  value=GetImageProperty(image,"reference-black");
2401  if (value != (const char *) NULL)
2402  reference_black=StringToDouble(value,(char **) NULL);
2403  reference_white=ReferenceWhite;
2404  value=GetImageProperty(image,"reference-white");
2405  if (value != (const char *) NULL)
2406  reference_white=StringToDouble(value,(char **) NULL);
2407  logmap=(Quantum *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2408  sizeof(*logmap));
2409  if (logmap == (Quantum *) NULL)
2410  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2411  image->filename);
2412  black=pow(10.0,(reference_black-reference_white)*(gamma/density)*0.002*
2413  PerceptibleReciprocal(film_gamma));
2414  for (i=0; i <= (ssize_t) (reference_black*MaxMap/1024.0); i++)
2415  logmap[i]=(Quantum) 0;
2416  for ( ; i < (ssize_t) (reference_white*MaxMap/1024.0); i++)
2417  logmap[i]=ClampToQuantum((MagickRealType) QuantumRange/(1.0-black)*
2418  (pow(10.0,(1024.0*i/MaxMap-reference_white)*(gamma/density)*0.002*
2419  PerceptibleReciprocal(film_gamma))-black));
2420  for ( ; i <= (ssize_t) MaxMap; i++)
2421  logmap[i]=QuantumRange;
2422  if (image->storage_class == PseudoClass)
2423  {
2424  if (SyncImage(image) == MagickFalse)
2425  return(MagickFalse);
2426  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2427  return(MagickFalse);
2428  }
2429  image_view=AcquireAuthenticCacheView(image,exception);
2430 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2431  #pragma omp parallel for schedule(static) shared(status) \
2432  magick_number_threads(image,image,image->rows,1)
2433 #endif
2434  for (y=0; y < (ssize_t) image->rows; y++)
2435  {
2436  MagickBooleanType
2437  sync;
2438 
2439  ssize_t
2440  x;
2441 
2442  PixelPacket
2443  *magick_restrict q;
2444 
2445  if (status == MagickFalse)
2446  continue;
2447  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2448  exception);
2449  if (q == (PixelPacket *) NULL)
2450  {
2451  status=MagickFalse;
2452  continue;
2453  }
2454  for (x=(ssize_t) image->columns; x != 0; x--)
2455  {
2456  Quantum
2457  blue,
2458  green,
2459  red;
2460 
2461  red=ClampToQuantum(EncodePixelGamma((MagickRealType)
2462  logmap[ScaleQuantumToMap(GetPixelRed(q))]));
2463  green=ClampToQuantum(EncodePixelGamma((MagickRealType)
2464  logmap[ScaleQuantumToMap(GetPixelGreen(q))]));
2465  blue=ClampToQuantum(EncodePixelGamma((MagickRealType)
2466  logmap[ScaleQuantumToMap(GetPixelBlue(q))]));
2467  SetPixelRed(q,red);
2468  SetPixelGreen(q,green);
2469  SetPixelBlue(q,blue);
2470  q++;
2471  }
2472  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2473  if (sync == MagickFalse)
2474  status=MagickFalse;
2475  }
2476  image_view=DestroyCacheView(image_view);
2477  logmap=(Quantum *) RelinquishMagickMemory(logmap);
2478  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2479  return(MagickFalse);
2480  return(status);
2481  }
2482  case RGBColorspace:
2483  case scRGBColorspace:
2484  {
2485  /*
2486  Transform linear RGB to sRGB colorspace.
2487  */
2488  if (image->storage_class == PseudoClass)
2489  {
2490  if (SyncImage(image) == MagickFalse)
2491  return(MagickFalse);
2492  if (SetImageStorageClass(image,DirectClass) == MagickFalse)
2493  return(MagickFalse);
2494  }
2495  image_view=AcquireAuthenticCacheView(image,exception);
2496 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2497  #pragma omp parallel for schedule(static) shared(status) \
2498  magick_number_threads(image,image,image->rows,1)
2499 #endif
2500  for (y=0; y < (ssize_t) image->rows; y++)
2501  {
2502  MagickBooleanType
2503  sync;
2504 
2505  ssize_t
2506  x;
2507 
2508  PixelPacket
2509  *magick_restrict q;
2510 
2511  if (status == MagickFalse)
2512  continue;
2513  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2514  exception);
2515  if (q == (PixelPacket *) NULL)
2516  {
2517  status=MagickFalse;
2518  continue;
2519  }
2520  for (x=(ssize_t) image->columns; x != 0; x--)
2521  {
2522  Quantum
2523  blue,
2524  green,
2525  red;
2526 
2527  red=ClampToQuantum(EncodePixelGamma((MagickRealType) GetPixelRed(q)));
2528  green=ClampToQuantum(EncodePixelGamma((MagickRealType)
2529  GetPixelGreen(q)));
2530  blue=ClampToQuantum(EncodePixelGamma((MagickRealType)
2531  GetPixelBlue(q)));
2532  SetPixelRed(q,red);
2533  SetPixelGreen(q,green);
2534  SetPixelBlue(q,blue);
2535  q++;
2536  }
2537  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2538  if (sync == MagickFalse)
2539  status=MagickFalse;
2540  }
2541  image_view=DestroyCacheView(image_view);
2542  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2543  return(MagickFalse);
2544  return(status);
2545  }
2546  default:
2547  break;
2548  }
2549  /*
2550  Allocate the tables.
2551  */
2552  x_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2553  sizeof(*x_map));
2554  y_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2555  sizeof(*y_map));
2556  z_map=(TransformPacket *) AcquireQuantumMemory((size_t) MaxMap+1UL,
2557  sizeof(*z_map));
2558  if ((x_map == (TransformPacket *) NULL) ||
2559  (y_map == (TransformPacket *) NULL) ||
2560  (z_map == (TransformPacket *) NULL))
2561  {
2562  if (z_map != (TransformPacket *) NULL)
2563  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2564  if (y_map != (TransformPacket *) NULL)
2565  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2566  if (x_map != (TransformPacket *) NULL)
2567  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2568  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
2569  image->filename);
2570  }
2571  switch (colorspace)
2572  {
2573  case OHTAColorspace:
2574  {
2575  /*
2576  Initialize OHTA tables:
2577 
2578  R = I1+1.00000*I2-0.66668*I3
2579  G = I1+0.00000*I2+1.33333*I3
2580  B = I1-1.00000*I2-0.66668*I3
2581 
2582  I and Q, normally -0.5 through 0.5, must be normalized to the range 0
2583  through QuantumRange.
2584  */
2585 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2586  #pragma omp parallel for schedule(static)
2587 #endif
2588  for (i=0; i <= (ssize_t) MaxMap; i++)
2589  {
2590  x_map[i].x=(1.0*(double) i);
2591  y_map[i].x=(0.5*1.00000*(2.0*(double) i-MaxMap));
2592  z_map[i].x=(-0.5*0.66668*(2.0*(double) i-MaxMap));
2593  x_map[i].y=(1.0*(double) i);
2594  y_map[i].y=(0.5*0.00000*(2.0*(double) i-MaxMap));
2595  z_map[i].y=(0.5*1.33333*(2.0*(double) i-MaxMap));
2596  x_map[i].z=(1.0*(double) i);
2597  y_map[i].z=(-0.5*1.00000*(2.0*(double) i-MaxMap));
2598  z_map[i].z=(-0.5*0.66668*(2.0*(double) i-MaxMap));
2599  }
2600  break;
2601  }
2602  case Rec601YCbCrColorspace:
2603  {
2604  /*
2605  Initialize YCbCr tables:
2606 
2607  R = Y +1.402000*Cr
2608  G = Y-0.344136*Cb-0.714136*Cr
2609  B = Y+1.772000*Cb
2610 
2611  Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2612  through QuantumRange.
2613  */
2614 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2615  #pragma omp parallel for schedule(static)
2616 #endif
2617  for (i=0; i <= (ssize_t) MaxMap; i++)
2618  {
2619  x_map[i].x=0.99999999999914679361*(double) i;
2620  y_map[i].x=0.5*(-1.2188941887145875e-06)*(2.00*(double) i-MaxMap);
2621  z_map[i].x=0.5*1.4019995886561440468*(2.00*(double) i-MaxMap);
2622  x_map[i].y=0.99999975910502514331*(double) i;
2623  y_map[i].y=0.5*(-0.34413567816504303521)*(2.00*(double) i-MaxMap);
2624  z_map[i].y=0.5*(-0.71413649331646789076)*(2.00*(double) i-MaxMap);
2625  x_map[i].z=1.00000124040004623180*(double) i;
2626  y_map[i].z=0.5*1.77200006607230409200*(2.00*(double) i-MaxMap);
2627  z_map[i].z=0.5*2.1453384174593273e-06*(2.00*(double) i-MaxMap);
2628  }
2629  break;
2630  }
2631  case Rec709YCbCrColorspace:
2632  {
2633  /*
2634  Initialize YCbCr tables:
2635 
2636  R = Y +1.574800*Cr
2637  G = Y-0.187324*Cb-0.468124*Cr
2638  B = Y+1.855600*Cb
2639 
2640  Cb and Cr, normally -0.5 through 0.5, must be normalized to the range 0
2641  through QuantumRange.
2642  */
2643 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2644  #pragma omp parallel for schedule(static)
2645 #endif
2646  for (i=0; i <= (ssize_t) MaxMap; i++)
2647  {
2648  x_map[i].x=(MagickRealType) (1.0*(double) i);
2649  y_map[i].x=(MagickRealType) (0.5*0.000000*(2.0*(double) i-MaxMap));
2650  z_map[i].x=(MagickRealType) (0.5*1.574800*(2.0*(double) i-MaxMap));
2651  x_map[i].y=(MagickRealType) (1.0*(double) i);
2652  y_map[i].y=(MagickRealType) (0.5*(-0.187324)*(2.0*(double) i-MaxMap));
2653  z_map[i].y=(MagickRealType) (0.5*(-0.468124)*(2.0*(double) i-MaxMap));
2654  x_map[i].z=(MagickRealType) (1.0*(double) i);
2655  y_map[i].z=(MagickRealType) (0.5*1.855600*(2.0*(double) i-MaxMap));
2656  z_map[i].z=(MagickRealType) (0.5*0.000000*(2.0*(double) i-MaxMap));
2657  }
2658  break;
2659  }
2660  case YCCColorspace:
2661  {
2662  /*
2663  Initialize YCC tables:
2664 
2665  R = Y +1.340762*C2
2666  G = Y-0.317038*C1-0.682243*C2
2667  B = Y+1.632639*C1
2668 
2669  YCC is scaled by 1.3584. C1 zero is 156 and C2 is at 137.
2670  */
2671 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2672  #pragma omp parallel for schedule(static)
2673 #endif
2674  for (i=0; i <= (ssize_t) MaxMap; i++)
2675  {
2676  x_map[i].x=(MagickRealType) (1.3584000*(double) i);
2677  y_map[i].x=(MagickRealType) (0.0000000);
2678  z_map[i].x=(MagickRealType) (1.8215000*((double) i-(MagickRealType)
2679  ScaleQuantumToMap(ScaleCharToQuantum(137))));
2680  x_map[i].y=(MagickRealType) (1.3584000*(double) i);
2681  y_map[i].y=(MagickRealType) ((-0.4302726)*((double) i-(MagickRealType)
2682  ScaleQuantumToMap(ScaleCharToQuantum(156))));
2683  z_map[i].y=(MagickRealType) ((-0.9271435)*((double) i-(MagickRealType)
2684  ScaleQuantumToMap(ScaleCharToQuantum(137))));
2685  x_map[i].z=(MagickRealType) (1.3584000*(double) i);
2686  y_map[i].z=(MagickRealType) (2.2179000*((double) i-(MagickRealType)
2687  ScaleQuantumToMap(ScaleCharToQuantum(156))));
2688  z_map[i].z=(MagickRealType) (0.0000000);
2689  }
2690  break;
2691  }
2692  default:
2693  {
2694  /*
2695  Linear conversion tables.
2696  */
2697 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2698  #pragma omp parallel for schedule(static)
2699 #endif
2700  for (i=0; i <= (ssize_t) MaxMap; i++)
2701  {
2702  x_map[i].x=(MagickRealType) (1.0*(double) i);
2703  y_map[i].x=(MagickRealType) 0.0;
2704  z_map[i].x=(MagickRealType) 0.0;
2705  x_map[i].y=(MagickRealType) 0.0;
2706  y_map[i].y=(MagickRealType) (1.0*(double) i);
2707  z_map[i].y=(MagickRealType) 0.0;
2708  x_map[i].z=(MagickRealType) 0.0;
2709  y_map[i].z=(MagickRealType) 0.0;
2710  z_map[i].z=(MagickRealType) (1.0*(double) i);
2711  }
2712  break;
2713  }
2714  }
2715  /*
2716  Convert to sRGB.
2717  */
2718  switch (image->storage_class)
2719  {
2720  case DirectClass:
2721  default:
2722  {
2723  /*
2724  Convert DirectClass image.
2725  */
2726  image_view=AcquireAuthenticCacheView(image,exception);
2727 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2728  #pragma omp parallel for schedule(static) shared(status) \
2729  magick_number_threads(image,image,image->rows,1)
2730 #endif
2731  for (y=0; y < (ssize_t) image->rows; y++)
2732  {
2733  MagickBooleanType
2734  sync;
2735 
2737  pixel;
2738 
2739  ssize_t
2740  x;
2741 
2742  PixelPacket
2743  *magick_restrict q;
2744 
2745  if (status == MagickFalse)
2746  continue;
2747  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
2748  exception);
2749  if (q == (PixelPacket *) NULL)
2750  {
2751  status=MagickFalse;
2752  continue;
2753  }
2754  for (x=0; x < (ssize_t) image->columns; x++)
2755  {
2756  size_t
2757  blue,
2758  green,
2759  red;
2760 
2761  red=ScaleQuantumToMap(GetPixelRed(q));
2762  green=ScaleQuantumToMap(GetPixelGreen(q));
2763  blue=ScaleQuantumToMap(GetPixelBlue(q));
2764  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2765  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2766  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2767  if (colorspace == YCCColorspace)
2768  {
2769  pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2770  (double) MaxMap)];
2771  pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2772  (double) MaxMap)];
2773  pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2774  (double) MaxMap)];
2775  }
2776  else
2777  {
2778  pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2779  pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2780  pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2781  }
2782  SetPixelRed(q,ClampToQuantum(pixel.red));
2783  SetPixelGreen(q,ClampToQuantum(pixel.green));
2784  SetPixelBlue(q,ClampToQuantum(pixel.blue));
2785  q++;
2786  }
2787  sync=SyncCacheViewAuthenticPixels(image_view,exception);
2788  if (sync == MagickFalse)
2789  status=MagickFalse;
2790  if (image->progress_monitor != (MagickProgressMonitor) NULL)
2791  {
2792  MagickBooleanType
2793  proceed;
2794 
2795 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2796  #pragma omp atomic
2797 #endif
2798  progress++;
2799  proceed=SetImageProgress(image,TransformRGBImageTag,progress,
2800  image->rows);
2801  if (proceed == MagickFalse)
2802  status=MagickFalse;
2803  }
2804  }
2805  image_view=DestroyCacheView(image_view);
2806  break;
2807  }
2808  case PseudoClass:
2809  {
2810  /*
2811  Convert PseudoClass image.
2812  */
2813 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2814  #pragma omp parallel for schedule(static) shared(status) \
2815  magick_number_threads(image,image,image->colors,1)
2816 #endif
2817  for (i=0; i < (ssize_t) image->colors; i++)
2818  {
2820  pixel;
2821 
2822  size_t
2823  blue,
2824  green,
2825  red;
2826 
2827  red=ScaleQuantumToMap(image->colormap[i].red);
2828  green=ScaleQuantumToMap(image->colormap[i].green);
2829  blue=ScaleQuantumToMap(image->colormap[i].blue);
2830  pixel.red=x_map[red].x+y_map[green].x+z_map[blue].x;
2831  pixel.green=x_map[red].y+y_map[green].y+z_map[blue].y;
2832  pixel.blue=x_map[red].z+y_map[green].z+z_map[blue].z;
2833  if (colorspace == YCCColorspace)
2834  {
2835  pixel.red=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.red/
2836  (double) MaxMap)];
2837  pixel.green=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.green/
2838  (double) MaxMap)];
2839  pixel.blue=QuantumRange*YCCMap[RoundToYCC(1024.0*pixel.blue/
2840  (double) MaxMap)];
2841  }
2842  else
2843  {
2844  pixel.red=(MagickRealType) ScaleMapToQuantum(pixel.red);
2845  pixel.green=(MagickRealType) ScaleMapToQuantum(pixel.green);
2846  pixel.blue=(MagickRealType) ScaleMapToQuantum(pixel.blue);
2847  }
2848  image->colormap[i].red=ClampToQuantum(pixel.red);
2849  image->colormap[i].green=ClampToQuantum(pixel.green);
2850  image->colormap[i].blue=ClampToQuantum(pixel.blue);
2851  }
2852  (void) SyncImage(image);
2853  break;
2854  }
2855  }
2856  /*
2857  Relinquish resources.
2858  */
2859  z_map=(TransformPacket *) RelinquishMagickMemory(z_map);
2860  y_map=(TransformPacket *) RelinquishMagickMemory(y_map);
2861  x_map=(TransformPacket *) RelinquishMagickMemory(x_map);
2862  if (SetImageColorspace(image,sRGBColorspace) == MagickFalse)
2863  return(MagickFalse);
2864  return(MagickTrue);
2865 }
Definition: image.h:152