| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright 2007 The Android Open Source Project |    2  * Copyright 2007 The Android Open Source Project | 
|    3  * |    3  * | 
|    4  * Use of this source code is governed by a BSD-style license that can be |    4  * Use of this source code is governed by a BSD-style license that can be | 
|    5  * found in the LICENSE file. |    5  * found in the LICENSE file. | 
|    6  */ |    6  */ | 
|    7  |    7  | 
|    8  |    8  | 
|    9 #include "SkScaledBitmapSampler.h" |    9 #include "SkScaledBitmapSampler.h" | 
|   10 #include "SkBitmap.h" |   10 #include "SkBitmap.h" | 
|   11 #include "SkColorPriv.h" |   11 #include "SkColorPriv.h" | 
|   12 #include "SkDither.h" |   12 #include "SkDither.h" | 
|   13 #include "SkTypes.h" |   13 #include "SkTypes.h" | 
|   14  |   14  | 
|   15 // 8888 |   15 // 8888 | 
|   16  |   16  | 
|   17 static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow, |   17 static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow, | 
|   18                               const uint8_t* SK_RESTRICT src, |   18                               const uint8_t* SK_RESTRICT src, | 
|   19                               int width, int deltaSrc, int, const SkPMColor[]) { |   19                               int width, int deltaSrc, int, const SkPMColor[]) { | 
|   20     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |   20     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
|   21     for (int x = 0; x < width; x++) { |   21     for (int x = 0; x < width; x++) { | 
|   22         dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]); |   22         dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]); | 
|   23         src += deltaSrc; |   23         src += deltaSrc; | 
|   24     } |   24     } | 
|   25     return false; |   25     return false; | 
|   26 } |   26 } | 
|   27  |   27  | 
 |   28 static SkScaledBitmapSampler::RowProc get_gray_to_8888_proc(const SkImageDecoder
     & decoder) { | 
 |   29     // Dither, unpremul, and skipZeroes have no effect | 
 |   30     return Sample_Gray_D8888; | 
 |   31 } | 
 |   32  | 
|   28 static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow, |   33 static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow, | 
|   29                               const uint8_t* SK_RESTRICT src, |   34                               const uint8_t* SK_RESTRICT src, | 
|   30                               int width, int deltaSrc, int, const SkPMColor[]) { |   35                               int width, int deltaSrc, int, const SkPMColor[]) { | 
|   31     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |   36     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
|   32     for (int x = 0; x < width; x++) { |   37     for (int x = 0; x < width; x++) { | 
|   33         dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); |   38         dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); | 
|   34         src += deltaSrc; |   39         src += deltaSrc; | 
|   35     } |   40     } | 
|   36     return false; |   41     return false; | 
|   37 } |   42 } | 
|   38  |   43  | 
 |   44 static SkScaledBitmapSampler::RowProc get_RGBx_to_8888_proc(const SkImageDecoder
     & decoder) { | 
 |   45     // Dither, unpremul, and skipZeroes have no effect | 
 |   46     return Sample_RGBx_D8888; | 
 |   47 } | 
 |   48  | 
|   39 static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow, |   49 static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow, | 
|   40                               const uint8_t* SK_RESTRICT src, |   50                               const uint8_t* SK_RESTRICT src, | 
|   41                               int width, int deltaSrc, int, const SkPMColor[]) { |   51                               int width, int deltaSrc, int, const SkPMColor[]) { | 
|   42     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |   52     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
|   43     unsigned alphaMask = 0xFF; |   53     unsigned alphaMask = 0xFF; | 
|   44     for (int x = 0; x < width; x++) { |   54     for (int x = 0; x < width; x++) { | 
|   45         unsigned alpha = src[3]; |   55         unsigned alpha = src[3]; | 
|   46         dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |   56         dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 
|   47         src += deltaSrc; |   57         src += deltaSrc; | 
|   48         alphaMask &= alpha; |   58         alphaMask &= alpha; | 
|   49     } |   59     } | 
|   50     return alphaMask != 0xFF; |   60     return alphaMask != 0xFF; | 
|   51 } |   61 } | 
|   52  |   62  | 
 |   63 static bool Sample_RGBA_D8888_Unpremul(void* SK_RESTRICT dstRow, | 
 |   64                                        const uint8_t* SK_RESTRICT src, | 
 |   65                                        int width, int deltaSrc, int, | 
 |   66                                        const SkPMColor[]) { | 
 |   67     uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); | 
 |   68     unsigned alphaMask = 0xFF; | 
 |   69     for (int x = 0; x < width; x++) { | 
 |   70         unsigned alpha = src[3]; | 
 |   71         dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); | 
 |   72         src += deltaSrc; | 
 |   73         alphaMask &= alpha; | 
 |   74     } | 
 |   75     return alphaMask != 0xFF; | 
 |   76 } | 
 |   77  | 
 |   78 static bool Sample_RGBA_D8888_SkipZ(void* SK_RESTRICT dstRow, | 
 |   79                                     const uint8_t* SK_RESTRICT src, | 
 |   80                                     int width, int deltaSrc, int, | 
 |   81                                     const SkPMColor[]) { | 
 |   82     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
 |   83     unsigned alphaMask = 0xFF; | 
 |   84     for (int x = 0; x < width; x++) { | 
 |   85         unsigned alpha = src[3]; | 
 |   86         if (0 != alpha) { | 
 |   87             dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 
 |   88         } | 
 |   89         src += deltaSrc; | 
 |   90         alphaMask &= alpha; | 
 |   91     } | 
 |   92     return alphaMask != 0xFF; | 
 |   93 } | 
 |   94  | 
 |   95 static SkScaledBitmapSampler::RowProc get_RGBA_to_8888_proc(const SkImageDecoder
     & decoder) { | 
 |   96     // Dither has no effect. | 
 |   97     if (decoder.getRequireUnpremultipliedColors()) { | 
 |   98         // We could check each component for a zero, at the expense of extra che
     cks. | 
 |   99         // For now, just return unpremul. | 
 |  100         return Sample_RGBA_D8888_Unpremul; | 
 |  101     } | 
 |  102     // Supply the versions that premultiply the colors | 
 |  103     if (decoder.getSkipWritingZeroes()) { | 
 |  104         return Sample_RGBA_D8888_SkipZ; | 
 |  105     } | 
 |  106     return Sample_RGBA_D8888; | 
 |  107 } | 
 |  108  | 
