Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2015 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkImageInfoPriv.h"
      9 #include "SkSwizzle.h"
     10 #include "SkSwizzler.h"
     11 #include "Test.h"
     12 #include "SkOpts.h"
     13 
     14 static void check_fill(skiatest::Reporter* r,
     15                        const SkImageInfo& imageInfo,
     16                        uint32_t startRow,
     17                        uint32_t endRow,
     18                        size_t rowBytes,
     19                        uint32_t offset) {
     20 
     21     // Calculate the total size of the image in bytes.  Use the smallest possible size.
     22     // The offset value tells us to adjust the pointer from the memory we allocate in order
     23     // to test on different memory alignments.  If offset is nonzero, we need to increase the
     24     // size of the memory we allocate in order to make sure that we have enough.  We are
     25     // still allocating the smallest possible size.
     26     const size_t totalBytes = imageInfo.computeByteSize(rowBytes) + offset;
     27 
     28     // Create fake image data where every byte has a value of 0
     29     std::unique_ptr<uint8_t[]> storage(new uint8_t[totalBytes]);
     30     memset(storage.get(), 0, totalBytes);
     31     // Adjust the pointer in order to test on different memory alignments
     32     uint8_t* imageData = storage.get() + offset;
     33     uint8_t* imageStart = imageData + rowBytes * startRow;
     34     const SkImageInfo fillInfo = imageInfo.makeWH(imageInfo.width(), endRow - startRow + 1);
     35     SkSampler::Fill(fillInfo, imageStart, rowBytes, SkCodec::kNo_ZeroInitialized);
     36 
     37     // Ensure that the pixels are filled properly
     38     // The bots should catch any memory corruption
     39     uint8_t* indexPtr = imageData + startRow * rowBytes;
     40     uint8_t* grayPtr = indexPtr;
     41     uint32_t* colorPtr = (uint32_t*) indexPtr;
     42     uint16_t* color565Ptr = (uint16_t*) indexPtr;
     43     for (uint32_t y = startRow; y <= endRow; y++) {
     44         for (int32_t x = 0; x < imageInfo.width(); x++) {
     45             switch (imageInfo.colorType()) {
     46                 case kN32_SkColorType:
     47                     REPORTER_ASSERT(r, 0 == colorPtr[x]);
     48                     break;
     49                 case kGray_8_SkColorType:
     50                     REPORTER_ASSERT(r, 0 == grayPtr[x]);
     51                     break;
     52                 case kRGB_565_SkColorType:
     53                     REPORTER_ASSERT(r, 0 == color565Ptr[x]);
     54                     break;
     55                 default:
     56                     REPORTER_ASSERT(r, false);
     57                     break;
     58             }
     59         }
     60         indexPtr += rowBytes;
     61         colorPtr = (uint32_t*) indexPtr;
     62     }
     63 }
     64 
     65 // Test Fill() with different combinations of dimensions, alignment, and padding
     66 DEF_TEST(SwizzlerFill, r) {
     67     // Test on an invalid width and representative widths
     68     const uint32_t widths[] = { 0, 10, 50 };
     69 
     70     // In order to call Fill(), there must be at least one row to fill
     71     // Test on the smallest possible height and representative heights
     72     const uint32_t heights[] = { 1, 5, 10 };
     73 
     74     // Test on interesting possibilities for row padding
     75     const uint32_t paddings[] = { 0, 4 };
     76 
     77     // Iterate over test dimensions
     78     for (uint32_t width : widths) {
     79         for (uint32_t height : heights) {
     80 
     81             // Create image info objects
     82             const SkImageInfo colorInfo = SkImageInfo::MakeN32(width, height, kUnknown_SkAlphaType);
     83             const SkImageInfo grayInfo = colorInfo.makeColorType(kGray_8_SkColorType);
     84             const SkImageInfo color565Info = colorInfo.makeColorType(kRGB_565_SkColorType);
     85 
     86             for (uint32_t padding : paddings) {
     87 
     88                 // Calculate row bytes
     89                 const size_t colorRowBytes = SkColorTypeBytesPerPixel(kN32_SkColorType) * width
     90                         + padding;
     91                 const size_t indexRowBytes = width + padding;
     92                 const size_t grayRowBytes = indexRowBytes;
     93                 const size_t color565RowBytes =
     94                         SkColorTypeBytesPerPixel(kRGB_565_SkColorType) * width + padding;
     95 
     96                 // If there is padding, we can invent an offset to change the memory alignment
     97                 for (uint32_t offset = 0; offset <= padding; offset += 4) {
     98 
     99                     // Test all possible start rows with all possible end rows
    100                     for (uint32_t startRow = 0; startRow < height; startRow++) {
    101                         for (uint32_t endRow = startRow; endRow < height; endRow++) {
    102 
    103                             // Test fill with each color type
    104                             check_fill(r, colorInfo, startRow, endRow, colorRowBytes, offset);
    105                             check_fill(r, grayInfo, startRow, endRow, grayRowBytes, offset);
    106                             check_fill(r, color565Info, startRow, endRow, color565RowBytes, offset);
    107                         }
    108                     }
    109                 }
    110             }
    111         }
    112     }
    113 }
    114 
    115 DEF_TEST(SwizzleOpts, r) {
    116     uint32_t dst, src;
    117 
    118     // forall c, c*255 == c, c*0 == 0
    119     for (int c = 0; c <= 255; c++) {
    120         src = (255<<24) | c;
    121         SkOpts::RGBA_to_rgbA(&dst, &src, 1);
    122         REPORTER_ASSERT(r, dst == src);
    123         SkOpts::RGBA_to_bgrA(&dst, &src, 1);
    124         REPORTER_ASSERT(r, dst == (uint32_t)((255<<24) | (c<<16)));
    125 
    126         src = (0<<24) | c;
    127         SkOpts::RGBA_to_rgbA(&dst, &src, 1);
    128         REPORTER_ASSERT(r, dst == 0);
    129         SkOpts::RGBA_to_bgrA(&dst, &src, 1);
    130         REPORTER_ASSERT(r, dst == 0);
    131     }
    132 
    133     // check a totally arbitrary color
    134     src = 0xFACEB004;
    135     SkOpts::RGBA_to_rgbA(&dst, &src, 1);
    136     REPORTER_ASSERT(r, dst == 0xFACAAD04);
    137 
    138     // swap red and blue
    139     SkOpts::RGBA_to_BGRA(&dst, &src, 1);
    140     REPORTER_ASSERT(r, dst == 0xFA04B0CE);
    141 
    142     // all together now
    143     SkOpts::RGBA_to_bgrA(&dst, &src, 1);
    144     REPORTER_ASSERT(r, dst == 0xFA04ADCA);
    145 }
    146 
    147 DEF_TEST(PublicSwizzleOpts, r) {
    148     uint32_t dst, src;
    149 
    150     // check a totally arbitrary color
    151     src = 0xFACEB004;
    152     SkSwapRB(&dst, &src, 1);
    153     REPORTER_ASSERT(r, dst == 0xFA04B0CE);
    154 }
    155