2 Copyright 1999-2014 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);
241 *pixel=(unsigned int) (quantum & 0xffffffff);
244 quantum=(unsigned int) (*pixels++ << 24);
245 quantum|=(unsigned int) (*pixels++ << 16);
246 quantum|=(unsigned int) (*pixels++ << 8);
247 quantum|=(unsigned int) (*pixels++);
248 *pixel=(unsigned int) (quantum & 0xffffffff);
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)
274 #if !defined(MAGICKCORE_HDRI_SUPPORT)
275 return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
277 return((Quantum) (((double) QuantumRange*quantum)/range));
281 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
282 const QuantumAny range)
284 return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
287 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
288 static inline Quantum ScaleCharToQuantum(const unsigned char value)
290 return((Quantum) value);
293 static inline Quantum ScaleLongToQuantum(const unsigned int value)
295 #if !defined(MAGICKCORE_HDRI_SUPPORT)
296 return((Quantum) ((value+8421504UL)/16843009UL));
298 return((Quantum) (value/16843009.0));
302 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
304 #if !defined(MAGICKCORE_HDRI_SUPPORT)
305 return((Quantum) ((value+MagickULLConstant(551911719039))/
306 MagickULLConstant(1103823438079)));
308 return((Quantum) (value/1103823438079.0));
312 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
317 return(QuantumRange);
318 #if !defined(MAGICKCORE_HDRI_SUPPORT)
319 return((Quantum) (value+0.5));
321 return((Quantum) value);
325 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
327 #if !defined(MAGICKCORE_HDRI_SUPPORT)
328 return((unsigned int) (16843009UL*quantum));
332 if ((16843009.0*quantum) >= 4294967295.0)
333 return(4294967295UL);
334 return((unsigned int) (16843009.0*quantum+0.5));
338 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
340 #if !defined(MAGICKCORE_HDRI_SUPPORT)
341 return((MagickSizeType) (MagickULLConstant(551911719039)*quantum));
345 if ((551911719039.0*quantum) >= 18446744073709551615.0)
346 return(MagickULLConstant(18446744073709551615));
347 return((MagickSizeType) (1103823438079.0*quantum+0.5));
351 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
353 if (quantum >= (Quantum) MaxMap)
354 return((unsigned int) MaxMap);
355 #if !defined(MAGICKCORE_HDRI_SUPPORT)
356 return((unsigned int) quantum);
360 return((unsigned int) (quantum+0.5));
364 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
366 #if !defined(MAGICKCORE_HDRI_SUPPORT)
367 return((unsigned short) (257UL*quantum));
371 if ((257.0*quantum) >= 65535.0)
373 return((unsigned short) (257.0*quantum+0.5));
377 static inline Quantum ScaleShortToQuantum(const unsigned short value)
379 #if !defined(MAGICKCORE_HDRI_SUPPORT)
380 return((Quantum) ((value+128U)/257U));
382 return((Quantum) (value/257.0));
385 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
386 static inline Quantum ScaleCharToQuantum(const unsigned char value)
388 #if !defined(MAGICKCORE_HDRI_SUPPORT)
389 return((Quantum) (257U*value));
391 return((Quantum) (257.0*value));
395 static inline Quantum ScaleLongToQuantum(const unsigned int value)
397 #if !defined(MAGICKCORE_HDRI_SUPPORT)
398 return((Quantum) ((value+MagickULLConstant(32768))/
399 MagickULLConstant(65537)));
401 return((Quantum) (value/65537.0));
405 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
407 #if !defined(MAGICKCORE_HDRI_SUPPORT)
408 return((Quantum) ((value+MagickULLConstant(8421376))/
409 MagickULLConstant(16842752)));
411 return((Quantum) (value/16842752.0));
415 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
420 return(QuantumRange);
421 #if !defined(MAGICKCORE_HDRI_SUPPORT)
422 return((Quantum) (value+0.5));
424 return((Quantum) value);
428 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
430 #if !defined(MAGICKCORE_HDRI_SUPPORT)
431 return((unsigned int) (65537UL*quantum));
435 if ((65537.0*quantum) >= 4294967295.0)
437 return((unsigned int) (65537.0*quantum+0.5));
441 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
443 #if !defined(MAGICKCORE_HDRI_SUPPORT)
444 return((MagickSizeType) (MagickULLConstant(16842752)*quantum));
448 if ((65537.0*quantum) >= 18446744073709551615.0)
449 return(MagickULLConstant(18446744073709551615));
450 return((MagickSizeType) (16842752.0*quantum+0.5));
454 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
456 if (quantum >= (Quantum) MaxMap)
457 return((unsigned int) MaxMap);
458 #if !defined(MAGICKCORE_HDRI_SUPPORT)
459 return((unsigned int) quantum);
463 return((unsigned int) (quantum+0.5));
467 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
469 #if !defined(MAGICKCORE_HDRI_SUPPORT)
470 return((unsigned short) quantum);
474 if (quantum >= 65535.0)
476 return((unsigned short) (quantum+0.5));
480 static inline Quantum ScaleShortToQuantum(const unsigned short value)
482 return((Quantum) value);
484 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
485 static inline Quantum ScaleCharToQuantum(const unsigned char value)
487 #if !defined(MAGICKCORE_HDRI_SUPPORT)
488 return((Quantum) (16843009UL*value));
490 return((Quantum) (16843009.0*value));
494 static inline Quantum ScaleLongToQuantum(const unsigned int value)
496 return((Quantum) value);
499 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
501 return((Quantum) value);
504 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
508 if (value >= (Quantum) MaxMap)
509 return(QuantumRange);
510 #if !defined(MAGICKCORE_HDRI_SUPPORT)
511 return((Quantum) (65537.0*value+0.5));
513 return((Quantum) (65537.0*value));
517 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
519 #if !defined(MAGICKCORE_HDRI_SUPPORT)
520 return((unsigned int) quantum);
522 return((unsigned int) (quantum+0.5));
526 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
528 #if !defined(MAGICKCORE_HDRI_SUPPORT)
529 return((MagickSizeType) quantum);
531 return((MagickSizeType) (quantum+0.5));
535 static 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 return((unsigned int) (quantum/65537.0+0.5));
549 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
551 #if !defined(MAGICKCORE_HDRI_SUPPORT)
552 return((unsigned short) ((quantum+MagickULLConstant(32768))/
553 MagickULLConstant(65537)));
557 if ((quantum/65537.0) >= 65535.0)
559 return((unsigned short) (quantum/65537.0+0.5));
563 static inline Quantum ScaleShortToQuantum(const unsigned short value)
565 #if !defined(MAGICKCORE_HDRI_SUPPORT)
566 return((Quantum) (65537UL*value));
568 return((Quantum) (65537.0*value));
571 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
572 static inline Quantum ScaleCharToQuantum(const unsigned char value)
574 return((Quantum) (72340172838076673.0*value));
577 static inline Quantum ScaleLongToQuantum(const unsigned int value)
579 return((Quantum) (4294967297.0*value));
582 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
584 return((Quantum) (18446744073709551615.0*value));
587 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
592 return(QuantumRange);
593 return((Quantum) (281479271743489.0*value));
596 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
598 return((unsigned int) (quantum/4294967297.0+0.5));
601 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
603 return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
606 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
610 if ((quantum/281479271743489.0) >= MaxMap)
611 return((unsigned int) MaxMap);
612 return((unsigned int) (quantum/281479271743489.0+0.5));
615 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
619 if ((quantum/281479271743489.0) >= 65535.0)
621 return((unsigned short) (quantum/281479271743489.0+0.5));
624 static inline Quantum ScaleShortToQuantum(const unsigned short value)
626 return((Quantum) (281479271743489.0*value));
630 static inline unsigned short SinglePrecisionToHalf(const float value)
632 typedef union _SinglePrecision
644 register unsigned int
655 The IEEE 754 standard specifies half precision as having:
658 Exponent width: 5 bits
659 Significand precision: 11 (10 explicitly stored)
661 map.single_precision=value;
662 sign_bit=(map.fixed_point >> 16) & 0x00008000;
663 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
664 significand=map.fixed_point & 0x007fffff;
671 return((unsigned short) sign_bit);
672 significand=significand | 0x00800000;
673 shift=(int) (14-exponent);
674 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
675 ((significand >> shift) & 0x01)) >> shift);
676 return((unsigned short) (sign_bit | significand));
679 if (exponent == (0xff-ExponentBias))
681 if (significand == 0)
682 return((unsigned short) (sign_bit | ExponentMask));
685 significand>>=SignificandShift;
686 half=(unsigned short) (sign_bit | significand |
687 (significand == 0) | ExponentMask);
691 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
692 if ((significand & 0x00800000) != 0)
709 for (i=0; i < 10; i++)
711 return((unsigned short) (sign_bit | ExponentMask));
713 half=(unsigned short) (sign_bit | (exponent << 10) |
714 (significand >> SignificandShift));
718 #if defined(__cplusplus) || defined(c_plusplus)