|   53 // 565 |  109 // 565 | 
|   54  |  110  | 
|   55 static bool Sample_Gray_D565(void* SK_RESTRICT dstRow, |  111 static bool Sample_Gray_D565(void* SK_RESTRICT dstRow, | 
|   56                              const uint8_t* SK_RESTRICT src, |  112                              const uint8_t* SK_RESTRICT src, | 
|   57                              int width, int deltaSrc, int, const SkPMColor[]) { |  113                              int width, int deltaSrc, int, const SkPMColor[]) { | 
|   58     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |  114     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
|   59     for (int x = 0; x < width; x++) { |  115     for (int x = 0; x < width; x++) { | 
|   60         dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); |  116         dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); | 
|   61         src += deltaSrc; |  117         src += deltaSrc; | 
|   62     } |  118     } | 
|   63     return false; |  119     return false; | 
|   64 } |  120 } | 
|   65  |  121  | 
|   66 static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow, |  122 static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow, | 
|   67                                const uint8_t* SK_RESTRICT src, |  123                                const uint8_t* SK_RESTRICT src, | 
|   68                            int width, int deltaSrc, int y, const SkPMColor[]) { |  124                            int width, int deltaSrc, int y, const SkPMColor[]) { | 
|   69     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |  125     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
|   70     DITHER_565_SCAN(y); |  126     DITHER_565_SCAN(y); | 
|   71     for (int x = 0; x < width; x++) { |  127     for (int x = 0; x < width; x++) { | 
|   72         dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x)); |  128         dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x)); | 
|   73         src += deltaSrc; |  129         src += deltaSrc; | 
|   74     } |  130     } | 
|   75     return false; |  131     return false; | 
|   76 } |  132 } | 
|   77  |  133  | 
 |  134 static SkScaledBitmapSampler::RowProc get_gray_to_565_proc(const SkImageDecoder&
      decoder) { | 
 |  135     // Unpremul and skip zeroes make no difference | 
 |  136     if (decoder.getDitherImage()) { | 
 |  137         return Sample_Gray_D565_D; | 
 |  138     } | 
 |  139     return Sample_Gray_D565; | 
 |  140 } | 
 |  141  | 
|   78 static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, |  142 static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, | 
|   79                              const uint8_t* SK_RESTRICT src, |  143                              const uint8_t* SK_RESTRICT src, | 
|   80                              int width, int deltaSrc, int, const SkPMColor[]) { |  144                              int width, int deltaSrc, int, const SkPMColor[]) { | 
|   81     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |  145     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
|   82     for (int x = 0; x < width; x++) { |  146     for (int x = 0; x < width; x++) { | 
|   83         dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); |  147         dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); | 
|   84         src += deltaSrc; |  148         src += deltaSrc; | 
|   85     } |  149     } | 
|   86     return false; |  150     return false; | 
|   87 } |  151 } | 
|   88  |  152  | 
 |  153 static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, | 
 |  154                                const uint8_t* SK_RESTRICT src, | 
 |  155                                int width, int deltaSrc, int y, | 
 |  156                                const SkPMColor[]) { | 
 |  157     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
 |  158     DITHER_565_SCAN(y); | 
 |  159     for (int x = 0; x < width; x++) { | 
 |  160         dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x)); | 
 |  161         src += deltaSrc; | 
 |  162     } | 
 |  163     return false; | 
 |  164 } | 
 |  165  | 
 |  166 static SkScaledBitmapSampler::RowProc get_RGBx_to_565_proc(const SkImageDecoder&
      decoder) { | 
 |  167     // Unpremul and skip zeroes make no difference | 
 |  168     if (decoder.getDitherImage()) { | 
 |  169         return Sample_RGBx_D565_D; | 
 |  170     } | 
 |  171     return Sample_RGBx_D565; | 
 |  172 } | 
 |  173  | 
 |  174  | 
|   89 static bool Sample_D565_D565(void* SK_RESTRICT dstRow, |  175 static bool Sample_D565_D565(void* SK_RESTRICT dstRow, | 
|   90                              const uint8_t* SK_RESTRICT src, |  176                              const uint8_t* SK_RESTRICT src, | 
|   91                              int width, int deltaSrc, int, const SkPMColor[]) { |  177                              int width, int deltaSrc, int, const SkPMColor[]) { | 
|   92     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |  178     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
|   93     uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src; |  179     uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src; | 
|   94     for (int x = 0; x < width; x++) { |  180     for (int x = 0; x < width; x++) { | 
|   95         dst[x] = castedSrc[0]; |  181         dst[x] = castedSrc[0]; | 
|   96         castedSrc += deltaSrc >> 1; |  182         castedSrc += deltaSrc >> 1; | 
|   97     } |  183     } | 
|   98     return false; |  184     return false; | 
|   99 } |  185 } | 
|  100  |  186  | 
|  101 static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, |  187 static SkScaledBitmapSampler::RowProc get_565_to_565_proc(const SkImageDecoder& 
     decoder) { | 
|  102                                const uint8_t* SK_RESTRICT src, |  188     // Unpremul, dither, and skip zeroes have no effect | 
|  103                            int width, int deltaSrc, int y, const SkPMColor[]) { |  189     return Sample_D565_D565; | 
|  104     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |  | 
|  105     DITHER_565_SCAN(y); |  | 
|  106     for (int x = 0; x < width; x++) { |  | 
|  107         dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x)); |  | 
|  108         src += deltaSrc; |  | 
|  109     } |  | 
|  110     return false; |  | 
|  111 } |  190 } | 
|  112  |  191  | 
|  113 // 4444 |  192 // 4444 | 
|  114  |  193  | 
|  115 static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow, |  194 static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow, | 
|  116                               const uint8_t* SK_RESTRICT src, |  195                               const uint8_t* SK_RESTRICT src, | 
|  117                               int width, int deltaSrc, int, const SkPMColor[]) { |  196                               int width, int deltaSrc, int, const SkPMColor[]) { | 
|  118     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |  197     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
|  119     for (int x = 0; x < width; x++) { |  198     for (int x = 0; x < width; x++) { | 
|  120         unsigned gray = src[0] >> 4; |  199         unsigned gray = src[0] >> 4; | 
|  121         dst[x] = SkPackARGB4444(0xF, gray, gray, gray); |  200         dst[x] = SkPackARGB4444(0xF, gray, gray, gray); | 
|  122         src += deltaSrc; |  201         src += deltaSrc; | 
|  123     } |  202     } | 
|  124     return false; |  203     return false; | 
|  125 } |  204 } | 
|  126  |  205  | 
|  127 static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow, |  206 static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow, | 
|  128                                 const uint8_t* SK_RESTRICT src, |  207                                 const uint8_t* SK_RESTRICT src, | 
|  129                             int width, int deltaSrc, int y, const SkPMColor[]) { |  208                             int width, int deltaSrc, int y, const SkPMColor[]) { | 
|  130     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |  209     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
|  131     DITHER_4444_SCAN(y); |  210     DITHER_4444_SCAN(y); | 
|  132     for (int x = 0; x < width; x++) { |  211     for (int x = 0; x < width; x++) { | 
|  133         dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0], |  212         dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0], | 
|  134                                       DITHER_VALUE(x)); |  213                                       DITHER_VALUE(x)); | 
|  135         src += deltaSrc; |  214         src += deltaSrc; | 
|  136     } |  215     } | 
|  137     return false; |  216     return false; | 
|  138 } |  217 } | 
|  139  |  218  | 
 |  219 static SkScaledBitmapSampler::RowProc get_gray_to_4444_proc(const SkImageDecoder
     & decoder) { | 
 |  220     // Skip zeroes and unpremul make no difference | 
 |  221     if (decoder.getDitherImage()) { | 
 |  222         return Sample_Gray_D4444_D; | 
 |  223     } | 
 |  224     return Sample_Gray_D4444; | 
 |  225 } | 
 |  226  | 
