18#ifndef MAGICKCORE_QUANTUM_PRIVATE_H
19#define MAGICKCORE_QUANTUM_PRIVATE_H
21#include "magick/memory_.h"
22#include "magick/cache.h"
23#include "magick/image-private.h"
24#include "magick/pixel-accessor.h"
26#if defined(__cplusplus) || defined(c_plusplus)
91extern MagickPrivate
void
94static inline MagickSizeType GetQuantumRange(
const size_t depth)
105 max_depth=8*
sizeof(MagickSizeType);
106 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
107 ((one << (MagickMin(depth,max_depth)-1))-1)));
110static inline float HalfToSinglePrecision(
const unsigned short half)
112#define ExponentBias (127-15)
113#define ExponentMask (0x7c00U)
114#define ExponentShift 23
115#define SignBitShift 31
116#define SignificandShift 13
117#define SignificandMask (0x00000400U)
119 typedef union _SinglePrecision
146 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
147 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
148 significand=(
unsigned int) (half & 0x000003ff);
151 if (significand == 0)
152 value=sign_bit << SignBitShift;
155 while ((significand & SignificandMask) == 0)
161 significand&=(~SignificandMask);
162 exponent+=ExponentBias;
163 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
164 (significand << SignificandShift);
168 if (exponent == SignBitShift)
170 value=(sign_bit << SignBitShift) | 0x7f800000;
171 if (significand != 0)
172 value|=(significand << SignificandShift);
176 exponent+=ExponentBias;
177 significand<<=SignificandShift;
178 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
181 map.fixed_point=value;
182 return(map.single_precision);
185static inline unsigned char *PopCharPixel(
const unsigned char pixel,
186 unsigned char *magick_restrict pixels)
192static inline unsigned char *PopLongPixel(
const EndianType endian,
193 const unsigned int pixel,
unsigned char *magick_restrict pixels)
198 quantum=(
unsigned int) pixel;
199 if (endian == LSBEndian)
201 *pixels++=(
unsigned char) (quantum);
202 *pixels++=(
unsigned char) (quantum >> 8);
203 *pixels++=(
unsigned char) (quantum >> 16);
204 *pixels++=(
unsigned char) (quantum >> 24);
207 *pixels++=(
unsigned char) (quantum >> 24);
208 *pixels++=(
unsigned char) (quantum >> 16);
209 *pixels++=(
unsigned char) (quantum >> 8);
210 *pixels++=(
unsigned char) (quantum);
214static inline unsigned char *PopShortPixel(
const EndianType endian,
215 const unsigned short pixel,
unsigned char *magick_restrict pixels)
221 if (endian == LSBEndian)
223 *pixels++=(
unsigned char) (quantum);
224 *pixels++=(
unsigned char) (quantum >> 8);
227 *pixels++=(
unsigned char) (quantum >> 8);
228 *pixels++=(
unsigned char) (quantum);
232static inline const unsigned char *PushCharPixel(
233 const unsigned char *magick_restrict pixels,
234 unsigned char *magick_restrict pixel)
240static inline const unsigned char *PushLongPixel(
const EndianType endian,
241 const unsigned char *magick_restrict pixels,
242 unsigned int *magick_restrict pixel)
247 if (endian == LSBEndian)
249 quantum=((
unsigned int) *pixels++);
250 quantum|=((
unsigned int) *pixels++ << 8);
251 quantum|=((
unsigned int) *pixels++ << 16);
252 quantum|=((
unsigned int) *pixels++ << 24);
256 quantum=((
unsigned int) *pixels++ << 24);
257 quantum|=((
unsigned int) *pixels++ << 16);
258 quantum|=((
unsigned int) *pixels++ << 8);
259 quantum|=((
unsigned int) *pixels++);
264static inline const unsigned char *PushShortPixel(
const EndianType endian,
265 const unsigned char *magick_restrict pixels,
266 unsigned short *magick_restrict pixel)
271 if (endian == LSBEndian)
273 quantum=(
unsigned int) *pixels++;
274 quantum|=(
unsigned int) (*pixels++ << 8);
275 *pixel=(
unsigned short) (quantum & 0xffff);
278 quantum=(
unsigned int) (*pixels++ << 8);
279 quantum|=(
unsigned int) *pixels++;
280 *pixel=(
unsigned short) (quantum & 0xffff);
284static inline const unsigned char *PushFloatPixel(
const EndianType endian,
285 const unsigned char *magick_restrict pixels,
286 MagickFloatType *magick_restrict pixel)
297 if (endian == LSBEndian)
299 quantum.unsigned_value=((
unsigned int) *pixels++);
300 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
301 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
302 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
303 *pixel=quantum.float_value;
306 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
307 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
308 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
309 quantum.unsigned_value|=((
unsigned int) *pixels++);
310 *pixel=quantum.float_value;
314static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
315 const QuantumAny range)
318 return(QuantumRange);
319#if !defined(MAGICKCORE_HDRI_SUPPORT)
320 return((Quantum) ((
double) QuantumRange*(quantum*
321 PerceptibleReciprocal((
double) range))+0.5));
323 return((Quantum) ((
double) QuantumRange*(quantum*
324 PerceptibleReciprocal((
double) range))));
328static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
329 const QuantumAny range)
331#if !defined(MAGICKCORE_HDRI_SUPPORT)
332 return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange));
334 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
335 return((QuantumAny) 0UL);
336 if ((range*(MagickRealType) quantum/(MagickRealType) QuantumRange) >= 18446744073709551615.0)
337 return((QuantumAny) MagickULLConstant(18446744073709551615));
338 return((QuantumAny) (range*(MagickRealType) quantum/(MagickRealType) QuantumRange+0.5));
342#if (MAGICKCORE_QUANTUM_DEPTH == 8)
343static inline Quantum ScaleCharToQuantum(
const unsigned char value)
345 return((Quantum) value);
348static inline Quantum ScaleLongToQuantum(
const unsigned int value)
350#if !defined(MAGICKCORE_HDRI_SUPPORT)
351 return((Quantum) ((value)/16843009UL));
353 return((Quantum) (value/16843009.0));
357static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
362 return(QuantumRange);
363#if !defined(MAGICKCORE_HDRI_SUPPORT)
364 return((Quantum) (value+0.5));
366 return((Quantum) value);
370static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
372#if !defined(MAGICKCORE_HDRI_SUPPORT)
373 return((
unsigned int) (16843009UL*quantum));
375 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
377 if ((16843009.0*quantum) >= 4294967295.0)
378 return(4294967295UL);
379 return((
unsigned int) (16843009.0*quantum+0.5));
383static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
385 if (quantum >= (Quantum) MaxMap)
386 return((
unsigned int) MaxMap);
387#if !defined(MAGICKCORE_HDRI_SUPPORT)
388 return((
unsigned int) quantum);
390 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
392 return((
unsigned int) (quantum+0.5));
396static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
398#if !defined(MAGICKCORE_HDRI_SUPPORT)
399 return((
unsigned short) (257UL*quantum));
401 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
403 if ((257.0*quantum) >= 65535.0)
405 return((
unsigned short) (257.0*quantum+0.5));
409static inline Quantum ScaleShortToQuantum(
const unsigned short value)
411#if !defined(MAGICKCORE_HDRI_SUPPORT)
412 return((Quantum) ((value+128U)/257U));
414 return((Quantum) (value/257.0));
417#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
418static inline Quantum ScaleCharToQuantum(
const unsigned char value)
420#if !defined(MAGICKCORE_HDRI_SUPPORT)
421 return((Quantum) (257U*value));
423 return((Quantum) (257.0*value));
427static inline Quantum ScaleLongToQuantum(
const unsigned int value)
429#if !defined(MAGICKCORE_HDRI_SUPPORT)
430 return((Quantum) ((value)/MagickULLConstant(65537)));
432 return((Quantum) (value/65537.0));
436static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
441 return(QuantumRange);
442#if !defined(MAGICKCORE_HDRI_SUPPORT)
443 return((Quantum) (value+0.5));
445 return((Quantum) value);
449static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
451#if !defined(MAGICKCORE_HDRI_SUPPORT)
452 return((
unsigned int) (65537UL*quantum));
454 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
456 if ((65537.0f*quantum) >= 4294967295.0f)
458 return((
unsigned int) (65537.0f*quantum+0.5f));
462static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
464 if (quantum >= (Quantum) MaxMap)
465 return((
unsigned int) MaxMap);
466#if !defined(MAGICKCORE_HDRI_SUPPORT)
467 return((
unsigned int) quantum);
469 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
471 return((
unsigned int) (quantum+0.5f));
475static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
477#if !defined(MAGICKCORE_HDRI_SUPPORT)
478 return((
unsigned short) quantum);
480 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
482 if (quantum >= 65535.0f)
484 return((
unsigned short) (quantum+0.5f));
488static inline Quantum ScaleShortToQuantum(
const unsigned short value)
490 return((Quantum) value);
492#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
493static inline Quantum ScaleCharToQuantum(
const unsigned char value)
495#if !defined(MAGICKCORE_HDRI_SUPPORT)
496 return((Quantum) (16843009UL*value));
498 return((Quantum) (16843009.0*value));
502static inline Quantum ScaleLongToQuantum(
const unsigned int value)
504 return((Quantum) value);
507static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
511 if (value >= (Quantum) MaxMap)
512 return(QuantumRange);
513#if !defined(MAGICKCORE_HDRI_SUPPORT)
514 return((Quantum) (65537.0f*value+0.5f));
516 return((Quantum) (65537.0f*value));
520static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
522#if !defined(MAGICKCORE_HDRI_SUPPORT)
523 return((
unsigned int) quantum);
525 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
527 if ((quantum) >= 4294967295.0)
529 return((
unsigned int) (quantum+0.5));
533static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
535 if ((quantum/65537) >= (Quantum) MaxMap)
536 return((
unsigned int) MaxMap);
537#if !defined(MAGICKCORE_HDRI_SUPPORT)
538 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
539 MagickULLConstant(65537)));
541 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
543 return((
unsigned int) (quantum/65537.0+0.5));
547static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
549#if !defined(MAGICKCORE_HDRI_SUPPORT)
550 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
551 MagickULLConstant(65537)));
553 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
555 if ((quantum/65537.0) >= 65535.0)
557 return((
unsigned short) (quantum/65537.0+0.5));
561static inline Quantum ScaleShortToQuantum(
const unsigned short value)
563#if !defined(MAGICKCORE_HDRI_SUPPORT)
564 return((Quantum) (65537UL*value));
566 return((Quantum) (65537.0*value));
569#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
570static inline Quantum ScaleCharToQuantum(
const unsigned char value)
572 return((Quantum) (72340172838076673.0*value));
575static inline Quantum ScaleLongToQuantum(
const unsigned int value)
577 return((Quantum) (4294967297.0*value));
580static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
585 return(QuantumRange);
586 return((Quantum) (281479271743489.0*value));
589static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
591 return((
unsigned int) (quantum/4294967297.0+0.5));
594static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
596 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
598 if ((quantum/281479271743489.0) >= MaxMap)
599 return((
unsigned int) MaxMap);
600 return((
unsigned int) (quantum/281479271743489.0+0.5));
603static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
605 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
607 if ((quantum/281479271743489.0) >= 65535.0)
609 return((
unsigned short) (quantum/281479271743489.0+0.5));
612static inline Quantum ScaleShortToQuantum(
const unsigned short value)
614 return((Quantum) (281479271743489.0*value));
618static inline unsigned short SinglePrecisionToHalf(
const float value)
620 typedef union _SinglePrecision
649 map.single_precision=value;
650 sign_bit=(map.fixed_point >> 16) & 0x00008000;
651 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
652 significand=map.fixed_point & 0x007fffff;
659 return((
unsigned short) sign_bit);
660 significand=significand | 0x00800000;
661 shift=(int) (14-exponent);
662 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
663 ((significand >> shift) & 0x01)) >> shift);
664 return((
unsigned short) (sign_bit | significand));
667 if (exponent == (0xff-ExponentBias))
669 if (significand == 0)
670 return((
unsigned short) (sign_bit | ExponentMask));
673 significand>>=SignificandShift;
674 half=(
unsigned short) (sign_bit | significand |
675 (significand == 0) | ExponentMask);
679 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
680 if ((significand & 0x00800000) != 0)
697 for (i=0; i < 10; i++)
699 return((
unsigned short) (sign_bit | ExponentMask));
701 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
702 (significand >> SignificandShift));
706#if defined(__cplusplus) || defined(c_plusplus)