quantum-private.h

Go to the documentation of this file.
00001 /*
00002   Copyright 1999-2020 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 *magick_restrict 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 *magick_restrict 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 *magick_restrict 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(
00233   const unsigned char *magick_restrict pixels,
00234   unsigned char *magick_restrict pixel)
00235 {
00236   *pixel=(*pixels++);
00237   return(pixels);
00238 }
00239 
00240 static inline const unsigned char *PushLongPixel(const EndianType endian,
00241   const unsigned char *magick_restrict pixels,
00242   unsigned int *magick_restrict pixel)
00243 {
00244   register unsigned int
00245     quantum;
00246 
00247   if (endian == LSBEndian)
00248     {
00249       quantum=((unsigned int) *pixels++);
00250       quantum|=((unsigned int) *pixels++ << 8);
00251       quantum|=((unsigned int) *pixels++ << 16);
00252       quantum|=((unsigned int) *pixels++ << 24);
00253       *pixel=quantum;
00254       return(pixels);
00255     }
00256   quantum=((unsigned int) *pixels++ << 24);
00257   quantum|=((unsigned int) *pixels++ << 16);
00258   quantum|=((unsigned int) *pixels++ << 8);
00259   quantum|=((unsigned int) *pixels++);
00260   *pixel=quantum;
00261   return(pixels);
00262 }
00263 
00264 static inline const unsigned char *PushShortPixel(const EndianType endian,
00265   const unsigned char *magick_restrict pixels,
00266   unsigned short *magick_restrict pixel)
00267 {
00268   register unsigned int
00269     quantum;
00270 
00271   if (endian == LSBEndian)
00272     {
00273       quantum=(unsigned int) *pixels++;
00274       quantum|=(unsigned int) (*pixels++ << 8);
00275       *pixel=(unsigned short) (quantum & 0xffff);
00276       return(pixels);
00277     }
00278   quantum=(unsigned int) (*pixels++ << 8);
00279   quantum|=(unsigned int) *pixels++;
00280   *pixel=(unsigned short) (quantum & 0xffff);
00281   return(pixels);
00282 }
00283 
00284 static inline const unsigned char *PushFloatPixel(const EndianType endian,
00285   const unsigned char *magick_restrict pixels,
00286   MagickFloatType *magick_restrict pixel)
00287 {
00288   union
00289   {
00290     unsigned int
00291       unsigned_value;
00292 
00293     MagickFloatType
00294       float_value;
00295   } quantum;
00296 
00297   if (endian == LSBEndian)
00298     {
00299       quantum.unsigned_value=((unsigned int) *pixels++);
00300       quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00301       quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00302       quantum.unsigned_value|=((unsigned int) *pixels++ << 24);
00303       *pixel=quantum.float_value;
00304       return(pixels);
00305     }
00306   quantum.unsigned_value=((unsigned int) *pixels++ << 24);
00307   quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00308   quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00309   quantum.unsigned_value|=((unsigned int) *pixels++);
00310   *pixel=quantum.float_value;
00311   return(pixels);
00312 }
00313 
00314 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
00315   const QuantumAny range)
00316 {
00317   if (quantum > range)
00318     return(QuantumRange);
00319 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00320   return((Quantum) ((double) QuantumRange*(quantum*
00321     PerceptibleReciprocal((double) range))+0.5));
00322 #else
00323   return((Quantum) ((double) QuantumRange*(quantum*
00324     PerceptibleReciprocal((double) range))));
00325 #endif
00326 }
00327 
00328 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
00329   const QuantumAny range)
00330 {
00331 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00332   return((QuantumAny) ((double) range*quantum/QuantumRange));
00333 #else
00334   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00335     return((QuantumAny) 0UL);
00336   if (((double) range*quantum/QuantumRange) >= 18446744073709551615.0)
00337     return((QuantumAny) MagickULLConstant(18446744073709551615));
00338   return((QuantumAny) ((double) range*quantum/QuantumRange+0.5));
00339 #endif
00340 }
00341 
00342 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
00343 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00344 {
00345   return((Quantum) value);
00346 }
00347 
00348 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00349 {
00350 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00351   return((Quantum) ((value)/16843009UL));
00352 #else
00353   return((Quantum) (value/16843009.0));
00354 #endif
00355 }
00356 
00357 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00358 {
00359 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00360   return((Quantum) (value/MagickULLConstant(72340172838076673)));
00361 #else
00362   return((Quantum) (value/72340172838076673.0));
00363 #endif
00364 }
00365 
00366 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00367 {
00368   if (value <= 0.0)
00369     return((Quantum) 0);
00370   if (value >= MaxMap)
00371     return(QuantumRange);
00372 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00373   return((Quantum) (value+0.5));
00374 #else
00375   return((Quantum) value);
00376 #endif
00377 }
00378 
00379 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00380 {
00381 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00382   return((unsigned int) (16843009UL*quantum));
00383 #else
00384   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00385     return(0U);
00386   if ((16843009.0*quantum) >= 4294967295.0)
00387     return(4294967295UL);
00388   return((unsigned int) (16843009.0*quantum+0.5));
00389 #endif
00390 }
00391 
00392 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00393 {
00394 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00395   return((MagickSizeType) (MagickULLConstant(72340172838076673)*quantum));
00396 #else
00397   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00398     return(0UL);
00399   if ((72340172838076673.0*quantum) >= 18446744073709551615.0)
00400     return(MagickULLConstant(18446744073709551615));
00401   return((MagickSizeType) (72340172838076673*quantum+0.5));
00402 #endif
00403 }
00404 
00405 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00406 {
00407   if (quantum >= (Quantum) MaxMap)
00408     return((unsigned int) MaxMap);
00409 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00410   return((unsigned int) quantum);
00411 #else
00412   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00413     return(0U);
00414   return((unsigned int) (quantum+0.5));
00415 #endif
00416 }
00417 
00418 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00419 {
00420 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00421   return((unsigned short) (257UL*quantum));
00422 #else
00423   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00424     return(0);
00425   if ((257.0*quantum) >= 65535.0)
00426     return(65535);
00427   return((unsigned short) (257.0*quantum+0.5));
00428 #endif
00429 }
00430 
00431 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00432 {
00433 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00434   return((Quantum) ((value+128U)/257U));
00435 #else
00436   return((Quantum) (value/257.0));
00437 #endif
00438 }
00439 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
00440 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00441 {
00442 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00443   return((Quantum) (257U*value));
00444 #else
00445   return((Quantum) (257.0*value));
00446 #endif
00447 }
00448 
00449 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00450 {
00451 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00452   return((Quantum) ((value)/MagickULLConstant(65537)));
00453 #else
00454   return((Quantum) (value/65537.0));
00455 #endif
00456 }
00457 
00458 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00459 {
00460 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00461   return((Quantum) ((value)/MagickULLConstant(281479271743489)));
00462 #else
00463   return((Quantum) (value/281479271743489.0));
00464 #endif
00465 }
00466 
00467 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00468 {
00469   if (value <= 0.0)
00470     return((Quantum) 0);
00471   if (value >= MaxMap)
00472     return(QuantumRange);
00473 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00474   return((Quantum) (value+0.5));
00475 #else
00476   return((Quantum) value);
00477 #endif
00478 }
00479 
00480 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00481 {
00482 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00483   return((unsigned int) (65537UL*quantum));
00484 #else
00485   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00486     return(0U);
00487   if ((65537.0*quantum) >= 4294967295.0)
00488     return(4294967295U);
00489   return((unsigned int) (65537.0*quantum+0.5));
00490 #endif
00491 }
00492 
00493 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00494 {
00495 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00496   return((MagickSizeType) (MagickULLConstant(281479271743489)*quantum));
00497 #else
00498   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00499     return(0UL);
00500   if ((281479271743489.0*quantum) >= 18446744073709551615.0)
00501     return(MagickULLConstant(18446744073709551615));
00502   return((MagickSizeType) (281479271743489.0*quantum+0.5));
00503 #endif
00504 }
00505 
00506 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00507 {
00508   if (quantum >= (Quantum) MaxMap)
00509     return((unsigned int) MaxMap);
00510 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00511   return((unsigned int) quantum);
00512 #else
00513   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00514     return(0U);
00515   return((unsigned int) (quantum+0.5));
00516 #endif
00517 }
00518 
00519 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00520 {
00521 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00522   return((unsigned short) quantum);
00523 #else
00524   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00525     return(0);
00526   if (quantum >= 65535.0)
00527     return(65535);
00528   return((unsigned short) (quantum+0.5));
00529 #endif
00530 }
00531 
00532 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00533 {
00534   return((Quantum) value);
00535 }
00536 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
00537 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00538 {
00539 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00540   return((Quantum) (16843009UL*value));
00541 #else
00542   return((Quantum) (16843009.0*value));
00543 #endif
00544 }
00545 
00546 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00547 {
00548   return((Quantum) value);
00549 }
00550 
00551 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00552 {
00553 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00554   return((Quantum) ((value)/MagickULLConstant(4294967297)));
00555 #else
00556   return((Quantum) (value/4294967297.0));
00557 #endif
00558 }
00559 
00560 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00561 {
00562   if (value <= 0.0)
00563     return((Quantum) 0);
00564   if (value >= (Quantum) MaxMap)
00565     return(QuantumRange);
00566 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00567   return((Quantum) (65537.0*value+0.5));
00568 #else
00569   return((Quantum) (65537.0*value));
00570 #endif
00571 }
00572 
00573 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00574 {
00575 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00576   return((unsigned int) quantum);
00577 #else
00578   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00579     return(0U);
00580   if ((quantum) >= 4294967295.0)
00581     return(4294967295);
00582   return((unsigned int) (quantum+0.5));
00583 #endif
00584 }
00585 
00586 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00587 {
00588 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00589   return((MagickSizeType) (MagickULLConstant(4294967297)*quantum));
00590 #else
00591   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00592     return(0UL);
00593   if ((4294967297.0*quantum) >= 18446744073709551615.0)
00594     return(MagickULLConstant(18446744073709551615));
00595   return((MagickSizeType) (4294967297.0*quantum+0.5));
00596 #endif
00597 }
00598 
00599 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00600 {
00601   if ((quantum/65537) >= (Quantum) MaxMap)
00602     return((unsigned int) MaxMap);
00603 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00604   return((unsigned int) ((quantum+MagickULLConstant(32768))/
00605     MagickULLConstant(65537)));
00606 #else
00607   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00608     return(0U);
00609   return((unsigned int) (quantum/65537.0+0.5));
00610 #endif
00611 }
00612 
00613 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00614 {
00615 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00616   return((unsigned short) ((quantum+MagickULLConstant(32768))/
00617     MagickULLConstant(65537)));
00618 #else
00619   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00620     return(0);
00621   if ((quantum/65537.0) >= 65535.0)
00622     return(65535);
00623   return((unsigned short) (quantum/65537.0+0.5));
00624 #endif
00625 }
00626 
00627 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00628 {
00629 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00630   return((Quantum) (65537UL*value));
00631 #else
00632   return((Quantum) (65537.0*value));
00633 #endif
00634 }
00635 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
00636 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00637 {
00638   return((Quantum) (72340172838076673.0*value));
00639 }
00640 
00641 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00642 {
00643   return((Quantum) (4294967297.0*value));
00644 }
00645 
00646 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
00647 {
00648   return((Quantum) (value));
00649 }
00650 
00651 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00652 {
00653   if (value <= 0.0)
00654     return((Quantum) 0);
00655   if (value >= MaxMap)
00656     return(QuantumRange);
00657   return((Quantum) (281479271743489.0*value));
00658 }
00659 
00660 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00661 {
00662   return((unsigned int) (quantum/4294967297.0+0.5));
00663 }
00664 
00665 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
00666 {
00667 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00668   return((MagickSizeType) quantum);
00669 #else
00670   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00671     return(0UL);
00672   if (quantum >= 18446744073709551615.0)
00673     return(MagickULLConstant(18446744073709551615));
00674   return((MagickSizeType) (quantum+0.5));
00675 #endif
00676 }
00677 
00678 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00679 {
00680   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00681     return(0U);
00682   if ((quantum/281479271743489.0) >= MaxMap)
00683     return((unsigned int) MaxMap);
00684   return((unsigned int) (quantum/281479271743489.0+0.5));
00685 }
00686 
00687 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00688 {
00689   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00690     return(0);
00691   if ((quantum/281479271743489.0) >= 65535.0)
00692     return(65535);
00693   return((unsigned short) (quantum/281479271743489.0+0.5));
00694 }
00695 
00696 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00697 {
00698   return((Quantum) (281479271743489.0*value));
00699 }
00700 #endif
00701 
00702 static inline unsigned short SinglePrecisionToHalf(const float value)
00703 {
00704   typedef union _SinglePrecision
00705   {
00706     unsigned int
00707       fixed_point;
00708 
00709     float
00710       single_precision;
00711   } SinglePrecision;
00712 
00713   register int
00714     exponent;
00715 
00716   register unsigned int
00717     significand,
00718     sign_bit;
00719 
00720   SinglePrecision
00721     map;
00722 
00723   unsigned short
00724     half;
00725 
00726   /*
00727     The IEEE 754 standard specifies half precision as having:
00728 
00729       Sign bit: 1 bit
00730       Exponent width: 5 bits
00731       Significand precision: 11 (10 explicitly stored)
00732   */
00733   map.single_precision=value;
00734   sign_bit=(map.fixed_point >> 16) & 0x00008000;
00735   exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
00736   significand=map.fixed_point & 0x007fffff;
00737   if (exponent <= 0)
00738     {
00739       int
00740         shift;
00741 
00742       if (exponent < -10)
00743         return((unsigned short) sign_bit);
00744       significand=significand | 0x00800000;
00745       shift=(int) (14-exponent);
00746       significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
00747         ((significand >> shift) & 0x01)) >> shift);
00748       return((unsigned short) (sign_bit | significand));
00749     }
00750   else
00751     if (exponent == (0xff-ExponentBias))
00752       {
00753         if (significand == 0)
00754           return((unsigned short) (sign_bit | ExponentMask));
00755         else
00756           {
00757             significand>>=SignificandShift;
00758             half=(unsigned short) (sign_bit | significand |
00759               (significand == 0) | ExponentMask);
00760             return(half);
00761           }
00762       }
00763   significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
00764   if ((significand & 0x00800000) != 0)
00765     {
00766       significand=0;
00767       exponent++;
00768     }
00769   if (exponent > 30)
00770     {
00771       float
00772         alpha;
00773 
00774       register int
00775         i;
00776 
00777       /*
00778         Float overflow.
00779       */
00780       alpha=1.0e10;
00781       for (i=0; i < 10; i++)
00782         alpha*=alpha;
00783       return((unsigned short) (sign_bit | ExponentMask));
00784     }
00785   half=(unsigned short) (sign_bit | (exponent << 10) |
00786     (significand >> SignificandShift));
00787   return(half);
00788 }
00789 
00790 #if defined(__cplusplus) || defined(c_plusplus)
00791 }
00792 #endif
00793 
00794 #endif

Generated on 17 Mar 2020 for MagickCore by  doxygen 1.6.1