Home | History | Annotate | Download | only in tests
      1 #include "Test.h"
      2 #include "SkBitmap.h"
      3 #include "SkRect.h"
      4 
      5 static const char* boolStr(bool value) {
      6     return value ? "true" : "false";
      7 }
      8 
      9 // these are in the same order as the SkBitmap::Config enum
     10 static const char* gConfigName[] = {
     11     "None", "A1", "A8", "Index8", "565", "4444", "8888", "RLE_Index8"
     12 };
     13 
     14 static void report_opaqueness(skiatest::Reporter* reporter, const SkBitmap& src,
     15                               const SkBitmap& dst) {
     16     SkString str;
     17     str.printf("src %s opaque:%d, dst %s opaque:%d",
     18                gConfigName[src.config()], src.isOpaque(),
     19                gConfigName[dst.config()], dst.isOpaque());
     20     reporter->reportFailed(str);
     21 }
     22 
     23 static bool canHaveAlpha(SkBitmap::Config config) {
     24     return config != SkBitmap::kRGB_565_Config;
     25 }
     26 
     27 // copyTo() should preserve isOpaque when it makes sense
     28 static void test_isOpaque(skiatest::Reporter* reporter, const SkBitmap& src,
     29                           SkBitmap::Config dstConfig) {
     30     SkBitmap bitmap(src);
     31     SkBitmap dst;
     32 
     33     // we need the lock so that we get a valid colorTable (when available)
     34     SkAutoLockPixels alp(bitmap);
     35     SkColorTable* ctable = bitmap.getColorTable();
     36     unsigned ctableFlags = ctable ? ctable->getFlags() : 0;
     37 
     38     if (canHaveAlpha(bitmap.config()) && canHaveAlpha(dstConfig)) {
     39         bitmap.setIsOpaque(false);
     40         if (ctable) {
     41             ctable->setFlags(ctableFlags & ~SkColorTable::kColorsAreOpaque_Flag);
     42         }
     43         REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig));
     44         REPORTER_ASSERT(reporter, dst.config() == dstConfig);
     45         if (bitmap.isOpaque() != dst.isOpaque()) {
     46             report_opaqueness(reporter, bitmap, dst);
     47         }
     48     }
     49 
     50     bitmap.setIsOpaque(true);
     51     if (ctable) {
     52         ctable->setFlags(ctableFlags | SkColorTable::kColorsAreOpaque_Flag);
     53     }
     54     REPORTER_ASSERT(reporter, bitmap.copyTo(&dst, dstConfig));
     55     REPORTER_ASSERT(reporter, dst.config() == dstConfig);
     56     if (bitmap.isOpaque() != dst.isOpaque()) {
     57         report_opaqueness(reporter, bitmap, dst);
     58     }
     59 
     60     if (ctable) {
     61         ctable->setFlags(ctableFlags);
     62     }
     63 }
     64 
     65 static void init_src(const SkBitmap& bitmap) {
     66     SkAutoLockPixels lock(bitmap);
     67     if (bitmap.getPixels()) {
     68         memset(bitmap.getPixels(), 4, bitmap.getSize());
     69     }
     70 }
     71 
     72 SkColorTable* init_ctable() {
     73     static const SkColor colors[] = {
     74         SK_ColorBLACK, SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE
     75     };
     76     return new SkColorTable(colors, SK_ARRAY_COUNT(colors));
     77 }
     78 
     79 struct Pair {
     80     SkBitmap::Config    fConfig;
     81     const char*         fValid;
     82 };
     83 
     84 static void TestBitmapCopy(skiatest::Reporter* reporter) {
     85     static const Pair gPairs[] = {
     86         { SkBitmap::kNo_Config,         "00000000"  },
     87         { SkBitmap::kA1_Config,         "01000000"  },
     88         { SkBitmap::kA8_Config,         "00101110"  },
     89         { SkBitmap::kIndex8_Config,     "00111110"  },
     90         { SkBitmap::kRGB_565_Config,    "00101110"  },
     91         { SkBitmap::kARGB_4444_Config,  "00101110"  },
     92         { SkBitmap::kARGB_8888_Config,  "00101110"  },
     93 // TODO: create valid RLE bitmap to test with
     94  //       { SkBitmap::kRLE_Index8_Config, "00101111"  }
     95     };
     96 
     97     const int W = 20;
     98     const int H = 33;
     99 
    100     for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
    101         for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) {
    102             SkBitmap src, dst;
    103             SkColorTable* ct = NULL;
    104 
    105             src.setConfig(gPairs[i].fConfig, W, H);
    106             if (SkBitmap::kIndex8_Config == src.config() ||
    107                     SkBitmap::kRLE_Index8_Config == src.config()) {
    108                 ct = init_ctable();
    109             }
    110             src.allocPixels(ct);
    111             SkSafeUnref(ct);
    112 
    113             init_src(src);
    114             bool success = src.copyTo(&dst, gPairs[j].fConfig);
    115             bool expected = gPairs[i].fValid[j] != '0';
    116             if (success != expected) {
    117                 SkString str;
    118                 str.printf("SkBitmap::copyTo from %s to %s. expected %s returned %s",
    119                            gConfigName[i], gConfigName[j], boolStr(expected),
    120                            boolStr(success));
    121                 reporter->reportFailed(str);
    122             }
    123 
    124             bool canSucceed = src.canCopyTo(gPairs[j].fConfig);
    125             if (success != canSucceed) {
    126                 SkString str;
    127                 str.printf("SkBitmap::copyTo from %s to %s. returned %s canCopyTo %s",
    128                            gConfigName[i], gConfigName[j], boolStr(success),
    129                            boolStr(canSucceed));
    130                 reporter->reportFailed(str);
    131             }
    132 
    133             if (success) {
    134                 REPORTER_ASSERT(reporter, src.width() == dst.width());
    135                 REPORTER_ASSERT(reporter, src.height() == dst.height());
    136                 REPORTER_ASSERT(reporter, dst.config() == gPairs[j].fConfig);
    137                 test_isOpaque(reporter, src, dst.config());
    138                 if (src.config() == dst.config()) {
    139                     SkAutoLockPixels srcLock(src);
    140                     SkAutoLockPixels dstLock(dst);
    141                     REPORTER_ASSERT(reporter, src.readyToDraw());
    142                     REPORTER_ASSERT(reporter, dst.readyToDraw());
    143                     const char* srcP = (const char*)src.getAddr(0, 0);
    144                     const char* dstP = (const char*)dst.getAddr(0, 0);
    145                     REPORTER_ASSERT(reporter, srcP != dstP);
    146                     REPORTER_ASSERT(reporter, !memcmp(srcP, dstP,
    147                                                       src.getSize()));
    148                 }
    149                 // test extractSubset
    150                 {
    151                     SkBitmap subset;
    152                     SkIRect r;
    153                     r.set(1, 1, 2, 2);
    154                     if (src.extractSubset(&subset, r)) {
    155                         REPORTER_ASSERT(reporter, subset.width() == 1);
    156                         REPORTER_ASSERT(reporter, subset.height() == 1);
    157 
    158                         SkBitmap copy;
    159                         REPORTER_ASSERT(reporter,
    160                                         subset.copyTo(&copy, subset.config()));
    161                         REPORTER_ASSERT(reporter, copy.width() == 1);
    162                         REPORTER_ASSERT(reporter, copy.height() == 1);
    163                         REPORTER_ASSERT(reporter, copy.rowBytes() <= 4);
    164 
    165                         SkAutoLockPixels alp0(subset);
    166                         SkAutoLockPixels alp1(copy);
    167                         // they should both have, or both not-have, a colortable
    168                         bool hasCT = subset.getColorTable() != NULL;
    169                         REPORTER_ASSERT(reporter,
    170                                     (copy.getColorTable() != NULL) == hasCT);
    171                     }
    172                 }
    173             } else {
    174                 // dst should be unchanged from its initial state
    175                 REPORTER_ASSERT(reporter, dst.config() == SkBitmap::kNo_Config);
    176                 REPORTER_ASSERT(reporter, dst.width() == 0);
    177                 REPORTER_ASSERT(reporter, dst.height() == 0);
    178             }
    179         }
    180     }
    181 }
    182 
    183 #include "TestClassDef.h"
    184 DEFINE_TESTCLASS("BitmapCopy", TestBitmapCopyClass, TestBitmapCopy)
    185