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)
95 extern MagickExport MagickBooleanType
98 extern MagickPrivate
void
101 static 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)));
117 static inline EndianType GetHostEndian(
void)
123 return((*(
char *) &lsb_first) == 1 ? LSBEndian : MSBEndian);
126 static inline float HalfToSinglePrecision(
const unsigned short half)
128 #define ExponentBias (127-15)
129 #define ExponentMask (0x7c00U)
130 #define ExponentShift 23
131 #define SignBitShift 31
132 #define SignificandShift 13
133 #define SignificandMask (0x00000400U)
135 typedef union _SinglePrecision
160 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
161 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
162 significand=(
unsigned int) (half & 0x000003ff);
165 if (significand == 0)
166 value=sign_bit << SignBitShift;
169 while ((significand & SignificandMask) == 0)
175 significand&=(~SignificandMask);
176 exponent+=ExponentBias;
177 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
178 (significand << SignificandShift);
182 if (exponent == SignBitShift)
184 value=(sign_bit << SignBitShift) | 0x7f800000;
185 if (significand != 0)
186 value|=(significand << SignificandShift);
190 exponent+=ExponentBias;
191 significand<<=SignificandShift;
192 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
195 map.fixed_point=value;
196 return(map.single_precision);
199 static inline unsigned char *PopCharPixel(
const unsigned char pixel,
200 unsigned char *magick_restrict pixels)
206 static inline unsigned char *PopLongPixel(
const EndianType endian,
207 const unsigned int pixel,
unsigned char *magick_restrict pixels)
212 quantum=(
unsigned int) pixel;
213 if (endian == LSBEndian)
215 *pixels++=(
unsigned char) (quantum);
216 *pixels++=(
unsigned char) (quantum >> 8);
217 *pixels++=(
unsigned char) (quantum >> 16);
218 *pixels++=(
unsigned char) (quantum >> 24);
221 *pixels++=(
unsigned char) (quantum >> 24);
222 *pixels++=(
unsigned char) (quantum >> 16);
223 *pixels++=(
unsigned char) (quantum >> 8);
224 *pixels++=(
unsigned char) (quantum);
228 static inline unsigned char *PopShortPixel(
const EndianType endian,
229 const unsigned short pixel,
unsigned char *magick_restrict pixels)
235 if (endian == LSBEndian)
237 *pixels++=(
unsigned char) (quantum);
238 *pixels++=(
unsigned char) (quantum >> 8);
241 *pixels++=(
unsigned char) (quantum >> 8);
242 *pixels++=(
unsigned char) (quantum);
246 static inline const unsigned char *PushCharPixel(
247 const unsigned char *magick_restrict pixels,
248 unsigned char *magick_restrict pixel)
254 static inline const unsigned char *PushLongPixel(
const EndianType endian,
255 const unsigned char *magick_restrict pixels,
256 unsigned int *magick_restrict pixel)
261 if (endian == LSBEndian)
263 quantum=((
unsigned int) *pixels++);
264 quantum|=((
unsigned int) *pixels++ << 8);
265 quantum|=((
unsigned int) *pixels++ << 16);
266 quantum|=((
unsigned int) *pixels++ << 24);
270 quantum=((
unsigned int) *pixels++ << 24);
271 quantum|=((
unsigned int) *pixels++ << 16);
272 quantum|=((
unsigned int) *pixels++ << 8);
273 quantum|=((
unsigned int) *pixels++);
278 static inline const unsigned char *PushShortPixel(
const EndianType endian,
279 const unsigned char *magick_restrict pixels,
280 unsigned short *magick_restrict pixel)
285 if (endian == LSBEndian)
287 quantum=(
unsigned int) *pixels++;
288 quantum|=(
unsigned int) (*pixels++ << 8);
289 *pixel=(
unsigned short) (quantum & 0xffff);
292 quantum=(
unsigned int) (*pixels++ << 8);
293 quantum|=(
unsigned int) *pixels++;
294 *pixel=(
unsigned short) (quantum & 0xffff);
298 static inline const unsigned char *PushFloatPixel(
const EndianType endian,
299 const unsigned char *magick_restrict pixels,
300 MagickFloatType *magick_restrict pixel)
311 if (endian == LSBEndian)
313 quantum.unsigned_value=((
unsigned int) *pixels++);
314 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
315 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
316 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
317 *pixel=quantum.float_value;
320 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
321 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
322 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
323 quantum.unsigned_value|=((
unsigned int) *pixels++);
324 *pixel=quantum.float_value;
328 static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
329 const QuantumAny range)
332 return(QuantumRange);
333 #if !defined(MAGICKCORE_HDRI_SUPPORT)
334 return((Quantum) ((
double) QuantumRange*(quantum*
335 MagickSafeReciprocal((
double) range))+0.5));
337 return((Quantum) ((
double) QuantumRange*(quantum*
338 MagickSafeReciprocal((
double) range))));
342 static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
343 const QuantumAny range)
345 #if !defined(MAGICKCORE_HDRI_SUPPORT)
346 return((QuantumAny) ((
double) range*quantum/QuantumRange));
348 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
349 return((QuantumAny) 0UL);
350 if (((
double) range*quantum/(
double) QuantumRange) >= 18446744073709551615.0)
351 return((QuantumAny) MagickULLConstant(18446744073709551615));
352 return((QuantumAny) (range*(
double) quantum/(
double) QuantumRange+0.5));
356 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
357 static inline Quantum ScaleCharToQuantum(
const unsigned char value)
359 return((Quantum) value);
362 static inline Quantum ScaleLongToQuantum(
const unsigned int value)
364 #if !defined(MAGICKCORE_HDRI_SUPPORT)
365 return((Quantum) ((value)/16843009UL));
367 return((Quantum) (value/16843009.0));
371 static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
373 #if !defined(MAGICKCORE_HDRI_SUPPORT)
374 return((Quantum) (value/MagickULLConstant(72340172838076673)));
376 return((Quantum) (value/72340172838076673.0));
380 static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
385 return(QuantumRange);
386 #if !defined(MAGICKCORE_HDRI_SUPPORT)
387 return((Quantum) (value+0.5));
389 return((Quantum) value);
393 static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
395 #if !defined(MAGICKCORE_HDRI_SUPPORT)
396 return((
unsigned int) (16843009UL*quantum));
398 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
400 if ((16843009.0*quantum) >= 4294967295.0)
401 return(4294967295UL);
402 return((
unsigned int) (16843009.0*quantum+0.5));
406 static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
408 #if !defined(MAGICKCORE_HDRI_SUPPORT)
409 return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
411 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
413 if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
414 return(MagickULLConstant(18446744073709551615));
415 return((MagickSizeType) (72340172838076673.0*quantum+0.5));
419 static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
421 if (quantum >= (Quantum) MaxMap)
422 return((
unsigned int) MaxMap);
423 #if !defined(MAGICKCORE_HDRI_SUPPORT)
424 return((
unsigned int) quantum);
426 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
428 return((
unsigned int) (quantum+0.5));
432 static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
434 #if !defined(MAGICKCORE_HDRI_SUPPORT)
435 return((
unsigned short) (257UL*quantum));
437 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
439 if ((257.0*quantum) >= 65535.0)
441 return((
unsigned short) (257.0*quantum+0.5));
445 static inline Quantum ScaleShortToQuantum(
const unsigned short value)
447 #if !defined(MAGICKCORE_HDRI_SUPPORT)
448 return((Quantum) ((value+128U)/257U));
450 return((Quantum) (value/257.0));
453 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
454 static inline Quantum ScaleCharToQuantum(
const unsigned char value)
456 #if !defined(MAGICKCORE_HDRI_SUPPORT)
457 return((Quantum) (257U*value));
459 return((Quantum) (257.0*value));
463 static inline Quantum ScaleLongToQuantum(
const unsigned int value)
465 #if !defined(MAGICKCORE_HDRI_SUPPORT)
466 return((Quantum) ((value)/MagickULLConstant(65537)));
468 return((Quantum) (value/65537.0));
472 static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
474 #if !defined(MAGICKCORE_HDRI_SUPPORT)
475 return((Quantum) ((value)/MagickULLConstant(281479271743489)));
477 return((Quantum) (value/281479271743489.0));
481 static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
486 return(QuantumRange);
487 #if !defined(MAGICKCORE_HDRI_SUPPORT)
488 return((Quantum) (value+0.5));
490 return((Quantum) value);
494 static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
496 #if !defined(MAGICKCORE_HDRI_SUPPORT)
497 return((
unsigned int) (65537UL*quantum));
499 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
501 if ((65537.0*(
double) quantum) >= 4294967295.0)
503 return((
unsigned int) (65537.0*(
double) quantum+0.5));
507 static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
509 #if !defined(MAGICKCORE_HDRI_SUPPORT)
510 return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
512 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
514 if ((281479271743489.0*(
double) quantum) >= 18446744073709551615.0)
515 return(MagickULLConstant(18446744073709551615));
516 return((MagickSizeType) (281479271743489.0*(
double) quantum+0.5));
520 static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
522 if (quantum >= (Quantum) MaxMap)
523 return((
unsigned int) MaxMap);
524 #if !defined(MAGICKCORE_HDRI_SUPPORT)
525 return((
unsigned int) quantum);
527 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
529 return((
unsigned int) (quantum+0.5f));
533 static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
535 #if !defined(MAGICKCORE_HDRI_SUPPORT)
536 return((
unsigned short) quantum);
538 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
540 if (quantum >= 65535.0f)
542 return((
unsigned short) (quantum+0.5f));
546 static inline Quantum ScaleShortToQuantum(
const unsigned short value)
548 return((Quantum) value);
550 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
551 static inline Quantum ScaleCharToQuantum(
const unsigned char value)
553 #if !defined(MAGICKCORE_HDRI_SUPPORT)
554 return((Quantum) (16843009UL*value));
556 return((Quantum) (16843009.0*value));
560 static inline Quantum ScaleLongToQuantum(
const unsigned int value)
562 return((Quantum) value);
565 static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
567 #if !defined(MAGICKCORE_HDRI_SUPPORT)
568 return((Quantum) ((value)/MagickULLConstant(4294967297)));
570 return((Quantum) (value/4294967297.0));
574 static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
578 if (value >= (Quantum) MaxMap)
579 return(QuantumRange);
580 #if !defined(MAGICKCORE_HDRI_SUPPORT)
581 return((Quantum) (65537.0*value+0.5));
583 return((Quantum) (65537.0*value));
587 static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
589 #if !defined(MAGICKCORE_HDRI_SUPPORT)
590 return((
unsigned int) quantum);
592 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
594 if ((quantum) >= 4294967295.0)
596 return((
unsigned int) (quantum+0.5));
600 static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
602 #if !defined(MAGICKCORE_HDRI_SUPPORT)
603 return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
605 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
607 if ((4294967297.0*quantum) >= 18446744073709551615.0)
608 return(MagickULLConstant(18446744073709551615));
609 return((MagickSizeType) (4294967297.0*quantum+0.5));
613 static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
615 if ((quantum/65537) >= (Quantum) MaxMap)
616 return((
unsigned int) MaxMap);
617 #if !defined(MAGICKCORE_HDRI_SUPPORT)
618 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
619 MagickULLConstant(65537)));
621 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
623 return((
unsigned int) (quantum/65537.0+0.5));
627 static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
629 #if !defined(MAGICKCORE_HDRI_SUPPORT)
630 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
631 MagickULLConstant(65537)));
633 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
635 if ((quantum/65537.0) >= 65535.0)
637 return((
unsigned short) (quantum/65537.0+0.5));
641 static inline Quantum ScaleShortToQuantum(
const unsigned short value)
643 #if !defined(MAGICKCORE_HDRI_SUPPORT)
644 return((Quantum) (65537UL*value));
646 return((Quantum) (65537.0*value));
649 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
650 static inline Quantum ScaleCharToQuantum(
const unsigned char value)
652 return((Quantum) (72340172838076673.0*value));
655 static inline Quantum ScaleLongToQuantum(
const unsigned int value)
657 return((Quantum) (4294967297.0*value));
660 static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
662 return((Quantum) (value));
665 static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
670 return(QuantumRange);
671 return((Quantum) (281479271743489.0*value));
674 static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
676 return((
unsigned int) (quantum/4294967297.0+0.5));
679 static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
681 #if !defined(MAGICKCORE_HDRI_SUPPORT)
682 return((MagickSizeType) quantum);
684 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
686 if (quantum >= 18446744073709551615.0)
687 return(MagickULLConstant(18446744073709551615));
688 return((MagickSizeType) (quantum+0.5));
692 static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
694 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
696 if ((quantum/281479271743489.0) >= MaxMap)
697 return((
unsigned int) MaxMap);
698 return((
unsigned int) (quantum/281479271743489.0+0.5));
701 static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
703 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
705 if ((quantum/281479271743489.0) >= 65535.0)
707 return((
unsigned short) (quantum/281479271743489.0+0.5));
710 static inline Quantum ScaleShortToQuantum(
const unsigned short value)
712 return((Quantum) (281479271743489.0*value));
716 static inline unsigned short SinglePrecisionToHalf(
const double value)
718 typedef union _SinglePrecision
747 map.single_precision=(float) value;
748 sign_bit=(map.fixed_point >> 16) & 0x00008000;
749 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
750 significand=map.fixed_point & 0x007fffff;
757 return((
unsigned short) sign_bit);
758 significand=significand | 0x00800000;
759 shift=(int) (14-exponent);
760 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
761 ((significand >> shift) & 0x01)) >> shift);
762 return((
unsigned short) (sign_bit | significand));
765 if (exponent == (0xff-ExponentBias))
767 if (significand == 0)
768 return((
unsigned short) (sign_bit | ExponentMask));
771 significand>>=SignificandShift;
772 half=(
unsigned short) (sign_bit | significand |
773 (significand == 0) | ExponentMask);
777 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
778 if ((significand & 0x00800000) != 0)
795 for (i=0; i < 10; i++)
797 return((
unsigned short) (sign_bit | ExponentMask));
799 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
800 (significand >> SignificandShift));
804 #if defined(__cplusplus) || defined(c_plusplus)