Cristy
2025-10-18 10:54:39 -04:00
parent d56b6afca2
commit 7b47fe369e
4 changed files with 91 additions and 64 deletions
+1 -1
View File
@@ -986,7 +986,7 @@ static MagickBooleanType CompositeOverImage(Image *image,
}
pixels=p;
if (x_offset < 0)
p-=(ptrdiff_t)CastDoubleToSsizeT((double) x_offset*
p-=(ptrdiff_t) CastDoubleToSsizeT((double) x_offset*
GetPixelChannels(source_image));
}
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
+26 -22
View File
@@ -69,6 +69,7 @@
#include "MagickCore/option.h"
#include "MagickCore/pixel.h"
#include "MagickCore/pixel-accessor.h"
#include "MagickCore/pixel-private.h"
#include "MagickCore/property.h"
#include "MagickCore/quantum.h"
#include "MagickCore/quantum-private.h"
@@ -318,11 +319,8 @@ static void ClipCLAHEHistogram(const double clip_limit,const size_t number_bins,
return;
cumulative_excess=0;
for (i=0; i < (ssize_t) number_bins; i++)
{
excess=(ssize_t) histogram[i]-(ssize_t) clip_limit;
if (excess > 0)
cumulative_excess+=excess;
}
if (histogram[i] > clip_limit)
cumulative_excess+=(ssize_t) (histogram[i]-clip_limit);
/*
Clip histogram and redistribute excess pixels across all bins.
*/
@@ -481,9 +479,6 @@ static MagickBooleanType CLAHE(const RectangleInfo *clahe_info,
MemoryInfo
*tile_cache;
unsigned short
*p;
size_t
limit,
*tiles;
@@ -492,15 +487,16 @@ static MagickBooleanType CLAHE(const RectangleInfo *clahe_info,
y;
unsigned short
*lut;
*lut,
*p;
/*
Contrast limited adapted histogram equalization.
*/
if (clip_limit == 1.0)
return(MagickTrue);
tile_cache=AcquireVirtualMemory((size_t) clahe_info->x*number_bins,
(size_t) clahe_info->y*sizeof(*tiles));
tile_cache=AcquireVirtualMemory((size_t) clahe_info->x*number_bins,(size_t)
clahe_info->y*sizeof(*tiles));
if (tile_cache == (MemoryInfo *) NULL)
return(MagickFalse);
lut=(unsigned short *) AcquireQuantumMemory(NumberCLAHEGrays,sizeof(*lut));
@@ -510,7 +506,8 @@ static MagickBooleanType CLAHE(const RectangleInfo *clahe_info,
return(MagickFalse);
}
tiles=(size_t *) GetVirtualMemoryBlob(tile_cache);
limit=(size_t) (clip_limit*(tile_info->width*tile_info->height)/number_bins);
limit=(size_t) (clip_limit*((double) tile_info->width*tile_info->height)/
number_bins);
if (limit < 1UL)
limit=1UL;
/*
@@ -535,7 +532,7 @@ static MagickBooleanType CLAHE(const RectangleInfo *clahe_info,
tile_info->height,histogram);
p+=(ptrdiff_t) tile_info->width;
}
p+=(ptrdiff_t) clahe_info->width*(tile_info->height-1);
p+=CastDoubleToPtrdiffT((double) clahe_info->width*(tile_info->height-1));
}
/*
Interpolate greylevel mappings to get CLAHE image.
@@ -576,6 +573,12 @@ static MagickBooleanType CLAHE(const RectangleInfo *clahe_info,
}
for (x=0; x <= (ssize_t) clahe_info->x; x++)
{
double
Q11,
Q12,
Q21,
Q22;
tile.width=tile_info->width;
tile.x=x-1;
offset.x=tile.x+1;
@@ -598,15 +601,16 @@ static MagickBooleanType CLAHE(const RectangleInfo *clahe_info,
tile.x=clahe_info->x-1;
offset.x=tile.x;
}
InterpolateCLAHE(clahe_info,
tiles+((ssize_t) number_bins*(tile.y*clahe_info->x+tile.x)), /* Q12 */
tiles+((ssize_t) number_bins*(tile.y*clahe_info->x+offset.x)), /* Q22 */
tiles+((ssize_t) number_bins*(offset.y*clahe_info->x+tile.x)), /* Q11 */
tiles+((ssize_t) number_bins*(offset.y*clahe_info->x+offset.x)), /* Q21 */
&tile,lut,p);
Q12=(double) number_bins*(tile.y*clahe_info->x+tile.x);
Q22=(double) number_bins*(tile.y*clahe_info->x+offset.x);
Q11=(double) number_bins*(offset.y*clahe_info->x+tile.x);
Q21=(double) number_bins*(offset.y*clahe_info->x+offset.x);
InterpolateCLAHE(clahe_info,tiles+CastDoubleToPtrdiffT(Q12),
tiles+CastDoubleToPtrdiffT(Q22),tiles+CastDoubleToPtrdiffT(Q11),
tiles+CastDoubleToPtrdiffT(Q21),&tile,lut,p);
p+=(ptrdiff_t) tile.width;
}
p+=(ptrdiff_t) clahe_info->width*(tile.height-1);
p+=CastDoubleToPtrdiffT((double) clahe_info->width*(tile.height-1));
}
lut=(unsigned short *) RelinquishMagickMemory(lut);
tile_cache=RelinquishVirtualMemory(tile_cache);
@@ -659,10 +663,10 @@ MagickExport MagickBooleanType CLAHEImage(Image *image,const size_t width,
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
range_info.min=0;
range_info.max=NumberCLAHEGrays-1;
tile_info.width=width;
tile_info.width=MagickMax(width,2);
if (tile_info.width == 0)
tile_info.width=image->columns >> 3;
tile_info.height=height;
tile_info.height=MagickMax(height,2);
if (tile_info.height == 0)
tile_info.height=image->rows >> 3;
tile_info.x=0;
+63 -40
View File
@@ -46,6 +46,8 @@ extern "C" {
#define MagickPHI 1.61803398874989484820458683436563811772030917980576
#define MagickPI2 1.57079632679489661923132169163975144209858469968755
#define MagickPI 3.1415926535897932384626433832795028841971693993751058209749445923078164062
#define MAGICK_PTRDIFF_MAX (PTRDIFF_MAX)
#define MAGICK_PTRDIFF_MIN (-PTRDIFF_MAX-1)
#define MagickSQ1_2 0.70710678118654752440084436210484903928483593768847
#define MagickSQ2 1.41421356237309504880168872420969807856967187537695
#define MagickSQ2PI 2.50662827463100024161235523934010416269302368164062
@@ -67,24 +69,52 @@ extern "C" {
#define UndefinedCompressionQuality 0UL
#define UndefinedTicksPerSecond 100L
static inline QuantumAny CastDoubleToQuantumAny(const double x)
static inline ptrdiff_t CastDoubleToPtrdiffT(const double x)
{
double
value;
if (IsNaN(x) != 0)
{
errno=ERANGE;
return(0);
}
if (x > ((double) ((QuantumAny) ~0)))
value=(x < 0.0) ? ceil(x) : floor(x);
if (value < ((double) MAGICK_PTRDIFF_MIN))
{
errno=ERANGE;
return(MAGICK_PTRDIFF_MIN);
}
if (value > ((double) MAGICK_PTRDIFF_MAX))
{
errno=ERANGE;
return(MAGICK_PTRDIFF_MAX);
}
return((ptrdiff_t) value);
}
static inline QuantumAny CastDoubleToQuantumAny(const double x)
{
double
value;
if (IsNaN(x) != 0)
{
errno=ERANGE;
return(0);
}
value=(x < 0.0) ? ceil(x) : floor(x);
if (value < 0.0)
{
errno=ERANGE;
return(0);
}
if (value > ((double) ((QuantumAny) ~0)))
{
errno=ERANGE;
return((QuantumAny) ~0);
}
if (x < 0.0)
{
errno=ERANGE;
return((QuantumAny) 0);
}
return((QuantumAny) (x+0.5));
return((QuantumAny) value);
}
static inline size_t CastDoubleToSizeT(const double x)
@@ -97,17 +127,17 @@ static inline size_t CastDoubleToSizeT(const double x)
errno=ERANGE;
return(0);
}
value=floor(x);
if (value >= ((double) MAGICK_SIZE_MAX))
{
errno=ERANGE;
return((size_t) MAGICK_SIZE_MAX);
}
value=(x < 0.0) ? ceil(x) : floor(x);
if (value < 0.0)
{
errno=ERANGE;
return(0);
}
if (value > ((double) MAGICK_SIZE_MAX))
{
errno=ERANGE;
return(MAGICK_SIZE_MAX);
}
return((size_t) value);
}
@@ -121,23 +151,16 @@ static inline ssize_t CastDoubleToSsizeT(const double x)
errno=ERANGE;
return(0);
}
if (x < 0.0)
value=(x < 0.0) ? ceil(x) : floor(x);
if (value < ((double) MAGICK_SSIZE_MIN))
{
value=ceil(x);
if (value < ((double) MAGICK_SSIZE_MIN))
{
errno=ERANGE;
return((ssize_t) MAGICK_SSIZE_MIN);
}
errno=ERANGE;
return(MAGICK_SSIZE_MIN);
}
else
if (value > ((double) MAGICK_SSIZE_MAX))
{
value=floor(x);
if (value > ((double) MAGICK_SSIZE_MAX))
{
errno=ERANGE;
return((ssize_t) MAGICK_SSIZE_MAX);
}
errno=ERANGE;
return(MAGICK_SSIZE_MAX);
}
return((ssize_t) value);
}
@@ -152,17 +175,17 @@ static inline unsigned int CastDoubleToUInt(const double x)
errno=ERANGE;
return(0);
}
value=floor(x);
if (value >= ((double) MAGICK_UINT_MAX))
{
errno=ERANGE;
return((unsigned int) MAGICK_UINT_MAX);
}
value=(x < 0.0) ? ceil(x) : floor(x);
if (value < 0.0)
{
errno=ERANGE;
return(0);
}
if (value > ((double) MAGICK_UINT_MAX))
{
errno=ERANGE;
return(MAGICK_UINT_MAX);
}
return((unsigned int) value);
}
@@ -176,17 +199,17 @@ static inline unsigned short CastDoubleToUShort(const double x)
errno=ERANGE;
return(0);
}
value=floor(x);
if (value >= ((double) MAGICK_USHORT_MAX))
{
errno=ERANGE;
return((unsigned short) MAGICK_USHORT_MAX);
}
value=(x < 0.0) ? ceil(x) : floor(x);
if (value < 0.0)
{
errno=ERANGE;
return(0);
}
if (value > ((double) MAGICK_USHORT_MAX))
{
errno=ERANGE;
return(MAGICK_USHORT_MAX);
}
return((unsigned short) value);
}
Vendored
+1 -1
View File
@@ -5371,7 +5371,7 @@ MAGICK_PATCHLEVEL_VERSION=8
MAGICK_VERSION=7.1.2-8
MAGICK_GIT_REVISION=47ef75820:20251014
MAGICK_GIT_REVISION=d56b6afca:20251014
# Substitute library versioning