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

       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 "SkBitmapSampler.h"
      11                 : 
      12               0 : static SkTileModeProc get_tilemode_proc(SkShader::TileMode mode)
      13                 : {
      14               0 :     switch (mode) {
      15                 :     case SkShader::kClamp_TileMode:
      16               0 :         return do_clamp;
      17                 :     case SkShader::kRepeat_TileMode:
      18               0 :         return do_repeat_mod;
      19                 :     case SkShader::kMirror_TileMode:
      20               0 :         return do_mirror_mod;
      21                 :     default:
      22               0 :         SkDEBUGFAIL("unknown mode");
      23               0 :         return NULL;
      24                 :     }
      25                 : }
      26                 : 
      27               0 : SkBitmapSampler::SkBitmapSampler(const SkBitmap& bm, bool filter,
      28                 :                                  SkShader::TileMode tmx, SkShader::TileMode tmy)
      29               0 :     : fBitmap(bm), fFilterBitmap(filter), fTileModeX(tmx), fTileModeY(tmy)
      30                 : {
      31               0 :     SkASSERT(bm.width() > 0 && bm.height() > 0);
      32                 : 
      33               0 :     fMaxX = SkToU16(bm.width() - 1);
      34               0 :     fMaxY = SkToU16(bm.height() - 1);
      35                 :     
      36               0 :     fTileProcX = get_tilemode_proc(tmx);
      37               0 :     fTileProcY = get_tilemode_proc(tmy);
      38               0 : }
      39                 : 
      40               0 : void SkBitmapSampler::setPaint(const SkPaint& paint)
      41                 : {
      42               0 : }
      43                 : 
      44               0 : class SkNullBitmapSampler : public SkBitmapSampler {
      45                 : public:
      46               0 :     SkNullBitmapSampler(const SkBitmap& bm, bool filter,
      47                 :                         SkShader::TileMode tmx, SkShader::TileMode tmy)
      48               0 :         : SkBitmapSampler(bm, filter, tmx, tmy) {}
      49                 : 
      50               0 :     virtual SkPMColor sample(SkFixed x, SkFixed y) const { return 0; }
      51                 : };
      52                 : 
      53                 : /////////////////////////////////////////////////////////////////////////////////
      54                 : /////////////////////////////////////////////////////////////////////////////////
      55                 : 
      56                 : #define BITMAP_CLASSNAME_PREFIX(name)           ARGB32##name
      57                 : #define BITMAP_PIXEL_TO_PMCOLOR(bitmap, x, y)   *bitmap.getAddr32(x, y)
      58                 : #include "SkBitmapSamplerTemplate.h"
      59                 : 
      60                 : #include "SkColorPriv.h"
      61                 : 
      62                 : #define BITMAP_CLASSNAME_PREFIX(name)           RGB16##name
      63                 : #define BITMAP_PIXEL_TO_PMCOLOR(bitmap, x, y)   SkPixel16ToPixel32(*bitmap.getAddr16(x, y))
      64                 : #include "SkBitmapSamplerTemplate.h"
      65                 : 
      66                 : #define BITMAP_CLASSNAME_PREFIX(name)           Index8##name
      67                 : #define BITMAP_PIXEL_TO_PMCOLOR(bitmap, x, y)   bitmap.getIndex8Color(x, y)
      68                 : #include "SkBitmapSamplerTemplate.h"
      69                 : 
      70                 : /////////////////////////////////////////////////////////////////////////////////
      71                 : /////////////////////////////////////////////////////////////////////////////////
      72                 : ///////////////// The Bilinear versions
      73                 : 
      74                 : #include "SkFilterProc.h"
      75                 : 
      76               0 : class ARGB32_Bilinear_Sampler : public SkBitmapSampler {
      77                 : public:
      78               0 :     ARGB32_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
      79               0 :         : SkBitmapSampler(bm, true, tmx, tmy)
      80                 :     {
      81               0 :         fPtrProcTable = SkGetBilinearFilterPtrProcTable();
      82               0 :     }
      83                 : 
      84               0 :     virtual SkPMColor sample(SkFixed x, SkFixed y) const
      85                 :     {
      86                 :         const uint32_t *p00, *p01, *p10, *p11;
      87                 : 
      88                 :         // turn pixel centers into the top-left of our filter-box
      89               0 :         x -= SK_FixedHalf;
      90               0 :         y -= SK_FixedHalf;
      91                 :     
      92                 :         // compute our pointers
      93                 :         {
      94               0 :             const SkBitmap* bitmap = &fBitmap;
      95               0 :             int ix = x >> 16;
      96               0 :             int iy = y >> 16;
      97                 :             
      98               0 :             int             maxX = fMaxX;
      99               0 :             SkTileModeProc  procX = fTileProcX;
     100               0 :             int             maxY = fMaxY;
     101               0 :             SkTileModeProc  procY = fTileProcY;
     102                 : 
     103               0 :             int tmpx = procX(ix, maxX);
     104               0 :             int tmpy = procY(iy, maxY);
     105               0 :             p00 = bitmap->getAddr32(tmpx, tmpy);
     106                 : 
     107               0 :             int tmpx1 = procX(ix + 1, maxX);
     108               0 :             p01 = bitmap->getAddr32(tmpx1, tmpy);
     109                 : 
     110               0 :             int tmpy1 = procY(iy + 1, maxY);
     111               0 :             p10 = bitmap->getAddr32(tmpx, tmpy1);
     112                 : 
     113               0 :             p11 = bitmap->getAddr32(tmpx1, tmpy1);
     114                 :         }
     115                 : 
     116               0 :         SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(fPtrProcTable, x, y);
     117               0 :         return proc(p00, p01, p10, p11);
     118                 :     }
     119                 :     
     120                 : private:
     121                 :     const SkFilterPtrProc* fPtrProcTable;
     122                 : };
     123                 : 
     124               0 : class RGB16_Bilinear_Sampler : public SkBitmapSampler {
     125                 : public:
     126               0 :     RGB16_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
     127               0 :         : SkBitmapSampler(bm, true, tmx, tmy)
     128                 :     {
     129               0 :         fProcTable = SkGetBilinearFilterProcTable();
     130               0 :     }
     131                 : 
     132               0 :     virtual SkPMColor sample(SkFixed x, SkFixed y) const
     133                 :     {
     134                 :         const uint16_t *p00, *p01, *p10, *p11;
     135                 : 
     136                 :         // turn pixel centers into the top-left of our filter-box
     137               0 :         x -= SK_FixedHalf;
     138               0 :         y -= SK_FixedHalf;
     139                 :     
     140                 :         // compute our pointers
     141                 :         {
     142               0 :             const SkBitmap* bitmap = &fBitmap;
     143               0 :             int ix = x >> 16;
     144               0 :             int iy = y >> 16;
     145                 :             
     146               0 :             int             maxX = fMaxX;
     147               0 :             SkTileModeProc  procX = fTileProcX;
     148               0 :             int             maxY = fMaxY;
     149               0 :             SkTileModeProc  procY = fTileProcY;
     150                 : 
     151               0 :             int tmpx = procX(ix, maxX);
     152               0 :             int tmpy = procY(iy, maxY);
     153               0 :             p00 = bitmap->getAddr16(tmpx, tmpy);
     154                 : 
     155               0 :             int tmpx1 = procX(ix + 1, maxX);
     156               0 :             p01 = bitmap->getAddr16(tmpx1, tmpy);
     157                 : 
     158               0 :             int tmpy1 = procY(iy + 1, maxY);
     159               0 :             p10 = bitmap->getAddr16(tmpx, tmpy1);
     160                 : 
     161               0 :             p11 = bitmap->getAddr16(tmpx1, tmpy1);
     162                 :         }
     163                 : 
     164               0 :         SkFilterProc proc = SkGetBilinearFilterProc(fProcTable, x, y);
     165                 :         uint32_t c = proc(SkExpand_rgb_16(*p00), SkExpand_rgb_16(*p01),
     166               0 :                           SkExpand_rgb_16(*p10), SkExpand_rgb_16(*p11));
     167                 : 
     168               0 :         return SkPixel16ToPixel32((uint16_t)SkCompact_rgb_16(c));
     169                 :     }
     170                 :     
     171                 : private:
     172                 :     const SkFilterProc* fProcTable;
     173                 : };
     174                 : 
     175                 : // If we had a init/term method on sampler, we could avoid the per-pixel
     176                 : // call to lockColors/unlockColors
     177                 : 
     178               0 : class Index8_Bilinear_Sampler : public SkBitmapSampler {
     179                 : public:
     180               0 :     Index8_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
     181               0 :         : SkBitmapSampler(bm, true, tmx, tmy)
     182                 :     {
     183               0 :         fPtrProcTable = SkGetBilinearFilterPtrProcTable();
     184               0 :     }
     185                 : 
     186               0 :     virtual SkPMColor sample(SkFixed x, SkFixed y) const
     187                 :     {
     188               0 :         const SkBitmap* bitmap = &fBitmap;
     189                 : 
     190                 :         const uint8_t *p00, *p01, *p10, *p11;
     191                 : 
     192                 :          // turn pixel centers into the top-left of our filter-box
     193               0 :         x -= SK_FixedHalf;
     194               0 :         y -= SK_FixedHalf;
     195                 :     
     196                 :        // compute our pointers
     197                 :         {
     198               0 :             int ix = x >> 16;
     199               0 :             int iy = y >> 16;
     200                 :             
     201               0 :             int             maxX = fMaxX;
     202               0 :             SkTileModeProc  procX = fTileProcX;
     203               0 :             int             maxY = fMaxY;
     204               0 :             SkTileModeProc  procY = fTileProcY;
     205                 : 
     206               0 :             int tmpx = procX(ix, maxX);
     207               0 :             int tmpy = procY(iy, maxY);
     208               0 :             p00 = bitmap->getAddr8(tmpx, tmpy);
     209                 : 
     210               0 :             int tmpx1 = procX(ix + 1, maxX);
     211               0 :             p01 = bitmap->getAddr8(tmpx1, tmpy);
     212                 : 
     213               0 :             int tmpy1 = procY(iy + 1, maxY);
     214               0 :             p10 = bitmap->getAddr8(tmpx, tmpy1);
     215                 : 
     216               0 :             p11 = bitmap->getAddr8(tmpx1, tmpy1);
     217                 :         }
     218                 : 
     219               0 :         const SkPMColor* colors = bitmap->getColorTable()->lockColors();
     220                 : 
     221               0 :         SkFilterPtrProc proc = SkGetBilinearFilterPtrProc(fPtrProcTable, x, y);
     222               0 :         uint32_t c = proc(&colors[*p00], &colors[*p01], &colors[*p10], &colors[*p11]);
     223                 : 
     224               0 :         bitmap->getColorTable()->unlockColors(false);
     225                 : 
     226               0 :         return c;
     227                 :     }
     228                 :     
     229                 : private:
     230                 :     const SkFilterPtrProc* fPtrProcTable;
     231                 : };
     232                 : 
     233               0 : class A8_Bilinear_Sampler : public SkBitmapSampler {
     234                 : public:
     235               0 :     A8_Bilinear_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
     236               0 :         : SkBitmapSampler(bm, true, tmx, tmy)
     237                 :     {
     238               0 :         fProcTable = SkGetBilinearFilterProcTable();
     239               0 :     }
     240                 : 
     241               0 :     virtual void setPaint(const SkPaint& paint)
     242                 :     {
     243               0 :         fColor = SkPreMultiplyColor(paint.getColor());
     244               0 :     }
     245                 : 
     246               0 :     virtual SkPMColor sample(SkFixed x, SkFixed y) const
     247                 :     {
     248                 :         const uint8_t *p00, *p01, *p10, *p11;
     249                 : 
     250                 :         // turn pixel centers into the top-left of our filter-box
     251               0 :         x -= SK_FixedHalf;
     252               0 :         y -= SK_FixedHalf;
     253                 :     
     254                 :         // compute our pointers
     255                 :         {
     256               0 :             const SkBitmap* bitmap = &fBitmap;
     257               0 :             int ix = x >> 16;
     258               0 :             int iy = y >> 16;
     259                 :             
     260               0 :             int             maxX = fMaxX;
     261               0 :             SkTileModeProc  procX = fTileProcX;
     262               0 :             int             maxY = fMaxY;
     263               0 :             SkTileModeProc  procY = fTileProcY;
     264                 : 
     265               0 :             int tmpx = procX(ix, maxX);
     266               0 :             int tmpy = procY(iy, maxY);
     267               0 :             p00 = bitmap->getAddr8(tmpx, tmpy);
     268                 : 
     269               0 :             int tmpx1 = procX(ix + 1, maxX);
     270               0 :             p01 = bitmap->getAddr8(tmpx1, tmpy);
     271                 : 
     272               0 :             int tmpy1 = procY(iy + 1, maxY);
     273               0 :             p10 = bitmap->getAddr8(tmpx, tmpy1);
     274                 : 
     275               0 :             p11 = bitmap->getAddr8(tmpx1, tmpy1);
     276                 :         }
     277                 : 
     278               0 :         SkFilterProc proc = SkGetBilinearFilterProc(fProcTable, x, y);
     279               0 :         int alpha = proc(*p00, *p01, *p10, *p11);
     280               0 :         return SkAlphaMulQ(fColor, SkAlpha255To256(alpha));
     281                 :     }
     282                 :     
     283                 : private:
     284                 :     const SkFilterProc* fProcTable;
     285                 :     SkPMColor           fColor;
     286                 : };
     287                 : 
     288               0 : class A8_NoFilter_Sampler : public SkBitmapSampler {
     289                 : public:
     290               0 :     A8_NoFilter_Sampler(const SkBitmap& bm, SkShader::TileMode tmx, SkShader::TileMode tmy)
     291               0 :         : SkBitmapSampler(bm, false, tmx, tmy)
     292                 :     {
     293               0 :     }
     294                 : 
     295               0 :     virtual void setPaint(const SkPaint& paint)
     296                 :     {
     297               0 :         fColor = SkPreMultiplyColor(paint.getColor());
     298               0 :     }
     299                 : 
     300               0 :     virtual SkPMColor sample(SkFixed x, SkFixed y) const
     301                 :     {
     302               0 :         int ix = SkFixedFloor(x);
     303               0 :         int iy = SkFixedFloor(y);
     304                 :         
     305               0 :         int alpha = *fBitmap.getAddr8(fTileProcX(ix, fMaxX), fTileProcY(iy, fMaxY));
     306               0 :         return SkAlphaMulQ(fColor, SkAlpha255To256(alpha));
     307                 :     }
     308                 :     
     309                 : private:
     310                 :     const SkFilterProc* fProcTable;
     311                 :     SkPMColor           fColor;
     312                 : };
     313                 : 
     314                 : ///////////////////////////////////////////////////////////////////////////////
     315                 : ///////////////////////////////////////////////////////////////////////////////
     316                 : 
     317               0 : SkBitmapSampler* SkBitmapSampler::Create(const SkBitmap& bm, bool doFilter,
     318                 :                                          SkShader::TileMode tmx,
     319                 :                                          SkShader::TileMode tmy)
     320                 : {
     321               0 :     switch (bm.getConfig()) {
     322                 :     case SkBitmap::kARGB_8888_Config:
     323               0 :         if (doFilter)
     324               0 :             return SkNEW_ARGS(ARGB32_Bilinear_Sampler, (bm, tmx, tmy));
     325                 : 
     326               0 :         if (tmx == tmy) {
     327               0 :             switch (tmx) {
     328                 :             case SkShader::kClamp_TileMode:
     329               0 :                 return SkNEW_ARGS(ARGB32_Point_Clamp_Sampler, (bm));
     330                 :             case SkShader::kRepeat_TileMode:
     331               0 :                 if (is_pow2(bm.width()) && is_pow2(bm.height()))
     332               0 :                     return SkNEW_ARGS(ARGB32_Point_Repeat_Pow2_Sampler, (bm));
     333                 :                 else
     334               0 :                     return SkNEW_ARGS(ARGB32_Point_Repeat_Mod_Sampler, (bm));
     335                 :             case SkShader::kMirror_TileMode:
     336               0 :                 if (is_pow2(bm.width()) && is_pow2(bm.height()))
     337               0 :                     return SkNEW_ARGS(ARGB32_Point_Mirror_Pow2_Sampler, (bm));
     338                 :                 else
     339               0 :                     return SkNEW_ARGS(ARGB32_Point_Mirror_Mod_Sampler, (bm));
     340                 :             default:
     341               0 :                 SkDEBUGFAIL("unknown mode");
     342                 :             }
     343                 :         }
     344                 :         else {  // tmx != tmy
     345               0 :             return SkNEW_ARGS(ARGB32_Point_Sampler, (bm, tmx, tmy));
     346                 :         }
     347               0 :         break;
     348                 : 
     349                 :     case SkBitmap::kRGB_565_Config:
     350               0 :         if (doFilter)
     351               0 :             return SkNEW_ARGS(RGB16_Bilinear_Sampler, (bm, tmx, tmy));
     352                 : 
     353               0 :         if (tmx == tmy) {
     354               0 :             switch (tmx) {
     355                 :             case SkShader::kClamp_TileMode:
     356               0 :                 return SkNEW_ARGS(RGB16_Point_Clamp_Sampler, (bm));
     357                 :             case SkShader::kRepeat_TileMode:
     358               0 :                 if (is_pow2(bm.width()) && is_pow2(bm.height()))
     359               0 :                     return SkNEW_ARGS(RGB16_Point_Repeat_Pow2_Sampler, (bm));
     360                 :                 else
     361               0 :                     return SkNEW_ARGS(RGB16_Point_Repeat_Mod_Sampler, (bm));
     362                 :             case SkShader::kMirror_TileMode:
     363               0 :                 if (is_pow2(bm.width()) && is_pow2(bm.height()))
     364               0 :                     return SkNEW_ARGS(RGB16_Point_Mirror_Pow2_Sampler, (bm));
     365                 :                 else
     366               0 :                     return SkNEW_ARGS(RGB16_Point_Mirror_Mod_Sampler, (bm));
     367                 :             default:
     368               0 :                 SkDEBUGFAIL("unknown mode");
     369                 :             }
     370                 :         }
     371                 :         else {  // tmx != tmy
     372               0 :             return SkNEW_ARGS(RGB16_Point_Sampler, (bm, tmx, tmy));
     373                 :         }
     374               0 :         break;
     375                 : 
     376                 :     case SkBitmap::kIndex8_Config:
     377               0 :         if (doFilter)
     378               0 :             return SkNEW_ARGS(Index8_Bilinear_Sampler, (bm, tmx, tmy));
     379                 : 
     380               0 :         if (tmx == tmy) {
     381               0 :             switch (tmx) {
     382                 :             case SkShader::kClamp_TileMode:
     383               0 :                 return SkNEW_ARGS(Index8_Point_Clamp_Sampler, (bm));
     384                 :             case SkShader::kRepeat_TileMode:
     385               0 :                 if (is_pow2(bm.width()) && is_pow2(bm.height()))
     386               0 :                     return SkNEW_ARGS(Index8_Point_Repeat_Pow2_Sampler, (bm));
     387                 :                 else
     388               0 :                     return SkNEW_ARGS(Index8_Point_Repeat_Mod_Sampler, (bm));
     389                 :             case SkShader::kMirror_TileMode:
     390               0 :                 if (is_pow2(bm.width()) && is_pow2(bm.height()))
     391               0 :                     return SkNEW_ARGS(Index8_Point_Mirror_Pow2_Sampler, (bm));
     392                 :                 else
     393               0 :                     return SkNEW_ARGS(Index8_Point_Mirror_Mod_Sampler, (bm));
     394                 :             default:
     395               0 :                 SkDEBUGFAIL("unknown mode");
     396                 :             }
     397                 :         }
     398                 :         else {  // tmx != tmy
     399               0 :             return SkNEW_ARGS(Index8_Point_Sampler, (bm, tmx, tmy));
     400                 :         }
     401               0 :         break;
     402                 : 
     403                 :     case SkBitmap::kA8_Config:
     404               0 :         if (doFilter)
     405               0 :             return SkNEW_ARGS(A8_Bilinear_Sampler, (bm, tmx, tmy));
     406                 :         else
     407               0 :             return SkNEW_ARGS(A8_NoFilter_Sampler, (bm, tmx, tmy));
     408                 :         break;
     409                 : 
     410                 :     default:
     411               0 :         SkDEBUGFAIL("unknown device");
     412                 :     }
     413               0 :     return SkNEW_ARGS(SkNullBitmapSampler, (bm, doFilter, tmx, tmy));
     414                 : }
     415                 : 

Generated by: LCOV version 1.7