2 Copyright 1999-2008 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 #if defined(__cplusplus) || defined(c_plusplus)
25 #include "MagickCore/cache.h"
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 >> 24);
192 *pixels++=(unsigned char) (quantum >> 16);
193 *pixels++=(unsigned char) (quantum >> 8);
194 *pixels++=(unsigned char) (quantum);
197 *pixels++=(unsigned char) (quantum);
198 *pixels++=(unsigned char) (quantum >> 8);
199 *pixels++=(unsigned char) (quantum >> 16);
200 *pixels++=(unsigned char) (quantum >> 24);
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 >> 8);
214 *pixels++=(unsigned char) (quantum);
217 *pixels++=(unsigned char) (quantum);
218 *pixels++=(unsigned char) (quantum >> 8);
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++ << 24);
238 quantum|=(unsigned int) (*pixels++ << 16);
239 quantum|=(unsigned int) (*pixels++ << 8);
240 quantum|=(unsigned int) (*pixels++);
244 quantum=(unsigned int) (*pixels++);
245 quantum|=(unsigned int) (*pixels++ << 8);
246 quantum|=(unsigned int) (*pixels++ << 16);
247 quantum|=(unsigned int) (*pixels++ << 24);
249 *pixel=(unsigned int) (quantum & 0xffffffff);
253 static inline const unsigned char *PushShortPixel(const EndianType endian,
254 const unsigned char *pixels,unsigned short *pixel)
256 register unsigned int
259 if (endian != LSBEndian)
261 quantum=(unsigned int) (*pixels++ << 8);
262 quantum|=(unsigned int) *pixels++;
266 quantum=(unsigned int) *pixels++;
267 quantum|=(unsigned int) (*pixels++ << 8);
269 *pixel=(unsigned short) (quantum & 0xffff);
273 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
274 const QuantumAny range)
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 double 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 double 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 double 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);
524 return((unsigned int) (quantum+0.5));
528 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
530 #if !defined(MAGICKCORE_HDRI_SUPPORT)
531 return((MagickSizeType) quantum);
533 return((MagickSizeType) (quantum+0.5));
537 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
541 if ((quantum/65537) >= (Quantum) MaxMap)
542 return((unsigned int) MaxMap);
543 #if !defined(MAGICKCORE_HDRI_SUPPORT)
544 return((unsigned int) ((quantum+MagickULLConstant(32768))/
545 MagickULLConstant(65537)));
547 return((unsigned int) (quantum/65537.0+0.5));
551 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
553 #if !defined(MAGICKCORE_HDRI_SUPPORT)
554 return((unsigned short) ((quantum+MagickULLConstant(32768))/
555 MagickULLConstant(65537)));
559 if ((quantum/65537.0) >= 65535.0)
561 return((unsigned short) (quantum/65537.0+0.5));
565 static 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)
574 static inline Quantum ScaleCharToQuantum(const unsigned char value)
576 return((Quantum) (72340172838076673.0*value));
579 static inline Quantum ScaleLongToQuantum(const unsigned int value)
581 return((Quantum) (4294967297.0*value));
584 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
586 return((Quantum) (18446744073709551615.0*value));
589 static inline Quantum ScaleMapToQuantum(const double value)
594 return(QuantumRange);
595 return((Quantum) (281479271743489.0*value));
598 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
600 return((unsigned int) (quantum/4294967297.0+0.5));
603 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
605 return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
608 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
612 if ((quantum/281479271743489.0) >= MaxMap)
613 return((unsigned int) MaxMap);
614 return((unsigned int) (quantum/281479271743489.0+0.5));
617 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
621 if ((quantum/281479271743489.0) >= 65535.0)
623 return((unsigned short) (quantum/281479271743489.0+0.5));
626 static inline Quantum ScaleShortToQuantum(const unsigned short value)
628 return((Quantum) (281479271743489.0*value));
632 static inline unsigned short SinglePrecisionToHalf(const float value)
634 typedef union _SinglePrecision
646 register unsigned int
657 The IEEE 754 standard specifies half precision as having:
660 Exponent width: 5 bits
661 Significand precision: 11 (10 explicitly stored)
663 map.single_precision=value;
664 sign_bit=(map.fixed_point >> 16) & 0x00008000;
665 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
666 significand=map.fixed_point & 0x007fffff;
673 return((unsigned short) sign_bit);
674 significand=significand | 0x00800000;
675 shift=(int) (14-exponent);
676 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
677 ((significand >> shift) & 0x01)) >> shift);
678 return((unsigned short) (sign_bit | significand));
681 if (exponent == (0xff-ExponentBias))
683 if (significand == 0)
684 return((unsigned short) (sign_bit | ExponentMask));
687 significand>>=SignificandShift;
688 half=(unsigned short) (sign_bit | significand |
689 (significand == 0) | ExponentMask);
693 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
694 if ((significand & 0x00800000) != 0)
711 for (i=0; i < 10; i++)
713 return((unsigned short) (sign_bit | ExponentMask));
715 half=(unsigned short) (sign_bit | (exponent << 10) |
716 (significand >> SignificandShift));
720 #if defined(__cplusplus) || defined(c_plusplus)