LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkFloatBits.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 94 0 0.0 %
Date: 2012-06-02 Functions: 8 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2011 Google Inc.
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : #include "SkFloatBits.h"
       9                 : #include "SkMath.h"
      10                 : 
      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
      17                 : 
      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                 : ******************************************************************************/
      23                 : 
      24                 : #define EXP_BIAS            (127+23)
      25                 : #define MATISSA_MAGIC_BIG   (1 << 23)
      26                 : 
      27               0 : static inline int unpack_exp(uint32_t packed) {
      28               0 :     return (packed << 1 >> 24);
      29                 : }
      30                 : 
      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
      38                 : 
      39                 : // returns the low 24-bits, so we need to OR in the magic_bit afterwards
      40               0 : static inline int unpack_matissa_dirty(uint32_t packed) {
      41               0 :     return packed & ~0xFF000000;
      42                 : }
      43                 : 
      44                 : // same as (int)float
      45               0 : int32_t SkFloatBits_toIntCast(int32_t packed) {
      46               0 :     int exp = unpack_exp(packed) - EXP_BIAS;
      47               0 :     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
      48                 :     
      49               0 :     if (exp >= 0) {
      50               0 :         if (exp > 7) {    // overflow
      51               0 :             value = SK_MaxS32;
      52                 :         } else {
      53               0 :             value <<= exp;
      54                 :         }
      55                 :     } else {
      56               0 :         exp = -exp;
      57               0 :         if (exp > 25) {   // underflow
      58               0 :             exp = 25;
      59                 :         }
      60               0 :         value >>= exp;
      61                 :     }
      62               0 :     return SkApplySign(value, SkExtractSign(packed));
      63                 : }
      64                 : 
      65                 : // same as (int)floor(float)
      66               0 : int32_t SkFloatBits_toIntFloor(int32_t packed) {
      67                 :     // curse you negative 0
      68               0 :     if ((packed << 1) == 0) {
      69               0 :         return 0;
      70                 :     }
      71                 :     
      72               0 :     int exp = unpack_exp(packed) - EXP_BIAS;
      73               0 :     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
      74                 : 
      75               0 :     if (exp >= 0) {
      76               0 :         if (exp > 7) {    // overflow
      77               0 :             value = SK_MaxS32;
      78                 :         } else {
      79               0 :             value <<= exp;
      80                 :         }
      81                 :         // apply the sign after we check for overflow
      82               0 :         return SkApplySign(value, SkExtractSign(packed));
      83                 :     } else {
      84                 :         // apply the sign before we right-shift
      85               0 :         value = SkApplySign(value, SkExtractSign(packed));
      86               0 :         exp = -exp;
      87               0 :         if (exp > 25) {   // underflow
      88               0 :             exp = 25;
      89                 :         }
      90                 :         // int add = 0;
      91               0 :         return value >> exp;
      92                 :     }
      93                 : }
      94                 : 
      95                 : // same as (int)floor(float + 0.5)
      96               0 : int32_t SkFloatBits_toIntRound(int32_t packed) {
      97                 :     // curse you negative 0
      98               0 :     if ((packed << 1) == 0) {
      99               0 :         return 0;
     100                 :     }
     101                 :     
     102               0 :     int exp = unpack_exp(packed) - EXP_BIAS;
     103               0 :     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
     104                 :     
     105               0 :     if (exp >= 0) {
     106               0 :         if (exp > 7) {    // overflow
     107               0 :             value = SK_MaxS32;
     108                 :         } else {
     109               0 :             value <<= exp;
     110                 :         }
     111                 :         // apply the sign after we check for overflow
     112               0 :         return SkApplySign(value, SkExtractSign(packed));
     113                 :     } else {
     114                 :         // apply the sign before we right-shift
     115               0 :         value = SkApplySign(value, SkExtractSign(packed));
     116               0 :         exp = -exp;
     117               0 :         if (exp > 25) {   // underflow
     118               0 :             exp = 25;
     119                 :         }
     120               0 :         int add = 1 << (exp - 1);
     121               0 :         return (value + add) >> exp;
     122                 :     }
     123                 : }
     124                 : 
     125                 : // same as (int)ceil(float)
     126               0 : int32_t SkFloatBits_toIntCeil(int32_t packed) {
     127                 :     // curse you negative 0
     128               0 :     if ((packed << 1) == 0) {
     129               0 :         return 0;
     130                 :     }
     131                 :     
     132               0 :     int exp = unpack_exp(packed) - EXP_BIAS;
     133               0 :     int value = unpack_matissa_dirty(packed) | MATISSA_MAGIC_BIG;
     134                 :     
     135               0 :     if (exp >= 0) {
     136               0 :         if (exp > 7) {    // overflow
     137               0 :             value = SK_MaxS32;
     138                 :         } else {
     139               0 :             value <<= exp;
     140                 :         }
     141                 :         // apply the sign after we check for overflow
     142               0 :         return SkApplySign(value, SkExtractSign(packed));
     143                 :     } else {
     144                 :         // apply the sign before we right-shift
     145               0 :         value = SkApplySign(value, SkExtractSign(packed));
     146               0 :         exp = -exp;
     147               0 :         if (exp > 25) {   // underflow
     148               0 :             exp = 25;
     149                 :         }
     150               0 :         int add = (1 << exp) - 1;
     151               0 :         return (value + add) >> exp;
     152                 :     }
     153                 : }
     154                 : 
     155                 : #ifdef SK_CAN_USE_FLOAT
     156                 : 
     157               0 : float SkIntToFloatCast(int32_t value) {
     158               0 :     if (0 == value) {
     159               0 :         return 0;
     160                 :     }
     161                 : 
     162               0 :     int shift = EXP_BIAS;
     163                 :     
     164                 :     // record the sign and make value positive
     165               0 :     int sign = SkExtractSign(value);
     166               0 :     value = SkApplySign(value, sign);
     167                 :     
     168               0 :     if (value >> 24) {    // value is too big (has more than 24 bits set)
     169               0 :         int bias = 8 - SkCLZ(value);
     170               0 :         SkDebugf("value = %d, bias = %d\n", value, bias);
     171               0 :         SkASSERT(bias > 0 && bias < 8);
     172               0 :         value >>= bias; // need to round?
     173               0 :         shift += bias;
     174                 :     } else {
     175               0 :         int zeros = SkCLZ(value << 8);
     176               0 :         SkASSERT(zeros >= 0 && zeros <= 23);
     177               0 :         value <<= zeros;
     178               0 :         shift -= zeros;
     179                 :     }
     180                 :     
     181                 :     // now value is left-aligned to 24 bits
     182               0 :     SkASSERT((value >> 23) == 1);
     183               0 :     SkASSERT(shift >= 0 && shift <= 255);
     184                 :     
     185                 :     SkFloatIntUnion data;
     186               0 :     data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
     187               0 :     return data.fFloat;
     188                 : }
     189                 : 
     190               0 : float SkIntToFloatCast_NoOverflowCheck(int32_t value) {
     191               0 :     if (0 == value) {
     192               0 :         return 0;
     193                 :     }
     194                 : 
     195               0 :     int shift = EXP_BIAS;
     196                 :     
     197                 :     // record the sign and make value positive
     198               0 :     int sign = SkExtractSign(value);
     199               0 :     value = SkApplySign(value, sign);
     200                 :     
     201               0 :     int zeros = SkCLZ(value << 8);
     202               0 :     value <<= zeros;
     203               0 :     shift -= zeros;
     204                 :     
     205                 :     SkFloatIntUnion data;
     206               0 :     data.fSignBitInt = (sign << 31) | (shift << 23) | (value & ~MATISSA_MAGIC_BIG);
     207               0 :     return data.fFloat;
     208                 : }
     209                 : 
     210                 : #endif

Generated by: LCOV version 1.7