OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
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 #include "Resources.h" | 8 #include "Resources.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCodec.h" | 10 #include "SkCodec.h" |
11 #include "SkMD5.h" | 11 #include "SkMD5.h" |
| 12 #include "SkRandom.h" |
12 #include "SkScanlineDecoder.h" | 13 #include "SkScanlineDecoder.h" |
13 #include "Test.h" | 14 #include "Test.h" |
14 | 15 |
15 static SkStreamAsset* resource(const char path[]) { | 16 static SkStreamAsset* resource(const char path[]) { |
16 SkString fullPath = GetResourcePath(path); | 17 SkString fullPath = GetResourcePath(path); |
17 return SkStream::NewFromFile(fullPath.c_str()); | 18 return SkStream::NewFromFile(fullPath.c_str()); |
18 } | 19 } |
19 | 20 |
20 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) { | 21 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) { |
21 SkAutoLockPixels autoLockPixels(bm); | 22 SkAutoLockPixels autoLockPixels(bm); |
(...skipping 12 matching lines...) Expand all Loading... |
34 * @param goodDigest The known good digest to compare to. | 35 * @param goodDigest The known good digest to compare to. |
35 * @param bm The bitmap to test. | 36 * @param bm The bitmap to test. |
36 */ | 37 */ |
37 static void compare_to_good_digest(skiatest::Reporter* r, const SkMD5::Digest& g
oodDigest, | 38 static void compare_to_good_digest(skiatest::Reporter* r, const SkMD5::Digest& g
oodDigest, |
38 const SkBitmap& bm) { | 39 const SkBitmap& bm) { |
39 SkMD5::Digest digest; | 40 SkMD5::Digest digest; |
40 md5(bm, &digest); | 41 md5(bm, &digest); |
41 REPORTER_ASSERT(r, digest == goodDigest); | 42 REPORTER_ASSERT(r, digest == goodDigest); |
42 } | 43 } |
43 | 44 |
| 45 SkIRect generate_random_subset(SkRandom* rand, int w, int h) { |
| 46 SkIRect rect; |
| 47 do { |
| 48 rect.fLeft = rand->nextRangeU(0, w); |
| 49 rect.fTop = rand->nextRangeU(0, h); |
| 50 rect.fRight = rand->nextRangeU(0, w); |
| 51 rect.fBottom = rand->nextRangeU(0, h); |
| 52 rect.sort(); |
| 53 } while (rect.isEmpty()); |
| 54 return rect; |
| 55 } |
| 56 |
44 static void check(skiatest::Reporter* r, | 57 static void check(skiatest::Reporter* r, |
45 const char path[], | 58 const char path[], |
46 SkISize size, | 59 SkISize size, |
47 bool supportsScanlineDecoding) { | 60 bool supportsScanlineDecoding, |
| 61 bool supportsSubsetDecoding) { |
48 SkAutoTDelete<SkStream> stream(resource(path)); | 62 SkAutoTDelete<SkStream> stream(resource(path)); |
49 if (!stream) { | 63 if (!stream) { |
50 SkDebugf("Missing resource '%s'\n", path); | 64 SkDebugf("Missing resource '%s'\n", path); |
51 return; | 65 return; |
52 } | 66 } |
53 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 67 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); |
54 if (!codec) { | 68 if (!codec) { |
55 ERRORF(r, "Unable to decode '%s'", path); | 69 ERRORF(r, "Unable to decode '%s'", path); |
56 return; | 70 return; |
57 } | 71 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 109 |
96 for (int y = 0; y < info.height(); y++) { | 110 for (int y = 0; y < info.height(); y++) { |
97 result = scanlineDecoder->getScanlines(bm.getAddr(0, y), 1, 0); | 111 result = scanlineDecoder->getScanlines(bm.getAddr(0, y), 1, 0); |
98 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 112 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
99 } | 113 } |
100 // verify that scanline decoding gives the same result. | 114 // verify that scanline decoding gives the same result. |
101 compare_to_good_digest(r, digest, bm); | 115 compare_to_good_digest(r, digest, bm); |
102 } else { | 116 } else { |
103 REPORTER_ASSERT(r, !scanlineDecoder); | 117 REPORTER_ASSERT(r, !scanlineDecoder); |
104 } | 118 } |
| 119 |
| 120 // The rest of this function tests decoding subsets, and will decode an arbi
trary number of |
| 121 // random subsets. |
| 122 // Do not attempt to decode subsets of an image of only once pixel, since th
ere is no |
| 123 // meaningful subset. |
| 124 if (size.width() * size.height() == 1) { |
| 125 return; |
| 126 } |
| 127 |
| 128 SkRandom rand; |
| 129 SkIRect subset; |
| 130 SkCodec::Options opts; |
| 131 opts.fSubset = ⊂ |
| 132 for (int i = 0; i < 5; i++) { |
| 133 subset = generate_random_subset(&rand, size.width(), size.height()); |
| 134 SkASSERT(!subset.isEmpty()); |
| 135 const bool supported = codec->getValidSubset(&subset); |
| 136 REPORTER_ASSERT(r, supported == supportsSubsetDecoding); |
| 137 |
| 138 SkImageInfo subsetInfo = info.makeWH(subset.width(), subset.height()); |
| 139 SkBitmap bm; |
| 140 bm.allocPixels(subsetInfo); |
| 141 const SkCodec::Result result = codec->getPixels(bm.info(), bm.getPixels(
), bm.rowBytes(), |
| 142 &opts, NULL, NULL); |
| 143 |
| 144 if (supportsSubsetDecoding) { |
| 145 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
| 146 // Webp is the only codec that supports subsets, and it will have mo
dified the subset |
| 147 // to have even left/top. |
| 148 REPORTER_ASSERT(r, SkIsAlign2(subset.fLeft) && SkIsAlign2(subset.fTo
p)); |
| 149 } else { |
| 150 // No subsets will work. |
| 151 REPORTER_ASSERT(r, result == SkCodec::kUnimplemented); |
| 152 } |
| 153 } |
105 } | 154 } |
106 | 155 |
107 DEF_TEST(Codec, r) { | 156 DEF_TEST(Codec, r) { |
108 // WBMP | 157 // WBMP |
109 check(r, "mandrill.wbmp", SkISize::Make(512, 512), false); | 158 check(r, "mandrill.wbmp", SkISize::Make(512, 512), false, false); |
110 | 159 |
111 // WEBP | 160 // WEBP |
112 check(r, "baby_tux.webp", SkISize::Make(386, 395), false); | 161 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); |
113 check(r, "color_wheel.webp", SkISize::Make(128, 128), false); | 162 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); |
114 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false); | 163 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true); |
115 | 164 |
116 // BMP | 165 // BMP |
117 check(r, "randPixels.bmp", SkISize::Make(8, 8), false); | 166 check(r, "randPixels.bmp", SkISize::Make(8, 8), false, false); |
118 | 167 |
119 // ICO | 168 // ICO |
120 // These two tests examine interestingly different behavior: | 169 // These two tests examine interestingly different behavior: |
121 // Decodes an embedded BMP image | 170 // Decodes an embedded BMP image |
122 check(r, "color_wheel.ico", SkISize::Make(128, 128), false); | 171 check(r, "color_wheel.ico", SkISize::Make(128, 128), false, false); |
123 // Decodes an embedded PNG image | 172 // Decodes an embedded PNG image |
124 check(r, "google_chrome.ico", SkISize::Make(256, 256), false); | 173 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false); |
125 | 174 |
126 // GIF | 175 // GIF |
127 check(r, "box.gif", SkISize::Make(200, 55), false); | 176 check(r, "box.gif", SkISize::Make(200, 55), false, false); |
128 check(r, "color_wheel.gif", SkISize::Make(128, 128), false); | 177 check(r, "color_wheel.gif", SkISize::Make(128, 128), false, false); |
129 check(r, "randPixels.gif", SkISize::Make(8, 8), false); | 178 check(r, "randPixels.gif", SkISize::Make(8, 8), false, false); |
130 | 179 |
131 // JPG | 180 // JPG |
132 check(r, "CMYK.jpg", SkISize::Make(642, 516), true); | 181 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false); |
133 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true); | 182 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false); |
134 check(r, "grayscale.jpg", SkISize::Make(128, 128), true); | 183 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false); |
135 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true); | 184 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false); |
136 check(r, "randPixels.jpg", SkISize::Make(8, 8), true); | 185 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false); |
137 | 186 |
138 // PNG | 187 // PNG |
139 check(r, "arrow.png", SkISize::Make(187, 312), true); | 188 check(r, "arrow.png", SkISize::Make(187, 312), true, false); |
140 check(r, "baby_tux.png", SkISize::Make(240, 246), true); | 189 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false); |
141 check(r, "color_wheel.png", SkISize::Make(128, 128), true); | 190 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false); |
142 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true); | 191 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals
e); |
143 check(r, "mandrill_128.png", SkISize::Make(128, 128), true); | 192 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false); |
144 check(r, "mandrill_16.png", SkISize::Make(16, 16), true); | 193 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false); |
145 check(r, "mandrill_256.png", SkISize::Make(256, 256), true); | 194 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false); |
146 check(r, "mandrill_32.png", SkISize::Make(32, 32), true); | 195 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false); |
147 check(r, "mandrill_512.png", SkISize::Make(512, 512), true); | 196 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false); |
148 check(r, "mandrill_64.png", SkISize::Make(64, 64), true); | 197 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false); |
149 check(r, "plane.png", SkISize::Make(250, 126), true); | 198 check(r, "plane.png", SkISize::Make(250, 126), true, false); |
150 check(r, "randPixels.png", SkISize::Make(8, 8), true); | 199 check(r, "randPixels.png", SkISize::Make(8, 8), true, false); |
151 check(r, "yellow_rose.png", SkISize::Make(400, 301), true); | 200 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false); |
152 } | 201 } |
153 | 202 |
154 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_
t len) { | 203 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_
t len) { |
155 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals
e)); | 204 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals
e)); |
156 // We should not have gotten a codec. Bots should catch us if we leaked anyt
hing. | 205 // We should not have gotten a codec. Bots should catch us if we leaked anyt
hing. |
157 REPORTER_ASSERT(r, !codec); | 206 REPORTER_ASSERT(r, !codec); |
158 } | 207 } |
159 | 208 |
160 // Ensure that SkCodec::NewFromStream handles freeing the passed in SkStream, | 209 // Ensure that SkCodec::NewFromStream handles freeing the passed in SkStream, |
161 // even on failure. Test some bad streams. | 210 // even on failure. Test some bad streams. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 test_empty(r, "empty_images/zero-embedded.ico"); | 285 test_empty(r, "empty_images/zero-embedded.ico"); |
237 test_empty(r, "empty_images/zero-width.bmp"); | 286 test_empty(r, "empty_images/zero-width.bmp"); |
238 test_empty(r, "empty_images/zero-height.bmp"); | 287 test_empty(r, "empty_images/zero-height.bmp"); |
239 test_empty(r, "empty_images/zero-width.jpg"); | 288 test_empty(r, "empty_images/zero-width.jpg"); |
240 test_empty(r, "empty_images/zero-height.jpg"); | 289 test_empty(r, "empty_images/zero-height.jpg"); |
241 test_empty(r, "empty_images/zero-width.png"); | 290 test_empty(r, "empty_images/zero-width.png"); |
242 test_empty(r, "empty_images/zero-height.png"); | 291 test_empty(r, "empty_images/zero-height.png"); |
243 test_empty(r, "empty_images/zero-width.wbmp"); | 292 test_empty(r, "empty_images/zero-width.wbmp"); |
244 test_empty(r, "empty_images/zero-height.wbmp"); | 293 test_empty(r, "empty_images/zero-height.wbmp"); |
245 } | 294 } |
OLD | NEW |