2 Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization
3 dedicated to making software imaging solutions freely available.
5 You may not use this file except in compliance with the License.
6 obtain a copy of the License at
8 https://www.imagemagick.org/script/license.php
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
16 MagickCore quantum inline methods.
18 #ifndef MAGICKCORE_QUANTUM_PRIVATE_H
19 #define MAGICKCORE_QUANTUM_PRIVATE_H
21 #include "MagickCore/cache.h"
23 #if defined(__cplusplus) || defined(c_plusplus)
27 typedef struct _QuantumState
88 extern MagickPrivate void
89 ResetQuantumState(QuantumInfo *);
91 static inline MagickSizeType GetQuantumRange(const size_t depth)
97 return((MagickSizeType) ((one << (depth-1))+((one << (depth-1))-1)));
100 static inline float HalfToSinglePrecision(const unsigned short half)
102 #define ExponentBias (127-15)
103 #define ExponentMask 0x7c00
104 #define ExponentShift 23
105 #define SignBitShift 31
106 #define SignificandShift 13
107 #define SignificandMask 0x00000400
109 typedef union _SinglePrecision
118 register unsigned int
130 The IEEE 754 standard specifies half precision as having:
133 Exponent width: 5 bits
134 Significand precision: 11 (10 explicitly stored)
136 sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
137 exponent=(unsigned int) ((half >> 10) & 0x0000001f);
138 significand=(unsigned int) (half & 0x000003ff);
141 if (significand == 0)
142 value=sign_bit << SignBitShift;
145 while ((significand & SignificandMask) == 0)
151 significand&=(~SignificandMask);
152 exponent+=ExponentBias;
153 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
154 (significand << SignificandShift);
158 if (exponent == SignBitShift)
160 value=(sign_bit << SignBitShift) | 0x7f800000;
161 if (significand != 0)
162 value|=(significand << SignificandShift);
166 exponent+=ExponentBias;
167 significand<<=SignificandShift;
168 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
171 map.fixed_point=value;
172 return(map.single_precision);
175 static inline unsigned char *PopCharPixel(const unsigned char pixel,
176 unsigned char *pixels)
182 static inline unsigned char *PopLongPixel(const EndianType endian,
183 const unsigned int pixel,unsigned char *pixels)
185 register unsigned int
188 quantum=(unsigned int) pixel;
189 if (endian == LSBEndian)
191 *pixels++=(unsigned char) (quantum);
192 *pixels++=(unsigned char) (quantum >> 8);
193 *pixels++=(unsigned char) (quantum >> 16);
194 *pixels++=(unsigned char) (quantum >> 24);
197 *pixels++=(unsigned char) (quantum >> 24);
198 *pixels++=(unsigned char) (quantum >> 16);
199 *pixels++=(unsigned char) (quantum >> 8);
200 *pixels++=(unsigned char) (quantum);
204 static inline unsigned char *PopShortPixel(const EndianType endian,
205 const unsigned short pixel,unsigned char *pixels)
207 register unsigned int
211 if (endian == LSBEndian)
213 *pixels++=(unsigned char) (quantum);
214 *pixels++=(unsigned char) (quantum >> 8);
217 *pixels++=(unsigned char) (quantum >> 8);
218 *pixels++=(unsigned char) (quantum);
222 static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
223 unsigned char *pixel)
229 static inline const unsigned char *PushLongPixel(const EndianType endian,
230 const unsigned char *pixels,unsigned int *pixel)
232 register unsigned int
235 if (endian == LSBEndian)
237 quantum=((unsigned int) *pixels++);
238 quantum|=((unsigned int) *pixels++ << 8);
239 quantum|=((unsigned int) *pixels++ << 16);
240 quantum|=((unsigned int) *pixels++ << 24);
244 quantum=((unsigned int) *pixels++ << 24);
245 quantum|=((unsigned int) *pixels++ << 16);
246 quantum|=((unsigned int) *pixels++ << 8);
247 quantum|=((unsigned int) *pixels++);
252 static inline const unsigned char *PushShortPixel(const EndianType endian,
253 const unsigned char *pixels,unsigned short *pixel)
255 register unsigned int
258 if (endian == LSBEndian)
260 quantum=(unsigned int) *pixels++;
261 quantum|=(unsigned int) (*pixels++ << 8);
262 *pixel=(unsigned short) (quantum & 0xffff);
265 quantum=(unsigned int) (*pixels++ << 8);
266 quantum|=(unsigned int) *pixels++;
267 *pixel=(unsigned short) (quantum & 0xffff);
271 static inline const unsigned char *PushFloatPixel(const EndianType endian,
272 const unsigned char *pixels,MagickFloatType *pixel)
283 if (endian == LSBEndian)
285 quantum.unsigned_value=((unsigned int) *pixels++);
286 quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
287 quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
288 quantum.unsigned_value|=((unsigned int) *pixels++ << 24);
289 *pixel=quantum.float_value;
292 quantum.unsigned_value=((unsigned int) *pixels++ << 24);
293 quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
294 quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
295 quantum.unsigned_value|=((unsigned int) *pixels++);
296 *pixel=quantum.float_value;
300 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
301 const QuantumAny range)
304 return(QuantumRange);
305 #if !defined(MAGICKCORE_HDRI_SUPPORT)
306 return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
308 return((Quantum) (((double) QuantumRange*quantum)/range));
312 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
313 const QuantumAny range)
315 return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
318 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
319 static inline Quantum ScaleCharToQuantum(const unsigned char value)
321 return((Quantum) value);
324 static inline Quantum ScaleLongToQuantum(const unsigned int value)
326 #if !defined(MAGICKCORE_HDRI_SUPPORT)
327 return((Quantum) ((value+8421504UL)/16843009UL));
329 return((Quantum) (value/16843009.0));
333 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
335 #if !defined(MAGICKCORE_HDRI_SUPPORT)
336 return((Quantum) ((value+MagickULLConstant(551911719039))/
337 MagickULLConstant(1103823438079)));
339 return((Quantum) (value/1103823438079.0));
343 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
348 return(QuantumRange);
349 #if !defined(MAGICKCORE_HDRI_SUPPORT)
350 return((Quantum) (value+0.5));
352 return((Quantum) value);
356 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
358 #if !defined(MAGICKCORE_HDRI_SUPPORT)
359 return((unsigned int) (16843009UL*quantum));
363 if ((16843009.0*quantum) >= 4294967295.0)
364 return(4294967295UL);
365 return((unsigned int) (16843009.0*quantum+0.5));
369 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
371 #if !defined(MAGICKCORE_HDRI_SUPPORT)
372 return((MagickSizeType) (MagickULLConstant(551911719039)*quantum));
376 if ((551911719039.0*quantum) >= 18446744073709551615.0)
377 return(MagickULLConstant(18446744073709551615));
378 return((MagickSizeType) (1103823438079.0*quantum+0.5));
382 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
384 if (quantum >= (Quantum) MaxMap)
385 return((unsigned int) MaxMap);
386 #if !defined(MAGICKCORE_HDRI_SUPPORT)
387 return((unsigned int) quantum);
391 return((unsigned int) (quantum+0.5));
395 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
397 #if !defined(MAGICKCORE_HDRI_SUPPORT)
398 return((unsigned short) (257UL*quantum));
402 if ((257.0*quantum) >= 65535.0)
404 return((unsigned short) (257.0*quantum+0.5));
408 static inline Quantum ScaleShortToQuantum(const unsigned short value)
410 #if !defined(MAGICKCORE_HDRI_SUPPORT)
411 return((Quantum) ((value+128U)/257U));
413 return((Quantum) (value/257.0));
416 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
417 static inline Quantum ScaleCharToQuantum(const unsigned char value)
419 #if !defined(MAGICKCORE_HDRI_SUPPORT)
420 return((Quantum) (257U*value));
422 return((Quantum) (257.0*value));
426 static inline Quantum ScaleLongToQuantum(const unsigned int value)
428 #if !defined(MAGICKCORE_HDRI_SUPPORT)
429 return((Quantum) ((value+MagickULLConstant(32768))/
430 MagickULLConstant(65537)));
432 return((Quantum) (value/65537.0));
436 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
438 #if !defined(MAGICKCORE_HDRI_SUPPORT)
439 return((Quantum) ((value+MagickULLConstant(8421376))/
440 MagickULLConstant(16842752)));
442 return((Quantum) (value/16842752.0));
446 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
451 return(QuantumRange);
452 #if !defined(MAGICKCORE_HDRI_SUPPORT)
453 return((Quantum) (value+0.5));
455 return((Quantum) value);
459 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
461 #if !defined(MAGICKCORE_HDRI_SUPPORT)
462 return((unsigned int) (65537UL*quantum));
466 if ((65537.0*quantum) >= 4294967295.0)
468 return((unsigned int) (65537.0*quantum+0.5));
472 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
474 #if !defined(MAGICKCORE_HDRI_SUPPORT)
475 return((MagickSizeType) (MagickULLConstant(16842752)*quantum));
479 if ((65537.0*quantum) >= 18446744073709551615.0)
480 return(MagickULLConstant(18446744073709551615));
481 return((MagickSizeType) (16842752.0*quantum+0.5));
485 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
487 if (quantum >= (Quantum) MaxMap)
488 return((unsigned int) MaxMap);
489 #if !defined(MAGICKCORE_HDRI_SUPPORT)
490 return((unsigned int) quantum);
494 return((unsigned int) (quantum+0.5));
498 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
500 #if !defined(MAGICKCORE_HDRI_SUPPORT)
501 return((unsigned short) quantum);
505 if (quantum >= 65535.0)
507 return((unsigned short) (quantum+0.5));
511 static inline Quantum ScaleShortToQuantum(const unsigned short value)
513 return((Quantum) value);
515 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
516 static inline Quantum ScaleCharToQuantum(const unsigned char value)
518 #if !defined(MAGICKCORE_HDRI_SUPPORT)
519 return((Quantum) (16843009UL*value));
521 return((Quantum) (16843009.0*value));
525 static inline Quantum ScaleLongToQuantum(const unsigned int value)
527 return((Quantum) value);
530 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
532 return((Quantum) value);
535 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
539 if (value >= (Quantum) MaxMap)
540 return(QuantumRange);
541 #if !defined(MAGICKCORE_HDRI_SUPPORT)
542 return((Quantum) (65537.0*value+0.5));
544 return((Quantum) (65537.0*value));
548 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
550 #if !defined(MAGICKCORE_HDRI_SUPPORT)
551 return((unsigned int) quantum);
555 if ((quantum) >= 4294967295.0)
557 return((unsigned int) (quantum+0.5));
561 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
563 #if !defined(MAGICKCORE_HDRI_SUPPORT)
564 return((MagickSizeType) quantum);
566 return((MagickSizeType) (quantum+0.5));
570 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
574 if ((quantum/65537) >= (Quantum) MaxMap)
575 return((unsigned int) MaxMap);
576 #if !defined(MAGICKCORE_HDRI_SUPPORT)
577 return((unsigned int) ((quantum+MagickULLConstant(32768))/
578 MagickULLConstant(65537)));
580 return((unsigned int) (quantum/65537.0+0.5));
584 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
586 #if !defined(MAGICKCORE_HDRI_SUPPORT)
587 return((unsigned short) ((quantum+MagickULLConstant(32768))/
588 MagickULLConstant(65537)));
592 if ((quantum/65537.0) >= 65535.0)
594 return((unsigned short) (quantum/65537.0+0.5));
598 static inline Quantum ScaleShortToQuantum(const unsigned short value)
600 #if !defined(MAGICKCORE_HDRI_SUPPORT)
601 return((Quantum) (65537UL*value));
603 return((Quantum) (65537.0*value));
606 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
607 static inline Quantum ScaleCharToQuantum(const unsigned char value)
609 return((Quantum) (72340172838076673.0*value));
612 static inline Quantum ScaleLongToQuantum(const unsigned int value)
614 return((Quantum) (4294967297.0*value));
617 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
619 return((Quantum) (18446744073709551615.0*value));
622 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
627 return(QuantumRange);
628 return((Quantum) (281479271743489.0*value));
631 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
633 return((unsigned int) (quantum/4294967297.0+0.5));
636 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
638 return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
641 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
645 if ((quantum/281479271743489.0) >= MaxMap)
646 return((unsigned int) MaxMap);
647 return((unsigned int) (quantum/281479271743489.0+0.5));
650 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
654 if ((quantum/281479271743489.0) >= 65535.0)
656 return((unsigned short) (quantum/281479271743489.0+0.5));
659 static inline Quantum ScaleShortToQuantum(const unsigned short value)
661 return((Quantum) (281479271743489.0*value));
665 static inline unsigned short SinglePrecisionToHalf(const float value)
667 typedef union _SinglePrecision
679 register unsigned int
690 The IEEE 754 standard specifies half precision as having:
693 Exponent width: 5 bits
694 Significand precision: 11 (10 explicitly stored)
696 map.single_precision=value;
697 sign_bit=(map.fixed_point >> 16) & 0x00008000;
698 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
699 significand=map.fixed_point & 0x007fffff;
706 return((unsigned short) sign_bit);
707 significand=significand | 0x00800000;
708 shift=(int) (14-exponent);
709 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
710 ((significand >> shift) & 0x01)) >> shift);
711 return((unsigned short) (sign_bit | significand));
714 if (exponent == (0xff-ExponentBias))
716 if (significand == 0)
717 return((unsigned short) (sign_bit | ExponentMask));
720 significand>>=SignificandShift;
721 half=(unsigned short) (sign_bit | significand |
722 (significand == 0) | ExponentMask);
726 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
727 if ((significand & 0x00800000) != 0)
744 for (i=0; i < 10; i++)
746 return((unsigned short) (sign_bit | ExponentMask));
748 half=(unsigned short) (sign_bit | (exponent << 10) |
749 (significand >> SignificandShift));
753 #if defined(__cplusplus) || defined(c_plusplus)