From 2f4e2b26f7cf50f05545eef88b6038a876040182 Mon Sep 17 00:00:00 2001 From: Cristy Date: Sun, 22 Jan 2017 17:25:53 -0500 Subject: [PATCH] Fix finite percision problem when computing CCL mean color --- MagickCore/magick-type.h | 10 +++---- MagickCore/quantize.c | 58 ++++++++++++++++++++-------------------- MagickCore/vision.c | 13 ++++----- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/MagickCore/magick-type.h b/MagickCore/magick-type.h index 8b6b0e329..a7b76d297 100644 --- a/MagickCore/magick-type.h +++ b/MagickCore/magick-type.h @@ -46,10 +46,10 @@ typedef float float_t; #if (MAGICKCORE_QUANTUM_DEPTH == 8) #define MaxColormapSize 256UL #define MaxMap 255UL -typedef float_t MagickRealType; +typedef double_t MagickRealType; #if defined(MAGICKCORE_HDRI_SUPPORT) -typedef float Quantum; +typedef float_t Quantum; #define QuantumRange 255.0 #define QuantumFormat "%g" #else @@ -60,10 +60,10 @@ typedef unsigned char Quantum; #elif (MAGICKCORE_QUANTUM_DEPTH == 16) #define MaxColormapSize 65536UL #define MaxMap 65535UL -typedef float_t MagickRealType; +typedef double_t MagickRealType; #if defined(MAGICKCORE_HDRI_SUPPORT) -typedef float Quantum; +typedef float_t Quantum; #define QuantumRange 65535.0f #define QuantumFormat "%g" #else @@ -74,7 +74,7 @@ typedef unsigned short Quantum; #elif (MAGICKCORE_QUANTUM_DEPTH == 32) #define MaxColormapSize 65536UL #define MaxMap 65535UL -typedef float_t MagickRealType; +typedef double_t MagickRealType; #if defined(MAGICKCORE_HDRI_SUPPORT) typedef double Quantum; diff --git a/MagickCore/quantize.c b/MagickCore/quantize.c index 7ebb35aa4..281ad0533 100644 --- a/MagickCore/quantize.c +++ b/MagickCore/quantize.c @@ -217,14 +217,14 @@ /* Typdef declarations. */ -typedef struct _DoublePixelInfo +typedef struct _DoublePixelPacket { double red, green, blue, alpha; -} DoublePixelInfo; +} DoublePixelPacket; typedef struct _NodeInfo { @@ -235,7 +235,7 @@ typedef struct _NodeInfo MagickSizeType number_unique; - DoublePixelInfo + DoublePixelPacket total_color; double @@ -271,7 +271,7 @@ typedef struct _CubeInfo MagickSizeType transparent_pixels; - DoublePixelInfo + DoublePixelPacket target; double @@ -296,7 +296,7 @@ typedef struct _CubeInfo ssize_t *cache; - DoublePixelInfo + DoublePixelPacket error[ErrorQueueLength]; double @@ -435,7 +435,7 @@ MagickExport QuantizeInfo *AcquireQuantizeInfo(const ImageInfo *image_info) */ static inline void AssociateAlphaPixel(const Image *image, - const CubeInfo *cube_info,const Quantum *pixel,DoublePixelInfo *alpha_pixel) + const CubeInfo *cube_info,const Quantum *pixel,DoublePixelPacket *alpha_pixel) { double alpha; @@ -457,7 +457,7 @@ static inline void AssociateAlphaPixel(const Image *image, } static inline void AssociateAlphaPixelInfo(const CubeInfo *cube_info, - const PixelInfo *pixel,DoublePixelInfo *alpha_pixel) + const PixelInfo *pixel,DoublePixelPacket *alpha_pixel) { double alpha; @@ -479,7 +479,7 @@ static inline void AssociateAlphaPixelInfo(const CubeInfo *cube_info, } static inline size_t ColorToNodeId(const CubeInfo *cube_info, - const DoublePixelInfo *pixel,size_t index) + const DoublePixelPacket *pixel,size_t index) { size_t id; @@ -562,7 +562,7 @@ static MagickBooleanType AssignImageColors(Image *image,CubeInfo *cube_info, cube=(*cube_info); for (x=0; x < (ssize_t) image->columns; x+=count) { - DoublePixelInfo + DoublePixelPacket pixel; register const NodeInfo @@ -756,7 +756,7 @@ static MagickBooleanType ClassifyImageColors(CubeInfo *cube_info, CacheView *image_view; - DoublePixelInfo + DoublePixelPacket error, mid, midpoint, @@ -1113,7 +1113,7 @@ static void ClosestColor(const Image *image,CubeInfo *cube_info, beta, distance; - register DoublePixelInfo + register DoublePixelPacket *magick_restrict q; register PixelInfo @@ -1424,22 +1424,22 @@ MagickExport QuantizeInfo *DestroyQuantizeInfo(QuantizeInfo *quantize_info) % */ -static DoublePixelInfo **DestroyPixelThreadSet(DoublePixelInfo **pixels) +static DoublePixelPacket **DestroyPixelThreadSet(DoublePixelPacket **pixels) { register ssize_t i; - assert(pixels != (DoublePixelInfo **) NULL); + assert(pixels != (DoublePixelPacket **) NULL); for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++) - if (pixels[i] != (DoublePixelInfo *) NULL) - pixels[i]=(DoublePixelInfo *) RelinquishMagickMemory(pixels[i]); - pixels=(DoublePixelInfo **) RelinquishMagickMemory(pixels); + if (pixels[i] != (DoublePixelPacket *) NULL) + pixels[i]=(DoublePixelPacket *) RelinquishMagickMemory(pixels[i]); + pixels=(DoublePixelPacket **) RelinquishMagickMemory(pixels); return(pixels); } -static DoublePixelInfo **AcquirePixelThreadSet(const size_t count) +static DoublePixelPacket **AcquirePixelThreadSet(const size_t count) { - DoublePixelInfo + DoublePixelPacket **pixels; register ssize_t @@ -1449,23 +1449,23 @@ static DoublePixelInfo **AcquirePixelThreadSet(const size_t count) number_threads; number_threads=(size_t) GetMagickResourceLimit(ThreadResource); - pixels=(DoublePixelInfo **) AcquireQuantumMemory(number_threads, + pixels=(DoublePixelPacket **) AcquireQuantumMemory(number_threads, sizeof(*pixels)); - if (pixels == (DoublePixelInfo **) NULL) - return((DoublePixelInfo **) NULL); + if (pixels == (DoublePixelPacket **) NULL) + return((DoublePixelPacket **) NULL); (void) ResetMagickMemory(pixels,0,number_threads*sizeof(*pixels)); for (i=0; i < (ssize_t) number_threads; i++) { - pixels[i]=(DoublePixelInfo *) AcquireQuantumMemory(count,2* + pixels[i]=(DoublePixelPacket *) AcquireQuantumMemory(count,2* sizeof(**pixels)); - if (pixels[i] == (DoublePixelInfo *) NULL) + if (pixels[i] == (DoublePixelPacket *) NULL) return(DestroyPixelThreadSet(pixels)); } return(pixels); } static inline ssize_t CacheOffset(CubeInfo *cube_info, - const DoublePixelInfo *pixel) + const DoublePixelPacket *pixel) { #define RedShift(pixel) (((pixel) >> CacheShift) << (0*(8-CacheShift))) #define GreenShift(pixel) (((pixel) >> CacheShift) << (1*(8-CacheShift))) @@ -1491,7 +1491,7 @@ static MagickBooleanType FloydSteinbergDither(Image *image,CubeInfo *cube_info, CacheView *image_view; - DoublePixelInfo + DoublePixelPacket **pixels; MagickBooleanType @@ -1504,7 +1504,7 @@ static MagickBooleanType FloydSteinbergDither(Image *image,CubeInfo *cube_info, Distribute quantization error using Floyd-Steinberg. */ pixels=AcquirePixelThreadSet(image->columns); - if (pixels == (DoublePixelInfo **) NULL) + if (pixels == (DoublePixelPacket **) NULL) return(MagickFalse); status=MagickTrue; image_view=AcquireAuthenticCacheView(image,exception); @@ -1516,7 +1516,7 @@ static MagickBooleanType FloydSteinbergDither(Image *image,CubeInfo *cube_info, CubeInfo cube; - DoublePixelInfo + DoublePixelPacket *current, *previous; @@ -1546,7 +1546,7 @@ static MagickBooleanType FloydSteinbergDither(Image *image,CubeInfo *cube_info, v=(ssize_t) ((y & 0x01) != 0 ? -1 : 1); for (x=0; x < (ssize_t) image->columns; x++) { - DoublePixelInfo + DoublePixelPacket color, pixel; @@ -1808,7 +1808,7 @@ static MagickBooleanType RiemersmaDither(Image *image,CacheView *image_view, { #define DitherImageTag "Dither/Image" - DoublePixelInfo + DoublePixelPacket color, pixel; diff --git a/MagickCore/vision.c b/MagickCore/vision.c index 3d4a0a7bb..7a35bfd90 100644 --- a/MagickCore/vision.c +++ b/MagickCore/vision.c @@ -374,18 +374,15 @@ MagickExport Image *ConnectedComponentsImage(const Image *image, offset=y*image->columns+x; status=GetMatrixElement(equivalences,offset,0,&id); - if (id == offset) + if (id != offset) + status=GetMatrixElement(equivalences,id,0,&id); + else { id=n++; - if (n > (ssize_t) MaxColormapSize) + if (id >= (ssize_t) MaxColormapSize) break; - status=SetMatrixElement(equivalences,offset,0,&id); - } - else - { - status=GetMatrixElement(equivalences,id,0,&id); - status=SetMatrixElement(equivalences,offset,0,&id); } + status=SetMatrixElement(equivalences,offset,0,&id); if (x < object[id].bounding_box.x) object[id].bounding_box.x=x; if (x >= (ssize_t) object[id].bounding_box.width) -- 2.40.0