gfx/skia/trunk/src/core/SkFloatBits.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2  * Copyright 2011 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #include "SkFloatBits.h"
     9 #include "SkMathPriv.h"
    11 /******************************************************************************
    12     SkFloatBits_toInt[Floor, Round, Ceil] are identical except for what they
    13     do right before they return ... >> exp;
    14     Floor - adds nothing
    15     Round - adds 1 << (exp - 1)
    16     Ceil - adds (1 << exp) - 1
    18     Floor and Cast are very similar, but Cast applies its sign after all other
    19     computations on value. Also, Cast does not need to check for negative zero,
    20     as that value (0x80000000) "does the right thing" for Ceil. Note that it
    21     doesn't for Floor/Round/Ceil, hence the explicit check.
    22 ******************************************************************************/
    24 #define EXP_BIAS            (127+23)
    25 #define MATISSA_MAGIC_BIG   (1 << 23)
    27 static inline int unpack_exp(uint32_t packed) {
    28     return (packed << 1 >> 24);
    29 }
    31 #if 0
    32 // the ARM compiler generates an extra BIC, so I use the dirty version instead
    33 static inline int unpack_matissa(uint32_t packed) {
    34     // we could mask with 0x7FFFFF, but that is harder for ARM to encode
    35     return (packed & ~0xFF000000) | MATISSA_MAGIC_BIG;
    36 }
    37 #endif
    39 // returns the low 24-bits, so we need to OR in the magic_bit afterwards
    40 static inline int unpack_matissa_dirty(uint32_t packed) {
    41     return packed & ~0xFF000000;
    42 }
    44 // same as (int)float
    45 int32_t SkFloatBits_toIntCast(int32_t packed) {
    46     int exp = unpack_exp(packed) - EXP_BIAS;
    47     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
    49     if (exp >= 0) {
    50         if (exp > 7) {    // overflow
    51             value = SK_MaxS32;
    52         } else {
    53             value <<= exp;
    54         }
    55     } else {
    56         exp = -exp;
    57         if (exp > 25) {   // underflow
    58             exp = 25;
    59         }
    60         value >>= exp;
    61     }
    62     return SkApplySign(value, SkExtractSign(packed));
    63 }
    65 // same as (int)floor(float)
    66 int32_t SkFloatBits_toIntFloor(int32_t packed) {
    67     // curse you negative 0
    68     if ((packed << 1) == 0) {
    69         return 0;
    70     }
    72     int exp = unpack_exp(packed) - EXP_BIAS;
    73     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
    75     if (exp >= 0) {
    76         if (exp > 7) {    // overflow
    77             value = SK_MaxS32;
    78         } else {
    79             value <<= exp;
    80         }
    81         // apply the sign after we check for overflow
    82         return SkApplySign(value, SkExtractSign(packed));
    83     } else {
    84         // apply the sign before we right-shift
    85         value = SkApplySign(value, SkExtractSign(packed));
    86         exp = -exp;
    87         if (exp > 25) {   // underflow
    88             exp = 25;
    89         }
    90         // int add = 0;
    91         return value >> exp;
    92     }
    93 }
    95 // same as (int)floor(float + 0.5)
    96 int32_t SkFloatBits_toIntRound(int32_t packed) {
    97     // curse you negative 0
    98     if ((packed << 1) == 0) {
    99         return 0;
   100     }
   102     int exp = unpack_exp(packed) - EXP_BIAS;
   103     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
   105     if (exp >= 0) {
   106         if (exp > 7) {    // overflow
   107             value = SK_MaxS32;
   108         } else {
   109             value <<= exp;
   110         }
   111         // apply the sign after we check for overflow
   112         return SkApplySign(value, SkExtractSign(packed));
   113     } else {
   114         // apply the sign before we right-shift
   115         value = SkApplySign(value, SkExtractSign(packed));
   116         exp = -exp;
   117         if (exp > 25) {   // underflow
   118             exp = 25;
   119         }
   120         int add = 1 << (exp - 1);
   121         return (value + add) >> exp;
   122     }
   123 }
   125 // same as (int)ceil(float)
   126 int32_t SkFloatBits_toIntCeil(int32_t packed) {
   127     // curse you negative 0
   128     if ((packed << 1) == 0) {
   129         return 0;
   130     }
   132     int exp = unpack_exp(packed) - EXP_BIAS;
   133     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
   135     if (exp >= 0) {
   136         if (exp > 7) {    // overflow
   137             value = SK_MaxS32;
   138         } else {
   139             value <<= exp;
   140         }
   141         // apply the sign after we check for overflow
   142         return SkApplySign(value, SkExtractSign(packed));
   143     } else {
   144         // apply the sign before we right-shift
   145         value = SkApplySign(value, SkExtractSign(packed));
   146         exp = -exp;
   147         if (exp > 25) {   // underflow
   148             exp = 25;
   149         }
   150         int add = (1 << exp) - 1;
   151         return (value + add) >> exp;
   152     }
   153 }
   155 float SkIntToFloatCast(int32_t value) {
   156     if (0 == value) {
   157         return 0;
   158     }
   160     int shift = EXP_BIAS;
   162     // record the sign and make value positive
   163     int sign = SkExtractSign(value);
   164     value = SkApplySign(value, sign);
   166     if (value >> 24) {    // value is too big (has more than 24 bits set)
   167         int bias = 8 - SkCLZ(value);
   168         SkDebugf("value = %d, bias = %d\n", value, bias);
   169         SkASSERT(bias > 0 && bias < 8);
   170         value >>= bias; // need to round?
   171         shift += bias;
   172     } else {
   173         int zeros = SkCLZ(value << 8);
   174         SkASSERT(zeros >= 0 && zeros <= 23);
   175         value <<= zeros;
   176         shift -= zeros;
   177     }
   179     // now value is left-aligned to 24 bits
   180     SkASSERT((value >> 23) == 1);
   181     SkASSERT(shift >= 0 && shift <= 255);
   183     SkFloatIntUnion data;
   184     data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
   185     return data.fFloat;
   186 }
   188 float SkIntToFloatCast_NoOverflowCheck(int32_t value) {
   189     if (0 == value) {
   190         return 0;
   191     }
   193     int shift = EXP_BIAS;
   195     // record the sign and make value positive
   196     int sign = SkExtractSign(value);
   197     value = SkApplySign(value, sign);
   199     int zeros = SkCLZ(value << 8);
   200     value <<= zeros;
   201     shift -= zeros;
   203     SkFloatIntUnion data;
   204     data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
   205     return data.fFloat;
   206 }

mercurial