2 Copyright 1999-2017 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 http://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 Quantum ScaleAnyToQuantum(const QuantumAny quantum,
272 const QuantumAny range)
275 return(QuantumRange);
276 #if !defined(MAGICKCORE_HDRI_SUPPORT)
277 return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
279 return((Quantum) (((double) QuantumRange*quantum)/range));
283 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
284 const QuantumAny range)
286 return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
289 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
290 static inline Quantum ScaleCharToQuantum(const unsigned char value)
292 return((Quantum) value);
295 static inline Quantum ScaleLongToQuantum(const unsigned int value)
297 #if !defined(MAGICKCORE_HDRI_SUPPORT)
298 return((Quantum) ((value+8421504UL)/16843009UL));
300 return((Quantum) (value/16843009.0));
304 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
306 #if !defined(MAGICKCORE_HDRI_SUPPORT)
307 return((Quantum) ((value+MagickULLConstant(551911719039))/
308 MagickULLConstant(1103823438079)));
310 return((Quantum) (value/1103823438079.0));
314 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
319 return(QuantumRange);
320 #if !defined(MAGICKCORE_HDRI_SUPPORT)
321 return((Quantum) (value+0.5));
323 return((Quantum) value);
327 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
329 #if !defined(MAGICKCORE_HDRI_SUPPORT)
330 return((unsigned int) (16843009UL*quantum));
334 if ((16843009.0*quantum) >= 4294967295.0)
335 return(4294967295UL);
336 return((unsigned int) (16843009.0*quantum+0.5));
340 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
342 #if !defined(MAGICKCORE_HDRI_SUPPORT)
343 return((MagickSizeType) (MagickULLConstant(551911719039)*quantum));
347 if ((551911719039.0*quantum) >= 18446744073709551615.0)
348 return(MagickULLConstant(18446744073709551615));
349 return((MagickSizeType) (1103823438079.0*quantum+0.5));
353 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
355 if (quantum >= (Quantum) MaxMap)
356 return((unsigned int) MaxMap);
357 #if !defined(MAGICKCORE_HDRI_SUPPORT)
358 return((unsigned int) quantum);
362 return((unsigned int) (quantum+0.5));
366 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
368 #if !defined(MAGICKCORE_HDRI_SUPPORT)
369 return((unsigned short) (257UL*quantum));
373 if ((257.0*quantum) >= 65535.0)
375 return((unsigned short) (257.0*quantum+0.5));
379 static inline Quantum ScaleShortToQuantum(const unsigned short value)
381 #if !defined(MAGICKCORE_HDRI_SUPPORT)
382 return((Quantum) ((value+128U)/257U));
384 return((Quantum) (value/257.0));
387 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
388 static inline Quantum ScaleCharToQuantum(const unsigned char value)
390 #if !defined(MAGICKCORE_HDRI_SUPPORT)
391 return((Quantum) (257U*value));
393 return((Quantum) (257.0*value));
397 static inline Quantum ScaleLongToQuantum(const unsigned int value)
399 #if !defined(MAGICKCORE_HDRI_SUPPORT)
400 return((Quantum) ((value+MagickULLConstant(32768))/
401 MagickULLConstant(65537)));
403 return((Quantum) (value/65537.0));
407 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
409 #if !defined(MAGICKCORE_HDRI_SUPPORT)
410 return((Quantum) ((value+MagickULLConstant(8421376))/
411 MagickULLConstant(16842752)));
413 return((Quantum) (value/16842752.0));
417 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
422 return(QuantumRange);
423 #if !defined(MAGICKCORE_HDRI_SUPPORT)
424 return((Quantum) (value+0.5));
426 return((Quantum) value);
430 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
432 #if !defined(MAGICKCORE_HDRI_SUPPORT)
433 return((unsigned int) (65537UL*quantum));
437 if ((65537.0*quantum) >= 4294967295.0)
439 return((unsigned int) (65537.0*quantum+0.5));
443 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
445 #if !defined(MAGICKCORE_HDRI_SUPPORT)
446 return((MagickSizeType) (MagickULLConstant(16842752)*quantum));
450 if ((65537.0*quantum) >= 18446744073709551615.0)
451 return(MagickULLConstant(18446744073709551615));
452 return((MagickSizeType) (16842752.0*quantum+0.5));
456 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
458 if (quantum >= (Quantum) MaxMap)
459 return((unsigned int) MaxMap);
460 #if !defined(MAGICKCORE_HDRI_SUPPORT)
461 return((unsigned int) quantum);
465 return((unsigned int) (quantum+0.5));
469 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
471 #if !defined(MAGICKCORE_HDRI_SUPPORT)
472 return((unsigned short) quantum);
476 if (quantum >= 65535.0)
478 return((unsigned short) (quantum+0.5));
482 static inline Quantum ScaleShortToQuantum(const unsigned short value)
484 return((Quantum) value);
486 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
487 static inline Quantum ScaleCharToQuantum(const unsigned char value)
489 #if !defined(MAGICKCORE_HDRI_SUPPORT)
490 return((Quantum) (16843009UL*value));
492 return((Quantum) (16843009.0*value));
496 static inline Quantum ScaleLongToQuantum(const unsigned int value)
498 return((Quantum) value);
501 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
503 return((Quantum) value);
506 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
510 if (value >= (Quantum) MaxMap)
511 return(QuantumRange);
512 #if !defined(MAGICKCORE_HDRI_SUPPORT)
513 return((Quantum) (65537.0*value+0.5));
515 return((Quantum) (65537.0*value));
519 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
521 #if !defined(MAGICKCORE_HDRI_SUPPORT)
522 return((unsigned int) quantum);
526 if ((quantum) >= 4294967295.0)
528 return((unsigned int) (quantum+0.5));
532 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
534 #if !defined(MAGICKCORE_HDRI_SUPPORT)
535 return((MagickSizeType) quantum);
537 return((MagickSizeType) (quantum+0.5));
541 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
545 if ((quantum/65537) >= (Quantum) MaxMap)
546 return((unsigned int) MaxMap);
547 #if !defined(MAGICKCORE_HDRI_SUPPORT)
548 return((unsigned int) ((quantum+MagickULLConstant(32768))/
549 MagickULLConstant(65537)));
551 return((unsigned int) (quantum/65537.0+0.5));
555 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
557 #if !defined(MAGICKCORE_HDRI_SUPPORT)
558 return((unsigned short) ((quantum+MagickULLConstant(32768))/
559 MagickULLConstant(65537)));
563 if ((quantum/65537.0) >= 65535.0)
565 return((unsigned short) (quantum/65537.0+0.5));
569 static inline Quantum ScaleShortToQuantum(const unsigned short value)
571 #if !defined(MAGICKCORE_HDRI_SUPPORT)
572 return((Quantum) (65537UL*value));
574 return((Quantum) (65537.0*value));
577 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
578 static inline Quantum ScaleCharToQuantum(const unsigned char value)
580 return((Quantum) (72340172838076673.0*value));
583 static inline Quantum ScaleLongToQuantum(const unsigned int value)
585 return((Quantum) (4294967297.0*value));
588 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
590 return((Quantum) (18446744073709551615.0*value));
593 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
598 return(QuantumRange);
599 return((Quantum) (281479271743489.0*value));
602 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
604 return((unsigned int) (quantum/4294967297.0+0.5));
607 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
609 return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
612 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
616 if ((quantum/281479271743489.0) >= MaxMap)
617 return((unsigned int) MaxMap);
618 return((unsigned int) (quantum/281479271743489.0+0.5));
621 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
625 if ((quantum/281479271743489.0) >= 65535.0)
627 return((unsigned short) (quantum/281479271743489.0+0.5));
630 static inline Quantum ScaleShortToQuantum(const unsigned short value)
632 return((Quantum) (281479271743489.0*value));
636 static inline unsigned short SinglePrecisionToHalf(const float value)
638 typedef union _SinglePrecision
650 register unsigned int
661 The IEEE 754 standard specifies half precision as having:
664 Exponent width: 5 bits
665 Significand precision: 11 (10 explicitly stored)
667 map.single_precision=value;
668 sign_bit=(map.fixed_point >> 16) & 0x00008000;
669 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
670 significand=map.fixed_point & 0x007fffff;
677 return((unsigned short) sign_bit);
678 significand=significand | 0x00800000;
679 shift=(int) (14-exponent);
680 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
681 ((significand >> shift) & 0x01)) >> shift);
682 return((unsigned short) (sign_bit | significand));
685 if (exponent == (0xff-ExponentBias))
687 if (significand == 0)
688 return((unsigned short) (sign_bit | ExponentMask));
691 significand>>=SignificandShift;
692 half=(unsigned short) (sign_bit | significand |
693 (significand == 0) | ExponentMask);
697 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
698 if ((significand & 0x00800000) != 0)
715 for (i=0; i < 10; i++)
717 return((unsigned short) (sign_bit | ExponentMask));
719 half=(unsigned short) (sign_bit | (exponent << 10) |
720 (significand >> SignificandShift));
724 #if defined(__cplusplus) || defined(c_plusplus)