Commit 0ce63275c for imagemagick.org
commit 0ce63275c2609e97abc6400dbccbd0a2420dea42
Author: Dirk Lemstra <dirk@lemstra.org>
Date: Sun Nov 15 18:56:00 2026 +0100
Fix 24-bit floating-point quantum decoding
diff --git a/MagickCore/quantum-import.c b/MagickCore/quantum-import.c
index d0a1ab1bc..818262e3a 100644
--- a/MagickCore/quantum-import.c
+++ b/MagickCore/quantum-import.c
@@ -201,39 +201,55 @@ static inline const unsigned char *PushQuantumFloat24Pixel(
const QuantumInfo *quantum_info,const unsigned char *magick_restrict pixels,
float *pixel)
{
- unsigned char
- quantum[4];
+ union
+ {
+ unsigned int
+ fixed_point;
+
+ float
+ single_precision;
+ } map;
+
+ unsigned int
+ exponent,
+ significand,
+ sign_bit,
+ value;
+ value=0U;
if (quantum_info->endian == LSBEndian)
{
- quantum[0]=(*pixels++);
- quantum[1]=(*pixels++);
- quantum[2]=(*pixels++);
+ value=(unsigned int) *pixels++;
+ value|=(unsigned int) *pixels++ << 8;
+ value|=(unsigned int) *pixels++ << 16;
}
else
{
- quantum[2]=(*pixels++);
- quantum[1]=(*pixels++);
- quantum[0]=(*pixels++);
+ value=(unsigned int) *pixels++ << 16;
+ value|=(unsigned int) *pixels++ << 8;
+ value|=(unsigned int) *pixels++;
}
- if ((quantum[0] | quantum[1] | quantum[2]) == 0U)
- quantum[3]=0;
- else
+ sign_bit=(value & 0x00800000U) << 8;
+ exponent=(value >> 16) & 0x7fU;
+ significand=value & 0xffffU;
+ if (exponent == 0U)
{
- unsigned char
- exponent,
- sign_bit;
-
- sign_bit=(quantum[2] & 0x80);
- exponent=(quantum[2] & 0x7F);
- if (exponent != 0)
- exponent=exponent-63+127;
- quantum[3]=sign_bit | (exponent >> 1);
- quantum[2]=((exponent & 1) << 7) | ((quantum[1] & 0xFE) >> 1);
- quantum[1]=((quantum[1] & 0x01) << 7) | ((quantum[0] & 0xFE) >> 1);
- quantum[0]=(quantum[0] & 0x01) << 7;
+ if (significand != 0U)
+ {
+ exponent=65U;
+ while ((significand & 0x10000U) == 0U)
+ {
+ significand<<=1;
+ exponent--;
+ }
+ significand&=0xffffU;
+ }
}
- *pixel=ScaleFloatPixel(quantum_info,quantum);
+ else
+ exponent=exponent == 127U ? 255U : exponent+64U;
+ map.fixed_point=sign_bit | (exponent << 23) | (significand << 7);
+ *pixel=ScaleFloatPixel(quantum_info,(const unsigned char *)
+ &map.single_precision);
return(pixels);
}