|  140 static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow, |  227 static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow, | 
|  141                               const uint8_t* SK_RESTRICT src, |  228                               const uint8_t* SK_RESTRICT src, | 
|  142                               int width, int deltaSrc, int, const SkPMColor[]) { |  229                               int width, int deltaSrc, int, const SkPMColor[]) { | 
|  143     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |  230     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
|  144     for (int x = 0; x < width; x++) { |  231     for (int x = 0; x < width; x++) { | 
|  145         dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4); |  232         dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4); | 
|  146         src += deltaSrc; |  233         src += deltaSrc; | 
|  147     } |  234     } | 
|  148     return false; |  235     return false; | 
|  149 } |  236 } | 
|  150  |  237  | 
|  151 static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow, |  238 static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow, | 
|  152                                 const uint8_t* SK_RESTRICT src, |  239                                 const uint8_t* SK_RESTRICT src, | 
|  153                             int width, int deltaSrc, int y, const SkPMColor[]) { |  240                             int width, int deltaSrc, int y, const SkPMColor[]) { | 
|  154     SkPMColor16* dst = (SkPMColor16*)dstRow; |  241     SkPMColor16* dst = (SkPMColor16*)dstRow; | 
|  155     DITHER_4444_SCAN(y); |  242     DITHER_4444_SCAN(y); | 
|  156  |  243  | 
|  157     for (int x = 0; x < width; x++) { |  244     for (int x = 0; x < width; x++) { | 
|  158         dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2], |  245         dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2], | 
|  159                                       DITHER_VALUE(x)); |  246                                       DITHER_VALUE(x)); | 
|  160         src += deltaSrc; |  247         src += deltaSrc; | 
|  161     } |  248     } | 
|  162     return false; |  249     return false; | 
|  163 } |  250 } | 
|  164  |  251  | 
 |  252 static SkScaledBitmapSampler::RowProc get_RGBx_to_4444_proc(const SkImageDecoder
     & decoder) { | 
 |  253     // Skip zeroes and unpremul make no difference | 
 |  254     if (decoder.getDitherImage()) { | 
 |  255         return Sample_RGBx_D4444_D; | 
 |  256     } | 
 |  257     return Sample_RGBx_D4444; | 
 |  258 } | 
 |  259  | 
|  165 static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow, |  260 static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow, | 
|  166                               const uint8_t* SK_RESTRICT src, |  261                               const uint8_t* SK_RESTRICT src, | 
|  167                               int width, int deltaSrc, int, const SkPMColor[]) { |  262                               int width, int deltaSrc, int, const SkPMColor[]) { | 
|  168     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |  263     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
|  169     unsigned alphaMask = 0xFF; |  264     unsigned alphaMask = 0xFF; | 
|  170  |  265  | 
|  171     for (int x = 0; x < width; x++) { |  266     for (int x = 0; x < width; x++) { | 
|  172         unsigned alpha = src[3]; |  267         unsigned alpha = src[3]; | 
|  173         SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |  268         SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 
|  174         dst[x] = SkPixel32ToPixel4444(c); |  269         dst[x] = SkPixel32ToPixel4444(c); | 
|  175         src += deltaSrc; |  270         src += deltaSrc; | 
|  176         alphaMask &= alpha; |  271         alphaMask &= alpha; | 
|  177     } |  272     } | 
|  178     return alphaMask != 0xFF; |  273     return alphaMask != 0xFF; | 
|  179 } |  274 } | 
|  180  |  275  | 
 |  276 static bool Sample_RGBA_D4444_SkipZ(void* SK_RESTRICT dstRow, | 
 |  277                                     const uint8_t* SK_RESTRICT src, | 
 |  278                                     int width, int deltaSrc, int, | 
 |  279                                     const SkPMColor[]) { | 
 |  280     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
 |  281     unsigned alphaMask = 0xFF; | 
 |  282  | 
 |  283     for (int x = 0; x < width; x++) { | 
 |  284         unsigned alpha = src[3]; | 
 |  285         if (alpha != 0) { | 
 |  286             SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 
 |  287             dst[x] = SkPixel32ToPixel4444(c); | 
 |  288         } | 
 |  289         src += deltaSrc; | 
 |  290         alphaMask &= alpha; | 
 |  291     } | 
 |  292     return alphaMask != 0xFF; | 
 |  293 } | 
 |  294  | 
 |  295  | 
|  181 static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow, |  296 static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow, | 
|  182                                 const uint8_t* SK_RESTRICT src, |  297                                 const uint8_t* SK_RESTRICT src, | 
|  183                             int width, int deltaSrc, int y, const SkPMColor[]) { |  298                                 int width, int deltaSrc, int y, | 
 |  299                                 const SkPMColor[]) { | 
|  184     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |  300     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
|  185     unsigned alphaMask = 0xFF; |  301     unsigned alphaMask = 0xFF; | 
|  186     DITHER_4444_SCAN(y); |  302     DITHER_4444_SCAN(y); | 
|  187  |  303  | 
|  188     for (int x = 0; x < width; x++) { |  304     for (int x = 0; x < width; x++) { | 
|  189         unsigned alpha = src[3]; |  305         unsigned alpha = src[3]; | 
|  190         SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |  306         SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 
|  191         dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); |  307         dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | 
|  192         src += deltaSrc; |  308         src += deltaSrc; | 
|  193         alphaMask &= alpha; |  309         alphaMask &= alpha; | 
|  194     } |  310     } | 
|  195     return alphaMask != 0xFF; |  311     return alphaMask != 0xFF; | 
|  196 } |  312 } | 
|  197  |  313  | 
 |  314 static bool Sample_RGBA_D4444_D_SkipZ(void* SK_RESTRICT dstRow, | 
 |  315                                       const uint8_t* SK_RESTRICT src, | 
 |  316                                       int width, int deltaSrc, int y, | 
 |  317                                       const SkPMColor[]) { | 
 |  318     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
 |  319     unsigned alphaMask = 0xFF; | 
 |  320     DITHER_4444_SCAN(y); | 
 |  321  | 
 |  322     for (int x = 0; x < width; x++) { | 
 |  323         unsigned alpha = src[3]; | 
 |  324         if (alpha != 0) { | 
 |  325             SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 
 |  326             dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | 
 |  327         } | 
 |  328         src += deltaSrc; | 
 |  329         alphaMask &= alpha; | 
 |  330     } | 
 |  331     return alphaMask != 0xFF; | 
 |  332 } | 
 |  333  | 
 |  334 static SkScaledBitmapSampler::RowProc get_RGBA_to_4444_proc(const SkImageDecoder
     & decoder) { | 
 |  335     if (decoder.getRequireUnpremultipliedColors()) { | 
 |  336         // Unpremultiplied is not supported for 4444 | 
 |  337         return NULL; | 
 |  338     } | 
 |  339     const bool dither = decoder.getDitherImage(); | 
 |  340     if (decoder.getSkipWritingZeroes()) { | 
 |  341         if (dither) { | 
 |  342             return Sample_RGBA_D4444_D_SkipZ; | 
 |  343         } | 
 |  344         return Sample_RGBA_D4444_SkipZ; | 
 |  345     } | 
 |  346     if (dither) { | 
 |  347         return Sample_RGBA_D4444_D; | 
 |  348     } | 
 |  349     return Sample_RGBA_D4444; | 
 |  350 } | 
 |  351  | 
