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"
26#if defined(__cplusplus) || defined(c_plusplus)
91extern MagickPrivate
void
94static inline MagickSizeType GetQuantumRange(
const size_t depth)
105 max_depth=8*
sizeof(MagickSizeType);
106 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
107 ((one << (MagickMin(depth,max_depth)-1))-1)));
110static inline float HalfToSinglePrecision(
const unsigned short half)
112#define ExponentBias (127-15)
113#define ExponentMask (0x7c00U)
114#define ExponentShift 23
115#define SignBitShift 31
116#define SignificandShift 13
117#define SignificandMask (0x00000400U)
119 typedef union _SinglePrecision
144 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
145 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
146 significand=(
unsigned int) (half & 0x000003ff);
149 if (significand == 0)
150 value=sign_bit << SignBitShift;
153 while ((significand & SignificandMask) == 0)
159 significand&=(~SignificandMask);
160 exponent+=ExponentBias;
161 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
162 (significand << SignificandShift);
166 if (exponent == SignBitShift)
168 value=(sign_bit << SignBitShift) | 0x7f800000;
169 if (significand != 0)
170 value|=(significand << SignificandShift);
174 exponent+=ExponentBias;
175 significand<<=SignificandShift;
176 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
179 map.fixed_point=value;
180 return(map.single_precision);
183static inline unsigned char *PopCharPixel(
const unsigned char pixel,
184 unsigned char *magick_restrict pixels)
190static inline unsigned char *PopLongPixel(
const EndianType endian,
191 const unsigned int pixel,
unsigned char *magick_restrict pixels)
196 quantum=(
unsigned int) pixel;
197 if (endian == LSBEndian)
199 *pixels++=(
unsigned char) (quantum);
200 *pixels++=(
unsigned char) (quantum >> 8);
201 *pixels++=(
unsigned char) (quantum >> 16);
202 *pixels++=(
unsigned char) (quantum >> 24);
205 *pixels++=(
unsigned char) (quantum >> 24);
206 *pixels++=(
unsigned char) (quantum >> 16);
207 *pixels++=(
unsigned char) (quantum >> 8);
208 *pixels++=(
unsigned char) (quantum);
212static inline unsigned char *PopShortPixel(
const EndianType endian,
213 const unsigned short pixel,
unsigned char *magick_restrict pixels)
219 if (endian == LSBEndian)
221 *pixels++=(
unsigned char) (quantum);
222 *pixels++=(
unsigned char) (quantum >> 8);
225 *pixels++=(
unsigned char) (quantum >> 8);
226 *pixels++=(
unsigned char) (quantum);
230static inline const unsigned char *PushCharPixel(
231 const unsigned char *magick_restrict pixels,
232 unsigned char *magick_restrict pixel)
238static inline const unsigned char *PushLongPixel(
const EndianType endian,
239 const unsigned char *magick_restrict pixels,
240 unsigned int *magick_restrict pixel)
245 if (endian == LSBEndian)
247 quantum=((
unsigned int) *pixels++);
248 quantum|=((
unsigned int) *pixels++ << 8);
249 quantum|=((
unsigned int) *pixels++ << 16);
250 quantum|=((
unsigned int) *pixels++ << 24);
254 quantum=((
unsigned int) *pixels++ << 24);
255 quantum|=((
unsigned int) *pixels++ << 16);
256 quantum|=((
unsigned int) *pixels++ << 8);
257 quantum|=((
unsigned int) *pixels++);
262static inline const unsigned char *PushShortPixel(
const EndianType endian,
263 const unsigned char *magick_restrict pixels,
264 unsigned short *magick_restrict pixel)
269 if (endian == LSBEndian)
271 quantum=(
unsigned int) *pixels++;
272 quantum|=(
unsigned int) (*pixels++ << 8);
273 *pixel=(
unsigned short) (quantum & 0xffff);
276 quantum=(
unsigned int) (*pixels++ << 8);
277 quantum|=(
unsigned int) *pixels++;
278 *pixel=(
unsigned short) (quantum & 0xffff);
282static inline const unsigned char *PushFloatPixel(
const EndianType endian,
283 const unsigned char *magick_restrict pixels,
284 MagickFloatType *magick_restrict pixel)
295 if (endian == LSBEndian)
297 quantum.unsigned_value=((
unsigned int) *pixels++);
298 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
299 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
300 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
301 *pixel=quantum.float_value;
304 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
305 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
306 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
307 quantum.unsigned_value|=((
unsigned int) *pixels++);
308 *pixel=quantum.float_value;
312static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
313 const QuantumAny range)
316 return(QuantumRange);
317#if !defined(MAGICKCORE_HDRI_SUPPORT)
318 return((Quantum) ((
double) QuantumRange*(quantum*
319 PerceptibleReciprocal((
double) range))+0.5));
321 return((Quantum) ((
double) QuantumRange*(quantum*
322 PerceptibleReciprocal((
double) range))));
326static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
327 const QuantumAny range)
329#if !defined(MAGICKCORE_HDRI_SUPPORT)
330 return((QuantumAny) ((
double) range*quantum/QuantumRange));
332 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
333 return((QuantumAny) 0UL);
334 if ((range*(
double) quantum/(
double) QuantumRange) >= 18446744073709551615.0)
335 return((QuantumAny) MagickULLConstant(18446744073709551615));
336 return((QuantumAny) (range*(
double) quantum/(
double) QuantumRange+0.5));
340#if (MAGICKCORE_QUANTUM_DEPTH == 8)
341static inline Quantum ScaleCharToQuantum(
const unsigned char value)
343 return((Quantum) value);
346static inline Quantum ScaleLongToQuantum(
const unsigned int value)
348#if !defined(MAGICKCORE_HDRI_SUPPORT)
349 return((Quantum) ((value)/16843009UL));
351 return((Quantum) (value/16843009.0));
355static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
357#if !defined(MAGICKCORE_HDRI_SUPPORT)
358 return((Quantum) (value/MagickULLConstant(72340172838076673)));
360 return((Quantum) (value/72340172838076673.0));
364static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
369 return(QuantumRange);
370#if !defined(MAGICKCORE_HDRI_SUPPORT)
371 return((Quantum) (value+0.5));
373 return((Quantum) value);
377static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
379#if !defined(MAGICKCORE_HDRI_SUPPORT)
380 return((
unsigned int) (16843009UL*quantum));
382 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
384 if ((16843009.0*quantum) >= 4294967295.0)
385 return(4294967295UL);
386 return((
unsigned int) (16843009.0*quantum+0.5));
390static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
392#if !defined(MAGICKCORE_HDRI_SUPPORT)
393 return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
395 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
397 if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
398 return(MagickULLConstant(18446744073709551615));
399 return((MagickSizeType) (72340172838076673.0*quantum+0.5));
403static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
405 if (quantum >= (Quantum) MaxMap)
406 return((
unsigned int) MaxMap);
407#if !defined(MAGICKCORE_HDRI_SUPPORT)
408 return((
unsigned int) quantum);
410 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
412 return((
unsigned int) (quantum+0.5));
416static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
418#if !defined(MAGICKCORE_HDRI_SUPPORT)
419 return((
unsigned short) (257UL*quantum));
421 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
423 if ((257.0*quantum) >= 65535.0)
425 return((
unsigned short) (257.0*quantum+0.5));
429static inline Quantum ScaleShortToQuantum(
const unsigned short value)
431#if !defined(MAGICKCORE_HDRI_SUPPORT)
432 return((Quantum) ((value+128U)/257U));
434 return((Quantum) (value/257.0));
437#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
438static inline Quantum ScaleCharToQuantum(
const unsigned char value)
440#if !defined(MAGICKCORE_HDRI_SUPPORT)
441 return((Quantum) (257U*value));
443 return((Quantum) (257.0*value));
447static inline Quantum ScaleLongToQuantum(
const unsigned int value)
449#if !defined(MAGICKCORE_HDRI_SUPPORT)
450 return((Quantum) ((value)/MagickULLConstant(65537)));
452 return((Quantum) (value/65537.0));
456static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
458#if !defined(MAGICKCORE_HDRI_SUPPORT)
459 return((Quantum) ((value)/MagickULLConstant(281479271743489)));
461 return((Quantum) (value/281479271743489.0));
465static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
470 return(QuantumRange);
471#if !defined(MAGICKCORE_HDRI_SUPPORT)
472 return((Quantum) (value+0.5));
474 return((Quantum) value);
478static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
480#if !defined(MAGICKCORE_HDRI_SUPPORT)
481 return((
unsigned int) (65537UL*quantum));
483 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
485 if ((65537.0*(
double) quantum) >= 4294967295.0)
487 return((
unsigned int) (65537.0*(
double) quantum+0.5));
491static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
493#if !defined(MAGICKCORE_HDRI_SUPPORT)
494 return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
496 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
498 if ((281479271743489.0*(
double) quantum) >= 18446744073709551615.0)
499 return(MagickULLConstant(18446744073709551615));
500 return((MagickSizeType) (281479271743489.0*(
double) quantum+0.5));
504static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
506 if (quantum >= (Quantum) MaxMap)
507 return((
unsigned int) MaxMap);
508#if !defined(MAGICKCORE_HDRI_SUPPORT)
509 return((
unsigned int) quantum);
511 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
513 return((
unsigned int) (quantum+0.5f));
517static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
519#if !defined(MAGICKCORE_HDRI_SUPPORT)
520 return((
unsigned short) quantum);
522 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
524 if (quantum >= 65535.0f)
526 return((
unsigned short) (quantum+0.5f));
530static inline Quantum ScaleShortToQuantum(
const unsigned short value)
532 return((Quantum) value);
534#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
535static inline Quantum ScaleCharToQuantum(
const unsigned char value)
537#if !defined(MAGICKCORE_HDRI_SUPPORT)
538 return((Quantum) (16843009UL*value));
540 return((Quantum) (16843009.0*value));
544static inline Quantum ScaleLongToQuantum(
const unsigned int value)
546 return((Quantum) value);
549static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
551#if !defined(MAGICKCORE_HDRI_SUPPORT)
552 return((Quantum) ((value)/MagickULLConstant(4294967297)));
554 return((Quantum) (value/4294967297.0));
558static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
562 if (value >= (Quantum) MaxMap)
563 return(QuantumRange);
564#if !defined(MAGICKCORE_HDRI_SUPPORT)
565 return((Quantum) (65537.0*value+0.5));
567 return((Quantum) (65537.0*value));
571static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
573#if !defined(MAGICKCORE_HDRI_SUPPORT)
574 return((
unsigned int) quantum);
576 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
578 if ((quantum) >= 4294967295.0)
580 return((
unsigned int) (quantum+0.5));
584static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
586#if !defined(MAGICKCORE_HDRI_SUPPORT)
587 return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
589 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
591 if ((4294967297.0*quantum) >= 18446744073709551615.0)
592 return(MagickULLConstant(18446744073709551615));
593 return((MagickSizeType) (4294967297.0*quantum+0.5));
597static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
599 if ((quantum/65537) >= (Quantum) MaxMap)
600 return((
unsigned int) MaxMap);
601#if !defined(MAGICKCORE_HDRI_SUPPORT)
602 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
603 MagickULLConstant(65537)));
605 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
607 return((
unsigned int) (quantum/65537.0+0.5));
611static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
613#if !defined(MAGICKCORE_HDRI_SUPPORT)
614 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
615 MagickULLConstant(65537)));
617 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
619 if ((quantum/65537.0) >= 65535.0)
621 return((
unsigned short) (quantum/65537.0+0.5));
625static inline Quantum ScaleShortToQuantum(
const unsigned short value)
627#if !defined(MAGICKCORE_HDRI_SUPPORT)
628 return((Quantum) (65537UL*value));
630 return((Quantum) (65537.0*value));
633#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
634static inline Quantum ScaleCharToQuantum(
const unsigned char value)
636 return((Quantum) (72340172838076673.0*value));
639static inline Quantum ScaleLongToQuantum(
const unsigned int value)
641 return((Quantum) (4294967297.0*value));
644static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
646 return((Quantum) (value));
649static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
654 return(QuantumRange);
655 return((Quantum) (281479271743489.0*value));
658static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
660 return((
unsigned int) (quantum/4294967297.0+0.5));
663static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
665#if !defined(MAGICKCORE_HDRI_SUPPORT)
666 return((MagickSizeType) quantum);
668 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
670 if (quantum >= 18446744073709551615.0)
671 return(MagickULLConstant(18446744073709551615));
672 return((MagickSizeType) (quantum+0.5));
676static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
678 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
680 if ((quantum/281479271743489.0) >= MaxMap)
681 return((
unsigned int) MaxMap);
682 return((
unsigned int) (quantum/281479271743489.0+0.5));
685static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
687 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
689 if ((quantum/281479271743489.0) >= 65535.0)
691 return((
unsigned short) (quantum/281479271743489.0+0.5));
694static inline Quantum ScaleShortToQuantum(
const unsigned short value)
696 return((Quantum) (281479271743489.0*value));
700static inline unsigned short SinglePrecisionToHalf(
const float value)
702 typedef union _SinglePrecision
731 map.single_precision=value;
732 sign_bit=(map.fixed_point >> 16) & 0x00008000;
733 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
734 significand=map.fixed_point & 0x007fffff;
741 return((
unsigned short) sign_bit);
742 significand=significand | 0x00800000;
743 shift=(int) (14-exponent);
744 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
745 ((significand >> shift) & 0x01)) >> shift);
746 return((
unsigned short) (sign_bit | significand));
749 if (exponent == (0xff-ExponentBias))
751 if (significand == 0)
752 return((
unsigned short) (sign_bit | ExponentMask));
755 significand>>=SignificandShift;
756 half=(
unsigned short) (sign_bit | significand |
757 (significand == 0) | ExponentMask);
761 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
762 if ((significand & 0x00800000) != 0)
779 for (i=0; i < 10; i++)
781 return((
unsigned short) (sign_bit | ExponentMask));
783 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
784 (significand >> SignificandShift));
788#if defined(__cplusplus) || defined(c_plusplus)