% July 1992 %
% %
% %
-% Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2019 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 %
% obtain a copy of the License at %
% %
-% https://www.imagemagick.org/script/license.php %
+% https://imagemagick.org/script/license.php %
% %
% Unless required by applicable law or agreed to in writing, software %
% distributed under the License is distributed on an "AS IS" BASIS, %
Include declarations.
*/
#include "MagickCore/studio.h"
+#include "MagickCore/artifact.h"
#include "MagickCore/attribute.h"
#include "MagickCore/cache-view.h"
#include "MagickCore/color.h"
#include "MagickCore/quantum-private.h"
#include "MagickCore/resource_.h"
#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
#include "MagickCore/thread-private.h"
\f
/*
status=MagickTrue;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(status) \
+ #pragma omp parallel for schedule(static) shared(status) \
magick_number_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
MagickBooleanType
proceed;
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_AssignImageColors)
-#endif
proceed=SetImageProgress(image,AssignImageTag,(MagickOffsetType) y,
image->rows);
if (proceed == MagickFalse)
ClampPixel(pixel.alpha);
else
node_info->total_color.alpha+=count*QuantumScale*
- ClampPixel(OpaqueAlpha);
+ ClampPixel((MagickRealType) OpaqueAlpha);
p+=count*GetPixelChannels(image);
}
if (cube_info->colors > cube_info->maximum_colors)
ClampPixel(pixel.alpha);
else
node_info->total_color.alpha+=count*QuantumScale*
- ClampPixel(OpaqueAlpha);
+ ClampPixel((MagickRealType) OpaqueAlpha);
p+=count*GetPixelChannels(image);
}
proceed=SetImageProgress(image,ClassifyImageTag,(MagickOffsetType) y,
CacheView
*image_view;
+ const char
+ *artifact;
+
+ double
+ amount;
+
DoublePixelPacket
**pixels;
if (pixels == (DoublePixelPacket **) NULL)
return(MagickFalse);
status=MagickTrue;
+ amount=1.0;
+ artifact=GetImageArtifact(image,"dither:diffusion-amount");
+ if (artifact != (const char *) NULL)
+ amount=StringToDoubleInterval(artifact,1.0);
image_view=AcquireAuthenticCacheView(image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
AssociateAlphaPixel(image,&cube,q+u*GetPixelChannels(image),&pixel);
if (x > 0)
{
- pixel.red+=7*current[u-v].red/16;
- pixel.green+=7*current[u-v].green/16;
- pixel.blue+=7*current[u-v].blue/16;
+ pixel.red+=7.0*amount*current[u-v].red/16;
+ pixel.green+=7.0*amount*current[u-v].green/16;
+ pixel.blue+=7.0*amount*current[u-v].blue/16;
if (cube.associate_alpha != MagickFalse)
- pixel.alpha+=7*current[u-v].alpha/16;
+ pixel.alpha+=7.0*amount*current[u-v].alpha/16;
}
if (y > 0)
{
if (cube.associate_alpha != MagickFalse)
pixel.alpha+=previous[u+v].alpha/16;
}
- pixel.red+=5*previous[u].red/16;
- pixel.green+=5*previous[u].green/16;
- pixel.blue+=5*previous[u].blue/16;
+ pixel.red+=5.0*amount*previous[u].red/16;
+ pixel.green+=5.0*amount*previous[u].green/16;
+ pixel.blue+=5.0*amount*previous[u].blue/16;
if (cube.associate_alpha != MagickFalse)
- pixel.alpha+=5*previous[u].alpha/16;
+ pixel.alpha+=5.0*amount*previous[u].alpha/16;
if (x > 0)
{
- pixel.red+=3*previous[u-v].red/16;
- pixel.green+=3*previous[u-v].green/16;
- pixel.blue+=3*previous[u-v].blue/16;
+ pixel.red+=3.0*amount*previous[u-v].red/16;
+ pixel.green+=3.0*amount*previous[u-v].green/16;
+ pixel.blue+=3.0*amount*previous[u-v].blue/16;
if (cube.associate_alpha != MagickFalse)
- pixel.alpha+=3*previous[u-v].alpha/16;
+ pixel.alpha+=3.0*amount*previous[u-v].alpha/16;
}
}
pixel.red=(double) ClampPixel(pixel.red);
/*
Distribute quantization error along a Hilbert curve.
*/
- (void) memset(cube_info->error,0,ErrorQueueLength*
- sizeof(*cube_info->error));
+ (void) memset(cube_info->error,0,ErrorQueueLength*sizeof(*cube_info->error));
cube_info->x=0;
cube_info->y=0;
i=MagickMax((ssize_t) image->columns,(ssize_t) image->rows);
/*
Initialize color cache.
*/
- (void) memset(cube_info->cache,(-1),sizeof(*cube_info->cache)*
- length);
+ (void) memset(cube_info->cache,(-1),sizeof(*cube_info->cache)*length);
/*
Distribute weights along a curve of exponential decay.
*/
mean_error,
mean_error_per_pixel;
- size_t
- index;
-
ssize_t
+ index,
y;
assert(image != (Image *) NULL);
break;
for (x=0; x < (ssize_t) image->columns; x++)
{
- index=GetPixelIndex(image,p);
+ index=(ssize_t) GetPixelIndex(image,p);
if (image->alpha_trait == BlendPixelTrait)
{
alpha=(double) (QuantumScale*GetPixelAlpha(image,p));
const DitherMethod dither_method,ExceptionInfo *exception)
{
#define PosterizeImageTag "Posterize/Image"
-#define PosterizePixel(pixel) (Quantum) (QuantumRange*(MagickRound( \
- QuantumScale*pixel*(levels-1)))/MagickMax((ssize_t) levels-1,1))
+#define PosterizePixel(pixel) ClampToQuantum((MagickRealType) QuantumRange*( \
+ MagickRound(QuantumScale*pixel*(levels-1)))/MagickMax((ssize_t) levels-1,1))
CacheView
*image_view;
assert(exception->signature == MagickCoreSignature);
if (image->storage_class == PseudoClass)
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
+ #pragma omp parallel for schedule(static) shared(progress,status) \
magick_number_threads(image,image,image->colors,1)
#endif
for (i=0; i < (ssize_t) image->colors; i++)
progress=0;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
+ #pragma omp parallel for schedule(static) shared(progress,status) \
magick_number_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_PosterizeImage)
+ #pragma omp atomic
#endif
- proceed=SetImageProgress(image,PosterizeImageTag,progress++,
- image->rows);
+ progress++;
+ proceed=SetImageProgress(image,PosterizeImageTag,progress,image->rows);
if (proceed == MagickFalse)
status=MagickFalse;
}
if (SetImageGray(image,exception) != MagickFalse)
(void) SetGrayscaleImage(image,exception);
}
- if ((image->storage_class == PseudoClass) &&
+ if ((quantize_info->dither_method == NoDitherMethod) &&
+ (image->storage_class == PseudoClass) &&
(image->colors <= maximum_colors))
{
if ((quantize_info->colorspace != UndefinedColorspace) &&
if (status != MagickFalse)
{
/*
- Reduce the number of colors in the image if it contains more than the
- maximum, otherwise we can disable dithering to improve the performance.
+ Reduce the number of colors in the image.
*/
if (cube_info->colors > cube_info->maximum_colors)
ReduceImageColors(image,cube_info);
- else
- cube_info->quantize_info->dither_method=NoDitherMethod;
status=AssignImageColors(image,cube_info,exception);
}
DestroyCubeInfo(cube_info);
color_2=(PixelInfo *) y;
intensity=GetPixelInfoIntensity((const Image *) NULL,color_1)-
GetPixelInfoIntensity((const Image *) NULL,color_2);
+ if (intensity > (double) INT_MAX)
+ intensity=(double) INT_MAX;
+ if (intensity < (double) INT_MIN)
+ intensity=(double) INT_MIN;
return((int) intensity);
}
register ssize_t
i;
+ size_t
+ extent;
+
ssize_t
*colormap_index,
j,
assert(image->signature == MagickCoreSignature);
if (image->type != GrayscaleType)
(void) TransformImageColorspace(image,GRAYColorspace,exception);
- if (image->storage_class == PseudoClass)
- colormap_index=(ssize_t *) AcquireQuantumMemory(image->colors,
- sizeof(*colormap_index));
- else
- colormap_index=(ssize_t *) AcquireQuantumMemory(MaxColormapSize,
- sizeof(*colormap_index));
+ extent=MagickMax(image->colors+1,MagickMax(MaxColormapSize,MaxMap+1));
+ colormap_index=(ssize_t *) AcquireQuantumMemory(extent,
+ sizeof(*colormap_index));
if (colormap_index == (ssize_t *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
if (image->storage_class != PseudoClass)
{
- (void) memset(colormap_index,(-1),MaxColormapSize*
- sizeof(*colormap_index));
+ (void) memset(colormap_index,(-1),extent*sizeof(*colormap_index));
if (AcquireImageColormap(image,MaxColormapSize,exception) == MagickFalse)
{
colormap_index=(ssize_t *) RelinquishMagickMemory(colormap_index);
status=MagickTrue;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(status) \
+ #pragma omp parallel for schedule(static) shared(status) \
magick_number_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
}
image_view=DestroyCacheView(image_view);
}
+ (void) memset(colormap_index,0,extent*sizeof(*colormap_index));
for (i=0; i < (ssize_t) image->colors; i++)
image->colormap[i].alpha=(double) i;
qsort((void *) image->colormap,image->colors,sizeof(PixelInfo),
status=MagickTrue;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(status) \
+ #pragma omp parallel for schedule(static) shared(status) \
magick_number_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)