|  198 // Index |  352 // Index | 
|  199  |  353  | 
|  200 #define A32_MASK_IN_PLACE   (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT) |  354 #define A32_MASK_IN_PLACE   (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT) | 
|  201  |  355  | 
|  202 static bool Sample_Index_D8888(void* SK_RESTRICT dstRow, |  356 static bool Sample_Index_D8888(void* SK_RESTRICT dstRow, | 
|  203                                const uint8_t* SK_RESTRICT src, |  357                                const uint8_t* SK_RESTRICT src, | 
|  204                        int width, int deltaSrc, int, const SkPMColor ctable[]) { |  358                        int width, int deltaSrc, int, const SkPMColor ctable[]) { | 
|  205  |  359  | 
|  206     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |  360     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
|  207     SkPMColor cc = A32_MASK_IN_PLACE; |  361     SkPMColor cc = A32_MASK_IN_PLACE; | 
|  208     for (int x = 0; x < width; x++) { |  362     for (int x = 0; x < width; x++) { | 
|  209         SkPMColor c = ctable[*src]; |  363         SkPMColor c = ctable[*src]; | 
|  210         cc &= c; |  364         cc &= c; | 
|  211         dst[x] = c; |  365         dst[x] = c; | 
|  212         src += deltaSrc; |  366         src += deltaSrc; | 
|  213     } |  367     } | 
|  214     return cc != A32_MASK_IN_PLACE; |  368     return cc != A32_MASK_IN_PLACE; | 
|  215 } |  369 } | 
|  216  |  370  | 
 |  371 static bool Sample_Index_D8888_SkipZ(void* SK_RESTRICT dstRow, | 
 |  372                                      const uint8_t* SK_RESTRICT src, | 
 |  373                                      int width, int deltaSrc, int, | 
 |  374                                      const SkPMColor ctable[]) { | 
 |  375  | 
 |  376     SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 
 |  377     SkPMColor cc = A32_MASK_IN_PLACE; | 
 |  378     for (int x = 0; x < width; x++) { | 
 |  379         SkPMColor c = ctable[*src]; | 
 |  380         cc &= c; | 
 |  381         if (c != 0) { | 
 |  382             dst[x] = c; | 
 |  383         } | 
 |  384         src += deltaSrc; | 
 |  385     } | 
 |  386     return cc != A32_MASK_IN_PLACE; | 
 |  387 } | 
 |  388  | 
 |  389 static SkScaledBitmapSampler::RowProc get_index_to_8888_proc(const SkImageDecode
     r& decoder) { | 
 |  390     if (decoder.getRequireUnpremultipliedColors()) { | 
 |  391         // Unpremultiplied is not supported for an index source. | 
 |  392         return NULL; | 
 |  393     } | 
 |  394     // Dither makes no difference | 
 |  395     if (decoder.getSkipWritingZeroes()) { | 
 |  396         return Sample_Index_D8888_SkipZ; | 
 |  397     } | 
 |  398     return Sample_Index_D8888; | 
 |  399 } | 
 |  400  | 
|  217 static bool Sample_Index_D565(void* SK_RESTRICT dstRow, |  401 static bool Sample_Index_D565(void* SK_RESTRICT dstRow, | 
|  218                                const uint8_t* SK_RESTRICT src, |  402                                const uint8_t* SK_RESTRICT src, | 
|  219                        int width, int deltaSrc, int, const SkPMColor ctable[]) { |  403                        int width, int deltaSrc, int, const SkPMColor ctable[]) { | 
|  220  |  404  | 
|  221     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |  405     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
|  222     for (int x = 0; x < width; x++) { |  406     for (int x = 0; x < width; x++) { | 
|  223         dst[x] = SkPixel32ToPixel16(ctable[*src]); |  407         dst[x] = SkPixel32ToPixel16(ctable[*src]); | 
|  224         src += deltaSrc; |  408         src += deltaSrc; | 
|  225     } |  409     } | 
|  226     return false; |  410     return false; | 
|  227 } |  411 } | 
|  228  |  412  | 
|  229 static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow, |  413 static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow, | 
|  230                                 const uint8_t* SK_RESTRICT src, int width, |  414                                 const uint8_t* SK_RESTRICT src, int width, | 
|  231                                 int deltaSrc, int y, const SkPMColor ctable[]) { |  415                                 int deltaSrc, int y, const SkPMColor ctable[]) { | 
|  232  |  416  | 
|  233     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |  417     uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 
|  234     DITHER_565_SCAN(y); |  418     DITHER_565_SCAN(y); | 
|  235  |  419  | 
|  236     for (int x = 0; x < width; x++) { |  420     for (int x = 0; x < width; x++) { | 
|  237         SkPMColor c = ctable[*src]; |  421         SkPMColor c = ctable[*src]; | 
|  238         dst[x] = SkDitherRGBTo565(SkGetPackedR32(c), SkGetPackedG32(c), |  422         dst[x] = SkDitherRGBTo565(SkGetPackedR32(c), SkGetPackedG32(c), | 
|  239                                   SkGetPackedB32(c), DITHER_VALUE(x)); |  423                                   SkGetPackedB32(c), DITHER_VALUE(x)); | 
|  240         src += deltaSrc; |  424         src += deltaSrc; | 
|  241     } |  425     } | 
|  242     return false; |  426     return false; | 
|  243 } |  427 } | 
|  244  |  428  | 
 |  429 static SkScaledBitmapSampler::RowProc get_index_to_565_proc(const SkImageDecoder
     & decoder) { | 
 |  430     // Unpremultiplied and skip zeroes make no difference | 
 |  431     if (decoder.getDitherImage()) { | 
 |  432         return Sample_Index_D565_D; | 
 |  433     } | 
 |  434     return Sample_Index_D565; | 
 |  435 } | 
 |  436  | 
