Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      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 
      9 
     10 #include "SkFilterProc.h"
     11 
     12 class BILERP_BITMAP16_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader {
     13 public:
     14     BILERP_BITMAP16_SHADER_CLASS(const SkBitmap& src)
     15         : HasSpan16_Sampler_BitmapShader(src, true,
     16                                          SkShader::kClamp_TileMode,
     17                                          SkShader::kClamp_TileMode)
     18     {
     19     }
     20 
     21     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count)
     22     {
     23         SkASSERT(count > 0);
     24 
     25         U8CPU alpha = this->getPaintAlpha();
     26 
     27         const SkMatrix& inv = this->getTotalInverse();
     28         const SkBitmap& srcBitmap = this->getSrcBitmap();
     29         unsigned        srcMaxX = srcBitmap.width() - 1;
     30         unsigned        srcMaxY = srcBitmap.height() - 1;
     31         unsigned        srcRB = srcBitmap.rowBytes();
     32 
     33         BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
     34 
     35         const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
     36         const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
     37 
     38         if (this->getInverseClass() == kPerspective_MatrixClass)
     39         {
     40             SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
     41                                     SkIntToScalar(y) + SK_ScalarHalf, count);
     42             while ((count = iter.next()) != 0)
     43             {
     44                 const SkFixed* srcXY = iter.getXY();
     45                 while (--count >= 0)
     46                 {
     47                     SkFixed fx = *srcXY++ - SK_FixedHalf;
     48                     SkFixed fy = *srcXY++ - SK_FixedHalf;
     49                     int ix = fx >> 16;
     50                     int iy = fy >> 16;
     51                     int x = SkClampMax(ix, srcMaxX);
     52                     int y = SkClampMax(iy, srcMaxY);
     53 
     54                     const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
     55 
     56                     p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + y * srcRB)) + x;
     57                     if ((unsigned)ix < srcMaxX)
     58                         p01 += 1;
     59                     p10 = p00;
     60                     p11 = p01;
     61                     if ((unsigned)iy < srcMaxY)
     62                     {
     63                         p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
     64                         p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
     65                     }
     66 
     67                     SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
     68                     uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
     69                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
     70                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
     71                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
     72 
     73                     *dstC++ = expanded_rgb16_to_8888(c, alpha);
     74                 }
     75             }
     76         }
     77         else    // linear case
     78         {
     79             SkFixed fx, fy, dx, dy;
     80 
     81             // now init fx, fy, dx, dy
     82             {
     83                 SkPoint srcPt;
     84                 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
     85                                                  SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
     86 
     87                 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
     88                 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
     89 
     90                 if (this->getInverseClass() == kFixedStepInX_MatrixClass)
     91                     (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
     92                 else
     93                 {
     94                     dx = SkScalarToFixed(inv.getScaleX());
     95                     dy = SkScalarToFixed(inv.getSkewY());
     96                 }
     97             }
     98 
     99             do {
    100                 int ix = fx >> 16;
    101                 int iy = fy >> 16;
    102 
    103                 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
    104 
    105                 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
    106                                                                    SkClampMax(iy, srcMaxY) * srcRB)) +
    107                                                                    SkClampMax(ix, srcMaxX);
    108                 if ((unsigned)ix < srcMaxX)
    109                     p01 += 1;
    110                 p10 = p00;
    111                 p11 = p01;
    112                 if ((unsigned)iy < srcMaxY)
    113                 {
    114                     p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
    115                     p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
    116                 }
    117 
    118                 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
    119                 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
    120                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
    121                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
    122                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
    123                 *dstC++ = expanded_rgb16_to_8888(c, alpha);
    124 
    125                 fx += dx;
    126                 fy += dy;
    127             } while (--count != 0);
    128         }
    129         BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
    130     }
    131 
    132     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count)
    133     {
    134         SkASSERT(count > 0);
    135 
    136         const SkMatrix& inv = this->getTotalInverse();
    137         const SkBitmap& srcBitmap = this->getSrcBitmap();
    138         unsigned        srcMaxX = srcBitmap.width() - 1;
    139         unsigned        srcMaxY = srcBitmap.height() - 1;
    140         unsigned        srcRB = srcBitmap.rowBytes();
    141 
    142         BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap);
    143 
    144         const SkFilterProc* proc_table = SkGetBilinearFilterProcTable();
    145         const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels();
    146 
    147         if (this->getInverseClass() == kPerspective_MatrixClass)
    148         {
    149             SkPerspIter   iter(inv, SkIntToScalar(x) + SK_ScalarHalf,
    150                                     SkIntToScalar(y) + SK_ScalarHalf, count);
    151             while ((count = iter.next()) != 0)
    152             {
    153                 const SkFixed* srcXY = iter.getXY();
    154                 while (--count >= 0)
    155                 {
    156                     SkFixed fx = *srcXY++ - SK_FixedHalf;
    157                     SkFixed fy = *srcXY++ - SK_FixedHalf;
    158                     int ix = fx >> 16;
    159                     int iy = fy >> 16;
    160 
    161                     const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
    162 
    163                     p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
    164                                                                       SkClampMax(iy, srcMaxY) * srcRB)) +
    165                                                                       SkClampMax(ix, srcMaxX);
    166                     if ((unsigned)ix < srcMaxX)
    167                         p01 += 1;
    168                     p10 = p00;
    169                     p11 = p01;
    170                     if ((unsigned)iy < srcMaxY)
    171                     {
    172                         p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
    173                         p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
    174                     }
    175 
    176                     SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
    177                     uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
    178                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
    179                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
    180                                       SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
    181                     *dstC++ = SkCompact_rgb_16(c);
    182                 }
    183             }
    184         }
    185         else    // linear case
    186         {
    187             SkFixed fx, fy, dx, dy;
    188 
    189             // now init fx, fy, dx, dy
    190             {
    191                 SkPoint srcPt;
    192                 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf,
    193                                                  SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
    194 
    195                 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf;
    196                 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf;
    197 
    198                 if (this->getInverseClass() == kFixedStepInX_MatrixClass)
    199                     (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy);
    200                 else
    201                 {
    202                     dx = SkScalarToFixed(inv.getScaleX());
    203                     dy = SkScalarToFixed(inv.getSkewY());
    204                 }
    205             }
    206 
    207             do {
    208                 int ix = fx >> 16;
    209                 int iy = fy >> 16;
    210 
    211                 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11;
    212 
    213                 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels +
    214                                                                   SkClampMax(iy, srcMaxY) * srcRB)) +
    215                                                                   SkClampMax(ix, srcMaxX);
    216                 if ((unsigned)ix < srcMaxX)
    217                     p01 += 1;
    218                 p10 = p00;
    219                 p11 = p01;
    220                 if ((unsigned)iy < srcMaxY)
    221                 {
    222                     p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB);
    223                     p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB);
    224                 }
    225 
    226                 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy);
    227                 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)),
    228                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)),
    229                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)),
    230                                   SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11)));
    231                 *dstC++ = SkCompact_rgb_16(c);
    232 
    233                 fx += dx;
    234                 fy += dy;
    235             } while (--count != 0);
    236         }
    237         BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap);
    238     }
    239 };
    240 
    241 #undef BILERP_BITMAP16_SHADER_CLASS
    242 #undef BILERP_BITMAP16_SHADER_TYPE
    243 #undef BILERP_BITMAP16_SHADER_PREAMBLE
    244 #undef BILERP_BITMAP16_SHADER_PIXEL
    245 #undef BILERP_BITMAP16_SHADER_POSTAMBLE
    246