quantum-private.h

Go to the documentation of this file.
00001 /*
00002   Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization
00003   dedicated to making software imaging solutions freely available.
00004 
00005   You may not use this file except in compliance with the License.  You may
00006   obtain a copy of the License at
00007 
00008     https://imagemagick.org/script/license.php
00009 
00010   Unless required by applicable law or agreed to in writing, software
00011   distributed under the License is distributed on an "AS IS" BASIS,
00012   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013   See the License for the specific language governing permissions and
00014   limitations under the License.
00015 
00016   MagickCore quantum inline methods.
00017 */
00018 #ifndef MAGICKCORE_QUANTUM_PRIVATE_H
00019 #define MAGICKCORE_QUANTUM_PRIVATE_H
00020 
00021 #include "MagickCore/memory_.h"
00022 #include "MagickCore/cache.h"
00023 #include "MagickCore/image-private.h"
00024 #include "MagickCore/pixel-accessor.h"
00025 
00026 #if defined(__cplusplus) || defined(c_plusplus)
00027 extern "C" {
00028 #endif
00029 
00030 typedef struct _QuantumState
00031 {
00032   double
00033     inverse_scale;
00034 
00035   unsigned int
00036     pixel;
00037 
00038   size_t
00039     bits;
00040 
00041   const unsigned int
00042     *mask;
00043 } QuantumState;
00044 
00045 struct _QuantumInfo
00046 {
00047   size_t
00048     depth,
00049     quantum;
00050 
00051   QuantumFormatType
00052     format;
00053 
00054   double
00055     minimum,
00056     maximum,
00057     scale;
00058 
00059   size_t
00060     pad;
00061 
00062   MagickBooleanType
00063     min_is_white,
00064     pack;
00065 
00066   QuantumAlphaType
00067     alpha_type;
00068 
00069   size_t
00070     number_threads;
00071 
00072   MemoryInfo
00073     **pixels;
00074 
00075   size_t
00076     extent;
00077 
00078   EndianType
00079     endian;
00080 
00081   QuantumState
00082     state;
00083 
00084   SemaphoreInfo
00085     *semaphore;
00086 
00087   size_t
00088     signature;
00089 };
00090 
00091 extern MagickPrivate void
00092   ResetQuantumState(QuantumInfo *);
00093 
00094 static inline MagickSizeType GetQuantumRange(const size_t depth)
00095 {
00096   MagickSizeType
00097     one;
00098 
00099   size_t
00100     max_depth;
00101 
00102   if (depth == 0)
00103     return(0);
00104   one=1;
00105   max_depth=8*sizeof(MagickSizeType);
00106   return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
00107     ((one << (MagickMin(depth,max_depth)-1))-1)));
00108 }
00109 
00110 static inline float HalfToSinglePrecision(const unsigned short half)
00111 {
00112 #define ExponentBias  (127-15)
00113 #define ExponentMask  0x7c00
00114 #define ExponentShift  23
00115 #define SignBitShift  31
00116 #define SignificandShift  13
00117 #define SignificandMask  0x00000400
00118 
00119   typedef union _SinglePrecision
00120   {
00121     unsigned int
00122       fixed_point;
00123 
00124     float
00125       single_precision;
00126   } SinglePrecision;
00127 
00128   register unsigned int
00129     exponent,
00130     significand,
00131     sign_bit;
00132 
00133   SinglePrecision
00134     map;
00135 
00136   unsigned int
00137     value;
00138 
00139   /*
00140     The IEEE 754 standard specifies half precision as having:
00141 
00142       Sign bit: 1 bit
00143       Exponent width: 5 bits
00144       Significand precision: 11 (10 explicitly stored)
00145   */
00146   sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
00147   exponent=(unsigned int) ((half >> 10) & 0x0000001f);
00148   significand=(unsigned int) (half & 0x000003ff);
00149   if (exponent == 0)
00150     {
00151       if (significand == 0)
00152         value=sign_bit << SignBitShift;
00153       else
00154         {
00155           while ((significand & SignificandMask) == 0)
00156           {
00157             significand<<=1;
00158             exponent--;
00159           }
00160           exponent++;
00161           significand&=(~SignificandMask);
00162           exponent+=ExponentBias;
00163           value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
00164             (significand << SignificandShift);
00165         }
00166     }
00167   else
00168     if (exponent == SignBitShift)
00169       {
00170         value=(sign_bit << SignBitShift) | 0x7f800000;
00171         if (significand != 0)
00172           value|=(significand << SignificandShift);
00173       }
00174     else
00175       {
00176         exponent+=ExponentBias;
00177         significand<<=SignificandShift;
00178         value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
00179           significand;
00180       }
00181   map.fixed_point=value;
00182   return(map.single_precision);
00183 }
00184 
00185 static inline unsigned char *PopCharPixel(const unsigned char pixel,
00186   unsigned char *pixels)
00187 {
00188   *pixels++=pixel;
00189   return(pixels);
00190 }
00191 
00192 static inline unsigned char *PopLongPixel(const EndianType endian,
00193   const unsigned int pixel,unsigned char *pixels)
00194 {
00195   register unsigned int
00196     quantum;
00197 
00198   quantum=(unsigned int) pixel;
00199   if (endian == LSBEndian)
00200     {
00201       *pixels++=(unsigned char) (quantum);
00202       *pixels++=(unsigned char) (quantum >> 8);
00203       *pixels++=(unsigned char) (quantum >> 16);
00204       *pixels++=(unsigned char) (quantum >> 24);
00205       return(pixels);
00206     }
00207   *pixels++=(unsigned char) (quantum >> 24);
00208   *pixels++=(unsigned char) (quantum >> 16);
00209   *pixels++=(unsigned char) (quantum >> 8);
00210   *pixels++=(unsigned char) (quantum);
00211   return(pixels);
00212 }
00213 
00214 static inline unsigned char *PopShortPixel(const EndianType endian,
00215   const unsigned short pixel,unsigned char *pixels)
00216 {
00217   register unsigned int
00218     quantum;
00219 
00220   quantum=pixel;
00221   if (endian == LSBEndian)
00222     {
00223       *pixels++=(unsigned char) (quantum);
00224       *pixels++=(unsigned char) (quantum >> 8);
00225       return(pixels);
00226     }
00227   *pixels++=(unsigned char) (quantum >> 8);
00228   *pixels++=(unsigned char) (quantum);
00229   return(pixels);
00230 }
00231 
00232 static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
00233   unsigned char *pixel)
00234 {
00235   *pixel=(*pixels++);
00236   return(pixels);
00237 }
00238 
00239 static inline const unsigned char *PushLongPixel(const EndianType endian,
00240   const unsigned char *pixels,unsigned int *pixel)
00241 {
00242   register unsigned int
00243     quantum;
00244 
00245   if (endian == LSBEndian)
00246     {
00247       quantum=((unsigned int) *pixels++);
00248       quantum|=((unsigned int) *pixels++ << 8);
00249       quantum|=((unsigned int) *pixels++ << 16);
00250       quantum|=((unsigned int) *pixels++ << 24);
00251       *pixel=quantum;
00252       return(pixels);
00253     }
00254   quantum=((unsigned int) *pixels++ << 24);
00255   quantum|=((unsigned int) *pixels++ << 16);
00256   quantum|=((unsigned int) *pixels++ << 8);
00257   quantum|=((unsigned int) *pixels++);
00258   *pixel=quantum;
00259   return(pixels);
00260 }
00261 
00262 static inline const unsigned char *PushShortPixel(const EndianType endian,
00263   const unsigned char *pixels,unsigned short *pixel)
00264 {
00265   register unsigned int
00266     quantum;
00267 
00268   if (endian == LSBEndian)
00269     {
00270       quantum=(unsigned int) *pixels++;
00271       quantum|=(unsigned int) (*pixels++ << 8);
00272       *pixel=(unsigned short) (quantum & 0xffff);
00273       return(pixels);
00274     }
00275   quantum=(unsigned int) (*pixels++ << 8);
00276   quantum|=(unsigned int) *pixels++;
00277   *pixel=(unsigned short) (quantum & 0xffff);
00278   return(pixels);
00279 }
00280 
00281 static inline const unsigned char *PushFloatPixel(const EndianType endian,
00282   const unsigned char *pixels,MagickFloatType *pixel)
00283 {
00284   union
00285   {
00286     unsigned int
00287       unsigned_value;
00288 
00289     MagickFloatType
00290       float_value;
00291   } quantum;
00292 
00293   if (endian == LSBEndian)
00294     {
00295       quantum.unsigned_value=((unsigned int) *pixels++);
00296       quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00297       quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00298       quantum.unsigned_value|=((unsigned int) *pixels++ << 24);
00299       *pixel=quantum.float_value;
00300       return(pixels);
00301     }
00302   quantum.unsigned_value=((unsigned int) *pixels++ << 24);
00303   quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00304   quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00305   quantum.unsigned_value|=((unsigned int) *pixels++);
00306   *pixel=quantum.float_value;
00307   return(pixels);
00308 }
00309 
00310 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
00311   const QuantumAny range)
00312 {
00313   if (quantum > range)
00314     return(QuantumRange);
00315 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00316   return((Quantum) (((double) QuantumRange*quantum)*
00317     PerceptibleReciprocal((double) range)+0.5));
00318 #else
00319   return((Quantum) (((double) QuantumRange*quantum)*
00320     PerceptibleReciprocal((double) range)));
00321 #endif
00322 }
00323 
00324 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
00325   const QuantumAny range)
00326 {
00327 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00328   return((QuantumAny) ((double) range*quantum/QuantumRange));
00329 #else
00330   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00331     return((QuantumAny) 0UL);
00332   if (((double) range*quantum/QuantumRange) >= 18446744073709551615.0)
00333     return((QuantumAny) MagickULLConstant(18446744073709551615));
00334   return((QuantumAny) ((double) range*quantum/QuantumRange+0.5));
00335 #endif
00336 }
00337 
00338 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
00339 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00340 {
00341   return((Quantum) value);
00342 }
00343 
00344 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00345 {
00346 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00347   return((Quantum) ((value)/16843009UL));
00348 #else
00349   return((Quantum) (value/16843009.0));
00350 #endif
00351 }
00352 
00353 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00354 {
00355 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00356   return((Quantum) (value/MagickULLConstant(72340172838076673)));
00357 #else
00358   return((Quantum) (value/72340172838076673.0));
00359 #endif
00360 }
00361 
00362 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00363 {
00364   if (value <= 0.0)
00365     return((Quantum) 0);
00366   if (value >= MaxMap)
00367     return(QuantumRange);
00368 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00369   return((Quantum) (value+0.5));
00370 #else
00371   return((Quantum) value);
00372 #endif
00373 }
00374 
00375 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00376 {
00377 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00378   return((unsigned int) (16843009UL*quantum));
00379 #else
00380   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00381     return(0U);
00382   if ((16843009.0*quantum) >= 4294967295.0)
00383     return(4294967295UL);
00384   return((unsigned int) (16843009.0*quantum+0.5));
00385 #endif
00386 }
00387 
00388 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00389 {
00390 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00391   return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
00392 #else
00393   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00394     return(0UL);
00395   if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
00396     return(MagickULLConstant(18446744073709551615));
00397   return((MagickSizeType) (72340172838076673*quantum+0.5));
00398 #endif
00399 }
00400 
00401 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00402 {
00403   if (quantum >= (Quantum) MaxMap)
00404     return((unsigned int) MaxMap);
00405 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00406   return((unsigned int) quantum);
00407 #else
00408   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00409     return(0U);
00410   return((unsigned int) (quantum+0.5));
00411 #endif
00412 }
00413 
00414 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00415 {
00416 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00417   return((unsigned short) (257UL*quantum));
00418 #else
00419   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00420     return(0);
00421   if ((257.0*quantum) >= 65535.0)
00422     return(65535);
00423   return((unsigned short) (257.0*quantum+0.5));
00424 #endif
00425 }
00426 
00427 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00428 {
00429 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00430   return((Quantum) ((value+128U)/257U));
00431 #else
00432   return((Quantum) (value/257.0));
00433 #endif
00434 }
00435 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
00436 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00437 {
00438 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00439   return((Quantum) (257U*value));
00440 #else
00441   return((Quantum) (257.0*value));
00442 #endif
00443 }
00444 
00445 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00446 {
00447 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00448   return((Quantum) ((value)/MagickULLConstant(65537)));
00449 #else
00450   return((Quantum) (value/65537.0));
00451 #endif
00452 }
00453 
00454 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00455 {
00456 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00457   return((Quantum) ((value)/MagickULLConstant(281479271743489)));
00458 #else
00459   return((Quantum) (value/281479271743489.0));
00460 #endif
00461 }
00462 
00463 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00464 {
00465   if (value <= 0.0)
00466     return((Quantum) 0);
00467   if (value >= MaxMap)
00468     return(QuantumRange);
00469 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00470   return((Quantum) (value+0.5));
00471 #else
00472   return((Quantum) value);
00473 #endif
00474 }
00475 
00476 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00477 {
00478 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00479   return((unsigned int) (65537UL*quantum));
00480 #else
00481   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00482     return(0U);
00483   if ((65537.0*quantum) >= 4294967295.0)
00484     return(4294967295U);
00485   return((unsigned int) (65537.0*quantum+0.5));
00486 #endif
00487 }
00488 
00489 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00490 {
00491 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00492   return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
00493 #else
00494   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00495     return(0UL);
00496   if ((281479271743489.0*quantum) >= 18446744073709551615.0)
00497     return(MagickULLConstant(18446744073709551615));
00498   return((MagickSizeType) (281479271743489.0*quantum+0.5));
00499 #endif
00500 }
00501 
00502 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00503 {
00504   if (quantum >= (Quantum) MaxMap)
00505     return((unsigned int) MaxMap);
00506 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00507   return((unsigned int) quantum);
00508 #else
00509   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00510     return(0U);
00511   return((unsigned int) (quantum+0.5));
00512 #endif
00513 }
00514 
00515 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00516 {
00517 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00518   return((unsigned short) quantum);
00519 #else
00520   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00521     return(0);
00522   if (quantum >= 65535.0)
00523     return(65535);
00524   return((unsigned short) (quantum+0.5));
00525 #endif
00526 }
00527 
00528 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00529 {
00530   return((Quantum) value);
00531 }
00532 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
00533 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00534 {
00535 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00536   return((Quantum) (16843009UL*value));
00537 #else
00538   return((Quantum) (16843009.0*value));
00539 #endif
00540 }
00541 
00542 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00543 {
00544   return((Quantum) value);
00545 }
00546 
00547 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00548 {
00549 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00550   return((Quantum) ((value)/MagickULLConstant(4294967297)));
00551 #else
00552   return((Quantum) (value/4294967297.0));
00553 #endif
00554 }
00555 
00556 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00557 {
00558   if (value <= 0.0)
00559     return((Quantum) 0);
00560   if (value >= (Quantum) MaxMap)
00561     return(QuantumRange);
00562 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00563   return((Quantum) (65537.0*value+0.5));
00564 #else
00565   return((Quantum) (65537.0*value));
00566 #endif
00567 }
00568 
00569 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00570 {
00571 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00572   return((unsigned int) quantum);
00573 #else
00574   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00575     return(0U);
00576   if ((quantum) >= 4294967295.0)
00577     return(4294967295);
00578   return((unsigned int) (quantum+0.5));
00579 #endif
00580 }
00581 
00582 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00583 {
00584 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00585   return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
00586 #else
00587   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00588     return(0UL);
00589   if ((4294967297.0*quantum) >= 18446744073709551615.0)
00590     return(MagickULLConstant(18446744073709551615));
00591   return((MagickSizeType) (4294967297.0*quantum+0.5));
00592 #endif
00593 }
00594 
00595 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00596 {
00597   if ((quantum/65537) >= (Quantum) MaxMap)
00598     return((unsigned int) MaxMap);
00599 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00600   return((unsigned int) ((quantum+MagickULLConstant(32768))/
00601     MagickULLConstant(65537)));
00602 #else
00603   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00604     return(0U);
00605   return((unsigned int) (quantum/65537.0+0.5));
00606 #endif
00607 }
00608 
00609 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00610 {
00611 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00612   return((unsigned short) ((quantum+MagickULLConstant(32768))/
00613     MagickULLConstant(65537)));
00614 #else
00615   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00616     return(0);
00617   if ((quantum/65537.0) >= 65535.0)
00618     return(65535);
00619   return((unsigned short) (quantum/65537.0+0.5));
00620 #endif
00621 }
00622 
00623 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00624 {
00625 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00626   return((Quantum) (65537UL*value));
00627 #else
00628   return((Quantum) (65537.0*value));
00629 #endif
00630 }
00631 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
00632 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00633 {
00634   return((Quantum) (72340172838076673.0*value));
00635 }
00636 
00637 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00638 {
00639   return((Quantum) (4294967297.0*value));
00640 }
00641 
00642 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00643 {
00644   return((Quantum) (value));
00645 }
00646 
00647 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00648 {
00649   if (value <= 0.0)
00650     return((Quantum) 0);
00651   if (value >= MaxMap)
00652     return(QuantumRange);
00653   return((Quantum) (281479271743489.0*value));
00654 }
00655 
00656 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00657 {
00658   return((unsigned int) (quantum/4294967297.0+0.5));
00659 }
00660 
00661 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00662 {
00663 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00664   return((MagickSizeType) quantum);
00665 #else
00666   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00667     return(0UL);
00668   if (quantum >= 18446744073709551615.0)
00669     return(MagickULLConstant(18446744073709551615));
00670   return((MagickSizeType) (quantum+0.5));
00671 #endif
00672 }
00673 
00674 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00675 {
00676   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00677     return(0U);
00678   if ((quantum/281479271743489.0) >= MaxMap)
00679     return((unsigned int) MaxMap);
00680   return((unsigned int) (quantum/281479271743489.0+0.5));
00681 }
00682 
00683 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00684 {
00685   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00686     return(0);
00687   if ((quantum/281479271743489.0) >= 65535.0)
00688     return(65535);
00689   return((unsigned short) (quantum/281479271743489.0+0.5));
00690 }
00691 
00692 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00693 {
00694   return((Quantum) (281479271743489.0*value));
00695 }
00696 #endif
00697 
00698 static inline unsigned short SinglePrecisionToHalf(const float value)
00699 {
00700   typedef union _SinglePrecision
00701   {
00702     unsigned int
00703       fixed_point;
00704 
00705     float
00706       single_precision;
00707   } SinglePrecision;
00708 
00709   register int
00710     exponent;
00711 
00712   register unsigned int
00713     significand,
00714     sign_bit;
00715 
00716   SinglePrecision
00717     map;
00718 
00719   unsigned short
00720     half;
00721 
00722   /*
00723     The IEEE 754 standard specifies half precision as having:
00724 
00725       Sign bit: 1 bit
00726       Exponent width: 5 bits
00727       Significand precision: 11 (10 explicitly stored)
00728   */
00729   map.single_precision=value;
00730   sign_bit=(map.fixed_point >> 16) & 0x00008000;
00731   exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
00732   significand=map.fixed_point & 0x007fffff;
00733   if (exponent <= 0)
00734     {
00735       int
00736         shift;
00737 
00738       if (exponent < -10)
00739         return((unsigned short) sign_bit);
00740       significand=significand | 0x00800000;
00741       shift=(int) (14-exponent);
00742       significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
00743         ((significand >> shift) & 0x01)) >> shift);
00744       return((unsigned short) (sign_bit | significand));
00745     }
00746   else
00747     if (exponent == (0xff-ExponentBias))
00748       {
00749         if (significand == 0)
00750           return((unsigned short) (sign_bit | ExponentMask));
00751         else
00752           {
00753             significand>>=SignificandShift;
00754             half=(unsigned short) (sign_bit | significand |
00755               (significand == 0) | ExponentMask);
00756             return(half);
00757           }
00758       }
00759   significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
00760   if ((significand & 0x00800000) != 0)
00761     {
00762       significand=0;
00763       exponent++;
00764     }
00765   if (exponent > 30)
00766     {
00767       float
00768         alpha;
00769 
00770       register int
00771         i;
00772 
00773       /*
00774         Float overflow.
00775       */
00776       alpha=1.0e10;
00777       for (i=0; i < 10; i++)
00778         alpha*=alpha;
00779       return((unsigned short) (sign_bit | ExponentMask));
00780     }
00781   half=(unsigned short) (sign_bit | (exponent << 10) |
00782     (significand >> SignificandShift));
00783   return(half);
00784 }
00785 
00786 #if defined(__cplusplus) || defined(c_plusplus)
00787 }
00788 #endif
00789 
00790 #endif

Generated on 31 Oct 2019 for MagickCore by  doxygen 1.6.1