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 "SkData.h" |
11 #include "SkMD5.h" | 12 #include "SkMD5.h" |
12 #include "SkRandom.h" | 13 #include "SkRandom.h" |
13 #include "SkScaledCodec.h" | 14 #include "SkScaledCodec.h" |
14 #include "Test.h" | 15 #include "Test.h" |
15 | 16 |
16 static SkStreamAsset* resource(const char path[]) { | 17 static SkStreamAsset* resource(const char path[]) { |
17 SkString fullPath = GetResourcePath(path); | 18 SkString fullPath = GetResourcePath(path); |
18 return SkStream::NewFromFile(fullPath.c_str()); | 19 return SkStream::NewFromFile(fullPath.c_str()); |
19 } | 20 } |
20 | 21 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 rect.fLeft = rand->nextRangeU(0, w); | 69 rect.fLeft = rand->nextRangeU(0, w); |
69 rect.fTop = rand->nextRangeU(0, h); | 70 rect.fTop = rand->nextRangeU(0, h); |
70 rect.fRight = rand->nextRangeU(0, w); | 71 rect.fRight = rand->nextRangeU(0, w); |
71 rect.fBottom = rand->nextRangeU(0, h); | 72 rect.fBottom = rand->nextRangeU(0, h); |
72 rect.sort(); | 73 rect.sort(); |
73 } while (rect.isEmpty()); | 74 } while (rect.isEmpty()); |
74 return rect; | 75 return rect; |
75 } | 76 } |
76 | 77 |
77 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons
t SkImageInfo& info, | 78 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons
t SkImageInfo& info, |
78 const SkISize& size, bool supports565, SkMD5::Digest* digest, | 79 const SkISize& size, bool supports565, SkCodec::Result expectedResult, |
79 const SkMD5::Digest* goodDigest) { | 80 SkMD5::Digest* digest, const SkMD5::Digest* goodDigest) { |
| 81 |
80 REPORTER_ASSERT(r, info.dimensions() == size); | 82 REPORTER_ASSERT(r, info.dimensions() == size); |
81 bm.allocPixels(info); | 83 bm.allocPixels(info); |
82 SkAutoLockPixels autoLockPixels(bm); | 84 SkAutoLockPixels autoLockPixels(bm); |
83 | 85 |
84 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(
)); | 86 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(
)); |
85 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 87 REPORTER_ASSERT(r, result == expectedResult); |
86 | 88 |
87 md5(bm, digest); | 89 md5(bm, digest); |
88 if (goodDigest) { | 90 if (goodDigest) { |
89 REPORTER_ASSERT(r, *digest == *goodDigest); | 91 REPORTER_ASSERT(r, *digest == *goodDigest); |
90 } | 92 } |
91 | 93 |
92 { | 94 { |
93 // Test decoding to 565 | 95 // Test decoding to 565 |
94 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); | 96 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); |
95 SkCodec::Result expected = (supports565 && info.alphaType() == kOpaque_S
kAlphaType) ? | 97 SkCodec::Result expected565 = (supports565 && info.alphaType() == kOpaqu
e_SkAlphaType) ? |
96 SkCodec::kSuccess : SkCodec::kInvalidConversion; | 98 expectedResult : SkCodec::kInvalidConversion; |
97 test_info(r, codec, info565, expected, nullptr); | 99 test_info(r, codec, info565, expected565, nullptr); |
98 } | 100 } |
99 | 101 |
100 // Verify that re-decoding gives the same result. It is interesting to chec
k this after | 102 // Verify that re-decoding gives the same result. It is interesting to chec
k this after |
101 // a decode to 565, since choosing to decode to 565 may result in some of th
e decode | 103 // a decode to 565, since choosing to decode to 565 may result in some of th
e decode |
102 // options being modified. These options should return to their defaults on
another | 104 // options being modified. These options should return to their defaults on
another |
103 // decode to kN32, so the new digest should match the old digest. | 105 // decode to kN32, so the new digest should match the old digest. |
104 test_info(r, codec, info, SkCodec::kSuccess, digest); | 106 test_info(r, codec, info, expectedResult, digest); |
105 | 107 |
106 { | 108 { |
107 // Check alpha type conversions | 109 // Check alpha type conversions |
108 if (info.alphaType() == kOpaque_SkAlphaType) { | 110 if (info.alphaType() == kOpaque_SkAlphaType) { |
109 test_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType), | 111 test_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType), |
110 SkCodec::kInvalidConversion, nullptr); | 112 SkCodec::kInvalidConversion, nullptr); |
111 test_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType), | 113 test_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType), |
112 SkCodec::kInvalidConversion, nullptr); | 114 SkCodec::kInvalidConversion, nullptr); |
113 } else { | 115 } else { |
114 // Decoding to opaque should fail | 116 // Decoding to opaque should fail |
115 test_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType), | 117 test_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType), |
116 SkCodec::kInvalidConversion, nullptr); | 118 SkCodec::kInvalidConversion, nullptr); |
117 SkAlphaType otherAt = info.alphaType(); | 119 SkAlphaType otherAt = info.alphaType(); |
118 if (kPremul_SkAlphaType == otherAt) { | 120 if (kPremul_SkAlphaType == otherAt) { |
119 otherAt = kUnpremul_SkAlphaType; | 121 otherAt = kUnpremul_SkAlphaType; |
120 } else { | 122 } else { |
121 otherAt = kPremul_SkAlphaType; | 123 otherAt = kPremul_SkAlphaType; |
122 } | 124 } |
123 // The other non-opaque alpha type should always succeed, but not ma
tch. | 125 // The other non-opaque alpha type should always succeed, but not ma
tch. |
124 test_info(r, codec, info.makeAlphaType(otherAt), SkCodec::kSuccess,
nullptr); | 126 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul
lptr); |
125 } | 127 } |
126 } | 128 } |
127 } | 129 } |
128 | 130 |
129 static void check(skiatest::Reporter* r, | 131 static void check(skiatest::Reporter* r, |
130 const char path[], | 132 const char path[], |
131 SkISize size, | 133 SkISize size, |
132 bool supportsScanlineDecoding, | 134 bool supportsScanlineDecoding, |
133 bool supportsSubsetDecoding, | 135 bool supportsSubsetDecoding, |
134 bool supports565 = true) { | 136 bool supports565 = true, |
| 137 bool supportsIncomplete = true) { |
135 | 138 |
136 SkAutoTDelete<SkStream> stream(resource(path)); | 139 SkAutoTDelete<SkStream> stream(resource(path)); |
137 if (!stream) { | 140 if (!stream) { |
138 SkDebugf("Missing resource '%s'\n", path); | 141 SkDebugf("Missing resource '%s'\n", path); |
139 return; | 142 return; |
140 } | 143 } |
141 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 144 |
| 145 SkAutoTDelete<SkCodec> codec(nullptr); |
| 146 bool isIncomplete = supportsIncomplete; |
| 147 if (isIncomplete) { |
| 148 size_t size = stream->getLength(); |
| 149 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)))
; |
| 150 codec.reset(SkCodec::NewFromData(data)); |
| 151 } else { |
| 152 codec.reset(SkCodec::NewFromStream(stream.detach())); |
| 153 } |
142 if (!codec) { | 154 if (!codec) { |
143 ERRORF(r, "Unable to decode '%s'", path); | 155 ERRORF(r, "Unable to decode '%s'", path); |
144 return; | 156 return; |
145 } | 157 } |
146 | 158 |
147 // Test full image decodes with SkCodec | 159 // Test full image decodes with SkCodec |
148 SkMD5::Digest codecDigest; | 160 SkMD5::Digest codecDigest; |
149 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); | 161 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); |
150 SkBitmap bm; | 162 SkBitmap bm; |
151 test_codec(r, codec, bm, info, size, supports565, &codecDigest, nullptr); | 163 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput :
SkCodec::kSuccess; |
| 164 test_codec(r, codec, bm, info, size, supports565, expectedResult, &codecDige
st, nullptr); |
152 | 165 |
153 // Scanline decoding follows. | 166 // Scanline decoding follows. |
154 // Need to call startScanlineDecode() first. | 167 // Need to call startScanlineDecode() first. |
155 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | 168 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) |
156 == SkCodec::kScanlineDecodingNotStarted); | 169 == 0); |
157 REPORTER_ASSERT(r, codec->skipScanlines(1) | 170 REPORTER_ASSERT(r, codec->skipScanlines(1) |
158 == SkCodec::kScanlineDecodingNotStarted); | 171 == 0); |
159 | 172 |
160 const SkCodec::Result startResult = codec->startScanlineDecode(info); | 173 const SkCodec::Result startResult = codec->startScanlineDecode(info); |
161 if (supportsScanlineDecoding) { | 174 if (supportsScanlineDecoding) { |
162 bm.eraseColor(SK_ColorYELLOW); | 175 bm.eraseColor(SK_ColorYELLOW); |
163 | 176 |
164 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess); | 177 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess); |
165 | 178 |
166 for (int y = 0; y < info.height(); y++) { | 179 for (int y = 0; y < info.height(); y++) { |
167 SkCodec::Result result = codec->getScanlines(bm.getAddr(0, y), 1, 0)
; | 180 const int lines = codec->getScanlines(bm.getAddr(0, y), 1, 0); |
168 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 181 if (!isIncomplete) { |
| 182 REPORTER_ASSERT(r, 1 == lines); |
| 183 } |
169 } | 184 } |
170 // verify that scanline decoding gives the same result. | 185 // verify that scanline decoding gives the same result. |
171 if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) { | 186 if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) { |
172 compare_to_good_digest(r, codecDigest, bm); | 187 compare_to_good_digest(r, codecDigest, bm); |
173 } | 188 } |
174 | 189 |
175 // Cannot continue to decode scanlines beyond the end | 190 // Cannot continue to decode scanlines beyond the end |
176 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | 191 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) |
177 == SkCodec::kInvalidParameters); | 192 == 0); |
178 | 193 |
179 // Interrupting a scanline decode with a full decode starts from | 194 // Interrupting a scanline decode with a full decode starts from |
180 // scratch | 195 // scratch |
181 REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess
); | 196 REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess
); |
| 197 const int lines = codec->getScanlines(bm.getAddr(0, 0), 1, 0); |
| 198 if (!isIncomplete) { |
| 199 REPORTER_ASSERT(r, lines == 1); |
| 200 } |
| 201 REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowByt
es()) |
| 202 == expectedResult); |
182 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | 203 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) |
183 == SkCodec::kSuccess); | 204 == 0); |
184 REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowByt
es()) | |
185 == SkCodec::kSuccess); | |
186 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | |
187 == SkCodec::kScanlineDecodingNotStarted); | |
188 REPORTER_ASSERT(r, codec->skipScanlines(1) | 205 REPORTER_ASSERT(r, codec->skipScanlines(1) |
189 == SkCodec::kScanlineDecodingNotStarted); | 206 == 0); |
190 } else { | 207 } else { |
191 REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented); | 208 REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented); |
192 } | 209 } |
193 | 210 |
194 // The rest of this function tests decoding subsets, and will decode an arbi
trary number of | 211 // The rest of this function tests decoding subsets, and will decode an arbi
trary number of |
195 // random subsets. | 212 // random subsets. |
196 // Do not attempt to decode subsets of an image of only once pixel, since th
ere is no | 213 // Do not attempt to decode subsets of an image of only once pixel, since th
ere is no |
197 // meaningful subset. | 214 // meaningful subset. |
198 if (size.width() * size.height() == 1) { | 215 if (size.width() * size.height() == 1) { |
199 return; | 216 return; |
200 } | 217 } |
201 | 218 |
202 SkRandom rand; | 219 SkRandom rand; |
203 SkIRect subset; | 220 SkIRect subset; |
204 SkCodec::Options opts; | 221 SkCodec::Options opts; |
205 opts.fSubset = ⊂ | 222 opts.fSubset = ⊂ |
206 for (int i = 0; i < 5; i++) { | 223 for (int i = 0; i < 5; i++) { |
207 subset = generate_random_subset(&rand, size.width(), size.height()); | 224 subset = generate_random_subset(&rand, size.width(), size.height()); |
208 SkASSERT(!subset.isEmpty()); | 225 SkASSERT(!subset.isEmpty()); |
209 const bool supported = codec->getValidSubset(&subset); | 226 const bool supported = codec->getValidSubset(&subset); |
210 REPORTER_ASSERT(r, supported == supportsSubsetDecoding); | 227 REPORTER_ASSERT(r, supported == supportsSubsetDecoding); |
211 | 228 |
212 SkImageInfo subsetInfo = info.makeWH(subset.width(), subset.height()); | 229 SkImageInfo subsetInfo = info.makeWH(subset.width(), subset.height()); |
213 SkBitmap bm; | 230 SkBitmap bm; |
214 bm.allocPixels(subsetInfo); | 231 bm.allocPixels(subsetInfo); |
215 const SkCodec::Result result = codec->getPixels(bm.info(), bm.getPixels(
), bm.rowBytes(), | 232 const SkCodec::Result result = codec->getPixels(bm.info(), bm.getPixels(
), bm.rowBytes(), |
216 &opts, nullptr, nullptr)
; | 233 &opts, nullptr, nullptr)
; |
217 | 234 |
218 if (supportsSubsetDecoding) { | 235 if (supportsSubsetDecoding) { |
219 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 236 REPORTER_ASSERT(r, result == expectedResult); |
220 // Webp is the only codec that supports subsets, and it will have mo
dified the subset | 237 // Webp is the only codec that supports subsets, and it will have mo
dified the subset |
221 // to have even left/top. | 238 // to have even left/top. |
222 REPORTER_ASSERT(r, SkIsAlign2(subset.fLeft) && SkIsAlign2(subset.fTo
p)); | 239 REPORTER_ASSERT(r, SkIsAlign2(subset.fLeft) && SkIsAlign2(subset.fTo
p)); |
223 } else { | 240 } else { |
224 // No subsets will work. | 241 // No subsets will work. |
225 REPORTER_ASSERT(r, result == SkCodec::kUnimplemented); | 242 REPORTER_ASSERT(r, result == SkCodec::kUnimplemented); |
226 } | 243 } |
227 } | 244 } |
228 | 245 |
229 // SkScaledCodec tests | 246 // SkScaledCodec tests |
230 if (supportsScanlineDecoding || supportsSubsetDecoding){ | 247 if (supportsScanlineDecoding || supportsSubsetDecoding){ |
231 SkAutoTDelete<SkStream> stream(resource(path)); | 248 SkAutoTDelete<SkStream> stream(resource(path)); |
232 if (!stream) { | 249 if (!stream) { |
233 SkDebugf("Missing resource '%s'\n", path); | 250 SkDebugf("Missing resource '%s'\n", path); |
234 return; | 251 return; |
235 } | 252 } |
236 SkAutoTDelete<SkCodec> codec(SkScaledCodec::NewFromStream(stream.detach(
))); | 253 |
| 254 SkAutoTDelete<SkCodec> codec(nullptr); |
| 255 if (isIncomplete) { |
| 256 size_t size = stream->getLength(); |
| 257 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size /
3))); |
| 258 codec.reset(SkScaledCodec::NewFromData(data)); |
| 259 } else { |
| 260 codec.reset(SkScaledCodec::NewFromStream(stream.detach())); |
| 261 } |
237 if (!codec) { | 262 if (!codec) { |
238 ERRORF(r, "Unable to decode '%s'", path); | 263 ERRORF(r, "Unable to decode '%s'", path); |
239 return; | 264 return; |
240 } | 265 } |
241 | 266 |
242 SkBitmap bm; | 267 SkBitmap bm; |
243 SkMD5::Digest scaledCodecDigest; | 268 SkMD5::Digest scaledCodecDigest; |
244 test_codec(r, codec, bm, info, size, supports565, &scaledCodecDigest, &c
odecDigest); | 269 test_codec(r, codec, bm, info, size, supports565, expectedResult, &scale
dCodecDigest, |
| 270 &codecDigest); |
| 271 } |
| 272 |
| 273 // If we've just tested incomplete decodes, let's run the same test again on
full decodes. |
| 274 if (isIncomplete) { |
| 275 check(r, path, size, supportsScanlineDecoding, supportsSubsetDecoding, s
upports565, false); |
245 } | 276 } |
246 } | 277 } |
247 | 278 |
248 DEF_TEST(Codec, r) { | 279 DEF_TEST(Codec, r) { |
249 // WBMP | 280 // WBMP |
250 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false); | 281 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false); |
251 | 282 |
252 // WEBP | 283 // WEBP |
253 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); | 284 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); |
254 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); | 285 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); |
255 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true); | 286 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true); |
256 | 287 |
257 // BMP | 288 // BMP |
258 check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false); | 289 check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false); |
259 | 290 |
260 // ICO | 291 // ICO |
| 292 // FIXME: We are not ready to test incomplete ICOs |
261 // These two tests examine interestingly different behavior: | 293 // These two tests examine interestingly different behavior: |
262 // Decodes an embedded BMP image | 294 // Decodes an embedded BMP image |
263 check(r, "color_wheel.ico", SkISize::Make(128, 128), false, false); | 295 check(r, "color_wheel.ico", SkISize::Make(128, 128), false, false, true, fal
se); |
264 // Decodes an embedded PNG image | 296 // Decodes an embedded PNG image |
265 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false); | 297 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, true, f
alse); |
266 | 298 |
267 // GIF | 299 // GIF |
268 check(r, "box.gif", SkISize::Make(200, 55), true, false); | 300 // FIXME: We are not ready to test incomplete GIFs |
269 check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false); | 301 check(r, "box.gif", SkISize::Make(200, 55), true, false, true, false); |
270 check(r, "randPixels.gif", SkISize::Make(8, 8), true, false); | 302 check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false, true, fals
e); |
| 303 // randPixels.gif is too small to test incomplete |
| 304 check(r, "randPixels.gif", SkISize::Make(8, 8), true, false, true, false); |
271 | 305 |
272 // JPG | 306 // JPG |
273 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, false); | 307 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, false); |
274 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false); | 308 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false); |
275 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false); | 309 // grayscale.jpg is too small to test incomplete |
| 310 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false, true, false)
; |
276 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false); | 311 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false); |
277 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false); | 312 // randPixels.jpg is too small to test incomplete |
| 313 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false, true, false); |
278 | 314 |
279 // PNG | 315 // PNG |
280 check(r, "arrow.png", SkISize::Make(187, 312), true, false); | 316 check(r, "arrow.png", SkISize::Make(187, 312), true, false, true, false); |
281 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false); | 317 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false, true, false); |
282 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false); | 318 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false, true, fals
e); |
283 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals
e); | 319 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals
e, true, false); |
284 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false); | 320 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false, true, fal
se); |
285 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false); | 321 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false, true, false)
; |
286 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false); | 322 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false, true, fal
se); |
287 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false); | 323 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false, true, false)
; |
288 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false); | 324 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false, true, fal
se); |
289 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false); | 325 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false, true, false)
; |
290 check(r, "plane.png", SkISize::Make(250, 126), true, false); | 326 check(r, "plane.png", SkISize::Make(250, 126), true, false, true, false); |
291 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false); | 327 // FIXME: We are not ready to test incomplete interlaced pngs |
292 check(r, "randPixels.png", SkISize::Make(8, 8), true, false); | 328 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false, true,
false); |
293 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false); | 329 check(r, "randPixels.png", SkISize::Make(8, 8), true, false, true, false); |
| 330 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false, true, fals
e); |
294 } | 331 } |
295 | 332 |
296 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode | 333 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode |
297 DEF_TEST(Codec_stripes, r) { | 334 DEF_TEST(Codec_stripes, r) { |
298 const char * path = "plane_interlaced.png"; | 335 const char * path = "plane_interlaced.png"; |
299 SkAutoTDelete<SkStream> stream(resource(path)); | 336 SkAutoTDelete<SkStream> stream(resource(path)); |
300 if (!stream) { | 337 if (!stream) { |
301 SkDebugf("Missing resource '%s'\n", path); | 338 SkDebugf("Missing resource '%s'\n", path); |
302 } | 339 } |
303 | 340 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 SkTDivMod(height, numStripes, &stripeHeight, &remainingLines); | 374 SkTDivMod(height, numStripes, &stripeHeight, &remainingLines); |
338 | 375 |
339 bm.eraseColor(SK_ColorYELLOW); | 376 bm.eraseColor(SK_ColorYELLOW); |
340 | 377 |
341 result = codec->startScanlineDecode(info); | 378 result = codec->startScanlineDecode(info); |
342 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 379 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
343 | 380 |
344 // Odd stripes | 381 // Odd stripes |
345 for (int i = 1; i < numStripes; i += 2) { | 382 for (int i = 1; i < numStripes; i += 2) { |
346 // Skip the even stripes | 383 // Skip the even stripes |
347 result = codec->skipScanlines(stripeHeight); | 384 bool skipResult = codec->skipScanlines(stripeHeight); |
348 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 385 REPORTER_ASSERT(r, skipResult); |
349 | 386 |
350 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig
ht, | 387 int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight),
stripeHeight, |
351 bm.rowBytes()); | 388 bm.rowBytes()); |
352 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 389 REPORTER_ASSERT(r, linesDecoded == stripeHeight); |
353 } | 390 } |
354 | 391 |
355 // Even stripes | 392 // Even stripes |
356 result = codec->startScanlineDecode(info); | 393 result = codec->startScanlineDecode(info); |
357 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 394 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
358 | 395 |
359 for (int i = 0; i < numStripes; i += 2) { | 396 for (int i = 0; i < numStripes; i += 2) { |
360 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig
ht, | 397 int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight),
stripeHeight, |
361 bm.rowBytes()); | 398 bm.rowBytes()); |
362 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 399 REPORTER_ASSERT(r, linesDecoded == stripeHeight); |
363 | 400 |
364 // Skip the odd stripes | 401 // Skip the odd stripes |
365 if (i + 1 < numStripes) { | 402 if (i + 1 < numStripes) { |
366 result = codec->skipScanlines(stripeHeight); | 403 bool skipResult = codec->skipScanlines(stripeHeight); |
367 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 404 REPORTER_ASSERT(r, skipResult); |
368 } | 405 } |
369 } | 406 } |
370 | 407 |
371 // Remainder at the end | 408 // Remainder at the end |
372 if (remainingLines > 0) { | 409 if (remainingLines > 0) { |
373 result = codec->startScanlineDecode(info); | 410 result = codec->startScanlineDecode(info); |
374 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 411 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
375 | 412 |
376 result = codec->skipScanlines(height - remainingLines); | 413 bool skipResult = codec->skipScanlines(height - remainingLines); |
377 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 414 REPORTER_ASSERT(r, skipResult); |
378 | 415 |
379 result = codec->getScanlines(bm.getAddr(0, height - remainingLines), | 416 int linesDecoded = codec->getScanlines(bm.getAddr(0, height - remainingL
ines), |
380 remainingLines, bm.rowBytes()); | 417 remainingLines, bm.rowBytes()); |
381 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 418 REPORTER_ASSERT(r, linesDecoded == remainingLines); |
382 } | 419 } |
383 | 420 |
384 compare_to_good_digest(r, digest, bm); | 421 compare_to_good_digest(r, digest, bm); |
385 } | 422 } |
386 | 423 |
387 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_
t len) { | 424 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_
t len) { |
388 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals
e)); | 425 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals
e)); |
389 // We should not have gotten a codec. Bots should catch us if we leaked anyt
hing. | 426 // We should not have gotten a codec. Bots should catch us if we leaked anyt
hing. |
390 REPORTER_ASSERT(r, !codec); | 427 REPORTER_ASSERT(r, !codec); |
391 } | 428 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); | 559 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); |
523 result = decoder->startScanlineDecode( | 560 result = decoder->startScanlineDecode( |
524 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); | 561 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); |
525 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); | 562 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); |
526 } | 563 } |
527 | 564 |
528 DEF_TEST(Codec_Params, r) { | 565 DEF_TEST(Codec_Params, r) { |
529 test_invalid_parameters(r, "index8.png"); | 566 test_invalid_parameters(r, "index8.png"); |
530 test_invalid_parameters(r, "mandrill.wbmp"); | 567 test_invalid_parameters(r, "mandrill.wbmp"); |
531 } | 568 } |
OLD | NEW |