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 "magick/cache.h"
27 typedef struct _QuantumState
87 static inline MagickSizeType GetQuantumRange(const size_t depth)
93 return((MagickSizeType) ((one << (depth-1))+((one << (depth-1))-1)));
96 static inline float HalfToSinglePrecision(const unsigned short half)
98 #define ExponentBias (127-15)
99 #define ExponentMask 0x7c00
100 #define ExponentShift 23
101 #define SignBitShift 31
102 #define SignificandShift 13
103 #define SignificandMask 0x00000400
105 typedef union _SinglePrecision
114 register unsigned int
126 The IEEE 754 standard specifies half precision as having:
129 Exponent width: 5 bits
130 Significand precision: 11 (10 explicitly stored)
132 sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
133 exponent=(unsigned int) ((half >> 10) & 0x0000001f);
134 significand=(unsigned int) (half & 0x000003ff);
137 if (significand == 0)
138 value=sign_bit << SignBitShift;
141 while ((significand & SignificandMask) == 0)
147 significand&=(~SignificandMask);
148 exponent+=ExponentBias;
149 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
150 (significand << SignificandShift);
154 if (exponent == SignBitShift)
156 value=(sign_bit << SignBitShift) | 0x7f800000;
157 if (significand != 0)
158 value|=(significand << SignificandShift);
162 exponent+=ExponentBias;
163 significand<<=SignificandShift;
164 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
167 map.fixed_point=value;
168 return(map.single_precision);
171 static inline void InitializeQuantumState(const QuantumInfo *quantum_info,
172 const EndianType endian,QuantumState *quantum_state)
174 static const unsigned int mask[32] =
176 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
177 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
178 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
179 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
180 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
181 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
182 0x3fffffffU, 0x7fffffffU
185 quantum_state->endian=endian;
186 quantum_state->minimum=quantum_info->minimum;
187 quantum_state->scale=quantum_info->scale;
188 quantum_state->inverse_scale=1.0;
189 if (quantum_state->scale != 0.0)
190 quantum_state->inverse_scale/=quantum_state->scale;
191 quantum_state->pixel=0U;
192 quantum_state->bits=0U;
193 quantum_state->mask=mask;
196 static inline unsigned char *PopCharPixel(const unsigned char pixel,
197 unsigned char *pixels)
203 static inline unsigned char *PopLongPixel(const EndianType endian,
204 const unsigned int pixel,unsigned char *pixels)
206 register unsigned int
209 quantum=(unsigned int) pixel;
210 if (endian != LSBEndian)
212 *pixels++=(unsigned char) (quantum >> 24);
213 *pixels++=(unsigned char) (quantum >> 16);
214 *pixels++=(unsigned char) (quantum >> 8);
215 *pixels++=(unsigned char) (quantum);
218 *pixels++=(unsigned char) (quantum);
219 *pixels++=(unsigned char) (quantum >> 8);
220 *pixels++=(unsigned char) (quantum >> 16);
221 *pixels++=(unsigned char) (quantum >> 24);
225 static inline unsigned char *PopShortPixel(const EndianType endian,
226 const unsigned short pixel,unsigned char *pixels)
228 register unsigned int
232 if (endian != LSBEndian)
234 *pixels++=(unsigned char) (quantum >> 8);
235 *pixels++=(unsigned char) (quantum);
238 *pixels++=(unsigned char) (quantum);
239 *pixels++=(unsigned char) (quantum >> 8);
243 static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
244 unsigned char *pixel)
250 static inline const unsigned char *PushLongPixel(const EndianType endian,
251 const unsigned char *pixels,unsigned int *pixel)
253 register unsigned int
256 if (endian != LSBEndian)
258 quantum=(unsigned int) (*pixels++ << 24);
259 quantum|=(unsigned int) (*pixels++ << 16);
260 quantum|=(unsigned int) (*pixels++ << 8);
261 quantum|=(unsigned int) (*pixels++);
265 quantum=(unsigned int) (*pixels++);
266 quantum|=(unsigned int) (*pixels++ << 8);
267 quantum|=(unsigned int) (*pixels++ << 16);
268 quantum|=(unsigned int) (*pixels++ << 24);
270 *pixel=(unsigned int) (quantum & 0xffffffff);
274 static inline const unsigned char *PushShortPixel(const EndianType endian,
275 const unsigned char *pixels,unsigned short *pixel)
277 register unsigned int
280 if (endian != LSBEndian)
282 quantum=(unsigned int) (*pixels++ << 8);
283 quantum|=(unsigned int) *pixels++;
287 quantum=(unsigned int) *pixels++;
288 quantum|=(unsigned int) (*pixels++ << 8);
290 *pixel=(unsigned short) (quantum & 0xffff);
294 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
295 const QuantumAny range)
297 #if !defined(MAGICKCORE_HDRI_SUPPORT)
298 return((Quantum) (((MagickRealType) QuantumRange*quantum)/range+0.5));
300 return((Quantum) (((MagickRealType) QuantumRange*quantum)/range));
304 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
305 const QuantumAny range)
307 return((QuantumAny) (((MagickRealType) range*quantum)/QuantumRange+0.5));
310 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
311 static inline Quantum ScaleCharToQuantum(const unsigned char value)
313 return((Quantum) value);
316 static inline Quantum ScaleLongToQuantum(const unsigned int value)
318 #if !defined(MAGICKCORE_HDRI_SUPPORT)
319 return((Quantum) ((value+8421504UL)/16843009UL));
321 return((Quantum) (value/16843009.0));
325 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
330 return((Quantum) QuantumRange);
331 #if !defined(MAGICKCORE_HDRI_SUPPORT)
332 return((Quantum) (value+0.5));
334 return((Quantum) value);
338 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
340 #if !defined(MAGICKCORE_HDRI_SUPPORT)
341 return((unsigned int) (16843009UL*quantum));
345 if ((16843009.0*quantum) >= 4294967295.0)
346 return(4294967295UL);
347 return((unsigned int) (16843009.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 ScaleMapToQuantum(const MagickRealType value)
410 return((Quantum) QuantumRange);
411 #if !defined(MAGICKCORE_HDRI_SUPPORT)
412 return((Quantum) (value+0.5));
414 return((Quantum) value);
418 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
420 #if !defined(MAGICKCORE_HDRI_SUPPORT)
421 return((unsigned int) (65537UL*quantum));
425 if ((65537.0*quantum) >= 4294967295.0)
426 return(4294967295UL);
427 return((unsigned int) (65537.0*quantum+0.5));
431 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
433 if (quantum >= (Quantum) MaxMap)
434 return((unsigned int) MaxMap);
435 #if !defined(MAGICKCORE_HDRI_SUPPORT)
436 return((unsigned int) quantum);
440 return((unsigned int) (quantum+0.5));
444 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
446 #if !defined(MAGICKCORE_HDRI_SUPPORT)
447 return((unsigned short) quantum);
451 if (quantum >= 65535.0)
453 return((unsigned short) (quantum+0.5));
457 static inline Quantum ScaleShortToQuantum(const unsigned short value)
459 return((Quantum) value);
461 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
462 static inline Quantum ScaleCharToQuantum(const unsigned char value)
464 #if !defined(MAGICKCORE_HDRI_SUPPORT)
465 return((Quantum) (16843009UL*value));
467 return((Quantum) (16843009.0*value));
471 static inline Quantum ScaleLongToQuantum(const unsigned int value)
473 return((Quantum) value);
476 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
480 if (value >= (Quantum) MaxMap)
481 return(QuantumRange);
482 #if !defined(MAGICKCORE_HDRI_SUPPORT)
483 return((Quantum) (65537.0*value+0.5));
485 return((Quantum) (65537.0*value));
489 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
491 #if !defined(MAGICKCORE_HDRI_SUPPORT)
492 return((unsigned int) quantum);
494 return((unsigned int) (quantum+0.5));
498 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
502 if ((quantum/65537) >= (Quantum) MaxMap)
503 return((unsigned int) MaxMap);
504 #if !defined(MAGICKCORE_HDRI_SUPPORT)
505 return((unsigned int) ((quantum+MagickULLConstant(32768))/
506 MagickULLConstant(65537)));
508 return((unsigned int) (quantum/65537.0+0.5));
512 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
514 #if !defined(MAGICKCORE_HDRI_SUPPORT)
515 return((unsigned short) ((quantum+MagickULLConstant(32768))/
516 MagickULLConstant(65537)));
520 if ((quantum/65537.0) >= 65535.0)
522 return((unsigned short) (quantum/65537.0+0.5));
526 static inline Quantum ScaleShortToQuantum(const unsigned short value)
528 #if !defined(MAGICKCORE_HDRI_SUPPORT)
529 return((Quantum) (65537UL*value));
531 return((Quantum) (65537.0*value));
534 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
535 static inline Quantum ScaleCharToQuantum(const unsigned char value)
537 return((Quantum) (72340172838076673.0*value));
540 static inline Quantum ScaleLongToQuantum(const unsigned int value)
542 return((Quantum) (4294967297.0*value));
545 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
550 return(QuantumRange);
551 return((Quantum) (281479271743489.0*value));
554 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
556 return((unsigned int) (quantum/4294967297.0+0.5));
559 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
563 if ((quantum/281479271743489.0) >= MaxMap)
564 return((unsigned int) MaxMap);
565 return((unsigned int) (quantum/281479271743489.0+0.5));
568 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
572 if ((quantum/281479271743489.0) >= 65535.0)
574 return((unsigned short) (quantum/281479271743489.0+0.5));
577 static inline Quantum ScaleShortToQuantum(const unsigned short value)
579 return((Quantum) (281479271743489.0*value));
583 static inline unsigned short SinglePrecisionToHalf(const float value)
585 typedef union _SinglePrecision
597 register unsigned int
608 The IEEE 754 standard specifies half precision as having:
611 Exponent width: 5 bits
612 Significand precision: 11 (10 explicitly stored)
614 map.single_precision=value;
615 sign_bit=(map.fixed_point >> 16) & 0x00008000;
616 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
617 significand=map.fixed_point & 0x007fffff;
624 return((unsigned short) sign_bit);
625 significand=significand | 0x00800000;
626 shift=(int) (14-exponent);
627 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
628 ((significand >> shift) & 0x01)) >> shift);
629 return((unsigned short) (sign_bit | significand));
632 if (exponent == (0xff-ExponentBias))
634 if (significand == 0)
635 return((unsigned short) (sign_bit | ExponentMask));
638 significand>>=SignificandShift;
639 half=(unsigned short) (sign_bit | significand |
640 (significand == 0) | ExponentMask);
644 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
645 if ((significand & 0x00800000) != 0)
662 for (i=0; i < 10; i++)
664 return((unsigned short) (sign_bit | ExponentMask));
666 half=(unsigned short) (sign_bit | (exponent << 10) |
667 (significand >> SignificandShift));
671 #if defined(__cplusplus) || defined(c_plusplus)