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)
92extern MagickPrivate
void
93 ResetQuantumState(QuantumInfo *);
95static inline MagickSizeType GetQuantumRange(
const size_t depth)
106 max_depth=8*
sizeof(MagickSizeType);
107 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
108 ((one << (MagickMin(depth,max_depth)-1))-1)));
111static inline float HalfToSinglePrecision(
const unsigned short half)
113#define ExponentBias (127-15)
114#define ExponentMask (0x7c00U)
115#define ExponentShift 23
116#define SignBitShift 31
117#define SignificandShift 13
118#define SignificandMask (0x00000400U)
120 typedef union _SinglePrecision
145 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
146 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
147 significand=(
unsigned int) (half & 0x000003ff);
150 if (significand == 0)
151 value=sign_bit << SignBitShift;
154 while ((significand & SignificandMask) == 0)
160 significand&=(~SignificandMask);
161 exponent+=ExponentBias;
162 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
163 (significand << SignificandShift);
167 if (exponent == SignBitShift)
169 value=(sign_bit << SignBitShift) | 0x7f800000;
170 if (significand != 0)
171 value|=(significand << SignificandShift);
175 exponent+=ExponentBias;
176 significand<<=SignificandShift;
177 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
180 map.fixed_point=value;
181 return(map.single_precision);
184static inline unsigned char *PopCharPixel(
const unsigned char pixel,
185 unsigned char *magick_restrict pixels)
191static inline unsigned char *PopLongPixel(
const EndianType endian,
192 const unsigned int pixel,
unsigned char *magick_restrict pixels)
197 quantum=(
unsigned int) pixel;
198 if (endian == LSBEndian)
200 *pixels++=(
unsigned char) (quantum);
201 *pixels++=(
unsigned char) (quantum >> 8);
202 *pixels++=(
unsigned char) (quantum >> 16);
203 *pixels++=(
unsigned char) (quantum >> 24);
206 *pixels++=(
unsigned char) (quantum >> 24);
207 *pixels++=(
unsigned char) (quantum >> 16);
208 *pixels++=(
unsigned char) (quantum >> 8);
209 *pixels++=(
unsigned char) (quantum);
213static inline unsigned char *PopShortPixel(
const EndianType endian,
214 const unsigned short pixel,
unsigned char *magick_restrict pixels)
220 if (endian == LSBEndian)
222 *pixels++=(
unsigned char) (quantum);
223 *pixels++=(
unsigned char) (quantum >> 8);
226 *pixels++=(
unsigned char) (quantum >> 8);
227 *pixels++=(
unsigned char) (quantum);
231static inline const unsigned char *PushCharPixel(
232 const unsigned char *magick_restrict pixels,
233 unsigned char *magick_restrict pixel)
239static inline const unsigned char *PushLongPixel(
const EndianType endian,
240 const unsigned char *magick_restrict pixels,
241 unsigned int *magick_restrict pixel)
246 if (endian == LSBEndian)
248 quantum=((
unsigned int) *pixels++);
249 quantum|=((
unsigned int) *pixels++ << 8);
250 quantum|=((
unsigned int) *pixels++ << 16);
251 quantum|=((
unsigned int) *pixels++ << 24);
255 quantum=((
unsigned int) *pixels++ << 24);
256 quantum|=((
unsigned int) *pixels++ << 16);
257 quantum|=((
unsigned int) *pixels++ << 8);
258 quantum|=((
unsigned int) *pixels++);
263static inline const unsigned char *PushShortPixel(
const EndianType endian,
264 const unsigned char *magick_restrict pixels,
265 unsigned short *magick_restrict pixel)
270 if (endian == LSBEndian)
272 quantum=(
unsigned int) *pixels++;
273 quantum|=(
unsigned int) (*pixels++ << 8);
274 *pixel=(
unsigned short) (quantum & 0xffff);
277 quantum=(
unsigned int) (*pixels++ << 8);
278 quantum|=(
unsigned int) *pixels++;
279 *pixel=(
unsigned short) (quantum & 0xffff);
283static inline const unsigned char *PushFloatPixel(
const EndianType endian,
284 const unsigned char *magick_restrict pixels,
285 MagickFloatType *magick_restrict pixel)
296 if (endian == LSBEndian)
298 quantum.unsigned_value=((
unsigned int) *pixels++);
299 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
300 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
301 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
302 *pixel=quantum.float_value;
305 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
306 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
307 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
308 quantum.unsigned_value|=((
unsigned int) *pixels++);
309 *pixel=quantum.float_value;
313static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
314 const QuantumAny range)
317 return(QuantumRange);
318#if !defined(MAGICKCORE_HDRI_SUPPORT)
319 return((Quantum) ((
double) QuantumRange*(quantum*
320 MagickSafeReciprocal((
double) range))+0.5));
322 return((Quantum) ((
double) QuantumRange*(quantum*
323 MagickSafeReciprocal((
double) range))));
327static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
328 const QuantumAny range)
330#if !defined(MAGICKCORE_HDRI_SUPPORT)
331 return((QuantumAny) ((
double) range*quantum/QuantumRange));
333 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
334 return((QuantumAny) 0UL);
335 if (((
double) range*quantum/(
double) QuantumRange) >= 18446744073709551615.0)
336 return((QuantumAny) MagickULLConstant(18446744073709551615));
337 return((QuantumAny) (range*(
double) quantum/(
double) QuantumRange+0.5));
341#if (MAGICKCORE_QUANTUM_DEPTH == 8)
342static inline Quantum ScaleCharToQuantum(
const unsigned char value)
344 return((Quantum) value);
347static inline Quantum ScaleLongToQuantum(
const unsigned int value)
349#if !defined(MAGICKCORE_HDRI_SUPPORT)
350 return((Quantum) ((value)/16843009UL));
352 return((Quantum) (value/16843009.0));
356static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
358#if !defined(MAGICKCORE_HDRI_SUPPORT)
359 return((Quantum) (value/MagickULLConstant(72340172838076673)));
361 return((Quantum) (value/72340172838076673.0));
365static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
370 return(QuantumRange);
371#if !defined(MAGICKCORE_HDRI_SUPPORT)
372 return((Quantum) (value+0.5));
374 return((Quantum) value);
378static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
380#if !defined(MAGICKCORE_HDRI_SUPPORT)
381 return((
unsigned int) (16843009UL*quantum));
383 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
385 if ((16843009.0*quantum) >= 4294967295.0)
386 return(4294967295UL);
387 return((
unsigned int) (16843009.0*quantum+0.5));
391static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
393#if !defined(MAGICKCORE_HDRI_SUPPORT)
394 return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
396 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
398 if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
399 return(MagickULLConstant(18446744073709551615));
400 return((MagickSizeType) (72340172838076673.0*quantum+0.5));
404static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
406 if (quantum >= (Quantum) MaxMap)
407 return((
unsigned int) MaxMap);
408#if !defined(MAGICKCORE_HDRI_SUPPORT)
409 return((
unsigned int) quantum);
411 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
413 return((
unsigned int) (quantum+0.5));
417static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
419#if !defined(MAGICKCORE_HDRI_SUPPORT)
420 return((
unsigned short) (257UL*quantum));
422 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
424 if ((257.0*quantum) >= 65535.0)
426 return((
unsigned short) (257.0*quantum+0.5));
430static inline Quantum ScaleShortToQuantum(
const unsigned short value)
432#if !defined(MAGICKCORE_HDRI_SUPPORT)
433 return((Quantum) ((value+128U)/257U));
435 return((Quantum) (value/257.0));
438#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
439static inline Quantum ScaleCharToQuantum(
const unsigned char value)
441#if !defined(MAGICKCORE_HDRI_SUPPORT)
442 return((Quantum) (257U*value));
444 return((Quantum) (257.0*value));
448static inline Quantum ScaleLongToQuantum(
const unsigned int value)
450#if !defined(MAGICKCORE_HDRI_SUPPORT)
451 return((Quantum) ((value)/MagickULLConstant(65537)));
453 return((Quantum) (value/65537.0));
457static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
459#if !defined(MAGICKCORE_HDRI_SUPPORT)
460 return((Quantum) ((value)/MagickULLConstant(281479271743489)));
462 return((Quantum) (value/281479271743489.0));
466static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
471 return(QuantumRange);
472#if !defined(MAGICKCORE_HDRI_SUPPORT)
473 return((Quantum) (value+0.5));
475 return((Quantum) value);
479static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
481#if !defined(MAGICKCORE_HDRI_SUPPORT)
482 return((
unsigned int) (65537UL*quantum));
484 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
486 if ((65537.0*(
double) quantum) >= 4294967295.0)
488 return((
unsigned int) (65537.0*(
double) quantum+0.5));
492static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
494#if !defined(MAGICKCORE_HDRI_SUPPORT)
495 return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
497 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
499 if ((281479271743489.0*(
double) quantum) >= 18446744073709551615.0)
500 return(MagickULLConstant(18446744073709551615));
501 return((MagickSizeType) (281479271743489.0*(
double) quantum+0.5));
505static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
507 if (quantum >= (Quantum) MaxMap)
508 return((
unsigned int) MaxMap);
509#if !defined(MAGICKCORE_HDRI_SUPPORT)
510 return((
unsigned int) quantum);
512 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
514 return((
unsigned int) (quantum+0.5f));
518static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
520#if !defined(MAGICKCORE_HDRI_SUPPORT)
521 return((
unsigned short) quantum);
523 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
525 if (quantum >= 65535.0f)
527 return((
unsigned short) (quantum+0.5f));
531static inline Quantum ScaleShortToQuantum(
const unsigned short value)
533 return((Quantum) value);
535#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
536static inline Quantum ScaleCharToQuantum(
const unsigned char value)
538#if !defined(MAGICKCORE_HDRI_SUPPORT)
539 return((Quantum) (16843009UL*value));
541 return((Quantum) (16843009.0*value));
545static inline Quantum ScaleLongToQuantum(
const unsigned int value)
547 return((Quantum) value);
550static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
552#if !defined(MAGICKCORE_HDRI_SUPPORT)
553 return((Quantum) ((value)/MagickULLConstant(4294967297)));
555 return((Quantum) (value/4294967297.0));
559static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
563 if (value >= (Quantum) MaxMap)
564 return(QuantumRange);
565#if !defined(MAGICKCORE_HDRI_SUPPORT)
566 return((Quantum) (65537.0*value+0.5));
568 return((Quantum) (65537.0*value));
572static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
574#if !defined(MAGICKCORE_HDRI_SUPPORT)
575 return((
unsigned int) quantum);
577 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
579 if ((quantum) >= 4294967295.0)
581 return((
unsigned int) (quantum+0.5));
585static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
587#if !defined(MAGICKCORE_HDRI_SUPPORT)
588 return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
590 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
592 if ((4294967297.0*quantum) >= 18446744073709551615.0)
593 return(MagickULLConstant(18446744073709551615));
594 return((MagickSizeType) (4294967297.0*quantum+0.5));
598static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
600 if ((quantum/65537) >= (Quantum) MaxMap)
601 return((
unsigned int) MaxMap);
602#if !defined(MAGICKCORE_HDRI_SUPPORT)
603 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
604 MagickULLConstant(65537)));
606 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
608 return((
unsigned int) (quantum/65537.0+0.5));
612static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
614#if !defined(MAGICKCORE_HDRI_SUPPORT)
615 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
616 MagickULLConstant(65537)));
618 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
620 if ((quantum/65537.0) >= 65535.0)
622 return((
unsigned short) (quantum/65537.0+0.5));
626static inline Quantum ScaleShortToQuantum(
const unsigned short value)
628#if !defined(MAGICKCORE_HDRI_SUPPORT)
629 return((Quantum) (65537UL*value));
631 return((Quantum) (65537.0*value));
634#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
635static inline Quantum ScaleCharToQuantum(
const unsigned char value)
637 return((Quantum) (72340172838076673.0*value));
640static inline Quantum ScaleLongToQuantum(
const unsigned int value)
642 return((Quantum) (4294967297.0*value));
645static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
647 return((Quantum) (value));
650static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
655 return(QuantumRange);
656 return((Quantum) (281479271743489.0*value));
659static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
661 return((
unsigned int) (quantum/4294967297.0+0.5));
664static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
666#if !defined(MAGICKCORE_HDRI_SUPPORT)
667 return((MagickSizeType) quantum);
669 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
671 if (quantum >= 18446744073709551615.0)
672 return(MagickULLConstant(18446744073709551615));
673 return((MagickSizeType) (quantum+0.5));
677static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
679 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
681 if ((quantum/281479271743489.0) >= MaxMap)
682 return((
unsigned int) MaxMap);
683 return((
unsigned int) (quantum/281479271743489.0+0.5));
686static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
688 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
690 if ((quantum/281479271743489.0) >= 65535.0)
692 return((
unsigned short) (quantum/281479271743489.0+0.5));
695static inline Quantum ScaleShortToQuantum(
const unsigned short value)
697 return((Quantum) (281479271743489.0*value));
701static inline unsigned short SinglePrecisionToHalf(
const double value)
703 typedef union _SinglePrecision
732 map.single_precision=(float) value;
733 sign_bit=(map.fixed_point >> 16) & 0x00008000;
734 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
735 significand=map.fixed_point & 0x007fffff;
742 return((
unsigned short) sign_bit);
743 significand=significand | 0x00800000;
744 shift=(int) (14-exponent);
745 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
746 ((significand >> shift) & 0x01)) >> shift);
747 return((
unsigned short) (sign_bit | significand));
750 if (exponent == (0xff-ExponentBias))
752 if (significand == 0)
753 return((
unsigned short) (sign_bit | ExponentMask));
756 significand>>=SignificandShift;
757 half=(
unsigned short) (sign_bit | significand |
758 (significand == 0) | ExponentMask);
762 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
763 if ((significand & 0x00800000) != 0)
780 for (i=0; i < 10; i++)
782 return((
unsigned short) (sign_bit | ExponentMask));
784 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
785 (significand >> SignificandShift));
789#if defined(__cplusplus) || defined(c_plusplus)