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 // If either dimension is zero, we will not be able to return a non-empty | |
47 // rectangle, resulting in an infinite loop. | |
48 SkASSERT(w > 1 && h > 1); | |
emmaleer
2015/07/21 15:24:55
Should this be SkASSERT(w > 0 && h > 0) ?
Since th
scroggo
2015/07/21 16:48:56
Ah, I meant either dimension of rect, down below,
| |
49 | |
50 SkIRect rect; | |
51 do { | |
52 rect.fLeft = rand->nextULessThan(w); | |
53 rect.fTop = rand->nextULessThan(h); | |
54 rect.fRight = rand->nextULessThan(w); | |
55 rect.fBottom = rand->nextULessThan(h); | |
56 rect.sort(); | |
57 } while (rect.isEmpty()); | |
58 return rect; | |
59 } | |
60 | |
44 static void check(skiatest::Reporter* r, | 61 static void check(skiatest::Reporter* r, |
45 const char path[], | 62 const char path[], |
46 SkISize size, | 63 SkISize size, |
47 bool supportsScanlineDecoding) { | 64 bool supportsScanlineDecoding, |
65 bool supportsSubsetDecoding) { | |
48 SkAutoTDelete<SkStream> stream(resource(path)); | 66 SkAutoTDelete<SkStream> stream(resource(path)); |
49 if (!stream) { | 67 if (!stream) { |
50 SkDebugf("Missing resource '%s'\n", path); | 68 SkDebugf("Missing resource '%s'\n", path); |
51 return; | 69 return; |
52 } | 70 } |
53 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 71 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); |
54 if (!codec) { | 72 if (!codec) { |
55 ERRORF(r, "Unable to decode '%s'", path); | 73 ERRORF(r, "Unable to decode '%s'", path); |
56 return; | 74 return; |
57 } | 75 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 | 113 |
96 for (int y = 0; y < info.height(); y++) { | 114 for (int y = 0; y < info.height(); y++) { |
97 result = scanlineDecoder->getScanlines(bm.getAddr(0, y), 1, 0); | 115 result = scanlineDecoder->getScanlines(bm.getAddr(0, y), 1, 0); |
98 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 116 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
99 } | 117 } |
100 // verify that scanline decoding gives the same result. | 118 // verify that scanline decoding gives the same result. |
101 compare_to_good_digest(r, digest, bm); | 119 compare_to_good_digest(r, digest, bm); |
102 } else { | 120 } else { |
103 REPORTER_ASSERT(r, !scanlineDecoder); | 121 REPORTER_ASSERT(r, !scanlineDecoder); |
104 } | 122 } |
123 | |
124 // Do not attempt to decode subsets of an image with a width and/or height o f 1. | |
emmaleer
2015/07/21 15:24:55
Why are we not attempting to decode subsets with a
scroggo
2015/07/21 16:48:56
Originally, I did not attempt to decode subsets of
| |
125 if (size.width() == 1 || size.height() == 1) { | |
126 return; | |
127 } | |
128 | |
129 // Test decoding subsets. Decode an arbitrary number of random subsets. | |
130 SkRandom rand; | |
131 for (int i = 0; i < 5; i++) { | |
132 SkCodec::Options opts; | |
133 opts.fSubset = generate_random_subset(&rand, size.width(), size.height() ); | |
134 SkASSERT(!opts.fSubset.isEmpty()); | |
135 const bool supported = codec->getValidSubset(&opts.fSubset); | |
136 REPORTER_ASSERT(r, supported == supportsSubsetDecoding); | |
137 | |
138 SkImageInfo subsetInfo = info.makeWH(opts.fSubset.width(), opts.fSubset. 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(opts.fSubset.fLeft) && SkIsAlign2(opts .fSubset.fTop)); | |
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 |