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 ScaleMapToQuantum(const double value)
307 return(QuantumRange);
308 #if !defined(MAGICKCORE_HDRI_SUPPORT)
309 return((Quantum) (value+0.5));
311 return((Quantum) value);
315 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
317 #if !defined(MAGICKCORE_HDRI_SUPPORT)
318 return((unsigned int) (16843009UL*quantum));
322 if ((16843009.0*quantum) >= 4294967295.0)
323 return(4294967295UL);
324 return((unsigned int) (16843009.0*quantum+0.5));
328 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
330 if (quantum >= (Quantum) MaxMap)
331 return((unsigned int) MaxMap);
332 #if !defined(MAGICKCORE_HDRI_SUPPORT)
333 return((unsigned int) quantum);
337 return((unsigned int) (quantum+0.5));
341 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
343 #if !defined(MAGICKCORE_HDRI_SUPPORT)
344 return((unsigned short) (257UL*quantum));
348 if ((257.0*quantum) >= 65535.0)
350 return((unsigned short) (257.0*quantum+0.5));
354 static inline Quantum ScaleShortToQuantum(const unsigned short value)
356 #if !defined(MAGICKCORE_HDRI_SUPPORT)
357 return((Quantum) ((value+128U)/257U));
359 return((Quantum) (value/257.0));
362 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
363 static inline Quantum ScaleCharToQuantum(const unsigned char value)
365 #if !defined(MAGICKCORE_HDRI_SUPPORT)
366 return((Quantum) (257U*value));
368 return((Quantum) (257.0*value));
372 static inline Quantum ScaleLongToQuantum(const unsigned int value)
374 #if !defined(MAGICKCORE_HDRI_SUPPORT)
375 return((Quantum) ((value+MagickULLConstant(32768))/
376 MagickULLConstant(65537)));
378 return((Quantum) (value/65537.0));
382 static inline Quantum ScaleMapToQuantum(const double value)
387 return(QuantumRange);
388 #if !defined(MAGICKCORE_HDRI_SUPPORT)
389 return((Quantum) (value+0.5));
391 return((Quantum) value);
395 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
397 #if !defined(MAGICKCORE_HDRI_SUPPORT)
398 return((unsigned int) (65537UL*quantum));
402 if ((65537.0*quantum) >= 4294967295.0)
404 return((unsigned int) (65537.0*quantum+0.5));
408 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
410 if (quantum >= (Quantum) MaxMap)
411 return((unsigned int) MaxMap);
412 #if !defined(MAGICKCORE_HDRI_SUPPORT)
413 return((unsigned int) quantum);
417 return((unsigned int) (quantum+0.5));
421 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
423 #if !defined(MAGICKCORE_HDRI_SUPPORT)
424 return((unsigned short) quantum);
428 if (quantum >= 65535.0)
430 return((unsigned short) (quantum+0.5));
434 static inline Quantum ScaleShortToQuantum(const unsigned short value)
436 return((Quantum) value);
438 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
439 static inline Quantum ScaleCharToQuantum(const unsigned char value)
441 #if !defined(MAGICKCORE_HDRI_SUPPORT)
442 return((Quantum) (16843009UL*value));
444 return((Quantum) (16843009.0*value));
448 static inline Quantum ScaleLongToQuantum(const unsigned int value)
450 return((Quantum) value);
453 static inline Quantum ScaleMapToQuantum(const double value)
457 if (value >= (Quantum) MaxMap)
458 return(QuantumRange);
459 #if !defined(MAGICKCORE_HDRI_SUPPORT)
460 return((Quantum) (65537.0*value+0.5));
462 return((Quantum) (65537.0*value));
466 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
468 #if !defined(MAGICKCORE_HDRI_SUPPORT)
469 return((unsigned int) quantum);
473 if ((quantum) >= 4294967295.0)
475 return((unsigned int) (quantum+0.5));
479 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
483 if ((quantum/65537) >= (Quantum) MaxMap)
484 return((unsigned int) MaxMap);
485 #if !defined(MAGICKCORE_HDRI_SUPPORT)
486 return((unsigned int) ((quantum+MagickULLConstant(32768))/
487 MagickULLConstant(65537)));
489 return((unsigned int) (quantum/65537.0+0.5));
493 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
495 #if !defined(MAGICKCORE_HDRI_SUPPORT)
496 return((unsigned short) ((quantum+MagickULLConstant(32768))/
497 MagickULLConstant(65537)));
501 if ((quantum/65537.0) >= 65535.0)
503 return((unsigned short) (quantum/65537.0+0.5));
507 static inline Quantum ScaleShortToQuantum(const unsigned short value)
509 #if !defined(MAGICKCORE_HDRI_SUPPORT)
510 return((Quantum) (65537UL*value));
512 return((Quantum) (65537.0*value));
515 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
516 static inline Quantum ScaleCharToQuantum(const unsigned char value)
518 return((Quantum) (72340172838076673.0*value));
521 static inline Quantum ScaleLongToQuantum(const unsigned int value)
523 return((Quantum) (4294967297.0*value));
526 static inline Quantum ScaleMapToQuantum(const double value)
531 return(QuantumRange);
532 return((Quantum) (281479271743489.0*value));
535 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
537 return((unsigned int) (quantum/4294967297.0+0.5));
540 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
544 if ((quantum/281479271743489.0) >= MaxMap)
545 return((unsigned int) MaxMap);
546 return((unsigned int) (quantum/281479271743489.0+0.5));
549 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
553 if ((quantum/281479271743489.0) >= 65535.0)
555 return((unsigned short) (quantum/281479271743489.0+0.5));
558 static inline Quantum ScaleShortToQuantum(const unsigned short value)
560 return((Quantum) (281479271743489.0*value));
564 static inline unsigned short SinglePrecisionToHalf(const float value)
566 typedef union _SinglePrecision
578 register unsigned int
589 The IEEE 754 standard specifies half precision as having:
592 Exponent width: 5 bits
593 Significand precision: 11 (10 explicitly stored)
595 map.single_precision=value;
596 sign_bit=(map.fixed_point >> 16) & 0x00008000;
597 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
598 significand=map.fixed_point & 0x007fffff;
605 return((unsigned short) sign_bit);
606 significand=significand | 0x00800000;
607 shift=(int) (14-exponent);
608 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
609 ((significand >> shift) & 0x01)) >> shift);
610 return((unsigned short) (sign_bit | significand));
613 if (exponent == (0xff-ExponentBias))
615 if (significand == 0)
616 return((unsigned short) (sign_bit | ExponentMask));
619 significand>>=SignificandShift;
620 half=(unsigned short) (sign_bit | significand |
621 (significand == 0) | ExponentMask);
625 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
626 if ((significand & 0x00800000) != 0)
643 for (i=0; i < 10; i++)
645 return((unsigned short) (sign_bit | ExponentMask));
647 half=(unsigned short) (sign_bit | (exponent << 10) |
648 (significand >> SignificandShift));
652 #if defined(__cplusplus) || defined(c_plusplus)