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 MagickPrivate
void
96 ResetQuantumState(QuantumInfo *);
98static inline MagickSizeType GetQuantumRange(
const size_t depth)
109 max_depth=8*
sizeof(MagickSizeType);
110 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
111 ((one << (MagickMin(depth,max_depth)-1))-1)));
114static inline float HalfToSinglePrecision(
const unsigned short half)
116#define ExponentBias (127-15)
117#define ExponentMask (0x7c00U)
118#define ExponentShift 23
119#define SignBitShift 31
120#define SignificandShift 13
121#define SignificandMask (0x00000400U)
123 typedef union _SinglePrecision
148 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
149 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
150 significand=(
unsigned int) (half & 0x000003ff);
153 if (significand == 0)
154 value=sign_bit << SignBitShift;
157 while ((significand & SignificandMask) == 0)
163 significand&=(~SignificandMask);
164 exponent+=ExponentBias;
165 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
166 (significand << SignificandShift);
170 if (exponent == SignBitShift)
172 value=(sign_bit << SignBitShift) | 0x7f800000;
173 if (significand != 0)
174 value|=(significand << SignificandShift);
178 exponent+=ExponentBias;
179 significand<<=SignificandShift;
180 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
183 map.fixed_point=value;
184 return(map.single_precision);
187static inline unsigned char *PopCharPixel(
const unsigned char pixel,
188 unsigned char *magick_restrict pixels)
194static inline unsigned char *PopLongPixel(
const EndianType endian,
195 const unsigned int pixel,
unsigned char *magick_restrict pixels)
200 quantum=(
unsigned int) pixel;
201 if (endian == LSBEndian)
203 *pixels++=(
unsigned char) (quantum);
204 *pixels++=(
unsigned char) (quantum >> 8);
205 *pixels++=(
unsigned char) (quantum >> 16);
206 *pixels++=(
unsigned char) (quantum >> 24);
209 *pixels++=(
unsigned char) (quantum >> 24);
210 *pixels++=(
unsigned char) (quantum >> 16);
211 *pixels++=(
unsigned char) (quantum >> 8);
212 *pixels++=(
unsigned char) (quantum);
216static inline unsigned char *PopShortPixel(
const EndianType endian,
217 const unsigned short pixel,
unsigned char *magick_restrict pixels)
223 if (endian == LSBEndian)
225 *pixels++=(
unsigned char) (quantum);
226 *pixels++=(
unsigned char) (quantum >> 8);
229 *pixels++=(
unsigned char) (quantum >> 8);
230 *pixels++=(
unsigned char) (quantum);
234static inline const unsigned char *PushCharPixel(
235 const unsigned char *magick_restrict pixels,
236 unsigned char *magick_restrict pixel)
242static inline const unsigned char *PushLongPixel(
const EndianType endian,
243 const unsigned char *magick_restrict pixels,
244 unsigned int *magick_restrict pixel)
249 if (endian == LSBEndian)
251 quantum=((
unsigned int) *pixels++);
252 quantum|=((
unsigned int) *pixels++ << 8);
253 quantum|=((
unsigned int) *pixels++ << 16);
254 quantum|=((
unsigned int) *pixels++ << 24);
258 quantum=((
unsigned int) *pixels++ << 24);
259 quantum|=((
unsigned int) *pixels++ << 16);
260 quantum|=((
unsigned int) *pixels++ << 8);
261 quantum|=((
unsigned int) *pixels++);
266static inline const unsigned char *PushShortPixel(
const EndianType endian,
267 const unsigned char *magick_restrict pixels,
268 unsigned short *magick_restrict pixel)
273 if (endian == LSBEndian)
275 quantum=(
unsigned int) *pixels++;
276 quantum|=(
unsigned int) (*pixels++ << 8);
277 *pixel=(
unsigned short) (quantum & 0xffff);
280 quantum=(
unsigned int) (*pixels++ << 8);
281 quantum|=(
unsigned int) *pixels++;
282 *pixel=(
unsigned short) (quantum & 0xffff);
286static inline const unsigned char *PushFloatPixel(
const EndianType endian,
287 const unsigned char *magick_restrict pixels,
288 MagickFloatType *magick_restrict pixel)
299 if (endian == LSBEndian)
301 quantum.unsigned_value=((
unsigned int) *pixels++);
302 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
303 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
304 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
305 *pixel=quantum.float_value;
308 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
309 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
310 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
311 quantum.unsigned_value|=((
unsigned int) *pixels++);
312 *pixel=quantum.float_value;
316static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
317 const QuantumAny range)
320 return(QuantumRange);
321#if !defined(MAGICKCORE_HDRI_SUPPORT)
322 return((Quantum) ((
double) QuantumRange*(quantum*
323 MagickSafeReciprocal((
double) range))+0.5));
325 return((Quantum) ((
double) QuantumRange*(quantum*
326 MagickSafeReciprocal((
double) range))));
330static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
331 const QuantumAny range)
333#if !defined(MAGICKCORE_HDRI_SUPPORT)
334 return((QuantumAny) ((
double) range*quantum/QuantumRange));
336 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
337 return((QuantumAny) 0UL);
338 if (((
double) range*quantum/(
double) QuantumRange) >= 18446744073709551615.0)
339 return((QuantumAny) MagickULLConstant(18446744073709551615));
340 return((QuantumAny) (range*(
double) quantum/(
double) QuantumRange+0.5));
344#if (MAGICKCORE_QUANTUM_DEPTH == 8)
345static inline Quantum ScaleCharToQuantum(
const unsigned char value)
347 return((Quantum) value);
350static inline Quantum ScaleLongToQuantum(
const unsigned int value)
352#if !defined(MAGICKCORE_HDRI_SUPPORT)
353 return((Quantum) ((value)/16843009UL));
355 return((Quantum) (value/16843009.0));
359static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
361#if !defined(MAGICKCORE_HDRI_SUPPORT)
362 return((Quantum) (value/MagickULLConstant(72340172838076673)));
364 return((Quantum) (value/72340172838076673.0));
368static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
373 return(QuantumRange);
374#if !defined(MAGICKCORE_HDRI_SUPPORT)
375 return((Quantum) (value+0.5));
377 return((Quantum) value);
381static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
383#if !defined(MAGICKCORE_HDRI_SUPPORT)
384 return((
unsigned int) (16843009UL*quantum));
386 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
388 if ((16843009.0*quantum) >= 4294967295.0)
389 return(4294967295UL);
390 return((
unsigned int) (16843009.0*quantum+0.5));
394static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
396#if !defined(MAGICKCORE_HDRI_SUPPORT)
397 return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
399 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
401 if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
402 return(MagickULLConstant(18446744073709551615));
403 return((MagickSizeType) (72340172838076673.0*quantum+0.5));
407static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
409 if (quantum >= (Quantum) MaxMap)
410 return((
unsigned int) MaxMap);
411#if !defined(MAGICKCORE_HDRI_SUPPORT)
412 return((
unsigned int) quantum);
414 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
416 return((
unsigned int) (quantum+0.5));
420static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
422#if !defined(MAGICKCORE_HDRI_SUPPORT)
423 return((
unsigned short) (257UL*quantum));
425 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
427 if ((257.0*quantum) >= 65535.0)
429 return((
unsigned short) (257.0*quantum+0.5));
433static inline Quantum ScaleShortToQuantum(
const unsigned short value)
435#if !defined(MAGICKCORE_HDRI_SUPPORT)
436 return((Quantum) ((value+128U)/257U));
438 return((Quantum) (value/257.0));
441#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
442static inline Quantum ScaleCharToQuantum(
const unsigned char value)
444#if !defined(MAGICKCORE_HDRI_SUPPORT)
445 return((Quantum) (257U*value));
447 return((Quantum) (257.0*value));
451static inline Quantum ScaleLongToQuantum(
const unsigned int value)
453#if !defined(MAGICKCORE_HDRI_SUPPORT)
454 return((Quantum) ((value)/MagickULLConstant(65537)));
456 return((Quantum) (value/65537.0));
460static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
462#if !defined(MAGICKCORE_HDRI_SUPPORT)
463 return((Quantum) ((value)/MagickULLConstant(281479271743489)));
465 return((Quantum) (value/281479271743489.0));
469static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
474 return(QuantumRange);
475#if !defined(MAGICKCORE_HDRI_SUPPORT)
476 return((Quantum) (value+0.5));
478 return((Quantum) value);
482static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
484#if !defined(MAGICKCORE_HDRI_SUPPORT)
485 return((
unsigned int) (65537UL*quantum));
487 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
489 if ((65537.0*(
double) quantum) >= 4294967295.0)
491 return((
unsigned int) (65537.0*(
double) quantum+0.5));
495static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
497#if !defined(MAGICKCORE_HDRI_SUPPORT)
498 return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
500 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
502 if ((281479271743489.0*(
double) quantum) >= 18446744073709551615.0)
503 return(MagickULLConstant(18446744073709551615));
504 return((MagickSizeType) (281479271743489.0*(
double) quantum+0.5));
508static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
510 if (quantum >= (Quantum) MaxMap)
511 return((
unsigned int) MaxMap);
512#if !defined(MAGICKCORE_HDRI_SUPPORT)
513 return((
unsigned int) quantum);
515 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
517 return((
unsigned int) (quantum+0.5f));
521static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
523#if !defined(MAGICKCORE_HDRI_SUPPORT)
524 return((
unsigned short) quantum);
526 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
528 if (quantum >= 65535.0f)
530 return((
unsigned short) (quantum+0.5f));
534static inline Quantum ScaleShortToQuantum(
const unsigned short value)
536 return((Quantum) value);
538#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
539static inline Quantum ScaleCharToQuantum(
const unsigned char value)
541#if !defined(MAGICKCORE_HDRI_SUPPORT)
542 return((Quantum) (16843009UL*value));
544 return((Quantum) (16843009.0*value));
548static inline Quantum ScaleLongToQuantum(
const unsigned int value)
550 return((Quantum) value);
553static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
555#if !defined(MAGICKCORE_HDRI_SUPPORT)
556 return((Quantum) ((value)/MagickULLConstant(4294967297)));
558 return((Quantum) (value/4294967297.0));
562static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
566 if (value >= (Quantum) MaxMap)
567 return(QuantumRange);
568#if !defined(MAGICKCORE_HDRI_SUPPORT)
569 return((Quantum) (65537.0*value+0.5));
571 return((Quantum) (65537.0*value));
575static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
577#if !defined(MAGICKCORE_HDRI_SUPPORT)
578 return((
unsigned int) quantum);
580 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
582 if ((quantum) >= 4294967295.0)
584 return((
unsigned int) (quantum+0.5));
588static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
590#if !defined(MAGICKCORE_HDRI_SUPPORT)
591 return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
593 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
595 if ((4294967297.0*quantum) >= 18446744073709551615.0)
596 return(MagickULLConstant(18446744073709551615));
597 return((MagickSizeType) (4294967297.0*quantum+0.5));
601static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
603 if ((quantum/65537) >= (Quantum) MaxMap)
604 return((
unsigned int) MaxMap);
605#if !defined(MAGICKCORE_HDRI_SUPPORT)
606 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
607 MagickULLConstant(65537)));
609 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
611 return((
unsigned int) (quantum/65537.0+0.5));
615static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
617#if !defined(MAGICKCORE_HDRI_SUPPORT)
618 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
619 MagickULLConstant(65537)));
621 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
623 if ((quantum/65537.0) >= 65535.0)
625 return((
unsigned short) (quantum/65537.0+0.5));
629static inline Quantum ScaleShortToQuantum(
const unsigned short value)
631#if !defined(MAGICKCORE_HDRI_SUPPORT)
632 return((Quantum) (65537UL*value));
634 return((Quantum) (65537.0*value));
637#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
638static inline Quantum ScaleCharToQuantum(
const unsigned char value)
640 return((Quantum) (72340172838076673.0*value));
643static inline Quantum ScaleLongToQuantum(
const unsigned int value)
645 return((Quantum) (4294967297.0*value));
648static inline Quantum ScaleLongLongToQuantum(
const MagickSizeType value)
650 return((Quantum) (value));
653static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
658 return(QuantumRange);
659 return((Quantum) (281479271743489.0*value));
662static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
664 return((
unsigned int) (quantum/4294967297.0+0.5));
667static inline MagickSizeType ScaleQuantumToLongLong(
const Quantum quantum)
669#if !defined(MAGICKCORE_HDRI_SUPPORT)
670 return((MagickSizeType) quantum);
672 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
674 if (quantum >= 18446744073709551615.0)
675 return(MagickULLConstant(18446744073709551615));
676 return((MagickSizeType) (quantum+0.5));
680static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
682 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
684 if ((quantum/281479271743489.0) >= MaxMap)
685 return((
unsigned int) MaxMap);
686 return((
unsigned int) (quantum/281479271743489.0+0.5));
689static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
691 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
693 if ((quantum/281479271743489.0) >= 65535.0)
695 return((
unsigned short) (quantum/281479271743489.0+0.5));
698static inline Quantum ScaleShortToQuantum(
const unsigned short value)
700 return((Quantum) (281479271743489.0*value));
704static inline unsigned short SinglePrecisionToHalf(
const double value)
706 typedef union _SinglePrecision
735 map.single_precision=(float) value;
736 sign_bit=(map.fixed_point >> 16) & 0x00008000;
737 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
738 significand=map.fixed_point & 0x007fffff;
745 return((
unsigned short) sign_bit);
746 significand=significand | 0x00800000;
747 shift=(int) (14-exponent);
748 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
749 ((significand >> shift) & 0x01)) >> shift);
750 return((
unsigned short) (sign_bit | significand));
753 if (exponent == (0xff-ExponentBias))
755 if (significand == 0)
756 return((
unsigned short) (sign_bit | ExponentMask));
759 significand>>=SignificandShift;
760 half=(
unsigned short) (sign_bit | significand |
761 (significand == 0) | ExponentMask);
765 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
766 if ((significand & 0x00800000) != 0)
783 for (i=0; i < 10; i++)
785 return((
unsigned short) (sign_bit | ExponentMask));
787 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
788 (significand >> SignificandShift));
792#if defined(__cplusplus) || defined(c_plusplus)