|  245 static bool Sample_Index_D4444(void* SK_RESTRICT dstRow, |  437 static bool Sample_Index_D4444(void* SK_RESTRICT dstRow, | 
|  246                                const uint8_t* SK_RESTRICT src, int width, |  438                                const uint8_t* SK_RESTRICT src, int width, | 
|  247                                int deltaSrc, int y, const SkPMColor ctable[]) { |  439                                int deltaSrc, int y, const SkPMColor ctable[]) { | 
|  248  |  440  | 
|  249     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |  441     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
|  250     SkPMColor cc = A32_MASK_IN_PLACE; |  442     SkPMColor cc = A32_MASK_IN_PLACE; | 
|  251     for (int x = 0; x < width; x++) { |  443     for (int x = 0; x < width; x++) { | 
|  252         SkPMColor c = ctable[*src]; |  444         SkPMColor c = ctable[*src]; | 
|  253         cc &= c; |  445         cc &= c; | 
|  254         dst[x] = SkPixel32ToPixel4444(c); |  446         dst[x] = SkPixel32ToPixel4444(c); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  267  |  459  | 
|  268     for (int x = 0; x < width; x++) { |  460     for (int x = 0; x < width; x++) { | 
|  269         SkPMColor c = ctable[*src]; |  461         SkPMColor c = ctable[*src]; | 
|  270         cc &= c; |  462         cc &= c; | 
|  271         dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); |  463         dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | 
|  272         src += deltaSrc; |  464         src += deltaSrc; | 
|  273     } |  465     } | 
|  274     return cc != A32_MASK_IN_PLACE; |  466     return cc != A32_MASK_IN_PLACE; | 
|  275 } |  467 } | 
|  276  |  468  | 
 |  469 static bool Sample_Index_D4444_SkipZ(void* SK_RESTRICT dstRow, | 
 |  470                                      const uint8_t* SK_RESTRICT src, int width, | 
 |  471                                      int deltaSrc, int y, const SkPMColor ctable
     []) { | 
 |  472  | 
 |  473     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
 |  474     SkPMColor cc = A32_MASK_IN_PLACE; | 
 |  475     for (int x = 0; x < width; x++) { | 
 |  476         SkPMColor c = ctable[*src]; | 
 |  477         cc &= c; | 
 |  478         if (c != 0) { | 
 |  479             dst[x] = SkPixel32ToPixel4444(c); | 
 |  480         } | 
 |  481         src += deltaSrc; | 
 |  482     } | 
 |  483     return cc != A32_MASK_IN_PLACE; | 
 |  484 } | 
 |  485  | 
 |  486 static bool Sample_Index_D4444_D_SkipZ(void* SK_RESTRICT dstRow, | 
 |  487                                        const uint8_t* SK_RESTRICT src, int width
     , | 
 |  488                                        int deltaSrc, int y, const SkPMColor ctab
     le[]) { | 
 |  489  | 
 |  490     SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 
 |  491     SkPMColor cc = A32_MASK_IN_PLACE; | 
 |  492     DITHER_4444_SCAN(y); | 
 |  493  | 
 |  494     for (int x = 0; x < width; x++) { | 
 |  495         SkPMColor c = ctable[*src]; | 
 |  496         cc &= c; | 
 |  497         if (c != 0) { | 
 |  498             dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | 
 |  499         } | 
 |  500         src += deltaSrc; | 
 |  501     } | 
 |  502     return cc != A32_MASK_IN_PLACE; | 
 |  503 } | 
 |  504  | 
 |  505 static SkScaledBitmapSampler::RowProc get_index_to_4444_proc(const SkImageDecode
     r& decoder) { | 
 |  506     // Unpremul not allowed | 
 |  507     if (decoder.getRequireUnpremultipliedColors()) { | 
 |  508         return NULL; | 
 |  509     } | 
 |  510     const bool dither = decoder.getDitherImage(); | 
 |  511     if (decoder.getSkipWritingZeroes()) { | 
 |  512         if (dither) { | 
 |  513             return Sample_Index_D4444_D_SkipZ; | 
 |  514         } | 
 |  515         return Sample_Index_D4444_SkipZ; | 
 |  516     } | 
 |  517     if (dither) { | 
 |  518         return Sample_Index_D4444_D; | 
 |  519     } | 
 |  520     return Sample_Index_D4444; | 
 |  521 } | 
 |  522  | 
|  277 static bool Sample_Index_DI(void* SK_RESTRICT dstRow, |  523 static bool Sample_Index_DI(void* SK_RESTRICT dstRow, | 
|  278                             const uint8_t* SK_RESTRICT src, |  524                             const uint8_t* SK_RESTRICT src, | 
|  279                             int width, int deltaSrc, int, const SkPMColor[]) { |  525                             int width, int deltaSrc, int, const SkPMColor[]) { | 
|  280     if (1 == deltaSrc) { |  526     if (1 == deltaSrc) { | 
|  281         memcpy(dstRow, src, width); |  527         memcpy(dstRow, src, width); | 
|  282     } else { |  528     } else { | 
|  283         uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow; |  529         uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow; | 
|  284         for (int x = 0; x < width; x++) { |  530         for (int x = 0; x < width; x++) { | 
|  285             dst[x] = src[0]; |  531             dst[x] = src[0]; | 
|  286             src += deltaSrc; |  532             src += deltaSrc; | 
|  287         } |  533         } | 
|  288     } |  534     } | 
|  289     return false; |  535     return false; | 
|  290 } |  536 } | 
|  291  |  537  | 
 |  538 static SkScaledBitmapSampler::RowProc get_index_to_index_proc(const SkImageDecod
     er& decoder) { | 
 |  539     // Unpremul not allowed | 
 |  540     if (decoder.getRequireUnpremultipliedColors()) { | 
 |  541         return NULL; | 
 |  542     } | 
 |  543     // Ignore dither and skip zeroes | 
 |  544     return Sample_Index_DI; | 
 |  545 } | 
 |  546  | 
|  292 // A8 |  547 // A8 | 
|  293 static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow, |  548 static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow, | 
|  294                             const uint8_t* SK_RESTRICT src, |  549                             const uint8_t* SK_RESTRICT src, | 
|  295                             int width, int deltaSrc, int, |  550                             int width, int deltaSrc, int, | 
|  296                             const SkPMColor[]) { |  551                             const SkPMColor[]) { | 
|  297     memcpy(dstRow, src, width); |  552     memcpy(dstRow, src, width); | 
|  298     return true; |  553     return true; | 
|  299 } |  554 } | 
|  300  |  555  | 
|  301 // 8888 Unpremul |  556 static SkScaledBitmapSampler::RowProc get_gray_to_A8_proc(const SkImageDecoder& 
     decoder) { | 
|  302  |  557     if (decoder.getRequireUnpremultipliedColors()) { | 
|  303 static bool Sample_Gray_D8888_Unpremul(void* SK_RESTRICT dstRow, |  558         return NULL; | 
|  304                                        const uint8_t* SK_RESTRICT src, |  | 
|  305                                        int width, int deltaSrc, int, |  | 
|  306                                        const SkPMColor[]) { |  | 
|  307     uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); |  | 
|  308     for (int x = 0; x < width; x++) { |  | 
|  309         dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[0], src[0]); |  | 
|  310         src += deltaSrc; |  | 
|  311     } |  559     } | 
|  312     return false; |  560     // Ignore skip and dither. | 
 |  561     return Sample_Gray_DA8; | 
