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. | |
epoger
2013/08/28 14:47:56
Can we leave the code in place, but only CALL it o
scroggo
2013/08/28 17:54:38
Won't our warnings complain that there is a static
| |
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::BitmapAndDigest bandd(bitmap); |
epoger
2013/08/28 14:47:56
Minor suggestion: maybe "bitmapAndDigest" instead
scroggo
2013/08/28 17:54:38
Done.
| |
420 if (compare_to_expectations_if_necessary(bandd.fDigest, 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 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX) | |
436 test_stream_without_length(srcPath, codec, bandd.fDigest); | |
437 #endif | |
438 | |
371 if (writePath != NULL) { | 439 if (writePath != NULL) { |
372 SkString outPath; | 440 SkString outPath; |
373 make_outname(&outPath, writePath->c_str(), srcPath, ".png"); | 441 make_outname(&outPath, writePath->c_str(), srcPath, ".png"); |
374 if (write_bitmap(outPath.c_str(), bitmap)) { | 442 if (write_bitmap(outPath.c_str(), bitmap)) { |
375 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str() ); | 443 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str() ); |
376 } else { | 444 } else { |
377 gEncodeFailures.push_back().set(outPath); | 445 gEncodeFailures.push_back().set(outPath); |
378 } | 446 } |
379 } | 447 } |
380 | 448 |
(...skipping 10 matching lines...) Expand all Loading... | |
391 // Call decodeSubset multiple times: | 459 // Call decodeSubset multiple times: |
392 SkRandom rand(0); | 460 SkRandom rand(0); |
393 for (int i = 0; i < 5; i++) { | 461 for (int i = 0; i < 5; i++) { |
394 SkBitmap bitmapFromDecodeSubset; | 462 SkBitmap bitmapFromDecodeSubset; |
395 // FIXME: Come up with a more representative set of rectangles. | 463 // FIXME: Come up with a more representative set of rectangles. |
396 SkIRect rect = generate_random_rect(&rand, width, height); | 464 SkIRect rect = generate_random_rect(&rand, width, height); |
397 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft, rect.fTop, | 465 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft, rect.fTop, |
398 rect.fRight, rect.fBottom); | 466 rect.fRight, rect.fBottom); |
399 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, gPrefConf ig)) { | 467 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, gPrefConf ig)) { |
400 SkString subsetName = SkStringPrintf("%s_%s", filename, subs etDim.c_str()); | 468 SkString subsetName = SkStringPrintf("%s_%s", filename, subs etDim.c_str()); |
401 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub set, | 469 skiagm::BitmapAndDigest subsetWithDigest(bitmapFromDecodeSub set); |
470 if (compare_to_expectations_if_necessary(subsetWithDigest.fD igest, | |
scroggo
2013/08/27 22:13:11
I could have left this as bitmapFromDecodeSubset,
epoger
2013/08/28 14:47:56
I don't know what the guidelines are for using the
scroggo
2013/08/28 17:54:38
Oh right, I do not need a BitmapAndDigest. (In fac
| |
402 subsetName.c_str(), | 471 subsetName.c_str(), |
403 &gFailedSubsetDecod es, | 472 &gFailedSubsetDecod es, |
404 &gMissingSubsetExpe ctations)) { | 473 &gMissingSubsetExpe ctations)) { |
405 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub set %s from %s", | 474 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub set %s from %s", |
406 subsetDim.c_str(), srcPath); | 475 subsetDim.c_str(), srcPath); |
407 } else if (!FLAGS_mismatchPath.isEmpty()) { | 476 } else if (!FLAGS_mismatchPath.isEmpty()) { |
408 write_subset(FLAGS_mismatchPath[0], filename, subsetDim. c_str(), | 477 write_subset(FLAGS_mismatchPath[0], filename, subsetDim. c_str(), |
409 &bitmapFromDecodeSubset, rect, bitmap); | 478 &bitmapFromDecodeSubset, rect, bitmap); |
410 } | 479 } |
411 | 480 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
626 } | 695 } |
627 | 696 |
628 return failed ? -1 : 0; | 697 return failed ? -1 : 0; |
629 } | 698 } |
630 | 699 |
631 #if !defined SK_BUILD_FOR_IOS | 700 #if !defined SK_BUILD_FOR_IOS |
632 int main(int argc, char * const argv[]) { | 701 int main(int argc, char * const argv[]) { |
633 return tool_main(argc, (char**) argv); | 702 return tool_main(argc, (char**) argv); |
634 } | 703 } |
635 #endif | 704 #endif |
OLD | NEW |