18#ifndef MAGICKCORE_QUANTUM_PRIVATE_H
19#define MAGICKCORE_QUANTUM_PRIVATE_H
22#include "MagickCore/memory_.h"
23#include "MagickCore/cache.h"
24#include "MagickCore/image-private.h"
25#include "MagickCore/pixel-accessor.h"
26#include "MagickCore/statistic-private.h"
28#if defined(__cplusplus) || defined(c_plusplus)
32#define MagickMax(x,y) (((x) > (y)) ? (x) : (y))
33#define MagickMin(x,y) (((x) < (y)) ? (x) : (y))
99extern MagickExport MagickBooleanType
100 SetQuantumExtent(
const Image *,QuantumInfo *);
102extern MagickPrivate
void
103 ResetQuantumState(QuantumInfo *);
105static inline MagickSizeType GetQuantumRange(
const size_t depth)
116 max_depth=8*
sizeof(MagickSizeType);
117 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
118 ((one << (MagickMin(depth,max_depth)-1))-1)));
121static inline EndianType GetHostEndian(
void)
127 return((*(
char *) &lsb_first) == 1 ? LSBEndian : MSBEndian);
130static inline float HalfToSinglePrecision(
const unsigned short half)
132#define ExponentBias (127-15)
133#define ExponentMask (0x7c00U)
134#define ExponentShift 23
135#define SignBitShift 31
136#define SignificandShift 13
137#define SignificandMask (0x00000400U)
139 typedef union _SinglePrecision
164 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
165 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
166 significand=(
unsigned int) (half & 0x000003ff);
169 if (significand == 0)
170 value=sign_bit << SignBitShift;
173 while ((significand & SignificandMask) == 0)
179 significand&=(~SignificandMask);
180 exponent+=ExponentBias;
181 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
182 (significand << SignificandShift);
186 if (exponent == SignBitShift)
188 value=(sign_bit << SignBitShift) | 0x7f800000;
189 if (significand != 0)
190 value|=(significand << SignificandShift);
194 exponent+=ExponentBias;
195 significand<<=SignificandShift;
196 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
199 map.fixed_point=value;
200 return(map.single_precision);
203static inline unsigned char *PopCharPixel(
const unsigned char pixel,
204 unsigned char *magick_restrict pixels)
210static inline unsigned char *PopLongPixel(
const EndianType endian,
211 const unsigned int pixel,
unsigned char *magick_restrict pixels)
216 quantum=(
unsigned int) pixel;
217 if (endian == LSBEndian)
219 *pixels++=(
unsigned char) (quantum);
220 *pixels++=(
unsigned char) (quantum >> 8);
221 *pixels++=(
unsigned char) (quantum >> 16);
222 *pixels++=(
unsigned char) (quantum >> 24);
225 *pixels++=(
unsigned char) (quantum >> 24);
226 *pixels++=(
unsigned char) (quantum >> 16);
227 *pixels++=(
unsigned char) (quantum >> 8);
228 *pixels++=(
unsigned char) (quantum);
232static inline unsigned char *PopShortPixel(
const EndianType endian,
233 const unsigned short pixel,
unsigned char *magick_restrict pixels)
239 if (endian == LSBEndian)
241 *pixels++=(
unsigned char) (quantum);
242 *pixels++=(
unsigned char) (quantum >> 8);
245 *pixels++=(
unsigned char) (quantum >> 8);
246 *pixels++=(
unsigned char) (quantum);
250static inline const unsigned char *PushCharPixel(
251 const unsigned char *magick_restrict pixels,
252 unsigned char *magick_restrict pixel)
258static inline const unsigned char *PushLongPixel(
const EndianType endian,
259 const unsigned char *magick_restrict pixels,
260 unsigned int *magick_restrict pixel)
265 if (endian == LSBEndian)
267 quantum=((
unsigned int) *pixels++);
268 quantum|=((
unsigned int) *pixels++ << 8);
269 quantum|=((
unsigned int) *pixels++ << 16);
270 quantum|=((
unsigned int) *pixels++ << 24);
274 quantum=((
unsigned int) *pixels++ << 24);
275 quantum|=((
unsigned int) *pixels++ << 16);
276 quantum|=((
unsigned int) *pixels++ << 8);
277 quantum|=((
unsigned int) *pixels++);
282static inline const unsigned char *PushShortPixel(
const EndianType endian,
283 const unsigned char *magick_restrict pixels,
284 unsigned short *magick_restrict pixel)
289 if (endian == LSBEndian)
291 quantum=(
unsigned int) *pixels++;
292 quantum|=(
unsigned int) (*pixels++ << 8);
293 *pixel=(
unsigned short) (quantum & 0xffff);
296 quantum=(
unsigned int) (*pixels++ << 8);
297 quantum|=(
unsigned int) *pixels++;
298 *pixel=(
unsigned short) (quantum & 0xffff);
302static inline const unsigned char *PushFloatPixel(
const EndianType endian,
303 const unsigned char *magick_restrict pixels,
304 MagickFloatType *magick_restrict pixel)
315 if (endian == LSBEndian)
317 quantum.unsigned_value=((
unsigned int) *pixels++);
318 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
319 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
320 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
321 *pixel=quantum.float_value;
324 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
325 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
326 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
327 quantum.unsigned_value|=((
unsigned int) *pixels++);
328 *pixel=quantum.float_value;
332static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
333 const QuantumAny range)
336 return(QuantumRange);
337#if !defined(MAGICKCORE_HDRI_SUPPORT)
338 return((Quantum) ((
double) QuantumRange*(quantum*
339 MagickSafeReciprocal((
double) range))+0.5));
341 return((Quantum) ((
double) QuantumRange*((
double) quantum*
342 MagickSafeReciprocal((
double) range))));
346static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
347 const QuantumAny range)
349#if !defined(MAGICKCORE_HDRI_SUPPORT)
350 return((QuantumAny) ((
double) range*quantum/QuantumRange));
352 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
353 return((QuantumAny) 0UL);
354 if (((
double) range*(
double) quantum/(
double) QuantumRange) >= 18446744073709551615.0)
355 return((QuantumAny) MagickULLConstant(18446744073709551615));
356 return((QuantumAny) ((
double) range*(
double) quantum/(
double) QuantumRange+0.5));
360#if (MAGICKCORE_QUANTUM_DEPTH == 8)
361static inline Quantum ScaleCharToQuantum(
const unsigned char value)
363 return((Quantum) value);
366static inline Quantum ScaleLongToQuantum(
const unsigned int value)
368#if !defined(MAGICKCORE_HDRI_SUPPORT)
369 return((Quantum) ((value)/16843009UL));
371 return((Quantum) (value/16843009.0));
375static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
377#if !defined(MAGICKCORE_HDRI_SUPPORT)
378 return((Quantum) (value/MagickULLConstant(72340172838076673)));
380 return((Quantum) (value/72340172838076673.0));
384static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
389 return(QuantumRange);
390#if !defined(MAGICKCORE_HDRI_SUPPORT)
391 return((Quantum) (value+0.5));
393 return((Quantum) value);
397static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
399#if !defined(MAGICKCORE_HDRI_SUPPORT)
400 return((
unsigned int) (16843009UL*quantum));
402 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
404 if ((16843009.0*quantum) >= 4294967295.0)
405 return(4294967295UL);
406 return((
unsigned int) (16843009.0*quantum+0.5));
410static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
412#if !defined(MAGICKCORE_HDRI_SUPPORT)
413 return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
415 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
417 if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
418 return(MagickULLConstant(18446744073709551615));
419 return((MagickSizeType) (72340172838076673.0*quantum+0.5));
423static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
425 if (quantum >= (Quantum) MaxMap)
426 return((
unsigned int) MaxMap);
427#if !defined(MAGICKCORE_HDRI_SUPPORT)
428 return((
unsigned int) quantum);
430 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
432 return((
unsigned int) (quantum+0.5));
436static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
438#if !defined(MAGICKCORE_HDRI_SUPPORT)
439 return((
unsigned short) (257UL*quantum));
441 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
443 if ((257.0*quantum) >= 65535.0)
445 return((
unsigned short) (257.0*quantum+0.5));
449static inline Quantum ScaleShortToQuantum(
const unsigned short value)
451#if !defined(MAGICKCORE_HDRI_SUPPORT)
452 return((Quantum) ((value+128U)/257U));
454 return((Quantum) (value/257.0));
457#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
458static inline Quantum ScaleCharToQuantum(
const unsigned char value)
460#if !defined(MAGICKCORE_HDRI_SUPPORT)
461 return((Quantum) (257U*value));
463 return((Quantum) (257.0*value));
467static inline Quantum ScaleLongToQuantum(
const unsigned int value)
469#if !defined(MAGICKCORE_HDRI_SUPPORT)
470 return((Quantum) ((value)/MagickULLConstant(65537)));
472 return((Quantum) (value/65537.0));
476static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
478#if !defined(MAGICKCORE_HDRI_SUPPORT)
479 return((Quantum) ((value)/MagickULLConstant(281479271743489)));
481 return((Quantum) ((
double) value/281479271743489.0));
485static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
490 return(QuantumRange);
491#if !defined(MAGICKCORE_HDRI_SUPPORT)
492 return((Quantum) (value+0.5));
494 return((Quantum) value);
498static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
500#if !defined(MAGICKCORE_HDRI_SUPPORT)
501 return((
unsigned int) (65537UL*quantum));
503 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
505 if ((65537.0*(
double) quantum) >= 4294967295.0)
507 return((
unsigned int) (65537.0*(
double) quantum+0.5));
511static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
513#if !defined(MAGICKCORE_HDRI_SUPPORT)
514 return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
516 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
518 if ((281479271743489.0*(
double) quantum) >= 18446744073709551615.0)
519 return(MagickULLConstant(18446744073709551615));
520 return((MagickSizeType) (281479271743489.0*(
double) quantum+0.5));
524static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
526 if (quantum >= (Quantum) MaxMap)
527 return((
unsigned int) MaxMap);
528#if !defined(MAGICKCORE_HDRI_SUPPORT)
529 return((
unsigned int) quantum);
531 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
533 return((
unsigned int) (quantum+0.5f));
537static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
539#if !defined(MAGICKCORE_HDRI_SUPPORT)
540 return((
unsigned short) quantum);
542 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
544 if (quantum >= 65535.0f)
546 return((
unsigned short) (quantum+0.5f));
550static inline Quantum ScaleShortToQuantum(
const unsigned short value)
552 return((Quantum) value);
554#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
555static inline Quantum ScaleCharToQuantum(
const unsigned char value)
557#if !defined(MAGICKCORE_HDRI_SUPPORT)
558 return((Quantum) (16843009UL*value));
560 return((Quantum) (16843009.0*value));
564static inline Quantum ScaleLongToQuantum(
const unsigned int value)
566 return((Quantum) value);
569static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
571#if !defined(MAGICKCORE_HDRI_SUPPORT)
572 return((Quantum) ((value)/MagickULLConstant(4294967297)));
574 return((Quantum) (value/4294967297.0));
578static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
582 if (value >= (Quantum) MaxMap)
583 return(QuantumRange);
584#if !defined(MAGICKCORE_HDRI_SUPPORT)
585 return((Quantum) (65537.0*value+0.5));
587 return((Quantum) (65537.0*value));
591static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
593#if !defined(MAGICKCORE_HDRI_SUPPORT)
594 return((
unsigned int) quantum);
596 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
598 if ((quantum) >= 4294967295.0)
600 return((
unsigned int) (quantum+0.5));
604static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
606#if !defined(MAGICKCORE_HDRI_SUPPORT)
607 return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
609 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
611 if ((4294967297.0*quantum) >= 18446744073709551615.0)
612 return(MagickULLConstant(18446744073709551615));
613 return((MagickSizeType) (4294967297.0*quantum+0.5));
617static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
619 if ((quantum/65537) >= (Quantum) MaxMap)
620 return((
unsigned int) MaxMap);
621#if !defined(MAGICKCORE_HDRI_SUPPORT)
622 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
623 MagickULLConstant(65537)));
625 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
627 return((
unsigned int) (quantum/65537.0+0.5));
631static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
633#if !defined(MAGICKCORE_HDRI_SUPPORT)
634 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
635 MagickULLConstant(65537)));
637 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
639 if ((quantum/65537.0) >= 65535.0)
641 return((
unsigned short) (quantum/65537.0+0.5));
645static inline Quantum ScaleShortToQuantum(
const unsigned short value)
647#if !defined(MAGICKCORE_HDRI_SUPPORT)
648 return((Quantum) (65537UL*value));
650 return((Quantum) (65537.0*value));
653#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
654static inline Quantum ScaleCharToQuantum(
const unsigned char value)
656 return((Quantum) (72340172838076673.0*value));
659static inline Quantum ScaleLongToQuantum(
const unsigned int value)
661 return((Quantum) (4294967297.0*value));
664static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
666 return((Quantum) (value));
669static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
674 return(QuantumRange);
675 return((Quantum) (281479271743489.0*value));
678static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
680 return((
unsigned int) (quantum/4294967297.0+0.5));
683static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
685#if !defined(MAGICKCORE_HDRI_SUPPORT)
686 return((MagickSizeType) quantum);
688 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
690 if (quantum >= 18446744073709551615.0)
691 return(MagickULLConstant(18446744073709551615));
692 return((MagickSizeType) (quantum+0.5));
696static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
698 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
700 if ((quantum/281479271743489.0) >= MaxMap)
701 return((
unsigned int) MaxMap);
702 return((
unsigned int) (quantum/281479271743489.0+0.5));
705static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
707 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
709 if ((quantum/281479271743489.0) >= 65535.0)
711 return((
unsigned short) (quantum/281479271743489.0+0.5));
714static inline Quantum ScaleShortToQuantum(
const unsigned short value)
716 return((Quantum) (281479271743489.0*value));
720static inline unsigned short SinglePrecisionToHalf(
const double value)
722 typedef union _SinglePrecision
751 map.single_precision=(float) value;
752 sign_bit=(map.fixed_point >> 16) & 0x00008000;
753 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
754 significand=map.fixed_point & 0x007fffff;
761 return((
unsigned short) sign_bit);
762 significand=significand | 0x00800000;
763 shift=(int) (14-exponent);
764 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
765 ((significand >> shift) & 0x01)) >> shift);
766 return((
unsigned short) (sign_bit | significand));
769 if (exponent == (0xff-ExponentBias))
771 if (significand == 0)
772 return((
unsigned short) (sign_bit | ExponentMask));
775 significand>>=SignificandShift;
776 half=(
unsigned short) (sign_bit | significand |
777 (significand == 0) | ExponentMask);
781 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
782 if ((significand & 0x00800000) != 0)
799 for (i=0; i < 10; i++)
801 return((
unsigned short) (sign_bit | ExponentMask));
803 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
804 (significand >> SignificandShift));
808#if defined(__cplusplus) || defined(c_plusplus)