|  313 } |  562 } | 
|  314  |  563  | 
|  315 // Sample_RGBx_D8888_Unpremul is no different from Sample_RGBx_D8888, since alph
     a |  564 typedef SkScaledBitmapSampler::RowProc (*RowProcChooser)(const SkImageDecoder& d
     ecoder); | 
|  316 // is 0xFF |  | 
|  317  |  | 
|  318 static bool Sample_RGBA_D8888_Unpremul(void* SK_RESTRICT dstRow, |  | 
|  319                                        const uint8_t* SK_RESTRICT src, |  | 
|  320                                        int width, int deltaSrc, int, |  | 
|  321                                        const SkPMColor[]) { |  | 
|  322     uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); |  | 
|  323     unsigned alphaMask = 0xFF; |  | 
|  324     for (int x = 0; x < width; x++) { |  | 
|  325         unsigned alpha = src[3]; |  | 
|  326         dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); |  | 
|  327         src += deltaSrc; |  | 
|  328         alphaMask &= alpha; |  | 
|  329     } |  | 
|  330     return alphaMask != 0xFF; |  | 
|  331 } |  | 
|  332  |  | 
|  333 // Sample_Index_D8888_Unpremul is the same as Sample_Index_D8888, since the |  | 
|  334 // color table has its colors inserted unpremultiplied. |  | 
|  335  |  | 
|  336 /////////////////////////////////////////////////////////////////////////////// |  565 /////////////////////////////////////////////////////////////////////////////// | 
|  337  |  566  | 
|  338 #include "SkScaledBitmapSampler.h" |  567 #include "SkScaledBitmapSampler.h" | 
|  339  |  568  | 
|  340 SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height, |  569 SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height, | 
|  341                                              int sampleSize) { |  570                                              int sampleSize) { | 
|  342     fCTable = NULL; |  571     fCTable = NULL; | 
|  343     fDstRow = NULL; |  572     fDstRow = NULL; | 
|  344     fRowProc = NULL; |  573     fRowProc = NULL; | 
|  345  |  574  | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|  370     SkASSERT(fX0 >= 0 && fX0 < width); |  599     SkASSERT(fX0 >= 0 && fX0 < width); | 
|  371     SkASSERT(fY0 >= 0 && fY0 < height); |  600     SkASSERT(fY0 >= 0 && fY0 < height); | 
|  372  |  601  | 
|  373     fDX = dx; |  602     fDX = dx; | 
|  374     fDY = dy; |  603     fDY = dy; | 
|  375  |  604  | 
|  376     SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width); |  605     SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width); | 
|  377     SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height); |  606     SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height); | 
|  378 } |  607 } | 
|  379  |  608  | 
|  380 bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither, |  609 bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, | 
|  381                                   const SkPMColor ctable[], |  610                                   const SkImageDecoder& decoder, | 
|  382                                   bool requireUnpremul) { |  611                                   const SkPMColor ctable[]) { | 
|  383     static const RowProc gProcs[] = { |  612     static const RowProcChooser gProcChoosers[] = { | 
|  384         // 8888 (no dither distinction) |  613         get_gray_to_8888_proc, | 
|  385         Sample_Gray_D8888,              Sample_Gray_D8888, |  614         get_RGBx_to_8888_proc, | 
|  386         Sample_RGBx_D8888,              Sample_RGBx_D8888, |  615         get_RGBA_to_8888_proc, | 
|  387         Sample_RGBA_D8888,              Sample_RGBA_D8888, |  616         get_index_to_8888_proc, | 
|  388         Sample_Index_D8888,             Sample_Index_D8888, |  617         NULL, // 565 to 8888 | 
|  389         NULL,                           NULL, |  618  | 
|  390         // 565 (no alpha distinction) |  619         get_gray_to_565_proc, | 
|  391         Sample_Gray_D565,               Sample_Gray_D565_D, |  620         get_RGBx_to_565_proc, | 
|  392         Sample_RGBx_D565,               Sample_RGBx_D565_D, |  621         get_RGBx_to_565_proc, // The source alpha will be ignored. | 
|  393         Sample_RGBx_D565,               Sample_RGBx_D565_D, |  622         get_index_to_565_proc, | 
|  394         Sample_Index_D565,              Sample_Index_D565_D, |  623         get_565_to_565_proc, | 
|  395         Sample_D565_D565,               Sample_D565_D565, |  624  | 
|  396         // 4444 |  625         get_gray_to_4444_proc, | 
|  397         Sample_Gray_D4444,              Sample_Gray_D4444_D, |  626         get_RGBx_to_4444_proc, | 
|  398         Sample_RGBx_D4444,              Sample_RGBx_D4444_D, |  627         get_RGBA_to_4444_proc, | 
|  399         Sample_RGBA_D4444,              Sample_RGBA_D4444_D, |  628         get_index_to_4444_proc, | 
|  400         Sample_Index_D4444,             Sample_Index_D4444_D, |  629         NULL, // 565 to 4444 | 
|  401         NULL,                           NULL, |  630  | 
|  402         // Index8 |  631         NULL, // gray to index | 
|  403         NULL,                           NULL, |  632         NULL, // rgbx to index | 
|  404         NULL,                           NULL, |  633         NULL, // rgba to index | 
|  405         NULL,                           NULL, |  634         get_index_to_index_proc, | 
|  406         Sample_Index_DI,                Sample_Index_DI, |  635         NULL, // 565 to index | 
|  407         NULL,                           NULL, |  636  | 
|  408         // A8 |  637         get_gray_to_A8_proc, | 
|  409         Sample_Gray_DA8,                Sample_Gray_DA8, |  638         NULL, // rgbx to a8 | 
|  410         NULL,                           NULL, |  639         NULL, // rgba to a8 | 
|  411         NULL,                           NULL, |  640         NULL, // index to a8 | 
|  412         NULL,                           NULL, |  641         NULL, // 565 to a8 | 
|  413         NULL,                           NULL, |  | 
|  414         // 8888 Unpremul (no dither distinction) |  | 
|  415         Sample_Gray_D8888_Unpremul,     Sample_Gray_D8888_Unpremul, |  | 
|  416         Sample_RGBx_D8888,              Sample_RGBx_D8888, |  | 
|  417         Sample_RGBA_D8888_Unpremul,     Sample_RGBA_D8888_Unpremul, |  | 
|  418         Sample_Index_D8888,             Sample_Index_D8888, |  | 
|  419         NULL,                           NULL, |  | 
|  420     }; |  642     }; | 
 |  643  | 
|  421     // The jump between dst configs in the table |  644     // The jump between dst configs in the table | 
|  422     static const int gProcDstConfigSpan = 10; |  645     static const int gProcDstConfigSpan = 5; | 
|  423     SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcs) == 6 * gProcDstConfigSpan, |  646     SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcChoosers) == 5 * gProcDstConfigSpan, | 
|  424                       gProcs_has_the_wrong_number_of_entries); |  647                       gProcs_has_the_wrong_number_of_entries); | 
|  425  |  648  | 
|  426     fCTable = ctable; |  649     fCTable = ctable; | 
|  427  |  650  | 
|  428     int index = 0; |  651     int index = 0; | 
|  429     if (dither) { |  | 
|  430         index += 1; |  | 
|  431     } |  | 
|  432     switch (sc) { |  652     switch (sc) { | 
|  433         case SkScaledBitmapSampler::kGray: |  653         case SkScaledBitmapSampler::kGray: | 
|  434             fSrcPixelSize = 1; |  654             fSrcPixelSize = 1; | 
|  435             index += 0; |  655             index += 0; | 
|  436             break; |  656             break; | 
|  437         case SkScaledBitmapSampler::kRGB: |  657         case SkScaledBitmapSampler::kRGB: | 
|  438             fSrcPixelSize = 3; |  658             fSrcPixelSize = 3; | 
|  439             index += 2; |  659             index += 1; | 
|  440             break; |  660             break; | 
|  441         case SkScaledBitmapSampler::kRGBX: |  661         case SkScaledBitmapSampler::kRGBX: | 
|  442             fSrcPixelSize = 4; |  662             fSrcPixelSize = 4; | 
|  443             index += 2; |  663             index += 1; | 
|  444             break; |  664             break; | 
|  445         case SkScaledBitmapSampler::kRGBA: |  665         case SkScaledBitmapSampler::kRGBA: | 
|  446             fSrcPixelSize = 4; |  666             fSrcPixelSize = 4; | 
|  447             index += 4; |  667             index += 2; | 
|  448             break; |  668             break; | 
|  449         case SkScaledBitmapSampler::kIndex: |  669         case SkScaledBitmapSampler::kIndex: | 
|  450             fSrcPixelSize = 1; |  670             fSrcPixelSize = 1; | 
|  451             index += 6; |  671             index += 3; | 
|  452             break; |  672             break; | 
|  453         case SkScaledBitmapSampler::kRGB_565: |  673         case SkScaledBitmapSampler::kRGB_565: | 
|  454             fSrcPixelSize = 2; |  674             fSrcPixelSize = 2; | 
|  455             index += 8; |  675             index += 4; | 
|  456             break; |  676             break; | 
|  457         default: |  677         default: | 
|  458             return false; |  678             return false; | 
|  459     } |  679     } | 
|  460  |  680  | 
|  461     switch (dst->config()) { |  681     switch (dst->config()) { | 
|  462         case SkBitmap::kARGB_8888_Config: |  682         case SkBitmap::kARGB_8888_Config: | 
|  463             index += 0 * gProcDstConfigSpan; |  683             index += 0 * gProcDstConfigSpan; | 
|  464             break; |  684             break; | 
|  465         case SkBitmap::kRGB_565_Config: |  685         case SkBitmap::kRGB_565_Config: | 
|  466             index += 1 * gProcDstConfigSpan; |  686             index += 1 * gProcDstConfigSpan; | 
|  467             break; |  687             break; | 
|  468         case SkBitmap::kARGB_4444_Config: |  688         case SkBitmap::kARGB_4444_Config: | 
|  469             index += 2 * gProcDstConfigSpan; |  689             index += 2 * gProcDstConfigSpan; | 
|  470             break; |  690             break; | 
|  471         case SkBitmap::kIndex8_Config: |  691         case SkBitmap::kIndex8_Config: | 
|  472             index += 3 * gProcDstConfigSpan; |  692             index += 3 * gProcDstConfigSpan; | 
|  473             break; |  693             break; | 
|  474         case SkBitmap::kA8_Config: |  694         case SkBitmap::kA8_Config: | 
|  475             index += 4 * gProcDstConfigSpan; |  695             index += 4 * gProcDstConfigSpan; | 
|  476             break; |  696             break; | 
|  477         default: |  697         default: | 
|  478             return false; |  698             return false; | 
|  479     } |  699     } | 
|  480  |  700  | 
|  481     if (requireUnpremul) { |  701     RowProcChooser chooser = gProcChoosers[index]; | 
|  482         if (dst->config() != SkBitmap::kARGB_8888_Config) { |  702     if (NULL == chooser) { | 
|  483             return false; |  703         fRowProc = NULL; | 
|  484         } |  704     } else { | 
|  485         index += 5 * gProcDstConfigSpan; |  705         fRowProc = chooser(decoder); | 
|  486     } |  706     } | 
|  487  |  | 
|  488     fRowProc = gProcs[index]; |  | 
|  489     fDstRow = (char*)dst->getPixels(); |  707     fDstRow = (char*)dst->getPixels(); | 
|  490     fDstRowBytes = dst->rowBytes(); |  708     fDstRowBytes = dst->rowBytes(); | 
|  491     fCurrY = 0; |  709     fCurrY = 0; | 
|  492     return fRowProc != NULL; |  710     return fRowProc != NULL; | 
|  493 } |  711 } | 
|  494  |  712  | 
|  495 bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) { |  713 bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) { | 
|  496     SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight); |  714     SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight); | 
|  497  |  715  | 
|  498     bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth, |  716     bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth, | 
|  499                              fDX * fSrcPixelSize, fCurrY, fCTable); |  717                              fDX * fSrcPixelSize, fCurrY, fCTable); | 
|  500     fDstRow += fDstRowBytes; |  718     fDstRow += fDstRowBytes; | 
|  501     fCurrY += 1; |  719     fCurrY += 1; | 
|  502     return hadAlpha; |  720     return hadAlpha; | 
|  503 } |  721 } | 
 |  722  | 
 |  723 #ifdef SK_DEBUG | 
 |  724 // The following code is for a test to ensure that changing the method to get th
     e right row proc | 
 |  725 // did not change the row proc unintentionally. Tested by ImageDecodingTest.cpp | 
 |  726  | 
 |  727 // friend of SkScaledBitmapSampler solely for the purpose of accessing fRowProc. | 
 |  728 class RowProcTester { | 
 |  729 public: | 
 |  730     static SkScaledBitmapSampler::RowProc getRowProc(const SkScaledBitmapSampler
     & sampler) { | 
 |  731         return sampler.fRowProc; | 
 |  732     } | 
 |  733 }; | 
 |  734  | 
 |  735  | 
 |  736 // Table showing the expected RowProc for each combination of inputs. | 
 |  737 // Table formated as follows: | 
 |  738 // Each group of 5 consecutive rows represents sampling from a single | 
 |  739 // SkScaledBitmapSampler::SrcConfig. | 
 |  740 // Within each set, each row represents a different destination SkBitmap::Config | 
 |  741 // Each column represents a different combination of dither and unpremul. | 
 |  742 // D = dither   ~D = no dither | 
 |  743 // U = unpremul ~U = no unpremul | 
 |  744 //  ~D~U                D~U                     ~DU                         DU | 
 |  745 SkScaledBitmapSampler::RowProc gTestProcs[] = { | 
 |  746     // Gray | 
 |  747     Sample_Gray_DA8,    Sample_Gray_DA8,        NULL,                       NULL
     ,                       // to A8 | 
 |  748     NULL,               NULL,                   NULL,                       NULL
     ,                       // to Index8 | 
 |  749     Sample_Gray_D565,   Sample_Gray_D565_D,     Sample_Gray_D565,           Samp
     le_Gray_D565_D,         // to 565 | 
 |  750     Sample_Gray_D4444,  Sample_Gray_D4444_D,    Sample_Gray_D4444,          Samp
     le_Gray_D4444_D,        // to 4444 | 
 |  751     Sample_Gray_D8888,  Sample_Gray_D8888,      Sample_Gray_D8888,          Samp
     le_Gray_D8888,          // to 8888 | 
 |  752     // Index | 
 |  753     NULL,               NULL,                   NULL,                       NULL
     ,                       // to A8 | 
 |  754     Sample_Index_DI,    Sample_Index_DI,        NULL,                       NULL
     ,                       // to Index8 | 
 |  755     Sample_Index_D565,  Sample_Index_D565_D,    Sample_Index_D565,          Samp
     le_Index_D565_D,        // to 565 | 
 |  756     Sample_Index_D4444, Sample_Index_D4444_D,   NULL,                       NULL
     ,                       // to 4444 | 
 |  757     Sample_Index_D8888, Sample_Index_D8888,     NULL,                       NULL
     ,                       // to 8888 | 
 |  758     // RGB | 
 |  759     NULL,               NULL,                   NULL,                       NULL
     ,                       // to A8 | 
 |  760     NULL,               NULL,                   NULL,                       NULL
     ,                       // to Index8 | 
 |  761     Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Samp
     le_RGBx_D565_D,         // to 565 | 
 |  762     Sample_RGBx_D4444,  Sample_RGBx_D4444_D,    Sample_RGBx_D4444,          Samp
     le_RGBx_D4444_D,        // to 4444 | 
 |  763     Sample_RGBx_D8888,  Sample_RGBx_D8888,      Sample_RGBx_D8888,          Samp
     le_RGBx_D8888,          // to 8888 | 
 |  764     // RGBx is the same as RGB | 
 |  765     NULL,               NULL,                   NULL,                       NULL
     ,                       // to A8 | 
 |  766     NULL,               NULL,                   NULL,                       NULL
     ,                       // to Index8 | 
 |  767     Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Samp
     le_RGBx_D565_D,         // to 565 | 
 |  768     Sample_RGBx_D4444,  Sample_RGBx_D4444_D,    Sample_RGBx_D4444,          Samp
     le_RGBx_D4444_D,        // to 4444 | 
 |  769     Sample_RGBx_D8888,  Sample_RGBx_D8888,      Sample_RGBx_D8888,          Samp
     le_RGBx_D8888,          // to 8888 | 
 |  770     // RGBA | 
 |  771     NULL,               NULL,                   NULL,                       NULL
     ,                       // to A8 | 
 |  772     NULL,               NULL,                   NULL,                       NULL
     ,                       // to Index8 | 
 |  773     Sample_RGBx_D565,   Sample_RGBx_D565_D,     Sample_RGBx_D565,           Samp
     le_RGBx_D565_D,         // to 565 | 
 |  774     Sample_RGBA_D4444,  Sample_RGBA_D4444_D,    NULL,                       NULL
     ,                       // to 4444 | 
 |  775     Sample_RGBA_D8888,  Sample_RGBA_D8888,      Sample_RGBA_D8888_Unpremul, Samp
     le_RGBA_D8888_Unpremul, // to 8888 | 
 |  776     // RGB_565 | 
 |  777     NULL,               NULL,                   NULL,                       NULL
     ,                       // to A8 | 
 |  778     NULL,               NULL,                   NULL,                       NULL
     ,                       // to Index8 | 
 |  779     Sample_D565_D565,   Sample_D565_D565,       Sample_D565_D565,           Samp
     le_D565_D565,           // to 565 | 
 |  780     NULL,               NULL,                   NULL,                       NULL
     ,                       // to 4444 | 
 |  781     NULL,               NULL,                   NULL,                       NULL
     ,                       // to 8888 | 
 |  782 }; | 
 |  783  | 
 |  784 // Dummy class that allows instantiation of an ImageDecoder, so begin can query 
     its fields. | 
 |  785 class DummyDecoder : public SkImageDecoder { | 
 |  786 public: | 
 |  787     DummyDecoder() {} | 
 |  788 protected: | 
 |  789     virtual bool onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode) SK_OVERRID
     E { | 
 |  790         return false; | 
 |  791     } | 
 |  792 }; | 
 |  793  | 
 |  794 void test_row_proc_choice() { | 
 |  795     SkBitmap dummyBitmap; | 
 |  796     DummyDecoder dummyDecoder; | 
 |  797     size_t procCounter = 0; | 
 |  798     for (int sc = SkScaledBitmapSampler::kGray; sc <= SkScaledBitmapSampler::kRG
     B_565; ++sc) { | 
 |  799         for (int c = SkBitmap::kA8_Config; c <= SkBitmap::kARGB_8888_Config; ++c
     ) { | 
 |  800             for (int unpremul = 0; unpremul <= 1; ++unpremul) { | 
 |  801                 for (int dither = 0; dither <= 1; ++dither) { | 
 |  802                     // Arbitrary width/height/sampleSize to allow SkScaledBitmap
     Sampler to | 
 |  803                     // be considered valid. | 
 |  804                     SkScaledBitmapSampler sampler(10, 10, 1); | 
 |  805                     dummyBitmap.setConfig((SkBitmap::Config) c, 10, 10); | 
 |  806                     dummyDecoder.setDitherImage(SkToBool(dither)); | 
 |  807                     dummyDecoder.setRequireUnpremultipliedColors(SkToBool(unprem
     ul)); | 
 |  808                     sampler.begin(&dummyBitmap, (SkScaledBitmapSampler::SrcConfi
     g) sc, | 
 |  809                                   dummyDecoder); | 
 |  810                     SkScaledBitmapSampler::RowProc expected = gTestProcs[procCou
     nter]; | 
 |  811                     SkScaledBitmapSampler::RowProc actual = RowProcTester::getRo
     wProc(sampler); | 
 |  812                     SkASSERT(expected == actual); | 
 |  813                     procCounter++; | 
 |  814                 } | 
 |  815             } | 
 |  816         } | 
 |  817     } | 
 |  818     SkASSERT(SK_ARRAY_COUNT(gTestProcs) == procCounter); | 
 |  819 } | 
 |  820 #endif // SK_DEBUG | 
| OLD | NEW |