• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
check_fill(skiatest::Reporter * r,const SkImageInfo & imageInfo,uint32_t startRow,uint32_t endRow,size_t rowBytes,uint32_t offset)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
DEF_TEST(SwizzlerFill,r)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 
DEF_TEST(SwizzleOpts,r)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 
DEF_TEST(PublicSwizzleOpts,r)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