% July 1992 %
% %
% %
-% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2012 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/color.h"
#include "MagickCore/color-private.h"
#include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
#include "MagickCore/composite-private.h"
#include "MagickCore/enhance.h"
#include "MagickCore/exception.h"
#include "MagickCore/monitor.h"
#include "MagickCore/monitor-private.h"
#include "MagickCore/option.h"
+#include "MagickCore/pixel.h"
#include "MagickCore/pixel-accessor.h"
#include "MagickCore/quantum.h"
#include "MagickCore/quantum-private.h"
ChannelType
channel_mask;
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
if ((traits & UpdatePixelTrait) == 0)
continue;
channel_mask=SetPixelChannelMask(image,(ChannelType) (1 << i));
*clut_view,
*image_view;
- double
- *clut_map;
-
MagickBooleanType
status;
MagickOffsetType
progress;
+ PixelInfo
+ *clut_map;
+
register ssize_t
- x;
+ i;
- ssize_t
- adjust,
+ ssize_t adjust,
y;
assert(image != (Image *) NULL);
assert(clut_image->signature == MagickSignature);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
- clut_map=(double *) AcquireQuantumMemory(MaxMap+1UL,GetPixelChannels(image)*
- sizeof(*clut_map));
- if (clut_map == (double *) NULL)
+ if (IsGrayColorspace(image->colorspace) != MagickFalse)
+ (void) TransformImageColorspace(image,sRGBColorspace,exception);
+ clut_map=(PixelInfo *) AcquireQuantumMemory(MaxMap+1UL,sizeof(*clut_map));
+ if (clut_map == (PixelInfo *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
/*
status=MagickTrue;
progress=0;
adjust=(ssize_t) (clut_image->interpolate == IntegerInterpolatePixel ? 0 : 1);
- clut_view=AcquireCacheView(clut_image);
+ clut_view=AcquireVirtualCacheView(clut_image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4)
+ #pragma omp parallel for schedule(static,4)
#endif
- for (x=0; x <= (ssize_t) MaxMap; x++)
+ for (i=0; i <= (ssize_t) MaxMap; i++)
{
- register ssize_t
- i;
-
- for (i=0; i < (ssize_t) GetPixelChannels(clut_image); i++)
- (void) InterpolatePixelChannel(clut_image,clut_view,(PixelChannel) i,
- method,QuantumScale*x*(clut_image->columns-adjust),QuantumScale*x*
- (clut_image->rows-adjust),clut_map+x*GetPixelChannels(clut_image)+i,
- exception);
+ GetPixelInfo(clut_image,clut_map+i);
+ (void) InterpolatePixelInfo(clut_image,clut_view,method,
+ QuantumScale*i*(clut_image->columns-adjust),QuantumScale*i*
+ (clut_image->rows-adjust),clut_map+i,exception);
}
clut_view=DestroyCacheView(clut_view);
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
+ PixelInfo
+ pixel;
+
register Quantum
*restrict q;
status=MagickFalse;
continue;
}
+ GetPixelInfo(image,&pixel);
for (x=0; x < (ssize_t) image->columns; x++)
{
- register ssize_t
- i;
-
- for (i=0; i < (ssize_t) GetPixelChannels(clut_image); i++)
- {
- PixelChannel
- channel;
-
- PixelTrait
- clut_traits,
- traits;
-
- clut_traits=GetPixelChannelMapTraits(clut_image,(PixelChannel) i);
- channel=GetPixelChannelMapChannel(clut_image,(PixelChannel) i);
- traits=GetPixelChannelMapTraits(clut_image,channel);
- if ((traits == UndefinedPixelTrait) ||
- (clut_traits == UndefinedPixelTrait) ||
- ((traits & UpdatePixelTrait) == 0))
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
continue;
- SetPixelChannel(clut_image,channel,ClampToQuantum(clut_map[
- ScaleQuantumToMap(GetPixelChannel(clut_image,channel,q))*
- GetPixelChannels(clut_image)+channel]),q);
- }
+ }
+ GetPixelInfoPixel(image,q,&pixel);
+ pixel.red=clut_map[ScaleQuantumToMap(pixel.red)].red;
+ pixel.green=clut_map[ScaleQuantumToMap(pixel.green)].green;
+ pixel.blue=clut_map[ScaleQuantumToMap(pixel.blue)].blue;
+ pixel.black=clut_map[ScaleQuantumToMap(pixel.black)].black;
+ pixel.alpha=clut_map[ScaleQuantumToMap(pixel.alpha)].alpha;
+ SetPixelInfoPixel(image,&pixel,q);
q+=GetPixelChannels(image);
}
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_ClutImage)
+ #pragma omp critical (MagickCore_ClutImage)
#endif
proceed=SetImageProgress(image,ClutImageTag,progress++,image->rows);
if (proceed == MagickFalse)
}
}
image_view=DestroyCacheView(image_view);
- clut_map=(double *) RelinquishMagickMemory(clut_map);
+ clut_map=(PixelInfo *) RelinquishMagickMemory(clut_map);
if ((clut_image->matte != MagickFalse) &&
((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0))
(void) SetImageAlphaChannel(image,ActivateAlphaChannel,exception);
content=GetXMLTreeContent(saturation);
p=(const char *) content;
GetMagickToken(p,&p,token);
- color_correction.saturation=StringToDouble(token,
- (char **) NULL);
+ color_correction.saturation=StringToDouble(token,(char **) NULL);
}
}
ccc=DestroyXMLTree(ccc);
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4)
+ #pragma omp parallel for schedule(static,4)
#endif
for (i=0; i <= (ssize_t) MaxMap; i++)
{
Apply transfer function to colormap.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
{
luma=0.2126*image->colormap[i].red+0.7152*image->colormap[i].green+
0.0722*image->colormap[i].blue;
- image->colormap[i].red=luma+color_correction.saturation*
- cdl_map[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[ScaleQuantumToMap(ClampToQuantum(
- image->colormap[i].blue))].blue-luma;
+ image->colormap[i].red=luma+color_correction.saturation*cdl_map[
+ 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[
+ ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue))].blue-
+ luma;
}
}
/*
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_ColorDecisionListImageChannel)
+ #pragma omp critical (MagickCore_ColorDecisionListImageChannel)
#endif
proceed=SetImageProgress(image,ColorDecisionListCorrectImageTag,
progress++,image->rows);
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_ContrastImage)
+ #pragma omp critical (MagickCore_ContrastImage)
#endif
proceed=SetImageProgress(image,ContrastImageTag,progress++,image->rows);
if (proceed == MagickFalse)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ContrastStretchImage() is a simple image enhancement technique that attempts
-% to improve the contrast in an image by `stretching' the range of intensity
+% to improve the contrast in an image by 'stretching' the range of intensity
% values it contains to span a desired range of values. It differs from the
% more sophisticated histogram equalization in that it can only apply a
% linear scaling function to the image pixel values. As a result the
-% `enhancement' is less harsh.
+% 'enhancement' is less harsh.
%
% The format of the ContrastStretchImage method is:
%
register ssize_t
i;
+ size_t
+ number_channels;
+
ssize_t
y;
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
black=(double *) AcquireQuantumMemory(GetPixelChannels(image),sizeof(*black));
white=(double *) AcquireQuantumMemory(GetPixelChannels(image),sizeof(*white));
- histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,
- GetPixelChannels(image)*sizeof(*histogram));
+ histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,GetPixelChannels(image)*
+ sizeof(*histogram));
stretch_map=(double *) AcquireQuantumMemory(MaxMap+1UL,
GetPixelChannels(image)*sizeof(*stretch_map));
if ((black == (double *) NULL) || (white == (double *) NULL) ||
status=MagickTrue;
(void) ResetMagickMemory(histogram,0,(MaxMap+1)*GetPixelChannels(image)*
sizeof(*histogram));
- image_view=AcquireCacheView(image);
+ image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
register const Quantum
p+=GetPixelChannels(image);
}
}
+ image_view=DestroyCacheView(image_view);
/*
Find the histogram boundaries by locating the black/white levels.
*/
+ number_channels=GetPixelChannels(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ for (i=0; i < (ssize_t) number_channels; i++)
{
double
intensity;
*/
(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(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ for (i=0; i < (ssize_t) number_channels; i++)
{
register ssize_t
j;
Stretch-contrast colormap.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (j=0; j < (ssize_t) image->colors; j++)
{
*/
status=MagickTrue;
progress=0;
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if (((traits & UpdatePixelTrait) != 0) && (black[i] != white[i]))
- q[i]=ClampToQuantum(stretch_map[GetPixelChannels(image)*
- ScaleQuantumToMap(q[i])+i]);
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if (((traits & UpdatePixelTrait) == 0) || (black[i] == white[i]))
+ continue;
+ q[i]=ClampToQuantum(stretch_map[GetPixelChannels(image)*
+ ScaleQuantumToMap(q[i])+i]);
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_ContrastStretchImage)
+ #pragma omp critical (MagickCore_ContrastStretchImage)
#endif
proceed=SetImageProgress(image,ContrastStretchImageTag,progress++,
image->rows);
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
- enhance_view=AcquireCacheView(enhance_image);
+ image_view=AcquireVirtualCacheView(image,exception);
+ enhance_view=AcquireAuthenticCacheView(enhance_image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,p) != 0)
+ {
+ p+=GetPixelChannels(image);
+ q+=GetPixelChannels(enhance_image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
MagickRealType
register const Quantum
*restrict r;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
enhance_traits=GetPixelChannelMapTraits(enhance_image,channel);
if ((traits == UndefinedPixelTrait) ||
(enhance_traits == UndefinedPixelTrait))
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_EnhanceImage)
+ #pragma omp critical (MagickCore_EnhanceImage)
#endif
proceed=SetImageProgress(image,EnhanceImageTag,progress++,image->rows);
if (proceed == MagickFalse)
register ssize_t
i;
+ size_t
+ number_channels;
+
ssize_t
y;
status=MagickTrue;
(void) ResetMagickMemory(histogram,0,(MaxMap+1)*GetPixelChannels(image)*
sizeof(*histogram));
- image_view=AcquireCacheView(image);
+ image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
register const Quantum
p+=GetPixelChannels(image);
}
}
+ image_view=DestroyCacheView(image_view);
/*
Integrate the histogram to get the equalization map.
*/
+ number_channels=GetPixelChannels(image);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ for (i=0; i < (ssize_t) number_channels; i++)
{
MagickRealType
intensity;
}
(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(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ for (i=0; i < (ssize_t) number_channels; i++)
{
register ssize_t
j;
Equalize colormap.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (j=0; j < (ssize_t) image->colors; j++)
{
Equalize image.
*/
progress=0;
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if (((traits & UpdatePixelTrait) != 0) && (black[i] != white[i]))
- q[i]=ClampToQuantum(equalize_map[GetPixelChannels(image)*
- ScaleQuantumToMap(q[i])+i]);
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if (((traits & UpdatePixelTrait) == 0) || (black[i] == white[i]))
+ continue;
+ q[i]=ClampToQuantum(equalize_map[GetPixelChannels(image)*
+ ScaleQuantumToMap(q[i])+i]);
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_EqualizeImage)
+ #pragma omp critical (MagickCore_EqualizeImage)
#endif
proceed=SetImageProgress(image,EqualizeImageTag,progress++,image->rows);
if (proceed == MagickFalse)
CacheView
*image_view;
- double
- *gamma_map;
-
MagickBooleanType
status;
MagickOffsetType
progress;
+ Quantum
+ *gamma_map;
+
register ssize_t
i;
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (gamma == 1.0)
return(MagickTrue);
- gamma_map=(double *) AcquireQuantumMemory(MaxMap+1UL,sizeof(*gamma_map));
- if (gamma_map == (double *) NULL)
+ gamma_map=(Quantum *) AcquireQuantumMemory(MaxMap+1UL,sizeof(*gamma_map));
+ if (gamma_map == (Quantum *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
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
+ #pragma omp parallel for
#endif
for (i=0; i <= (ssize_t) MaxMap; i++)
- gamma_map[i]=(MagickRealType) ScaleMapToQuantum((
- MagickRealType) (MaxMap*pow((double) i/MaxMap,1.0/gamma)));
+ gamma_map[i]=ScaleMapToQuantum((MagickRealType) (MaxMap*pow((double) i/
+ MaxMap,1.0/gamma)));
if (image->storage_class == PseudoClass)
{
/*
Gamma-correct colormap.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static) shared(progress,status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
{
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].red=gamma_map[
+ image->colormap[i].red=(MagickRealType) gamma_map[
ScaleQuantumToMap(ClampToQuantum(image->colormap[i].red))];
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].green=gamma_map[
+ image->colormap[i].green=(MagickRealType) gamma_map[
ScaleQuantumToMap(ClampToQuantum(image->colormap[i].green))];
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].blue=gamma_map[
+ image->colormap[i].blue=(MagickRealType) gamma_map[
ScaleQuantumToMap(ClampToQuantum(image->colormap[i].blue))];
if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].alpha=gamma_map[
+ image->colormap[i].alpha=(MagickRealType) gamma_map[
ScaleQuantumToMap(ClampToQuantum(image->colormap[i].alpha))];
}
}
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if ((traits & UpdatePixelTrait) != 0)
- q[i]=ClampToQuantum(gamma_map[ScaleQuantumToMap(q[i])]);
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits & UpdatePixelTrait) == 0)
+ continue;
+ q[i]=gamma_map[ScaleQuantumToMap(q[i])];
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_GammaImage)
+ #pragma omp critical (MagickCore_GammaImage)
#endif
proceed=SetImageProgress(image,GammaCorrectImageTag,progress++,
image->rows);
}
}
image_view=DestroyCacheView(image_view);
- gamma_map=(double *) RelinquishMagickMemory(gamma_map);
+ gamma_map=(Quantum *) RelinquishMagickMemory(gamma_map);
if (image->gamma != 0.0)
image->gamma*=gamma;
return(status);
assert(hald_image->signature == MagickSignature);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
+ if (IsGrayColorspace(image->colorspace) != MagickFalse)
+ (void) TransformImageColorspace(image,sRGBColorspace,exception);
if (image->matte == MagickFalse)
(void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
/*
cube_size=level*level;
width=(double) hald_image->columns;
GetPixelInfo(hald_image,&zero);
- image_view=AcquireCacheView(image);
- hald_view=AcquireCacheView(hald_image);
+ hald_view=AcquireVirtualCacheView(hald_image,exception);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_HaldClutImage)
+ #pragma omp critical (MagickCore_HaldClutImage)
#endif
proceed=SetImageProgress(image,HaldClutImageTag,progress++,image->rows);
if (proceed == MagickFalse)
% o exception: return any errors or warnings in this structure.
%
*/
+
+static inline MagickRealType LevelPixel(const double black_point,
+ const double white_point,const double gamma,const MagickRealType pixel)
+{
+ double
+ level_pixel,
+ scale;
+
+ if (pixel < black_point)
+ return(0.0);
+ if (pixel > white_point)
+ return((MagickRealType) QuantumRange);
+ scale=(white_point != black_point) ? 1.0/(white_point-black_point) : 1.0;
+ level_pixel=(MagickRealType) QuantumRange*pow(scale*((double) pixel-
+ black_point),1.0/gamma);
+ return(level_pixel);
+}
+
MagickExport MagickBooleanType LevelImage(Image *image,const double black_point,
const double white_point,const double gamma,ExceptionInfo *exception)
{
#define LevelImageTag "Level/Image"
-#define LevelQuantum(x) (ClampToQuantum((MagickRealType) QuantumRange* \
- pow(scale*((double) (x)-black_point),1.0/gamma)))
CacheView
*image_view;
MagickOffsetType
progress;
- register double
- scale;
-
register ssize_t
i;
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- scale=(white_point != black_point) ? 1.0/(white_point-black_point) : 1.0;
if (image->storage_class == PseudoClass)
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
{
Level colormap.
*/
if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].red=(double) LevelQuantum(
- image->colormap[i].red);
+ image->colormap[i].red=(double) ClampToQuantum(LevelPixel(black_point,
+ white_point,gamma,image->colormap[i].red));
if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].green=(double) LevelQuantum(
- image->colormap[i].green);
+ image->colormap[i].green=(double) ClampToQuantum(LevelPixel(black_point,
+ white_point,gamma,image->colormap[i].green));
if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].blue=(double) LevelQuantum(
- image->colormap[i].blue);
+ image->colormap[i].blue=(double) ClampToQuantum(LevelPixel(black_point,
+ white_point,gamma,image->colormap[i].blue));
if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
- image->colormap[i].alpha=(double) LevelQuantum(
- image->colormap[i].alpha);
+ image->colormap[i].alpha=(double) ClampToQuantum(LevelPixel(black_point,
+ white_point,gamma,image->colormap[i].alpha));
}
/*
Level image.
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if ((traits == UndefinedPixelTrait) ||
- ((traits & UpdatePixelTrait) == 0))
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits & UpdatePixelTrait) == 0)
continue;
- q[i]=LevelQuantum(q[i]);
+ q[i]=ClampToQuantum(LevelPixel(black_point,white_point,gamma,
+ (MagickRealType) q[i]));
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_LevelImage)
+ #pragma omp critical (MagickCore_LevelImage)
#endif
proceed=SetImageProgress(image,LevelImageTag,progress++,image->rows);
if (proceed == MagickFalse)
% LevelizeImage() can be called with by using a +level command line
% API option, or using a '!' on a -level or LevelImage() geometry string.
%
-% It can be used for example de-contrast a greyscale image to the exact
-% levels specified. Or by using specific levels for each channel of an image
-% you can convert a gray-scale image to any linear color gradient, according
-% to those levels.
+% It can be used to de-contrast a greyscale image to the exact levels
+% specified. Or by using specific levels for each channel of an image you
+% can convert a gray-scale image to any linear color gradient, according to
+% those levels.
%
% The format of the LevelizeImage method is:
%
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (image->storage_class == PseudoClass)
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
{
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if ((traits & UpdatePixelTrait) != 0)
- q[i]=LevelizeValue(q[i]);
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits & UpdatePixelTrait) == 0)
+ continue;
+ q[i]=LevelizeValue(q[i]);
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_LevelizeImage)
+ #pragma omp critical (MagickCore_LevelizeImage)
#endif
proceed=SetImageProgress(image,LevelizeImageTag,progress++,image->rows);
if (proceed == MagickFalse)
Form histogram.
*/
(void) ResetMagickMemory(histogram,0,(MaxMap+1)*sizeof(*histogram));
- image_view=AcquireCacheView(image);
+ image_view=AcquireVirtualCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
register const Quantum
Modulate colormap.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
switch (colorspace)
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_ModulateImage)
+ #pragma omp critical (MagickCore_ModulateImage)
#endif
proceed=SetImageProgress(image,ModulateImageTag,progress++,image->rows);
if (proceed == MagickFalse)
Negate colormap.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static) shared(progress,status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
{
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
if (grayscale != MagickFalse)
{
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
- if (IsPixelGray(image,q) != MagickFalse)
+ if ((GetPixelMask(image,q) != 0) ||
+ (IsPixelGray(image,q) != MagickFalse))
{
q+=GetPixelChannels(image);
continue;
}
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if ((traits & UpdatePixelTrait) != 0)
- q[i]=QuantumRange-q[i];
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits & UpdatePixelTrait) == 0)
+ continue;
+ q[i]=QuantumRange-q[i];
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_NegateImage)
+ #pragma omp critical (MagickCore_NegateImage)
#endif
proceed=SetImageProgress(image,NegateImageTag,progress++,
image->rows);
Negate image.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if ((traits & UpdatePixelTrait) != 0)
- q[i]=QuantumRange-q[i];
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits & UpdatePixelTrait) == 0)
+ continue;
+ q[i]=QuantumRange-q[i];
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_NegateImage)
+ #pragma omp critical (MagickCore_NegateImage)
#endif
proceed=SetImageProgress(image,NegateImageTag,progress++,image->rows);
if (proceed == MagickFalse)
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% NormalizeImage() enhances the contrast of a color image by mapping the
-% darkest 2 percent of all pixel to black and the brightest 1 percent to white.
+% The NormalizeImage() method enhances the contrast of a color image by
+% mapping the darkest 2 percent of all pixel to black and the brightest
+% 1 percent to white.
%
% The format of the NormalizeImage method is:
%
image->filename);
(void) ResetMagickMemory(sigmoidal_map,0,(MaxMap+1)*sizeof(*sigmoidal_map));
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static) shared(progress,status)
#endif
for (i=0; i <= (ssize_t) MaxMap; i++)
{
if (sharpen != MagickFalse)
{
+#define sigmoidal(a,b,x) (1/(1+exp((a)*((b)-(x)))))
+#if 1
+ /* Simpilified function scaling,
+ * with better 'contrast=0' or 'flatline' handling (greyscale)
+ */
+ double
+ u0 = sigmoidal(contrast,QuantumScale*midpoint,0.0),
+ u1 = sigmoidal(contrast,QuantumScale*midpoint,1.0);
+ sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum(
+ (MagickRealType)(MaxMap*(
+ (sigmoidal(contrast,QuantumScale*midpoint,(double)i/MaxMap)
+ -(u0+u1)/2.0)/(u1-u0+MagickEpsilon)+0.5) ));
+#else
+ /* Scaled sigmoidal formula...
+ (1/(1+exp(a*(b-u))) - 1/(1+exp(a))) /
+ (1/(1+exp(a*(b-1)))/(1+exp(a)))) */
sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum((MagickRealType)
(MaxMap*((1.0/(1.0+exp(contrast*(midpoint/(double) QuantumRange-
- (double) i/MaxMap))))-(1.0/(1.0+exp(contrast*(midpoint/(double)
- QuantumRange)))))/((1.0/(1.0+exp(contrast*(midpoint/(double)
- QuantumRange-1.0))))-(1.0/(1.0+exp(contrast*(midpoint/(double)
- QuantumRange)))))+0.5));
+ (double) i/MaxMap))))-(1.0/(1.0+exp(contrast*(midpoint/
+ (double) QuantumRange)))))/((1.0/(1.0+exp(contrast*(midpoint/
+ (double) QuantumRange-1.0))))-(1.0/(1.0+exp(contrast*(midpoint/
+ (double) QuantumRange)))))+0.5));
+#endif
continue;
}
+#if 1
+ {
+ /* Inverse -- See
+ http://osdir.com/ml/video.image-magick.devel/2005-04/msg00006.html
+ */
+ double
+ min = sigmoidal(contrast,1.0,0.0),
+ max = sigmoidal(contrast,QuantumScale*midpoint,1.0),
+ xi = min+(double)i/MaxMap*(max-min);
+ sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum(
+ (MagickRealType)(MaxMap*(
+ QuantumScale*midpoint-log((1-xi)/xi)/contrast) ));
+ }
+#else
+ /* expanded form of the above */
sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum((MagickRealType)
- (MaxMap*(QuantumScale*midpoint-log((1.0-(1.0/(1.0+exp(midpoint/(double)
- QuantumRange*contrast))+((double) i/MaxMap)*((1.0/(1.0+exp(contrast*(
- midpoint/(double) QuantumRange-1.0))))-(1.0/(1.0+exp(midpoint/(double)
- QuantumRange*contrast))))))/(1.0/(1.0+exp(midpoint/(double) QuantumRange*
- contrast))+((double) i/MaxMap)*((1.0/(1.0+exp(contrast*(midpoint/(double)
- QuantumRange-1.0))))-(1.0/(1.0+exp(midpoint/(double) QuantumRange*
- contrast))))))/contrast)));
+ (MaxMap*(QuantumScale*midpoint-log((1.0-(1.0/(1.0+exp(midpoint/
+ (double) QuantumRange*contrast))+((double) i/MaxMap)*((1.0/
+ (1.0+exp(contrast*(midpoint/(double) QuantumRange-1.0))))-(1.0/
+ (1.0+exp(midpoint/(double) QuantumRange*contrast))))))/
+ (1.0/(1.0+exp(midpoint/(double) QuantumRange*contrast))+
+ ((double) i/MaxMap)*((1.0/(1.0+exp(contrast*(midpoint/
+ (double) QuantumRange-1.0))))-(1.0/(1.0+exp(midpoint/
+ (double) QuantumRange*contrast))))))/contrast)));
+#endif
}
if (image->storage_class == PseudoClass)
{
Sigmoidal-contrast enhance colormap.
*/
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
{
*/
status=MagickTrue;
progress=0;
- image_view=AcquireCacheView(image);
+ image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic,4) shared(progress,status)
+ #pragma omp parallel for schedule(static,4) shared(progress,status)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register ssize_t
i;
+ if (GetPixelMask(image,q) != 0)
+ {
+ q+=GetPixelChannels(image);
+ continue;
+ }
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
+ PixelChannel
+ channel;
+
PixelTrait
traits;
- traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
- if ((traits & UpdatePixelTrait) != 0)
- q[i]=ClampToQuantum(sigmoidal_map[ScaleQuantumToMap(q[i])]);
+ channel=GetPixelChannelMapChannel(image,i);
+ traits=GetPixelChannelMapTraits(image,channel);
+ if ((traits & UpdatePixelTrait) == 0)
+ continue;
+ q[i]=ClampToQuantum(sigmoidal_map[ScaleQuantumToMap(q[i])]);
}
q+=GetPixelChannels(image);
}
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_SigmoidalContrastImage)
+ #pragma omp critical (MagickCore_SigmoidalContrastImage)
#endif
proceed=SetImageProgress(image,SigmoidalContrastImageTag,progress++,
image->rows);