Home | History | Annotate | Download | only in core
      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 "SkUtils.h"
      9 
     10 #if DSTSIZE==32
     11     #define DSTTYPE SkPMColor
     12 #elif DSTSIZE==16
     13     #define DSTTYPE uint16_t
     14 #else
     15     #error "need DSTSIZE to be 32 or 16"
     16 #endif
     17 
     18 #if (DSTSIZE == 32)
     19     #define BITMAPPROC_MEMSET(ptr, value, n) sk_memset32(ptr, value, n)
     20 #elif (DSTSIZE == 16)
     21     #define BITMAPPROC_MEMSET(ptr, value, n) sk_memset16(ptr, value, n)
     22 #else
     23     #error "unsupported DSTSIZE"
     24 #endif
     25 
     26 
     27 // declare functions externally to suppress warnings.
     28 void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
     29                               const uint32_t* SK_RESTRICT xy,
     30                               int count, DSTTYPE* SK_RESTRICT colors);
     31 void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
     32                             const uint32_t* SK_RESTRICT xy,
     33                             int count, DSTTYPE* SK_RESTRICT colors);
     34 void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
     35                           const uint32_t* SK_RESTRICT xy,
     36                            int count, DSTTYPE* SK_RESTRICT colors);
     37 void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
     38                             const uint32_t* SK_RESTRICT xy,
     39                             int count, DSTTYPE* SK_RESTRICT colors);
     40 
     41 void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
     42                               const uint32_t* SK_RESTRICT xy,
     43                               int count, DSTTYPE* SK_RESTRICT colors) {
     44     SkASSERT(count > 0 && colors != NULL);
     45     SkASSERT(s.fDoFilter == false);
     46     SkDEBUGCODE(CHECKSTATE(s);)
     47 
     48 #ifdef PREAMBLE
     49     PREAMBLE(s);
     50 #endif
     51     const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
     52     int i, rb = s.fBitmap->rowBytes();
     53 
     54     uint32_t XY;
     55     SRCTYPE src;
     56 
     57     for (i = (count >> 1); i > 0; --i) {
     58         XY = *xy++;
     59         SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
     60                  (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
     61         src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
     62         *colors++ = RETURNDST(src);
     63 
     64         XY = *xy++;
     65         SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
     66                  (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
     67         src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
     68         *colors++ = RETURNDST(src);
     69     }
     70     if (count & 1) {
     71         XY = *xy++;
     72         SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
     73                  (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
     74         src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
     75         *colors++ = RETURNDST(src);
     76     }
     77 
     78 #ifdef POSTAMBLE
     79     POSTAMBLE(s);
     80 #endif
     81 }
     82 
     83 void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
     84                             const uint32_t* SK_RESTRICT xy,
     85                             int count, DSTTYPE* SK_RESTRICT colors) {
     86     SkASSERT(count > 0 && colors != NULL);
     87     SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
     88     SkASSERT(s.fDoFilter == false);
     89     SkDEBUGCODE(CHECKSTATE(s);)
     90 
     91 #ifdef PREAMBLE
     92     PREAMBLE(s);
     93 #endif
     94     const SRCTYPE* SK_RESTRICT srcAddr = (const SRCTYPE*)s.fBitmap->getPixels();
     95 
     96     // buffer is y32, x16, x16, x16, x16, x16
     97     // bump srcAddr to the proper row, since we're told Y never changes
     98     SkASSERT((unsigned)xy[0] < (unsigned)s.fBitmap->height());
     99     srcAddr = (const SRCTYPE*)((const char*)srcAddr +
    100                                                 xy[0] * s.fBitmap->rowBytes());
    101     xy += 1;
    102 
    103     SRCTYPE src;
    104 
    105     if (1 == s.fBitmap->width()) {
    106         src = srcAddr[0];
    107         DSTTYPE dstValue = RETURNDST(src);
    108         BITMAPPROC_MEMSET(colors, dstValue, count);
    109     } else {
    110         int i;
    111         for (i = (count >> 2); i > 0; --i) {
    112             uint32_t xx0 = *xy++;
    113             uint32_t xx1 = *xy++;
    114             SRCTYPE x0 = srcAddr[UNPACK_PRIMARY_SHORT(xx0)];
    115             SRCTYPE x1 = srcAddr[UNPACK_SECONDARY_SHORT(xx0)];
    116             SRCTYPE x2 = srcAddr[UNPACK_PRIMARY_SHORT(xx1)];
    117             SRCTYPE x3 = srcAddr[UNPACK_SECONDARY_SHORT(xx1)];
    118 
    119             *colors++ = RETURNDST(x0);
    120             *colors++ = RETURNDST(x1);
    121             *colors++ = RETURNDST(x2);
    122             *colors++ = RETURNDST(x3);
    123         }
    124         const uint16_t* SK_RESTRICT xx = (const uint16_t*)(xy);
    125         for (i = (count & 3); i > 0; --i) {
    126             SkASSERT(*xx < (unsigned)s.fBitmap->width());
    127             src = srcAddr[*xx++]; *colors++ = RETURNDST(src);
    128         }
    129     }
    130 
    131 #ifdef POSTAMBLE
    132     POSTAMBLE(s);
    133 #endif
    134 }
    135 
    136 ///////////////////////////////////////////////////////////////////////////////
    137 
    138 void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
    139                           const uint32_t* SK_RESTRICT xy,
    140                            int count, DSTTYPE* SK_RESTRICT colors) {
    141     SkASSERT(count > 0 && colors != NULL);
    142     SkASSERT(s.fDoFilter);
    143     SkDEBUGCODE(CHECKSTATE(s);)
    144 
    145 #ifdef PREAMBLE
    146     PREAMBLE(s);
    147 #endif
    148     const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
    149     unsigned rb = s.fBitmap->rowBytes();
    150     unsigned subY;
    151     const SRCTYPE* SK_RESTRICT row0;
    152     const SRCTYPE* SK_RESTRICT row1;
    153 
    154     // setup row ptrs and update proc_table
    155     {
    156         uint32_t XY = *xy++;
    157         unsigned y0 = XY >> 14;
    158         row0 = (const SRCTYPE*)(srcAddr + (y0 >> 4) * rb);
    159         row1 = (const SRCTYPE*)(srcAddr + (XY & 0x3FFF) * rb);
    160         subY = y0 & 0xF;
    161     }
    162 
    163     do {
    164         uint32_t XX = *xy++;    // x0:14 | 4 | x1:14
    165         unsigned x0 = XX >> 14;
    166         unsigned x1 = XX & 0x3FFF;
    167         unsigned subX = x0 & 0xF;
    168         x0 >>= 4;
    169 
    170         FILTER_PROC(subX, subY,
    171                     SRC_TO_FILTER(row0[x0]),
    172                     SRC_TO_FILTER(row0[x1]),
    173                     SRC_TO_FILTER(row1[x0]),
    174                     SRC_TO_FILTER(row1[x1]),
    175                     colors);
    176         colors += 1;
    177 
    178     } while (--count != 0);
    179 
    180 #ifdef POSTAMBLE
    181     POSTAMBLE(s);
    182 #endif
    183 }
    184 void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
    185                             const uint32_t* SK_RESTRICT xy,
    186                             int count, DSTTYPE* SK_RESTRICT colors) {
    187     SkASSERT(count > 0 && colors != NULL);
    188     SkASSERT(s.fDoFilter);
    189     SkDEBUGCODE(CHECKSTATE(s);)
    190 
    191 #ifdef PREAMBLE
    192         PREAMBLE(s);
    193 #endif
    194     const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
    195     int rb = s.fBitmap->rowBytes();
    196 
    197     do {
    198         uint32_t data = *xy++;
    199         unsigned y0 = data >> 14;
    200         unsigned y1 = data & 0x3FFF;
    201         unsigned subY = y0 & 0xF;
    202         y0 >>= 4;
    203 
    204         data = *xy++;
    205         unsigned x0 = data >> 14;
    206         unsigned x1 = data & 0x3FFF;
    207         unsigned subX = x0 & 0xF;
    208         x0 >>= 4;
    209 
    210         const SRCTYPE* SK_RESTRICT row0 = (const SRCTYPE*)(srcAddr + y0 * rb);
    211         const SRCTYPE* SK_RESTRICT row1 = (const SRCTYPE*)(srcAddr + y1 * rb);
    212 
    213         FILTER_PROC(subX, subY,
    214                     SRC_TO_FILTER(row0[x0]),
    215                     SRC_TO_FILTER(row0[x1]),
    216                     SRC_TO_FILTER(row1[x0]),
    217                     SRC_TO_FILTER(row1[x1]),
    218                     colors);
    219         colors += 1;
    220     } while (--count != 0);
    221 
    222 #ifdef POSTAMBLE
    223     POSTAMBLE(s);
    224 #endif
    225 }
    226 
    227 #undef MAKENAME
    228 #undef DSTSIZE
    229 #undef DSTTYPE
    230 #undef SRCTYPE
    231 #undef CHECKSTATE
    232 #undef RETURNDST
    233 #undef SRC_TO_FILTER
    234 #undef FILTER_TO_DST
    235 
    236 #ifdef PREAMBLE
    237     #undef PREAMBLE
    238 #endif
    239 #ifdef POSTAMBLE
    240     #undef POSTAMBLE
    241 #endif
    242 
    243 #undef FILTER_PROC_TYPE
    244 #undef GET_FILTER_TABLE
    245 #undef GET_FILTER_ROW
    246 #undef GET_FILTER_ROW_PROC
    247 #undef GET_FILTER_PROC
    248 #undef BITMAPPROC_MEMSET
    249