OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "gm_expectations.h" | 8 #include "gm_expectations.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 static bool expect_to_fail(const char* filename) { | 177 static bool expect_to_fail(const char* filename) { |
178 if (NULL == gJsonExpectations.get()) { | 178 if (NULL == gJsonExpectations.get()) { |
179 return false; | 179 return false; |
180 } | 180 } |
181 skiagm::Expectations jsExpectations = gJsonExpectations->get(filename); | 181 skiagm::Expectations jsExpectations = gJsonExpectations->get(filename); |
182 return jsExpectations.ignoreFailure(); | 182 return jsExpectations.ignoreFailure(); |
183 } | 183 } |
184 | 184 |
185 /** | 185 /** |
186 * Compare against an expectation for this filename, if there is one. | 186 * Compare against an expectation for this filename, if there is one. |
187 * @param bitmap SkBitmap to compare to the expected value. | 187 * @param digest GmResultDigest, computed from the decoded bitmap, to compare t
o the |
| 188 * expectation. |
188 * @param filename String used to find the expected value. | 189 * @param filename String used to find the expected value. |
189 * @param failureArray Array to add a failure message to on failure. | 190 * @param failureArray Array to add a failure message to on failure. |
190 * @param missingArray Array to add missing expectation to on failure. | 191 * @param missingArray Array to add missing expectation to on failure. |
191 * @return bool True in any of these cases: | 192 * @return bool True in any of these cases: |
192 * - the bitmap matches the expectation. | 193 * - the bitmap matches the expectation. |
193 * False in any of these cases: | 194 * False in any of these cases: |
194 * - there is no expectations file. | 195 * - there is no expectations file. |
195 * - there is an expectations file, but no expectation for this
bitmap. | 196 * - there is an expectations file, but no expectation for this
bitmap. |
196 * - there is an expectation for this bitmap, but it did not ma
tch. | 197 * - there is an expectation for this bitmap, but it did not ma
tch. |
197 * - expectation could not be computed from the bitmap. | 198 * - expectation could not be computed from the bitmap. |
198 */ | 199 */ |
199 static bool compare_to_expectations_if_necessary(const SkBitmap& bitmap, const c
har* filename, | 200 static bool compare_to_expectations_if_necessary(const skiagm::GmResultDigest& d
igest, |
| 201 const char* filename, |
200 SkTArray<SkString, false>* fail
ureArray, | 202 SkTArray<SkString, false>* fail
ureArray, |
201 SkTArray<SkString, false>* miss
ingArray) { | 203 SkTArray<SkString, false>* miss
ingArray) { |
202 skiagm::GmResultDigest resultDigest(bitmap); | 204 if (!digest.isValid()) { |
203 if (!resultDigest.isValid()) { | |
204 if (failureArray != NULL) { | 205 if (failureArray != NULL) { |
205 failureArray->push_back().printf("decoded %s, but could not create a
GmResultDigest.", | 206 failureArray->push_back().printf("decoded %s, but could not create a
GmResultDigest.", |
206 filename); | 207 filename); |
207 } | 208 } |
208 return false; | 209 return false; |
209 } | 210 } |
210 | 211 |
211 if (NULL == gJsonExpectations.get()) { | 212 if (NULL == gJsonExpectations.get()) { |
212 return false; | 213 return false; |
213 } | 214 } |
214 | 215 |
215 skiagm::Expectations jsExpectation = gJsonExpectations->get(filename); | 216 skiagm::Expectations jsExpectation = gJsonExpectations->get(filename); |
216 if (jsExpectation.empty()) { | 217 if (jsExpectation.empty()) { |
217 if (missingArray != NULL) { | 218 if (missingArray != NULL) { |
218 missingArray->push_back().printf("decoded %s, but could not find exp
ectation.", | 219 missingArray->push_back().printf("decoded %s, but could not find exp
ectation.", |
219 filename); | 220 filename); |
220 } | 221 } |
221 return false; | 222 return false; |
222 } | 223 } |
223 | 224 |
224 if (jsExpectation.match(resultDigest)) { | 225 if (jsExpectation.match(digest)) { |
225 return true; | 226 return true; |
226 } | 227 } |
227 | 228 |
228 if (failureArray != NULL) { | 229 if (failureArray != NULL) { |
229 failureArray->push_back().printf("decoded %s, but the result does not ma
tch " | 230 failureArray->push_back().printf("decoded %s, but the result does not ma
tch " |
230 "expectations.", | 231 "expectations.", |
231 filename); | 232 filename); |
232 } | 233 } |
233 return false; | 234 return false; |
234 } | 235 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 "create a directory for extractS
ubset comparison.", | 298 "create a directory for extractS
ubset comparison.", |
298 subsetDim, filename); | 299 subsetDim, filename); |
299 return false; | 300 return false; |
300 } | 301 } |
301 | 302 |
302 make_outname(&outPath, dirExtracted.c_str(), filename, suffix.c_str()); | 303 make_outname(&outPath, dirExtracted.c_str(), filename, suffix.c_str()); |
303 SkAssertResult(write_bitmap(outPath.c_str(), extractedSubset)); | 304 SkAssertResult(write_bitmap(outPath.c_str(), extractedSubset)); |
304 return true; | 305 return true; |
305 } | 306 } |
306 | 307 |
| 308 // FIXME: This test could be run on windows/mac once we remove their dependence
on |
| 309 // getLength. See https://code.google.com/p/skia/issues/detail?id=1570 |
| 310 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX) |
| 311 |
| 312 /** |
| 313 * Dummy class for testing to ensure that a stream without a length decodes the
same |
| 314 * as a stream with a length. |
| 315 */ |
| 316 class FILEStreamWithoutLength : public SkFILEStream { |
| 317 public: |
| 318 FILEStreamWithoutLength(const char path[]) |
| 319 : INHERITED(path) {} |
| 320 |
| 321 virtual bool hasLength() const SK_OVERRIDE { |
| 322 return false; |
| 323 } |
| 324 |
| 325 private: |
| 326 typedef SkFILEStream INHERITED; |
| 327 }; |
| 328 |
| 329 /** |
| 330 * Test that decoding a stream which reports to not have a length still results
in the |
| 331 * same image as if it did report to have a length. Assumes that codec was used
to |
| 332 * successfully decode the file using SkFILEStream. |
| 333 * @param srcPath The path to the file, for recreating the length-less stream. |
| 334 * @param codec The SkImageDecoder originally used to decode srcPath, which wil
l be used |
| 335 * again to decode the length-less stream. |
| 336 * @param digest GmResultDigest computed from decoding the stream the first tim
e. |
| 337 * Decoding the length-less stream is expected to result in a matching dige
st. |
| 338 */ |
| 339 static void test_stream_without_length(const char srcPath[], SkImageDecoder* cod
ec, |
| 340 const skiagm::GmResultDigest& digest) { |
| 341 if (!digest.isValid()) { |
| 342 // An error was already reported. |
| 343 return; |
| 344 } |
| 345 SkASSERT(srcPath); |
| 346 SkASSERT(codec); |
| 347 FILEStreamWithoutLength stream(srcPath); |
| 348 // This will only be called after a successful decode. Creating a stream fro
m the same |
| 349 // path should never fail. |
| 350 SkASSERT(stream.isValid()); |
| 351 SkBitmap bm; |
| 352 if (!codec->decode(&stream, &bm, gPrefConfig, SkImageDecoder::kDecodePixels_
Mode)) { |
| 353 gDecodeFailures.push_back().appendf("Without using getLength, %s failed
to decode\n", |
| 354 srcPath); |
| 355 return; |
| 356 } |
| 357 skiagm::GmResultDigest lengthLessDigest(bm); |
| 358 if (!lengthLessDigest.isValid()) { |
| 359 gDecodeFailures.push_back().appendf("Without using getLength, %s failed
to build " |
| 360 "a digest\n", srcPath); |
| 361 return; |
| 362 } |
| 363 if (!lengthLessDigest.equals(digest)) { |
| 364 gDecodeFailures.push_back().appendf("Without using getLength, %s did not
match digest " |
| 365 "that uses getLength\n", srcPath); |
| 366 } |
| 367 } |
| 368 #endif // defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX) |
| 369 |
307 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath)
{ | 370 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath)
{ |
308 SkBitmap bitmap; | 371 SkBitmap bitmap; |
309 SkFILEStream stream(srcPath); | 372 SkFILEStream stream(srcPath); |
310 if (!stream.isValid()) { | 373 if (!stream.isValid()) { |
311 gInvalidStreams.push_back().set(srcPath); | 374 gInvalidStreams.push_back().set(srcPath); |
312 return; | 375 return; |
313 } | 376 } |
314 | 377 |
315 SkImageDecoder* codec = SkImageDecoder::Factory(&stream); | 378 SkImageDecoder* codec = SkImageDecoder::Factory(&stream); |
316 if (NULL == codec) { | 379 if (NULL == codec) { |
(...skipping 29 matching lines...) Expand all Loading... |
346 gDecodeFailures.push_back() = failure; | 409 gDecodeFailures.push_back() = failure; |
347 } else { | 410 } else { |
348 // Now check that the bounds match: | 411 // Now check that the bounds match: |
349 if (dim.width() != bitmap.width() || dim.height() != bitmap.height()
) { | 412 if (dim.width() != bitmap.width() || dim.height() != bitmap.height()
) { |
350 SkString failure = SkStringPrintf("bounds do not match for %s",
srcPath); | 413 SkString failure = SkStringPrintf("bounds do not match for %s",
srcPath); |
351 gDecodeFailures.push_back() = failure; | 414 gDecodeFailures.push_back() = failure; |
352 } | 415 } |
353 } | 416 } |
354 } | 417 } |
355 | 418 |
356 if (compare_to_expectations_if_necessary(bitmap, filename, | 419 skiagm::GmResultDigest digest(bitmap); |
| 420 if (compare_to_expectations_if_necessary(digest, filename, |
357 &gDecodeFailures, | 421 &gDecodeFailures, |
358 &gMissingExpectations)) { | 422 &gMissingExpectations)) { |
359 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.widt
h(), | 423 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.widt
h(), |
360 bitmap.height()); | 424 bitmap.height()); |
361 } else if (!FLAGS_mismatchPath.isEmpty()) { | 425 } else if (!FLAGS_mismatchPath.isEmpty()) { |
362 SkString outPath; | 426 SkString outPath; |
363 make_outname(&outPath, FLAGS_mismatchPath[0], srcPath, ".png"); | 427 make_outname(&outPath, FLAGS_mismatchPath[0], srcPath, ".png"); |
364 if (write_bitmap(outPath.c_str(), bitmap)) { | 428 if (write_bitmap(outPath.c_str(), bitmap)) { |
365 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str()
); | 429 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str()
); |
366 } else { | 430 } else { |
367 gEncodeFailures.push_back().set(outPath); | 431 gEncodeFailures.push_back().set(outPath); |
368 } | 432 } |
369 } | 433 } |
370 | 434 |
| 435 // FIXME: This test could be run on windows/mac once we remove their dependence
on |
| 436 // getLength. See https://code.google.com/p/skia/issues/detail?id=1570 |
| 437 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX) |
| 438 test_stream_without_length(srcPath, codec, digest); |
| 439 #endif |
| 440 |
371 if (writePath != NULL) { | 441 if (writePath != NULL) { |
372 SkString outPath; | 442 SkString outPath; |
373 make_outname(&outPath, writePath->c_str(), srcPath, ".png"); | 443 make_outname(&outPath, writePath->c_str(), srcPath, ".png"); |
374 if (write_bitmap(outPath.c_str(), bitmap)) { | 444 if (write_bitmap(outPath.c_str(), bitmap)) { |
375 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str()
); | 445 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str()
); |
376 } else { | 446 } else { |
377 gEncodeFailures.push_back().set(outPath); | 447 gEncodeFailures.push_back().set(outPath); |
378 } | 448 } |
379 } | 449 } |
380 | 450 |
(...skipping 10 matching lines...) Expand all Loading... |
391 // Call decodeSubset multiple times: | 461 // Call decodeSubset multiple times: |
392 SkRandom rand(0); | 462 SkRandom rand(0); |
393 for (int i = 0; i < 5; i++) { | 463 for (int i = 0; i < 5; i++) { |
394 SkBitmap bitmapFromDecodeSubset; | 464 SkBitmap bitmapFromDecodeSubset; |
395 // FIXME: Come up with a more representative set of rectangles. | 465 // FIXME: Come up with a more representative set of rectangles. |
396 SkIRect rect = generate_random_rect(&rand, width, height); | 466 SkIRect rect = generate_random_rect(&rand, width, height); |
397 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft,
rect.fTop, | 467 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft,
rect.fTop, |
398 rect.fRight, rect.fBottom); | 468 rect.fRight, rect.fBottom); |
399 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, gPrefConf
ig)) { | 469 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, gPrefConf
ig)) { |
400 SkString subsetName = SkStringPrintf("%s_%s", filename, subs
etDim.c_str()); | 470 SkString subsetName = SkStringPrintf("%s_%s", filename, subs
etDim.c_str()); |
401 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub
set, | 471 skiagm::GmResultDigest subsetDigest(bitmapFromDecodeSubset); |
| 472 if (compare_to_expectations_if_necessary(subsetDigest, |
402 subsetName.c_str(), | 473 subsetName.c_str(), |
403 &gFailedSubsetDecod
es, | 474 &gFailedSubsetDecod
es, |
404 &gMissingSubsetExpe
ctations)) { | 475 &gMissingSubsetExpe
ctations)) { |
405 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", | 476 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", |
406 subsetDim.c_str(),
srcPath); | 477 subsetDim.c_str(),
srcPath); |
407 } else if (!FLAGS_mismatchPath.isEmpty()) { | 478 } else if (!FLAGS_mismatchPath.isEmpty()) { |
408 write_subset(FLAGS_mismatchPath[0], filename, subsetDim.
c_str(), | 479 write_subset(FLAGS_mismatchPath[0], filename, subsetDim.
c_str(), |
409 &bitmapFromDecodeSubset, rect, bitmap); | 480 &bitmapFromDecodeSubset, rect, bitmap); |
410 } | 481 } |
411 | 482 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 } | 697 } |
627 | 698 |
628 return failed ? -1 : 0; | 699 return failed ? -1 : 0; |
629 } | 700 } |
630 | 701 |
631 #if !defined SK_BUILD_FOR_IOS | 702 #if !defined SK_BUILD_FOR_IOS |
632 int main(int argc, char * const argv[]) { | 703 int main(int argc, char * const argv[]) { |
633 return tool_main(argc, (char**) argv); | 704 return tool_main(argc, (char**) argv); |
634 } | 705 } |
635 #endif | 706 #endif |
OLD | NEW |