% July 1992 %
% %
% %
-% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
*/
#include "MagickCore/studio.h"
#include "MagickCore/artifact.h"
+#include "MagickCore/attribute.h"
#include "MagickCore/cache.h"
#include "MagickCore/cache-view.h"
#include "MagickCore/color.h"
ChannelType
channel_mask;
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
- channel_mask=SetPixelChannelMask(image,(ChannelType) (1 << i));
+ channel_mask=SetImageChannelMask(image,(ChannelType) (1 << i));
status=GetImageMean(image,&mean,&sans,exception);
gamma=log(mean*QuantumScale)/log_mean;
status&=LevelImage(image,0.0,(double) QuantumRange,gamma,exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
if (status == MagickFalse)
break;
}
assert(clut_image->signature == MagickSignature);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
- if (IsGrayColorspace(image->colorspace) != MagickFalse)
- (void) TransformImageColorspace(image,RGBColorspace,exception);
clut_map=(PixelInfo *) AcquireQuantumMemory(MaxMap+1UL,sizeof(*clut_map));
if (clut_map == (PixelInfo *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
progress=0;
adjust=(ssize_t) (clut_image->interpolate == IntegerInterpolatePixel ? 0 : 1);
clut_view=AcquireVirtualCacheView(clut_image,exception);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) \
- dynamic_number_threads(image,image->columns,1,1)
-#endif
for (i=0; i <= (ssize_t) MaxMap; i++)
{
GetPixelInfo(clut_image,clut_map+i);
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
GetPixelInfo(image,&pixel);
for (x=0; x < (ssize_t) image->columns; x++)
{
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
image_view=DestroyCacheView(image_view);
clut_map=(PixelInfo *) RelinquishMagickMemory(clut_map);
- if ((clut_image->matte != MagickFalse) &&
+ if ((clut_image->alpha_trait == BlendPixelTrait) &&
((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0))
(void) SetImageAlphaChannel(image,ActivateAlphaChannel,exception);
return(status);
if (cdl_map == (PixelInfo *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) \
- dynamic_number_threads(image,image->columns,1,1)
-#endif
for (i=0; i <= (ssize_t) MaxMap; i++)
{
cdl_map[i].red=(double) ScaleMapToQuantum((double)
for (i=0; i < (ssize_t) image->colors; i++)
{
/*
- Apply transfer function to colormap.
+ Apply transfer function to colormap.
*/
double
- luma;
+ luma;
- luma=0.21267*image->colormap[i].red+0.71526*image->colormap[i].green+
- 0.07217*image->colormap[i].blue;
+ luma=0.21267f*image->colormap[i].red+0.71526*image->colormap[i].green+
+ 0.07217f*image->colormap[i].blue;
image->colormap[i].red=luma+color_correction.saturation*cdl_map[
- ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red))].red-luma;
+ ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red))].red-luma;
image->colormap[i].green=luma+color_correction.saturation*cdl_map[
ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green))].green-luma;
image->colormap[i].blue=luma+color_correction.saturation*cdl_map[
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
}
for (x=0; x < (ssize_t) image->columns; x++)
{
- luma=0.21267*GetPixelRed(image,q)+0.71526*GetPixelGreen(image,q)+0.07217*
- GetPixelBlue(image,q);
+ luma=0.21267f*GetPixelRed(image,q)+0.71526*GetPixelGreen(image,q)+
+ 0.07217f*GetPixelBlue(image,q);
SetPixelRed(image,ClampToQuantum(luma+color_correction.saturation*
(cdl_map[ScaleQuantumToMap(GetPixelRed(image,q))].red-luma)),q);
SetPixelGreen(image,ClampToQuantum(luma+color_correction.saturation*
Contrast enhance colormap.
*/
for (i=0; i < (ssize_t) image->colors; i++)
- Contrast(sign,&image->colormap[i].red,&image->colormap[i].green,
- &image->colormap[i].blue);
+ {
+ double
+ blue,
+ green,
+ red;
+
+ Contrast(sign,&red,&green,&blue);
+ image->colormap[i].red=(MagickRealType) red;
+ image->colormap[i].red=(MagickRealType) red;
+ image->colormap[i].red=(MagickRealType) red;
+ }
}
/*
Contrast enhance image.
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
/*
Form histogram.
*/
+ if (IsImageGray(image,exception) != MagickFalse)
+ (void) SetImageColorspace(image,GRAYColorspace,exception);
status=MagickTrue;
(void) ResetMagickMemory(histogram,0,(MaxMap+1)*GetPixelChannels(image)*
sizeof(*histogram));
Find the histogram boundaries by locating the black/white levels.
*/
number_channels=GetPixelChannels(image);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,1,1)
-#endif
for (i=0; i < (ssize_t) number_channels; i++)
{
double
(void) ResetMagickMemory(stretch_map,0,(MaxMap+1)*GetPixelChannels(image)*
sizeof(*stretch_map));
number_channels=GetPixelChannels(image);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,1,1)
-#endif
for (i=0; i < (ssize_t) number_channels; i++)
{
register ssize_t
stretch_map[GetPixelChannels(image)*j+i]=0.0;
else
if (j > (ssize_t) white[i])
- stretch_map[GetPixelChannels(image)*j+i]=(double)
- QuantumRange;
+ stretch_map[GetPixelChannels(image)*j+i]=(double) QuantumRange;
else
if (black[i] != white[i])
- stretch_map[GetPixelChannels(image)*j+i]=(double)
- ScaleMapToQuantum((double) (MaxMap*(j-black[i])/
- (white[i]-black[i])));
+ stretch_map[GetPixelChannels(image)*j+i]=(double) ScaleMapToQuantum(
+ (double) (MaxMap*(j-black[i])/(white[i]-black[i])));
}
}
if (image->storage_class == PseudoClass)
{
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
{
- i=GetPixelChannelMapChannel(image,RedPixelChannel);
+ i=GetPixelChannelChannel(image,RedPixelChannel);
if (black[i] != white[i])
image->colormap[j].red=stretch_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].red))]+i;
}
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
{
- i=GetPixelChannelMapChannel(image,GreenPixelChannel);
+ i=GetPixelChannelChannel(image,GreenPixelChannel);
if (black[i] != white[i])
image->colormap[j].green=stretch_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].green))]+i;
}
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
{
- i=GetPixelChannelMapChannel(image,BluePixelChannel);
+ i=GetPixelChannelChannel(image,BluePixelChannel);
if (black[i] != white[i])
image->colormap[j].blue=stretch_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].blue))]+i;
}
if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
{
- i=GetPixelChannelMapChannel(image,AlphaPixelChannel);
+ i=GetPixelChannelChannel(image,AlphaPixelChannel);
if (black[i] != white[i])
image->colormap[j].alpha=stretch_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].alpha))]+i;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if (((traits & UpdatePixelTrait) == 0) || (black[i] == white[i]))
continue;
q[i]=ClampToQuantum(stretch_map[GetPixelChannels(image)*
{
#define EnhancePixel(weight) \
mean=((double) r[i]+GetPixelChannel(enhance_image,channel,q))/2.0; \
- distance=(double) r[i]-(double) GetPixelChannel( \
- enhance_image,channel,q); \
- distance_squared=QuantumScale*(2.0*((double) QuantumRange+1.0)+ \
- mean)*distance*distance; \
- if (distance_squared < ((double) QuantumRange*(double) \
- QuantumRange/25.0f)) \
+ distance=(double) r[i]-(double) GetPixelChannel(enhance_image,channel,q); \
+ distance_squared=QuantumScale*(2.0*((double) QuantumRange+1.0)+mean)* \
+ distance*distance; \
+ if (distance_squared < ((double) QuantumRange*(double) QuantumRange/25.0f)) \
{ \
aggregate+=(weight)*r[i]; \
total_weight+=(weight); \
enhance_view=AcquireAuthenticCacheView(enhance_image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,enhance_image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,p) != 0)
+ if (GetPixelMask(image,p) == 0)
{
p+=GetPixelChannels(image);
q+=GetPixelChannels(enhance_image);
mean,
total_weight;
- PixelChannel
- channel;
-
- PixelTrait
- enhance_traits,
- traits;
-
register const Quantum
*restrict r;
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
- enhance_traits=GetPixelChannelMapTraits(enhance_image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
+ PixelTrait enhance_traits=GetPixelChannelTraits(enhance_image,channel);
if ((traits == UndefinedPixelTrait) ||
(enhance_traits == UndefinedPixelTrait))
continue;
}
enhance_view=DestroyCacheView(enhance_view);
image_view=DestroyCacheView(image_view);
+ if (status == MagickFalse)
+ enhance_image=DestroyImage(enhance_image);
return(enhance_image);
}
\f
GetPixelChannels(image)*sizeof(*histogram));
map=(double *) AcquireQuantumMemory(MaxMap+1UL,
GetPixelChannels(image)*sizeof(*map));
- if ((equalize_map == (double *) NULL) ||
- (histogram == (double *) NULL) ||
+ if ((equalize_map == (double *) NULL) || (histogram == (double *) NULL) ||
(map == (double *) NULL))
{
if (map != (double *) NULL)
Integrate the histogram to get the equalization map.
*/
number_channels=GetPixelChannels(image);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,1,1)
-#endif
for (i=0; i < (ssize_t) number_channels; i++)
{
double
(void) ResetMagickMemory(equalize_map,0,(MaxMap+1)*GetPixelChannels(image)*
sizeof(*equalize_map));
number_channels=GetPixelChannels(image);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,1,1)
-#endif
for (i=0; i < (ssize_t) number_channels; i++)
{
register ssize_t
map=(double *) RelinquishMagickMemory(map);
if (image->storage_class == PseudoClass)
{
- PixelChannel
- channel;
-
register ssize_t
j;
{
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
{
- channel=GetPixelChannelMapChannel(image,RedPixelChannel);
+ PixelChannel channel=GetPixelChannelChannel(image,RedPixelChannel);
if (black[channel] != white[channel])
image->colormap[j].red=equalize_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].red))]+
}
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
{
- channel=GetPixelChannelMapChannel(image,GreenPixelChannel);
+ PixelChannel channel=GetPixelChannelChannel(image,
+ GreenPixelChannel);
if (black[channel] != white[channel])
image->colormap[j].green=equalize_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].green))]+
}
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
{
- channel=GetPixelChannelMapChannel(image,BluePixelChannel);
+ PixelChannel channel=GetPixelChannelChannel(image,BluePixelChannel);
if (black[channel] != white[channel])
image->colormap[j].blue=equalize_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].blue))]+
}
if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
{
- channel=GetPixelChannelMapChannel(image,AlphaPixelChannel);
+ PixelChannel channel=GetPixelChannelChannel(image,
+ AlphaPixelChannel);
if (black[channel] != white[channel])
image->colormap[j].alpha=equalize_map[GetPixelChannels(image)*
ScaleQuantumToMap(ClampToQuantum(image->colormap[j].alpha))]+
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if (((traits & UpdatePixelTrait) == 0) || (black[i] == white[i]))
continue;
q[i]=ClampToQuantum(equalize_map[GetPixelChannels(image)*
image->filename);
(void) ResetMagickMemory(gamma_map,0,(MaxMap+1)*sizeof(*gamma_map));
if (gamma != 0.0)
-#if defined(MAGICKCORE_OPENMP_SUPPORT) && (MaxMap > 256)
- #pragma omp parallel for \
- dynamic_number_threads(image,image->columns,1,1)
-#endif
for (i=0; i <= (ssize_t) MaxMap; i++)
gamma_map[i]=ScaleMapToQuantum((double) (MaxMap*pow((double) i/
MaxMap,1.0/gamma)));
for (i=0; i < (ssize_t) image->colors; i++)
{
/*
- Gamma-correct colormap.
+ Gamma-correct colormap.
*/
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].red=(double) gamma_map[
+ image->colormap[i].red=(double) gamma_map[
ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red))];
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
image->colormap[i].green=(double) gamma_map[
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
q[i]=gamma_map[ScaleQuantumToMap(q[i])];
% %
% %
% %
+% G r a y s c a l e I m a g e %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GrayscaleImage() converts the image to grayscale.
+%
+% The format of the GrayscaleImage method is:
+%
+% MagickBooleanType GrayscaleImage(Image *image,
+% const PixelIntensityMethod method ,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+% o method: the pixel intensity method.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+
+static inline MagickRealType MagickMax(const MagickRealType x,
+ const MagickRealType y)
+{
+ if (x > y)
+ return(x);
+ return(y);
+}
+
+static inline MagickRealType MagickMin(const MagickRealType x,
+ const MagickRealType y)
+{
+ if (x < y)
+ return(x);
+ return(y);
+}
+
+MagickExport MagickBooleanType GrayscaleImage(Image *image,
+ const PixelIntensityMethod grayscale,ExceptionInfo *exception)
+{
+#define GrayscaleImageTag "Grayscale/Image"
+
+ CacheView
+ *image_view;
+
+ MagickBooleanType
+ status;
+
+ MagickOffsetType
+ progress;
+
+ ssize_t
+ y;
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ if (image->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+ if (image->storage_class == PseudoClass)
+ {
+ if (SyncImage(image,exception) == MagickFalse)
+ return(MagickFalse);
+ if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+ return(MagickFalse);
+ }
+ /*
+ Grayscale image.
+ */
+ status=MagickTrue;
+ progress=0;
+ image_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static,4) shared(progress,status) \
+ magick_threads(image,image,image->rows,1)
+#endif
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ register Quantum
+ *restrict q;
+
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
+ q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
+ if (q == (Quantum *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ MagickRealType
+ blue,
+ green,
+ red,
+ intensity;
+
+ if (GetPixelMask(image,q) == 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
+ red=(MagickRealType) GetPixelRed(image,q);
+ green=(MagickRealType) GetPixelGreen(image,q);
+ blue=(MagickRealType) GetPixelBlue(image,q);
+ switch (image->intensity)
+ {
+ case AveragePixelIntensityMethod:
+ {
+ intensity=(red+green+blue)/3.0;
+ break;
+ }
+ case BrightnessPixelIntensityMethod:
+ {
+ intensity=MagickMax(MagickMax(red,green),blue);
+ break;
+ }
+ case LightnessPixelIntensityMethod:
+ {
+ intensity=MagickMin(MagickMin(red,green),blue);
+ break;
+ }
+ case Rec601LumaPixelIntensityMethod:
+ {
+ intensity=0.298839f*red+0.586811f*green+0.114350f*blue;
+ break;
+ }
+ case Rec601LuminancePixelIntensityMethod:
+ {
+ if (image->colorspace == sRGBColorspace)
+ {
+ red=DecodePixelGamma(red);
+ green=DecodePixelGamma(green);
+ blue=DecodePixelGamma(blue);
+ }
+ intensity=0.298839f*red+0.586811f*green+0.114350f*blue;
+ break;
+ }
+ case Rec709LumaPixelIntensityMethod:
+ default:
+ {
+ intensity=0.21260f*red+0.71520f*green+0.07220f*blue;
+ break;
+ }
+ case Rec709LuminancePixelIntensityMethod:
+ {
+ if (image->colorspace == sRGBColorspace)
+ {
+ red=DecodePixelGamma(red);
+ green=DecodePixelGamma(green);
+ blue=DecodePixelGamma(blue);
+ }
+ intensity=0.21260f*red+0.71520f*green+0.07220f*blue;
+ break;
+ }
+ case RMSPixelIntensityMethod:
+ {
+ intensity=(MagickRealType) sqrt((double) red*red+green*green+
+ blue*blue);
+ break;
+ }
+ }
+ SetPixelGray(image,ClampToQuantum(intensity),q);
+ q+=GetPixelChannels(image);
+ }
+ if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+ status=MagickFalse;
+ if (image->progress_monitor != (MagickProgressMonitor) NULL)
+ {
+ MagickBooleanType
+ proceed;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp critical (MagickCore_GrayscaleImage)
+#endif
+ proceed=SetImageProgress(image,GrayscaleImageTag,progress++,
+ image->rows);
+ if (proceed == MagickFalse)
+ status=MagickFalse;
+ }
+ }
+ image_view=DestroyCacheView(image_view);
+ return(status);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% H a l d C l u t I m a g e %
% %
% %
% o exception: return any errors or warnings in this structure.
%
*/
-
-static inline size_t MagickMin(const size_t x,const size_t y)
-{
- if (x < y)
- return(x);
- return(y);
-}
-
MagickExport MagickBooleanType HaldClutImage(Image *image,
const Image *hald_image,ExceptionInfo *exception)
{
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
if (IsGrayColorspace(image->colorspace) != MagickFalse)
- (void) TransformImageColorspace(image,RGBColorspace,exception);
- if (image->matte == MagickFalse)
+ (void) TransformImageColorspace(image,sRGBColorspace,exception);
+ if (image->alpha_trait != BlendPixelTrait)
(void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
/*
Hald clut image.
*/
status=MagickTrue;
progress=0;
- length=MagickMin(hald_image->columns,hald_image->rows);
+ length=(size_t) MagickMin((MagickRealType) hald_image->columns,
+ (MagickRealType) hald_image->rows);
for (level=2; (level*level*level) < length; level++) ;
level*=level;
cube_size=level*level;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
(image->colorspace == CMYKColorspace))
SetPixelBlack(image,ClampToQuantum(pixel.black),q);
if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- (image->matte != MagickFalse))
+ (image->alpha_trait == BlendPixelTrait))
SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
q+=GetPixelChannels(image);
}
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
q[i]=ClampToQuantum(LevelPixel(black_point,white_point,gamma,
}
}
image_view=DestroyCacheView(image_view);
- if (status != MagickFalse)
- (void) ClampImage(image,exception);
return(status);
}
\f
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (IsGrayColorspace(image->colorspace) != MagickFalse)
- (void) SetImageColorspace(image,RGBColorspace,exception);
+ (void) SetImageColorspace(image,sRGBColorspace,exception);
if (image->storage_class == PseudoClass)
for (i=0; i < (ssize_t) image->colors; i++)
{
Level colormap.
*/
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].red=(double) LevelizeValue(
- image->colormap[i].red);
+ image->colormap[i].red=(double) LevelizeValue(image->colormap[i].red);
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
image->colormap[i].green=(double) LevelizeValue(
image->colormap[i].green);
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].blue=(double) LevelizeValue(
- image->colormap[i].blue);
+ image->colormap[i].blue=(double) LevelizeValue(image->colormap[i].blue);
if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
image->colormap[i].alpha=(double) LevelizeValue(
image->colormap[i].alpha);
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
q[i]=LevelizeValue(q[i]);
{
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
{
- channel_mask=SetPixelChannelMask(image,RedChannel);
+ channel_mask=SetImageChannelMask(image,RedChannel);
status|=LevelImage(image,black_color->red,white_color->red,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
{
- channel_mask=SetPixelChannelMask(image,GreenChannel);
+ channel_mask=SetImageChannelMask(image,GreenChannel);
status|=LevelImage(image,black_color->green,white_color->green,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
{
- channel_mask=SetPixelChannelMask(image,BlueChannel);
+ channel_mask=SetImageChannelMask(image,BlueChannel);
status|=LevelImage(image,black_color->blue,white_color->blue,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
(image->colorspace == CMYKColorspace))
{
- channel_mask=SetPixelChannelMask(image,BlackChannel);
+ channel_mask=SetImageChannelMask(image,BlackChannel);
status|=LevelImage(image,black_color->black,white_color->black,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- (image->matte == MagickTrue))
+ (image->alpha_trait == BlendPixelTrait))
{
- channel_mask=SetPixelChannelMask(image,AlphaChannel);
+ channel_mask=SetImageChannelMask(image,AlphaChannel);
status|=LevelImage(image,black_color->alpha,white_color->alpha,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
}
else
{
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
{
- channel_mask=SetPixelChannelMask(image,RedChannel);
+ channel_mask=SetImageChannelMask(image,RedChannel);
status|=LevelizeImage(image,black_color->red,white_color->red,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
{
- channel_mask=SetPixelChannelMask(image,GreenChannel);
+ channel_mask=SetImageChannelMask(image,GreenChannel);
status|=LevelizeImage(image,black_color->green,white_color->green,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
{
- channel_mask=SetPixelChannelMask(image,BlueChannel);
+ channel_mask=SetImageChannelMask(image,BlueChannel);
status|=LevelizeImage(image,black_color->blue,white_color->blue,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
(image->colorspace == CMYKColorspace))
{
- channel_mask=SetPixelChannelMask(image,BlackChannel);
+ channel_mask=SetImageChannelMask(image,BlackChannel);
status|=LevelizeImage(image,black_color->black,white_color->black,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- (image->matte == MagickTrue))
+ (image->alpha_trait == BlendPixelTrait))
{
- channel_mask=SetPixelChannelMask(image,AlphaChannel);
+ channel_mask=SetImageChannelMask(image,AlphaChannel);
status|=LevelizeImage(image,black_color->alpha,white_color->alpha,1.0,
exception);
- (void) SetPixelChannelMask(image,channel_mask);
+ (void) SetImageChannelMask(image,channel_mask);
}
}
return(status == 0 ? MagickFalse : MagickTrue);
CacheView
*image_view;
- MagickBooleanType
- status;
-
double
*histogram,
intensity;
+ MagickBooleanType
+ status;
+
ssize_t
black,
white,
*/
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
- histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,
- sizeof(*histogram));
+ histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,sizeof(*histogram));
if (histogram == (double *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
blue=(double) GetPixelBlue(image,q);
switch (colorspace)
{
+ case HCLColorspace:
+ {
+ ModulateHCL(percent_hue,percent_saturation,percent_brightness,
+ &red,&green,&blue);
+ break;
+ }
case HSBColorspace:
{
ModulateHSB(percent_hue,percent_saturation,percent_brightness,
for (i=0; i < (ssize_t) image->colors; i++)
{
/*
- Negate colormap.
+ Negate colormap.
*/
if (grayscale != MagickFalse)
- if ((image->colormap[i].red != image->colormap[i].green) ||
- (image->colormap[i].green != image->colormap[i].blue))
- continue;
+ if ((image->colormap[i].red != image->colormap[i].green) ||
+ (image->colormap[i].green != image->colormap[i].blue))
+ continue;
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].red=QuantumRange-image->colormap[i].red;
+ image->colormap[i].red=QuantumRange-image->colormap[i].red;
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].green=QuantumRange-image->colormap[i].green;
+ image->colormap[i].green=QuantumRange-image->colormap[i].green;
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].blue=QuantumRange-image->colormap[i].blue;
+ image->colormap[i].blue=QuantumRange-image->colormap[i].blue;
}
/*
Negate image.
image_view=AcquireAuthenticCacheView(image,exception);
if (grayscale != MagickFalse)
{
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
-#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
MagickBooleanType
register ssize_t
i;
- if ((GetPixelMask(image,q) != 0) ||
+ if ((GetPixelMask(image,q) == 0) ||
(IsPixelGray(image,q) != MagickFalse))
{
q+=GetPixelChannels(image);
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
q[i]=QuantumRange-q[i];
Negate image.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ #pragma omp parallel for schedule(static,4) shared(progress,status) \
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
q[i]=QuantumRange-q[i];
%
% o sharpen: Increase or decrease image contrast.
%
-% o alpha: strength of the contrast, the larger the number the more
+% o contrast: strength of the contrast, the larger the number the more
% 'threshold-like' it becomes.
%
-% o beta: midpoint of the function as a color value 0 to QuantumRange.
+% o midpoint: midpoint of the function as a color value 0 to QuantumRange.
%
% o exception: return any errors or warnings in this structure.
%
*/
+
+/*
+ ImageMagick 6 has a version of this function which uses LUTs.
+*/
+
+/*
+ Sigmoidal function Sigmoidal with inflexion point moved to b and "slope
+ constant" set to a.
+
+ The first version, based on the hyperbolic tangent tanh, when combined with
+ the scaling step, is an exact arithmetic clone of the the sigmoid function
+ based on the logistic curve. The equivalence is based on the identity
+
+ 1/(1+exp(-t)) = (1+tanh(t/2))/2
+
+ (http://de.wikipedia.org/wiki/Sigmoidfunktion) and the fact that the
+ scaled sigmoidal derivation is invariant under affine transformations of
+ the ordinate.
+
+ The tanh version is almost certainly more accurate and cheaper. The 0.5
+ factor in the argument is to clone the legacy ImageMagick behavior. The
+ reason for making the define depend on atanh even though it only uses tanh
+ has to do with the construction of the inverse of the scaled sigmoidal.
+*/
+#if defined(MAGICKCORE_HAVE_ATANH)
+#define Sigmoidal(a,b,x) ( tanh((0.5*(a))*((x)-(b))) )
+#else
+#define Sigmoidal(a,b,x) ( 1.0/(1.0+exp((a)*((b)-(x)))) )
+#endif
+/*
+ Scaled sigmoidal function:
+
+ ( Sigmoidal(a,b,x) - Sigmoidal(a,b,0) ) /
+ ( Sigmoidal(a,b,1) - Sigmoidal(a,b,0) )
+
+ See http://osdir.com/ml/video.image-magick.devel/2005-04/msg00006.html and
+ http://www.cs.dartmouth.edu/farid/downloads/tutorials/fip.pdf. The limit
+ of ScaledSigmoidal as a->0 is the identity, but a=0 gives a division by
+ zero. This is fixed below by exiting immediately when contrast is small,
+ leaving the image (or colormap) unmodified. This appears to be safe because
+ the series expansion of the logistic sigmoidal function around x=b is
+
+ 1/2-a*(b-x)/4+...
+
+ so that the key denominator s(1)-s(0) is about a/4 (a/2 with tanh).
+*/
+#define ScaledSigmoidal(a,b,x) ( \
+ (Sigmoidal((a),(b),(x))-Sigmoidal((a),(b),0.0)) / \
+ (Sigmoidal((a),(b),1.0)-Sigmoidal((a),(b),0.0)) )
+/*
+ Inverse of ScaledSigmoidal, used for +sigmoidal-contrast. Because b
+ may be 0 or 1, the argument of the hyperbolic tangent (resp. logistic
+ sigmoidal) may be outside of the interval (-1,1) (resp. (0,1)), even
+ when creating a LUT from in gamut values, hence the branching. In
+ addition, HDRI may have out of gamut values.
+ InverseScaledSigmoidal is not a two-sided inverse of ScaledSigmoidal:
+ It is only a right inverse. This is unavoidable.
+*/
+static inline double InverseScaledSigmoidal(const double a,const double b,
+ const double x)
+{
+ const double sig0=Sigmoidal(a,b,0.0);
+ const double sig1=Sigmoidal(a,b,1.0);
+ const double argument=(sig1-sig0)*x+sig0;
+ const double clamped=
+ (
+#if defined(MAGICKCORE_HAVE_ATANH)
+ argument < -1+MagickEpsilon
+ ?
+ -1+MagickEpsilon
+ :
+ ( argument > 1-MagickEpsilon ? 1-MagickEpsilon : argument )
+ );
+ return(b+(2.0/a)*atanh(clamped));
+#else
+ argument < MagickEpsilon
+ ?
+ MagickEpsilon
+ :
+ ( argument > 1-MagickEpsilon ? 1-MagickEpsilon : argument )
+ );
+ return(b-log(1.0/clamped-1.0)/a);
+#endif
+}
+
MagickExport MagickBooleanType SigmoidalContrastImage(Image *image,
const MagickBooleanType sharpen,const double contrast,const double midpoint,
ExceptionInfo *exception)
{
#define SigmoidalContrastImageTag "SigmoidalContrast/Image"
+#define ScaledSig(x) ( ClampToQuantum(QuantumRange* \
+ ScaledSigmoidal(contrast,QuantumScale*midpoint,QuantumScale*(x))) )
+#define InverseScaledSig(x) ( ClampToQuantum(QuantumRange* \
+ InverseScaledSigmoidal(contrast,QuantumScale*midpoint,QuantumScale*(x))) )
CacheView
*image_view;
MagickOffsetType
progress;
- Quantum
- *sigmoidal_map;
-
- register ssize_t
- i;
-
ssize_t
y;
/*
- Sigmoidal with inflexion point moved to b and "slope constant" set to a.
- */
-#define Sigmoidal(a,b,x) ( 1.0/(1.0+exp((a)*((b)-(x)))) )
- /*
- Scaled sigmoidal formula: (1/(1+exp(a*(b-x))) - 1/(1+exp(a*b)))
- /
- (1/(1+exp(a*(b-1))) - 1/(1+exp(a*b))).
- See http://osdir.com/ml/video.image-magick.devel/2005-04/msg00006.html and
- http://www.cs.dartmouth.edu/farid/downloads/tutorials/fip.pdf.
- */
-#define ScaledSigmoidal(a,b,x) ( \
- (Sigmoidal((a),(b),(x))-Sigmoidal((a),(b),0.0)) / \
- (Sigmoidal((a),(b),1.0)-Sigmoidal((a),(b),0.0)) )
-#define InverseScaledSigmoidal(a,b,x) ( \
- (b) - log( -1.0+1.0/((Sigmoidal((a),(b),1.0)-Sigmoidal((a),(b),0.0))*(x)+ \
- Sigmoidal((a),(b),0.0)) ) / (a) )
- /*
- The limit of ScaledSigmoidal as a->0 is the identity, but a=0 gives a
- division by zero. This is fixed below by hardwiring the identity when a is
- small. This would appear to be safe because the series expansion of the
- sigmoidal function around x=b is 1/2-a*(b-x)/4+... so that s(1)-s(0) is
- about a/4.
- */
-
- /*
- Allocate and initialize sigmoidal maps.
+ Convenience macros.
*/
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- sigmoidal_map=(Quantum *) AcquireQuantumMemory(MaxMap+1UL,
- sizeof(*sigmoidal_map));
- if (sigmoidal_map == (Quantum *) NULL)
- ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
- image->filename);
- (void) ResetMagickMemory(sigmoidal_map,0,(MaxMap+1)*sizeof(*sigmoidal_map));
- if (contrast<4.0*MagickEpsilon)
- for (i=0; i <= (ssize_t) MaxMap; i++)
- sigmoidal_map[i]=ScaleMapToQuantum((double) i);
- else if (sharpen != MagickFalse)
- for (i=0; i <= (ssize_t) MaxMap; i++)
- sigmoidal_map[i]=ScaleMapToQuantum( (double) (MaxMap*
- ScaledSigmoidal(contrast,QuantumScale*midpoint,(double) i/MaxMap)));
- else
- for (i=0; i <= (ssize_t) MaxMap; i++)
- sigmoidal_map[i]=ScaleMapToQuantum((double) (MaxMap*
- InverseScaledSigmoidal(contrast,QuantumScale*midpoint,
- (double) i/MaxMap)));
+ /*
+ Side effect: may clamp values unless contrast<MagickEpsilon, in which
+ case nothing is done.
+ */
+ if (contrast < MagickEpsilon)
+ return(MagickTrue);
+ /*
+ Sigmoidal-contrast enhance colormap.
+ */
if (image->storage_class == PseudoClass)
- for (i=0; i < (ssize_t) image->colors; i++)
{
- /*
- Sigmoidal-contrast enhance colormap.
- */
- if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].red=(double) ClampToQuantum((double) sigmoidal_map[
- ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red))]);
- if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].green=(double) ClampToQuantum((double) sigmoidal_map[
- ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green))]);
- if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].blue=(double) ClampToQuantum((double) sigmoidal_map[
- ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue))]);
- if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].alpha=(double) ClampToQuantum((double) sigmoidal_map[
- ScaleQuantumToMap(ClampToQuantum(image->colormap[i].alpha))]);
+ register ssize_t
+ i;
+
+ if (sharpen != MagickFalse)
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].red=ScaledSig(image->colormap[i].red);
+ if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].green=ScaledSig(image->colormap[i].green);
+ if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].blue=ScaledSig(image->colormap[i].blue);
+ if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].alpha=ScaledSig(image->colormap[i].alpha);
+ }
+ else
+ for (i=0; i < (ssize_t) image->colors; i++)
+ {
+ if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].red=InverseScaledSig(image->colormap[i].red);
+ if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].green=InverseScaledSig(image->colormap[i].green);
+ if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].blue=InverseScaledSig(image->colormap[i].blue);
+ if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
+ image->colormap[i].alpha=InverseScaledSig(image->colormap[i].alpha);
+ }
}
/*
Sigmoidal-contrast enhance image.
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ magick_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (GetPixelMask(image,q) != 0)
+ if (GetPixelMask(image,q) == 0)
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- traits;
-
- channel=GetPixelChannelMapChannel(image,i);
- traits=GetPixelChannelMapTraits(image,channel);
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
- q[i]=ClampToQuantum((double) sigmoidal_map[ScaleQuantumToMap(q[i])]);
+ if (sharpen != MagickFalse)
+ q[i]=ScaledSig(q[i]);
+ else
+ q[i]=InverseScaledSig(q[i]);
}
q+=GetPixelChannels(image);
}
}
}
image_view=DestroyCacheView(image_view);
- sigmoidal_map=(Quantum *) RelinquishMagickMemory(sigmoidal_map);
return(status);
}