Home | History | Annotate | Download | only in MagickCore
      1 /*
      2   Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization
      3   dedicated to making software imaging solutions freely available.
      4 
      5   You may not use this file except in compliance with the License.  You may
      6   obtain a copy of the License at
      7 
      8     https://imagemagick.org/script/license.php
      9 
     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.
     15 
     16   MagickCore quantum inline methods.
     17 */
     18 #ifndef MAGICKCORE_QUANTUM_PRIVATE_H
     19 #define MAGICKCORE_QUANTUM_PRIVATE_H
     20 
     21 #include "MagickCore/memory_.h"
     22 #include "MagickCore/cache.h"
     23 #include "MagickCore/image-private.h"
     24 #include "MagickCore/pixel-accessor.h"
     25 
     26 #if defined(__cplusplus) || defined(c_plusplus)
     27 extern "C" {
     28 #endif
     29 
     30 typedef struct _QuantumState
     31 {
     32   double
     33     inverse_scale;
     34 
     35   unsigned int
     36     pixel;
     37 
     38   size_t
     39     bits;
     40 
     41   const unsigned int
     42     *mask;
     43 } QuantumState;
     44 
     45 struct _QuantumInfo
     46 {
     47   size_t
     48     depth,
     49     quantum;
     50 
     51   QuantumFormatType
     52     format;
     53 
     54   double
     55     minimum,
     56     maximum,
     57     scale;
     58 
     59   size_t
     60     pad;
     61 
     62   MagickBooleanType
     63     min_is_white,
     64     pack;
     65 
     66   QuantumAlphaType
     67     alpha_type;
     68 
     69   size_t
     70     number_threads;
     71 
     72   MemoryInfo
     73     **pixels;
     74 
     75   size_t
     76     extent;
     77 
     78   EndianType
     79     endian;
     80 
     81   QuantumState
     82     state;
     83 
     84   SemaphoreInfo
     85     *semaphore;
     86 
     87   size_t
     88     signature;
     89 };
     90 
     91 extern MagickPrivate void
     92   ResetQuantumState(QuantumInfo *);
     93 
     94 static inline MagickSizeType GetQuantumRange(const size_t depth)
     95 {
     96   MagickSizeType
     97     one;
     98 
     99   size_t
    100     max_depth;
    101 
    102   if (depth == 0)
    103     return(0);
    104   one=1;
    105   max_depth=8*sizeof(MagickSizeType);
    106   return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
    107     ((one << (MagickMin(depth,max_depth)-1))-1)));
    108 }
    109 
    110 static inline float HalfToSinglePrecision(const unsigned short half)
    111 {
    112 #define ExponentBias  (127-15)
    113 #define ExponentMask  0x7c00
    114 #define ExponentShift  23
    115 #define SignBitShift  31
    116 #define SignificandShift  13
    117 #define SignificandMask  0x00000400
    118 
    119   typedef union _SinglePrecision
    120   {
    121     unsigned int
    122       fixed_point;
    123 
    124     float
    125       single_precision;
    126   } SinglePrecision;
    127 
    128   register unsigned int
    129     exponent,
    130     significand,
    131     sign_bit;
    132 
    133   SinglePrecision
    134     map;
    135 
    136   unsigned int
    137     value;
    138 
    139   /*
    140     The IEEE 754 standard specifies half precision as having:
    141 
    142       Sign bit: 1 bit
    143       Exponent width: 5 bits
    144       Significand precision: 11 (10 explicitly stored)
    145   */
    146   sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
    147   exponent=(unsigned int) ((half >> 10) & 0x0000001f);
    148   significand=(unsigned int) (half & 0x000003ff);
    149   if (exponent == 0)
    150     {
    151       if (significand == 0)
    152         value=sign_bit << SignBitShift;
    153       else
    154         {
    155           while ((significand & SignificandMask) == 0)
    156           {
    157             significand<<=1;
    158             exponent--;
    159           }
    160           exponent++;
    161           significand&=(~SignificandMask);
    162           exponent+=ExponentBias;
    163           value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
    164             (significand << SignificandShift);
    165         }
    166     }
    167   else
    168     if (exponent == SignBitShift)
    169       {
    170         value=(sign_bit << SignBitShift) | 0x7f800000;
    171         if (significand != 0)
    172           value|=(significand << SignificandShift);
    173       }
    174     else
    175       {
    176         exponent+=ExponentBias;
    177         significand<<=SignificandShift;
    178         value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
    179           significand;
    180       }
    181   map.fixed_point=value;
    182   return(map.single_precision);
    183 }
    184 
    185 static inline unsigned char *PopCharPixel(const unsigned char pixel,
    186   unsigned char *pixels)
    187 {
    188   *pixels++=pixel;
    189   return(pixels);
    190 }
    191 
    192 static inline unsigned char *PopLongPixel(const EndianType endian,
    193   const unsigned int pixel,unsigned char *pixels)
    194 {
    195   register unsigned int
    196     quantum;
    197 
    198   quantum=(unsigned int) pixel;
    199   if (endian == LSBEndian)
    200     {
    201       *pixels++=(unsigned char) (quantum);
    202       *pixels++=(unsigned char) (quantum >> 8);
    203       *pixels++=(unsigned char) (quantum >> 16);
    204       *pixels++=(unsigned char) (quantum >> 24);
    205       return(pixels);
    206     }
    207   *pixels++=(unsigned char) (quantum >> 24);
    208   *pixels++=(unsigned char) (quantum >> 16);
    209   *pixels++=(unsigned char) (quantum >> 8);
    210   *pixels++=(unsigned char) (quantum);
    211   return(pixels);
    212 }
    213 
    214 static inline unsigned char *PopShortPixel(const EndianType endian,
    215   const unsigned short pixel,unsigned char *pixels)
    216 {
    217   register unsigned int
    218     quantum;
    219 
    220   quantum=pixel;
    221   if (endian == LSBEndian)
    222     {
    223       *pixels++=(unsigned char) (quantum);
    224       *pixels++=(unsigned char) (quantum >> 8);
    225       return(pixels);
    226     }
    227   *pixels++=(unsigned char) (quantum >> 8);
    228   *pixels++=(unsigned char) (quantum);
    229   return(pixels);
    230 }
    231 
    232 static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
    233   unsigned char *pixel)
    234 {
    235   *pixel=(*pixels++);
    236   return(pixels);
    237 }
    238 
    239 static inline const unsigned char *PushLongPixel(const EndianType endian,
    240   const unsigned char *pixels,unsigned int *pixel)
    241 {
    242   register unsigned int
    243     quantum;
    244 
    245   if (endian == LSBEndian)
    246     {
    247       quantum=((unsigned int) *pixels++);
    248       quantum|=((unsigned int) *pixels++ << 8);
    249       quantum|=((unsigned int) *pixels++ << 16);
    250       quantum|=((unsigned int) *pixels++ << 24);
    251       *pixel=quantum;
    252       return(pixels);
    253     }
    254   quantum=((unsigned int) *pixels++ << 24);
    255   quantum|=((unsigned int) *pixels++ << 16);
    256   quantum|=((unsigned int) *pixels++ << 8);
    257   quantum|=((unsigned int) *pixels++);
    258   *pixel=quantum;
    259   return(pixels);
    260 }
    261 
    262 static inline const unsigned char *PushShortPixel(const EndianType endian,
    263   const unsigned char *pixels,unsigned short *pixel)
    264 {
    265   register unsigned int
    266     quantum;
    267 
    268   if (endian == LSBEndian)
    269     {
    270       quantum=(unsigned int) *pixels++;
    271       quantum|=(unsigned int) (*pixels++ << 8);
    272       *pixel=(unsigned short) (quantum & 0xffff);
    273       return(pixels);
    274     }
    275   quantum=(unsigned int) (*pixels++ << 8);
    276   quantum|=(unsigned int) *pixels++;
    277   *pixel=(unsigned short) (quantum & 0xffff);
    278   return(pixels);
    279 }
    280 
    281 static inline const unsigned char *PushFloatPixel(const EndianType endian,
    282   const unsigned char *pixels,MagickFloatType *pixel)
    283 {
    284   union
    285   {
    286     unsigned int
    287       unsigned_value;
    288 
    289     MagickFloatType
    290       float_value;
    291   } quantum;
    292 
    293   if (endian == LSBEndian)
    294     {
    295       quantum.unsigned_value=((unsigned int) *pixels++);
    296       quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
    297       quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
    298       quantum.unsigned_value|=((unsigned int) *pixels++ << 24);
    299       *pixel=quantum.float_value;
    300       return(pixels);
    301     }
    302   quantum.unsigned_value=((unsigned int) *pixels++ << 24);
    303   quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
    304   quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
    305   quantum.unsigned_value|=((unsigned int) *pixels++);
    306   *pixel=quantum.float_value;
    307   return(pixels);
    308 }
    309 
    310 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
    311   const QuantumAny range)
    312 {
    313   if (quantum > range)
    314     return(QuantumRange);
    315 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    316   return((Quantum) (((double) QuantumRange*quantum)*
    317     PerceptibleReciprocal((double) range)+0.5));
    318 #else
    319   return((Quantum) (((double) QuantumRange*quantum)*
    320     PerceptibleReciprocal((double) range)));
    321 #endif
    322 }
    323 
    324 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
    325   const QuantumAny range)
    326 {
    327   return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
    328 }
    329 
    330 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
    331 static inline Quantum ScaleCharToQuantum(const unsigned char value)
    332 {
    333   return((Quantum) value);
    334 }
    335 
    336 static inline Quantum ScaleLongToQuantum(const unsigned int value)
    337 {
    338 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    339   return((Quantum) ((value)/16843009UL));
    340 #else
    341   return((Quantum) (value/16843009.0));
    342 #endif
    343 }
    344 
    345 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
    346 {
    347 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    348   return((Quantum) (value/MagickULLConstant(72340172838076673)));
    349 #else
    350   return((Quantum) (value/72340172838076673.0));
    351 #endif
    352 }
    353 
    354 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
    355 {
    356   if (value <= 0.0)
    357     return((Quantum) 0);
    358   if (value >= MaxMap)
    359     return(QuantumRange);
    360 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    361   return((Quantum) (value+0.5));
    362 #else
    363   return((Quantum) value);
    364 #endif
    365 }
    366 
    367 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
    368 {
    369 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    370   return((unsigned int) (16843009UL*quantum));
    371 #else
    372   if (quantum <= 0.0)
    373     return(0UL);
    374   if ((16843009.0*quantum) >= 4294967295.0)
    375     return(4294967295UL);
    376   return((unsigned int) (16843009.0*quantum+0.5));
    377 #endif
    378 }
    379 
    380 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
    381 {
    382 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    383   return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
    384 #else
    385   if (quantum <= 0.0)
    386     return(0UL);
    387   if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
    388     return(MagickULLConstant(18446744073709551615));
    389   return((MagickSizeType) (72340172838076673*quantum+0.5));
    390 #endif
    391 }
    392 
    393 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
    394 {
    395   if (quantum >= (Quantum) MaxMap)
    396     return((unsigned int) MaxMap);
    397 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    398   return((unsigned int) quantum);
    399 #else
    400   if (quantum < 0.0)
    401     return(0UL);
    402   return((unsigned int) (quantum+0.5));
    403 #endif
    404 }
    405 
    406 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
    407 {
    408 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    409   return((unsigned short) (257UL*quantum));
    410 #else
    411   if (quantum <= 0.0)
    412     return(0);
    413   if ((257.0*quantum) >= 65535.0)
    414     return(65535);
    415   return((unsigned short) (257.0*quantum+0.5));
    416 #endif
    417 }
    418 
    419 static inline Quantum ScaleShortToQuantum(const unsigned short value)
    420 {
    421 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    422   return((Quantum) ((value+128U)/257U));
    423 #else
    424   return((Quantum) (value/257.0));
    425 #endif
    426 }
    427 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
    428 static inline Quantum ScaleCharToQuantum(const unsigned char value)
    429 {
    430 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    431   return((Quantum) (257U*value));
    432 #else
    433   return((Quantum) (257.0*value));
    434 #endif
    435 }
    436 
    437 static inline Quantum ScaleLongToQuantum(const unsigned int value)
    438 {
    439 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    440   return((Quantum) ((value)/MagickULLConstant(65537)));
    441 #else
    442   return((Quantum) (value/65537.0));
    443 #endif
    444 }
    445 
    446 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
    447 {
    448 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    449   return((Quantum) ((value)/MagickULLConstant(281479271743489)));
    450 #else
    451   return((Quantum) (value/281479271743489.0));
    452 #endif
    453 }
    454 
    455 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
    456 {
    457   if (value <= 0.0)
    458     return((Quantum) 0);
    459   if (value >= MaxMap)
    460     return(QuantumRange);
    461 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    462   return((Quantum) (value+0.5));
    463 #else
    464   return((Quantum) value);
    465 #endif
    466 }
    467 
    468 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
    469 {
    470 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    471   return((unsigned int) (65537UL*quantum));
    472 #else
    473   if (quantum <= 0.0)
    474     return(0UL);
    475   if ((65537.0*quantum) >= 4294967295.0)
    476     return(4294967295U);
    477   return((unsigned int) (65537.0*quantum+0.5));
    478 #endif
    479 }
    480 
    481 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
    482 {
    483 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    484   return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
    485 #else
    486   if (quantum <= 0.0)
    487     return(0UL);
    488   if ((281479271743489.0*quantum) >= 18446744073709551615.0)
    489     return(MagickULLConstant(18446744073709551615));
    490   return((MagickSizeType) (281479271743489.0*quantum+0.5));
    491 #endif
    492 }
    493 
    494 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
    495 {
    496   if (quantum >= (Quantum) MaxMap)
    497     return((unsigned int) MaxMap);
    498 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    499   return((unsigned int) quantum);
    500 #else
    501   if (quantum < 0.0)
    502     return(0UL);
    503   return((unsigned int) (quantum+0.5));
    504 #endif
    505 }
    506 
    507 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
    508 {
    509 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    510   return((unsigned short) quantum);
    511 #else
    512   if (quantum <= 0.0)
    513     return(0);
    514   if (quantum >= 65535.0)
    515     return(65535);
    516   return((unsigned short) (quantum+0.5));
    517 #endif
    518 }
    519 
    520 static inline Quantum ScaleShortToQuantum(const unsigned short value)
    521 {
    522   return((Quantum) value);
    523 }
    524 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
    525 static inline Quantum ScaleCharToQuantum(const unsigned char value)
    526 {
    527 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    528   return((Quantum) (16843009UL*value));
    529 #else
    530   return((Quantum) (16843009.0*value));
    531 #endif
    532 }
    533 
    534 static inline Quantum ScaleLongToQuantum(const unsigned int value)
    535 {
    536   return((Quantum) value);
    537 }
    538 
    539 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
    540 {
    541 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    542   return((Quantum) ((value)/MagickULLConstant(4294967297)));
    543 #else
    544   return((Quantum) (value/4294967297.0));
    545 #endif
    546 }
    547 
    548 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
    549 {
    550   if (value <= 0.0)
    551     return((Quantum) 0);
    552   if (value >= (Quantum) MaxMap)
    553     return(QuantumRange);
    554 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    555   return((Quantum) (65537.0*value+0.5));
    556 #else
    557   return((Quantum) (65537.0*value));
    558 #endif
    559 }
    560 
    561 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
    562 {
    563 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    564   return((unsigned int) quantum);
    565 #else
    566   if (quantum <= 0.0)
    567     return(0);
    568   if ((quantum) >= 4294967295.0)
    569     return(4294967295);
    570   return((unsigned int) (quantum+0.5));
    571 #endif
    572 }
    573 
    574 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
    575 {
    576 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    577   return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
    578 #else
    579   if (quantum <= 0.0)
    580     return(0UL);
    581   if ((4294967297.0*quantum) >= 18446744073709551615.0)
    582     return(MagickULLConstant(18446744073709551615));
    583   return((MagickSizeType) (4294967297.0*quantum+0.5));
    584 #endif
    585 }
    586 
    587 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
    588 {
    589   if (quantum < 0.0)
    590     return(0UL);
    591   if ((quantum/65537) >= (Quantum) MaxMap)
    592     return((unsigned int) MaxMap);
    593 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    594   return((unsigned int) ((quantum+MagickULLConstant(32768))/
    595     MagickULLConstant(65537)));
    596 #else
    597   return((unsigned int) (quantum/65537.0+0.5));
    598 #endif
    599 }
    600 
    601 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
    602 {
    603 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    604   return((unsigned short) ((quantum+MagickULLConstant(32768))/
    605     MagickULLConstant(65537)));
    606 #else
    607   if (quantum <= 0.0)
    608     return(0);
    609   if ((quantum/65537.0) >= 65535.0)
    610     return(65535);
    611   return((unsigned short) (quantum/65537.0+0.5));
    612 #endif
    613 }
    614 
    615 static inline Quantum ScaleShortToQuantum(const unsigned short value)
    616 {
    617 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    618   return((Quantum) (65537UL*value));
    619 #else
    620   return((Quantum) (65537.0*value));
    621 #endif
    622 }
    623 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
    624 static inline Quantum ScaleCharToQuantum(const unsigned char value)
    625 {
    626   return((Quantum) (72340172838076673.0*value));
    627 }
    628 
    629 static inline Quantum ScaleLongToQuantum(const unsigned int value)
    630 {
    631   return((Quantum) (4294967297.0*value));
    632 }
    633 
    634 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
    635 {
    636   return((Quantum) (value));
    637 }
    638 
    639 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
    640 {
    641   if (value <= 0.0)
    642     return((Quantum) 0);
    643   if (value >= MaxMap)
    644     return(QuantumRange);
    645   return((Quantum) (281479271743489.0*value));
    646 }
    647 
    648 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
    649 {
    650   return((unsigned int) (quantum/4294967297.0+0.5));
    651 }
    652 
    653 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
    654 {
    655 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    656   return((MagickSizeType) quantum);
    657 #else
    658   if (quantum <= 0.0)
    659     return(0);
    660   if (quantum >= 18446744073709551615)
    661     return(18446744073709551615);
    662   return((MagickSizeType) (quantum+0.5));
    663 #endif
    664 }
    665 
    666 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
    667 {
    668   if (quantum <= 0.0)
    669     return(0UL);
    670   if ((quantum/281479271743489.0) >= MaxMap)
    671     return((unsigned int) MaxMap);
    672   return((unsigned int) (quantum/281479271743489.0+0.5));
    673 }
    674 
    675 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
    676 {
    677   if (quantum <= 0.0)
    678     return(0);
    679   if ((quantum/281479271743489.0) >= 65535.0)
    680     return(65535);
    681   return((unsigned short) (quantum/281479271743489.0+0.5));
    682 }
    683 
    684 static inline Quantum ScaleShortToQuantum(const unsigned short value)
    685 {
    686   return((Quantum) (281479271743489.0*value));
    687 }
    688 #endif
    689 
    690 static inline unsigned short SinglePrecisionToHalf(const float value)
    691 {
    692   typedef union _SinglePrecision
    693   {
    694     unsigned int
    695       fixed_point;
    696 
    697     float
    698       single_precision;
    699   } SinglePrecision;
    700 
    701   register int
    702     exponent;
    703 
    704   register unsigned int
    705     significand,
    706     sign_bit;
    707 
    708   SinglePrecision
    709     map;
    710 
    711   unsigned short
    712     half;
    713 
    714   /*
    715     The IEEE 754 standard specifies half precision as having:
    716 
    717       Sign bit: 1 bit
    718       Exponent width: 5 bits
    719       Significand precision: 11 (10 explicitly stored)
    720   */
    721   map.single_precision=value;
    722   sign_bit=(map.fixed_point >> 16) & 0x00008000;
    723   exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
    724   significand=map.fixed_point & 0x007fffff;
    725   if (exponent <= 0)
    726     {
    727       int
    728         shift;
    729 
    730       if (exponent < -10)
    731         return((unsigned short) sign_bit);
    732       significand=significand | 0x00800000;
    733       shift=(int) (14-exponent);
    734       significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
    735         ((significand >> shift) & 0x01)) >> shift);
    736       return((unsigned short) (sign_bit | significand));
    737     }
    738   else
    739     if (exponent == (0xff-ExponentBias))
    740       {
    741         if (significand == 0)
    742           return((unsigned short) (sign_bit | ExponentMask));
    743         else
    744           {
    745             significand>>=SignificandShift;
    746             half=(unsigned short) (sign_bit | significand |
    747               (significand == 0) | ExponentMask);
    748             return(half);
    749           }
    750       }
    751   significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
    752   if ((significand & 0x00800000) != 0)
    753     {
    754       significand=0;
    755       exponent++;
    756     }
    757   if (exponent > 30)
    758     {
    759       float
    760         alpha;
    761 
    762       register int
    763         i;
    764 
    765       /*
    766         Float overflow.
    767       */
    768       alpha=1.0e10;
    769       for (i=0; i < 10; i++)
    770         alpha*=alpha;
    771       return((unsigned short) (sign_bit | ExponentMask));
    772     }
    773   half=(unsigned short) (sign_bit | (exponent << 10) |
    774     (significand >> SignificandShift));
    775   return(half);
    776 }
    777 
    778 #if defined(__cplusplus) || defined(c_plusplus)
    779 }
    780 #endif
    781 
    782 #endif
    783