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 EndianType GetHostEndian(
void)
123 return((*(
char *) &lsb_first) == 1 ? LSBEndian : MSBEndian);
126static 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);
199static inline unsigned char *PopCharPixel(
const unsigned char pixel,
200 unsigned char *magick_restrict pixels)
206static 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);
228static 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);
246static inline const unsigned char *PushCharPixel(
247 const unsigned char *magick_restrict pixels,
248 unsigned char *magick_restrict pixel)
254static 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++);
278static 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);
298static 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;
328static 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))));
342static 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)
357static inline Quantum ScaleCharToQuantum(
const unsigned char value)
359 return((Quantum) value);
362static inline Quantum ScaleLongToQuantum(
const unsigned int value)
364#if !defined(MAGICKCORE_HDRI_SUPPORT)
365 return((Quantum) ((value)/16843009UL));
367 return((Quantum) (value/16843009.0));
371static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
373#if !defined(MAGICKCORE_HDRI_SUPPORT)
374 return((Quantum) (value/MagickULLConstant(72340172838076673)));
376 return((Quantum) (value/72340172838076673.0));
380static 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);
393static 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));
406static 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));
419static 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));
432static 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));
445static 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)
454static inline Quantum ScaleCharToQuantum(
const unsigned char value)
456#if !defined(MAGICKCORE_HDRI_SUPPORT)
457 return((Quantum) (257U*value));
459 return((Quantum) (257.0*value));
463static 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));
472static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
474#if !defined(MAGICKCORE_HDRI_SUPPORT)
475 return((Quantum) ((value)/MagickULLConstant(281479271743489)));
477 return((Quantum) (value/281479271743489.0));
481static 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);
494static 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));
507static 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));
520static 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));
533static 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));
546static inline Quantum ScaleShortToQuantum(
const unsigned short value)
548 return((Quantum) value);
550#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
551static inline Quantum ScaleCharToQuantum(
const unsigned char value)
553#if !defined(MAGICKCORE_HDRI_SUPPORT)
554 return((Quantum) (16843009UL*value));
556 return((Quantum) (16843009.0*value));
560static inline Quantum ScaleLongToQuantum(
const unsigned int value)
562 return((Quantum) value);
565static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
567#if !defined(MAGICKCORE_HDRI_SUPPORT)
568 return((Quantum) ((value)/MagickULLConstant(4294967297)));
570 return((Quantum) (value/4294967297.0));
574static 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));
587static 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));
600static 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));
613static 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));
627static 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));
641static 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)
650static inline Quantum ScaleCharToQuantum(
const unsigned char value)
652 return((Quantum) (72340172838076673.0*value));
655static inline Quantum ScaleLongToQuantum(
const unsigned int value)
657 return((Quantum) (4294967297.0*value));
660static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
662 return((Quantum) (value));
665static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
670 return(QuantumRange);
671 return((Quantum) (281479271743489.0*value));
674static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
676 return((
unsigned int) (quantum/4294967297.0+0.5));
679static 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));
692static 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));
701static 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));
710static inline Quantum ScaleShortToQuantum(
const unsigned short value)
712 return((Quantum) (281479271743489.0*value));
716static 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)