| 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 |