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