18#ifndef MAGICKCORE_QUANTUM_PRIVATE_H
19#define MAGICKCORE_QUANTUM_PRIVATE_H
21#include "magick/memory_.h"
22#include "magick/cache.h"
23#include "magick/image-private.h"
24#include "magick/pixel-accessor.h"
25#include "magick/statistic-private.h"
27#if defined(__cplusplus) || defined(c_plusplus)
92extern MagickExport MagickBooleanType
93 SetQuantumExtent(
const Image *,QuantumInfo *);
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
150 sign_bit=(
unsigned int) ((half >> 15) & 0x00000001);
151 exponent=(
unsigned int) ((half >> 10) & 0x0000001f);
152 significand=(
unsigned int) (half & 0x000003ff);
155 if (significand == 0)
156 value=sign_bit << SignBitShift;
159 while ((significand & SignificandMask) == 0)
165 significand&=(~SignificandMask);
166 exponent+=ExponentBias;
167 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
168 (significand << SignificandShift);
172 if (exponent == SignBitShift)
174 value=(sign_bit << SignBitShift) | 0x7f800000;
175 if (significand != 0)
176 value|=(significand << SignificandShift);
180 exponent+=ExponentBias;
181 significand<<=SignificandShift;
182 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
185 map.fixed_point=value;
186 return(map.single_precision);
189static inline unsigned char *PopCharPixel(
const unsigned char pixel,
190 unsigned char *magick_restrict pixels)
196static inline unsigned char *PopLongPixel(
const EndianType endian,
197 const unsigned int pixel,
unsigned char *magick_restrict pixels)
202 quantum=(
unsigned int) pixel;
203 if (endian == LSBEndian)
205 *pixels++=(
unsigned char) (quantum);
206 *pixels++=(
unsigned char) (quantum >> 8);
207 *pixels++=(
unsigned char) (quantum >> 16);
208 *pixels++=(
unsigned char) (quantum >> 24);
211 *pixels++=(
unsigned char) (quantum >> 24);
212 *pixels++=(
unsigned char) (quantum >> 16);
213 *pixels++=(
unsigned char) (quantum >> 8);
214 *pixels++=(
unsigned char) (quantum);
218static inline unsigned char *PopShortPixel(
const EndianType endian,
219 const unsigned short pixel,
unsigned char *magick_restrict pixels)
225 if (endian == LSBEndian)
227 *pixels++=(
unsigned char) (quantum);
228 *pixels++=(
unsigned char) (quantum >> 8);
231 *pixels++=(
unsigned char) (quantum >> 8);
232 *pixels++=(
unsigned char) (quantum);
236static inline const unsigned char *PushCharPixel(
237 const unsigned char *magick_restrict pixels,
238 unsigned char *magick_restrict pixel)
244static inline const unsigned char *PushLongPixel(
const EndianType endian,
245 const unsigned char *magick_restrict pixels,
246 unsigned int *magick_restrict pixel)
251 if (endian == LSBEndian)
253 quantum=((
unsigned int) *pixels++);
254 quantum|=((
unsigned int) *pixels++ << 8);
255 quantum|=((
unsigned int) *pixels++ << 16);
256 quantum|=((
unsigned int) *pixels++ << 24);
260 quantum=((
unsigned int) *pixels++ << 24);
261 quantum|=((
unsigned int) *pixels++ << 16);
262 quantum|=((
unsigned int) *pixels++ << 8);
263 quantum|=((
unsigned int) *pixels++);
268static inline const unsigned char *PushShortPixel(
const EndianType endian,
269 const unsigned char *magick_restrict pixels,
270 unsigned short *magick_restrict pixel)
275 if (endian == LSBEndian)
277 quantum=(
unsigned int) *pixels++;
278 quantum|=(
unsigned int) (*pixels++ << 8);
279 *pixel=(
unsigned short) (quantum & 0xffff);
282 quantum=(
unsigned int) (*pixels++ << 8);
283 quantum|=(
unsigned int) *pixels++;
284 *pixel=(
unsigned short) (quantum & 0xffff);
288static inline const unsigned char *PushFloatPixel(
const EndianType endian,
289 const unsigned char *magick_restrict pixels,
290 MagickFloatType *magick_restrict pixel)
301 if (endian == LSBEndian)
303 quantum.unsigned_value=((
unsigned int) *pixels++);
304 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
305 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
306 quantum.unsigned_value|=((
unsigned int) *pixels++ << 24);
307 *pixel=quantum.float_value;
310 quantum.unsigned_value=((
unsigned int) *pixels++ << 24);
311 quantum.unsigned_value|=((
unsigned int) *pixels++ << 16);
312 quantum.unsigned_value|=((
unsigned int) *pixels++ << 8);
313 quantum.unsigned_value|=((
unsigned int) *pixels++);
314 *pixel=quantum.float_value;
318static inline Quantum ScaleAnyToQuantum(
const QuantumAny quantum,
319 const QuantumAny range)
322 return(QuantumRange);
323#if !defined(MAGICKCORE_HDRI_SUPPORT)
324 return((Quantum) ((
double) QuantumRange*(quantum*
325 MagickSafeReciprocal((
double) range))+0.5));
327 return((Quantum) ((
double) QuantumRange*(quantum*
328 MagickSafeReciprocal((
double) range))));
332static inline QuantumAny ScaleQuantumToAny(
const Quantum quantum,
333 const QuantumAny range)
335#if !defined(MAGICKCORE_HDRI_SUPPORT)
336 return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange));
338 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
339 return((QuantumAny) 0UL);
340 if ((range*(MagickRealType) quantum/(MagickRealType) QuantumRange) >= 18446744073709551615.0)
341 return((QuantumAny) MagickULLConstant(18446744073709551615));
342 return((QuantumAny) (range*(MagickRealType) quantum/(MagickRealType) QuantumRange+0.5));
346#if (MAGICKCORE_QUANTUM_DEPTH == 8)
347static inline Quantum ScaleCharToQuantum(
const unsigned char value)
349 return((Quantum) value);
352static inline Quantum ScaleLongToQuantum(
const unsigned int value)
354#if !defined(MAGICKCORE_HDRI_SUPPORT)
355 return((Quantum) ((value)/16843009UL));
357 return((Quantum) (value/16843009.0));
361static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
366 return(QuantumRange);
367#if !defined(MAGICKCORE_HDRI_SUPPORT)
368 return((Quantum) (value+0.5));
370 return((Quantum) value);
374static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
376#if !defined(MAGICKCORE_HDRI_SUPPORT)
377 return((
unsigned int) (16843009UL*quantum));
379 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
381 if ((16843009.0*quantum) >= 4294967295.0)
382 return(4294967295UL);
383 return((
unsigned int) (16843009.0*quantum+0.5));
387static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
389 if (quantum >= (Quantum) MaxMap)
390 return((
unsigned int) MaxMap);
391#if !defined(MAGICKCORE_HDRI_SUPPORT)
392 return((
unsigned int) quantum);
394 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
396 return((
unsigned int) (quantum+0.5));
400static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
402#if !defined(MAGICKCORE_HDRI_SUPPORT)
403 return((
unsigned short) (257UL*quantum));
405 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
407 if ((257.0*quantum) >= 65535.0)
409 return((
unsigned short) (257.0*quantum+0.5));
413static inline Quantum ScaleShortToQuantum(
const unsigned short value)
415#if !defined(MAGICKCORE_HDRI_SUPPORT)
416 return((Quantum) ((value+128U)/257U));
418 return((Quantum) (value/257.0));
421#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
422static inline Quantum ScaleCharToQuantum(
const unsigned char value)
424#if !defined(MAGICKCORE_HDRI_SUPPORT)
425 return((Quantum) (257U*value));
427 return((Quantum) (257.0*value));
431static inline Quantum ScaleLongToQuantum(
const unsigned int value)
433#if !defined(MAGICKCORE_HDRI_SUPPORT)
434 return((Quantum) ((value)/MagickULLConstant(65537)));
436 return((Quantum) (value/65537.0));
440static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
445 return(QuantumRange);
446#if !defined(MAGICKCORE_HDRI_SUPPORT)
447 return((Quantum) (value+0.5));
449 return((Quantum) value);
453static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
455#if !defined(MAGICKCORE_HDRI_SUPPORT)
456 return((
unsigned int) (65537UL*quantum));
458 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
460 if ((65537.0f*quantum) >= 4294967295.0f)
462 return((
unsigned int) (65537.0f*quantum+0.5f));
466static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
468 if (quantum >= (Quantum) MaxMap)
469 return((
unsigned int) MaxMap);
470#if !defined(MAGICKCORE_HDRI_SUPPORT)
471 return((
unsigned int) quantum);
473 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
475 return((
unsigned int) (quantum+0.5f));
479static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
481#if !defined(MAGICKCORE_HDRI_SUPPORT)
482 return((
unsigned short) quantum);
484 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
486 if (quantum >= 65535.0f)
488 return((
unsigned short) (quantum+0.5f));
492static inline Quantum ScaleShortToQuantum(
const unsigned short value)
494 return((Quantum) value);
496#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
497static inline Quantum ScaleCharToQuantum(
const unsigned char value)
499#if !defined(MAGICKCORE_HDRI_SUPPORT)
500 return((Quantum) (16843009UL*value));
502 return((Quantum) (16843009.0*value));
506static inline Quantum ScaleLongToQuantum(
const unsigned int value)
508 return((Quantum) value);
511static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
515 if (value >= (Quantum) MaxMap)
516 return(QuantumRange);
517#if !defined(MAGICKCORE_HDRI_SUPPORT)
518 return((Quantum) (65537.0f*value+0.5f));
520 return((Quantum) (65537.0f*value));
524static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
526#if !defined(MAGICKCORE_HDRI_SUPPORT)
527 return((
unsigned int) quantum);
529 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
531 if ((quantum) >= 4294967295.0)
533 return((
unsigned int) (quantum+0.5));
537static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
539 if ((quantum/65537) >= (Quantum) MaxMap)
540 return((
unsigned int) MaxMap);
541#if !defined(MAGICKCORE_HDRI_SUPPORT)
542 return((
unsigned int) ((quantum+MagickULLConstant(32768))/
543 MagickULLConstant(65537)));
545 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
547 return((
unsigned int) (quantum/65537.0+0.5));
551static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
553#if !defined(MAGICKCORE_HDRI_SUPPORT)
554 return((
unsigned short) ((quantum+MagickULLConstant(32768))/
555 MagickULLConstant(65537)));
557 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
559 if ((quantum/65537.0) >= 65535.0)
561 return((
unsigned short) (quantum/65537.0+0.5));
565static inline Quantum ScaleShortToQuantum(
const unsigned short value)
567#if !defined(MAGICKCORE_HDRI_SUPPORT)
568 return((Quantum) (65537UL*value));
570 return((Quantum) (65537.0*value));
573#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
574static inline Quantum ScaleCharToQuantum(
const unsigned char value)
576 return((Quantum) (72340172838076673.0*value));
579static inline Quantum ScaleLongToQuantum(
const unsigned int value)
581 return((Quantum) (4294967297.0*value));
584static inline Quantum ScaleMapToQuantum(
const MagickRealType value)
589 return(QuantumRange);
590 return((Quantum) (281479271743489.0*value));
593static inline unsigned int ScaleQuantumToLong(
const Quantum quantum)
595 return((
unsigned int) (quantum/4294967297.0+0.5));
598static inline unsigned int ScaleQuantumToMap(
const Quantum quantum)
600 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
602 if ((quantum/281479271743489.0) >= MaxMap)
603 return((
unsigned int) MaxMap);
604 return((
unsigned int) (quantum/281479271743489.0+0.5));
607static inline unsigned short ScaleQuantumToShort(
const Quantum quantum)
609 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
611 if ((quantum/281479271743489.0) >= 65535.0)
613 return((
unsigned short) (quantum/281479271743489.0+0.5));
616static inline Quantum ScaleShortToQuantum(
const unsigned short value)
618 return((Quantum) (281479271743489.0*value));
622static inline unsigned short SinglePrecisionToHalf(
const float value)
624 typedef union _SinglePrecision
653 map.single_precision=value;
654 sign_bit=(map.fixed_point >> 16) & 0x00008000;
655 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
656 significand=map.fixed_point & 0x007fffff;
663 return((
unsigned short) sign_bit);
664 significand=significand | 0x00800000;
665 shift=(int) (14-exponent);
666 significand=(
unsigned int) ((significand+((1U << (shift-1))-1)+
667 ((significand >> shift) & 0x01)) >> shift);
668 return((
unsigned short) (sign_bit | significand));
671 if (exponent == (0xff-ExponentBias))
673 if (significand == 0)
674 return((
unsigned short) (sign_bit | ExponentMask));
677 significand>>=SignificandShift;
678 half=(
unsigned short) (sign_bit | significand |
679 (significand == 0) | ExponentMask);
683 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
684 if ((significand & 0x00800000) != 0)
701 for (i=0; i < 10; i++)
703 return((
unsigned short) (sign_bit | ExponentMask));
705 half=(
unsigned short) (sign_bit | ((
unsigned int) exponent << 10) |
706 (significand >> SignificandShift));
710#if defined(__cplusplus) || defined(c_plusplus)