18#ifndef MAGICKCORE_QUANTUM_PRIVATE_H
19#define MAGICKCORE_QUANTUM_PRIVATE_H
21#include "MagickCore/memory_.h"
22#include "MagickCore/cache.h"
23#include "MagickCore/image-private.h"
24#include "MagickCore/pixel-accessor.h"
25#include "MagickCore/statistic-private.h"
27#if defined(__cplusplus) || defined(c_plusplus)
95extern MagickExport MagickBooleanType
96 SetQuantumExtent(
const Image *,QuantumInfo *);
98extern MagickPrivate
void
99 ResetQuantumState(QuantumInfo *);
101static inline MagickSizeType GetQuantumRange(
const size_t depth)
112 max_depth=8*
sizeof(MagickSizeType);
113 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
114 ((one << (MagickMin(depth,max_depth)-1))-1)));
117static inline float HalfToSinglePrecision(
const unsigned short half)
119#define ExponentBias (127-15)
120#define ExponentMask (0x7c00U)
121#define ExponentShift 23
122#define SignBitShift 31
123#define SignificandShift 13
124#define SignificandMask (0x00000400U)
126 typedef union _SinglePrecision
151 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
152 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
153 significand=(
unsigned int) (half & 0x000003ff);
156 if (significand == 0)
157 value=sign_bit << SignBitShift;
160 while ((significand & SignificandMask) == 0)
166 significand&=(~SignificandMask);
167 exponent+=ExponentBias;
168 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
169 (significand << SignificandShift);
173 if (exponent == SignBitShift)
175 value=(sign_bit << SignBitShift) | 0x7f800000;
176 if (significand != 0)
177 value|=(significand << SignificandShift);
181 exponent+=ExponentBias;
182 significand<<=SignificandShift;
183 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
186 map.fixed_point=value;
187 return(map.single_precision);
190static inline unsigned char *PopCharPixel(
const unsigned char pixel,
191 unsigned char *magick_restrict pixels)
197static inline unsigned char *PopLongPixel(
const EndianType endian,
198 const unsigned int pixel,
unsigned char *magick_restrict pixels)
203 quantum=(
unsigned int) pixel;
204 if (endian == LSBEndian)
206 *pixels++=(
unsigned char) (quantum);
207 *pixels++=(
unsigned char) (quantum >> 8);
208 *pixels++=(
unsigned char) (quantum >> 16);
209 *pixels++=(
unsigned char) (quantum >> 24);
212 *pixels++=(
unsigned char) (quantum >> 24);
213 *pixels++=(
unsigned char) (quantum >> 16);
214 *pixels++=(
unsigned char) (quantum >> 8);
215 *pixels++=(
unsigned char) (quantum);
219static inline unsigned char *PopShortPixel(
const EndianType endian,
220 const unsigned short pixel,
unsigned char *magick_restrict pixels)
226 if (endian == LSBEndian)
228 *pixels++=(
unsigned char) (quantum);
229 *pixels++=(
unsigned char) (quantum >> 8);
232 *pixels++=(
unsigned char) (quantum >> 8);
233 *pixels++=(
unsigned char) (quantum);
237static inline const unsigned char *PushCharPixel(
238 const unsigned char *magick_restrict pixels,
239 unsigned char *magick_restrict pixel)
245static inline const unsigned char *PushLongPixel(
const EndianType endian,
246 const unsigned char *magick_restrict pixels,
247 unsigned int *magick_restrict pixel)
252 if (endian == LSBEndian)
254 quantum=((
unsigned int) *pixels++);
255 quantum|=((
unsigned int) *pixels++ << 8);
256 quantum|=((
unsigned int) *pixels++ << 16);
257 quantum|=((
unsigned int) *pixels++ << 24);
261 quantum=((
unsigned int) *pixels++ << 24);
262 quantum|=((
unsigned int) *pixels++ << 16);
263 quantum|=((
unsigned int) *pixels++ << 8);
264 quantum|=((
unsigned int) *pixels++);
269static inline const unsigned char *PushShortPixel(
const EndianType endian,
270 const unsigned char *magick_restrict pixels,
271 unsigned short *magick_restrict pixel)
276 if (endian == LSBEndian)
278 quantum=(
unsigned int) *pixels++;
279 quantum|=(
unsigned int) (*pixels++ << 8);
280 *pixel=(
unsigned short) (quantum & 0xffff);
283 quantum=(
unsigned int) (*pixels++ << 8);
284 quantum|=(
unsigned int) *pixels++;
285 *pixel=(
unsigned short) (quantum & 0xffff);
289static inline const unsigned char *PushFloatPixel(
const EndianType endian,
290 const unsigned char *magick_restrict pixels,
291 MagickFloatType *magick_restrict pixel)
302 if (endian == LSBEndian)
304 quantum.unsigned_value=((
unsigned int) *pixels++);
305 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
306 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
307 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
308 *pixel=quantum.float_value;
311 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
312 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
313 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
314 quantum.unsigned_value|=((
unsigned int) *pixels++);
315 *pixel=quantum.float_value;
319static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
320 const QuantumAny range)
323 return(QuantumRange);
324#if !defined(MAGICKCORE_HDRI_SUPPORT)
325 return((Quantum) ((
double) QuantumRange*(quantum*
326 MagickSafeReciprocal((
double) range))+0.5));
328 return((Quantum) ((
double) QuantumRange*(quantum*
329 MagickSafeReciprocal((
double) range))));
333static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
334 const QuantumAny range)
336#if !defined(MAGICKCORE_HDRI_SUPPORT)
337 return((QuantumAny) ((
double) range*quantum/QuantumRange));
339 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
340 return((QuantumAny) 0UL);
341 if (((
double) range*quantum/(
double) QuantumRange) >= 18446744073709551615.0)
342 return((QuantumAny) MagickULLConstant(18446744073709551615));
343 return((QuantumAny) (range*(
double) quantum/(
double) QuantumRange+0.5));
347#if (MAGICKCORE_QUANTUM_DEPTH == 8)
348static inline Quantum ScaleCharToQuantum(
const unsigned char value)
350 return((Quantum) value);
353static inline Quantum ScaleLongToQuantum(
const unsigned int value)
355#if !defined(MAGICKCORE_HDRI_SUPPORT)
356 return((Quantum) ((value)/16843009UL));
358 return((Quantum) (value/16843009.0));
362static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
364#if !defined(MAGICKCORE_HDRI_SUPPORT)
365 return((Quantum) (value/MagickULLConstant(72340172838076673)));
367 return((Quantum) (value/72340172838076673.0));
371static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
376 return(QuantumRange);
377#if !defined(MAGICKCORE_HDRI_SUPPORT)
378 return((Quantum) (value+0.5));
380 return((Quantum) value);
384static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
386#if !defined(MAGICKCORE_HDRI_SUPPORT)
387 return((
unsigned int) (16843009UL*quantum));
389 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
391 if ((16843009.0*quantum) >= 4294967295.0)
392 return(4294967295UL);
393 return((
unsigned int) (16843009.0*quantum+0.5));
397static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
399#if !defined(MAGICKCORE_HDRI_SUPPORT)
400 return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
402 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
404 if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
405 return(MagickULLConstant(18446744073709551615));
406 return((MagickSizeType) (72340172838076673.0*quantum+0.5));
410static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
412 if (quantum >= (Quantum) MaxMap)
413 return((
unsigned int) MaxMap);
414#if !defined(MAGICKCORE_HDRI_SUPPORT)
415 return((
unsigned int) quantum);
417 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
419 return((
unsigned int) (quantum+0.5));
423static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
425#if !defined(MAGICKCORE_HDRI_SUPPORT)
426 return((
unsigned short) (257UL*quantum));
428 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
430 if ((257.0*quantum) >= 65535.0)
432 return((
unsigned short) (257.0*quantum+0.5));
436static inline Quantum ScaleShortToQuantum(
const unsigned short value)
438#if !defined(MAGICKCORE_HDRI_SUPPORT)
439 return((Quantum) ((value+128U)/257U));
441 return((Quantum) (value/257.0));
444#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
445static inline Quantum ScaleCharToQuantum(
const unsigned char value)
447#if !defined(MAGICKCORE_HDRI_SUPPORT)
448 return((Quantum) (257U*value));
450 return((Quantum) (257.0*value));
454static inline Quantum ScaleLongToQuantum(
const unsigned int value)
456#if !defined(MAGICKCORE_HDRI_SUPPORT)
457 return((Quantum) ((value)/MagickULLConstant(65537)));
459 return((Quantum) (value/65537.0));
463static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
465#if !defined(MAGICKCORE_HDRI_SUPPORT)
466 return((Quantum) ((value)/MagickULLConstant(281479271743489)));
468 return((Quantum) (value/281479271743489.0));
472static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
477 return(QuantumRange);
478#if !defined(MAGICKCORE_HDRI_SUPPORT)
479 return((Quantum) (value+0.5));
481 return((Quantum) value);
485static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
487#if !defined(MAGICKCORE_HDRI_SUPPORT)
488 return((
unsigned int) (65537UL*quantum));
490 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
492 if ((65537.0*(
double) quantum) >= 4294967295.0)
494 return((
unsigned int) (65537.0*(
double) quantum+0.5));
498static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
500#if !defined(MAGICKCORE_HDRI_SUPPORT)
501 return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
503 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
505 if ((281479271743489.0*(
double) quantum) >= 18446744073709551615.0)
506 return(MagickULLConstant(18446744073709551615));
507 return((MagickSizeType) (281479271743489.0*(
double) quantum+0.5));
511static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
513 if (quantum >= (Quantum) MaxMap)
514 return((
unsigned int) MaxMap);
515#if !defined(MAGICKCORE_HDRI_SUPPORT)
516 return((
unsigned int) quantum);
518 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
520 return((
unsigned int) (quantum+0.5f));
524static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
526#if !defined(MAGICKCORE_HDRI_SUPPORT)
527 return((
unsigned short) quantum);
529 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
531 if (quantum >= 65535.0f)
533 return((
unsigned short) (quantum+0.5f));
537static inline Quantum ScaleShortToQuantum(
const unsigned short value)
539 return((Quantum) value);
541#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
542static inline Quantum ScaleCharToQuantum(
const unsigned char value)
544#if !defined(MAGICKCORE_HDRI_SUPPORT)
545 return((Quantum) (16843009UL*value));
547 return((Quantum) (16843009.0*value));
551static inline Quantum ScaleLongToQuantum(
const unsigned int value)
553 return((Quantum) value);
556static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
558#if !defined(MAGICKCORE_HDRI_SUPPORT)
559 return((Quantum) ((value)/MagickULLConstant(4294967297)));
561 return((Quantum) (value/4294967297.0));
565static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
569 if (value >= (Quantum) MaxMap)
570 return(QuantumRange);
571#if !defined(MAGICKCORE_HDRI_SUPPORT)
572 return((Quantum) (65537.0*value+0.5));
574 return((Quantum) (65537.0*value));
578static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
580#if !defined(MAGICKCORE_HDRI_SUPPORT)
581 return((
unsigned int) quantum);
583 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
585 if ((quantum) >= 4294967295.0)
587 return((
unsigned int) (quantum+0.5));
591static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
593#if !defined(MAGICKCORE_HDRI_SUPPORT)
594 return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
596 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
598 if ((4294967297.0*quantum) >= 18446744073709551615.0)
599 return(MagickULLConstant(18446744073709551615));
600 return((MagickSizeType) (4294967297.0*quantum+0.5));
604static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
606 if ((quantum/65537) >= (Quantum) MaxMap)
607 return((
unsigned int) MaxMap);
608#if !defined(MAGICKCORE_HDRI_SUPPORT)
609 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
610 MagickULLConstant(65537)));
612 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
614 return((
unsigned int) (quantum/65537.0+0.5));
618static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
620#if !defined(MAGICKCORE_HDRI_SUPPORT)
621 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
622 MagickULLConstant(65537)));
624 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
626 if ((quantum/65537.0) >= 65535.0)
628 return((
unsigned short) (quantum/65537.0+0.5));
632static inline Quantum ScaleShortToQuantum(
const unsigned short value)
634#if !defined(MAGICKCORE_HDRI_SUPPORT)
635 return((Quantum) (65537UL*value));
637 return((Quantum) (65537.0*value));
640#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
641static inline Quantum ScaleCharToQuantum(
const unsigned char value)
643 return((Quantum) (72340172838076673.0*value));
646static inline Quantum ScaleLongToQuantum(
const unsigned int value)
648 return((Quantum) (4294967297.0*value));
651static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
653 return((Quantum) (value));
656static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
661 return(QuantumRange);
662 return((Quantum) (281479271743489.0*value));
665static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
667 return((
unsigned int) (quantum/4294967297.0+0.5));
670static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
672#if !defined(MAGICKCORE_HDRI_SUPPORT)
673 return((MagickSizeType) quantum);
675 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
677 if (quantum >= 18446744073709551615.0)
678 return(MagickULLConstant(18446744073709551615));
679 return((MagickSizeType) (quantum+0.5));
683static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
685 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
687 if ((quantum/281479271743489.0) >= MaxMap)
688 return((
unsigned int) MaxMap);
689 return((
unsigned int) (quantum/281479271743489.0+0.5));
692static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
694 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
696 if ((quantum/281479271743489.0) >= 65535.0)
698 return((
unsigned short) (quantum/281479271743489.0+0.5));
701static inline Quantum ScaleShortToQuantum(
const unsigned short value)
703 return((Quantum) (281479271743489.0*value));
707static inline unsigned short SinglePrecisionToHalf(
const double value)
709 typedef union _SinglePrecision
738 map.single_precision=(float) value;
739 sign_bit=(map.fixed_point >> 16) & 0x00008000;
740 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
741 significand=map.fixed_point & 0x007fffff;
748 return((
unsigned short) sign_bit);
749 significand=significand | 0x00800000;
750 shift=(int) (14-exponent);
751 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
752 ((significand >> shift) & 0x01)) >> shift);
753 return((
unsigned short) (sign_bit | significand));
756 if (exponent == (0xff-ExponentBias))
758 if (significand == 0)
759 return((
unsigned short) (sign_bit | ExponentMask));
762 significand>>=SignificandShift;
763 half=(
unsigned short) (sign_bit | significand |
764 (significand == 0) | ExponentMask);
768 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
769 if ((significand & 0x00800000) != 0)
786 for (i=0; i < 10; i++)
788 return((
unsigned short) (sign_bit | ExponentMask));
790 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
791 (significand >> SignificandShift));
795#if defined(__cplusplus) || defined(c_plusplus)