| 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" |
| 11 #include "SkCommandLineFlags.h" | 11 #include "SkCommandLineFlags.h" |
| 12 #include "SkData.h" | 12 #include "SkData.h" |
| 13 #include "SkForceLinking.h" | 13 #include "SkForceLinking.h" |
| 14 #include "SkGraphics.h" | 14 #include "SkGraphics.h" |
| 15 #include "SkImageDecoder.h" | 15 #include "SkImageDecoder.h" |
| 16 #include "SkImageEncoder.h" | 16 #include "SkImageEncoder.h" |
| 17 #include "SkOSFile.h" | 17 #include "SkOSFile.h" |
| 18 #include "SkRandom.h" | 18 #include "SkRandom.h" |
| 19 #include "SkStream.h" | 19 #include "SkStream.h" |
| 20 #include "SkTArray.h" | 20 #include "SkTArray.h" |
| 21 #include "SkTemplates.h" | 21 #include "SkTemplates.h" |
| 22 | 22 |
| 23 __SK_FORCE_IMAGE_DECODER_LINKING; | 23 __SK_FORCE_IMAGE_DECODER_LINKING; |
| 24 | 24 |
| 25 DEFINE_string(createExpectationsPath, "", "Path to write JSON expectations."); | 25 DEFINE_string(createExpectationsPath, "", "Path to write JSON expectations."); |
| 26 DEFINE_string(mismatchPath, "", "Folder to write mismatched images to."); |
| 26 DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required.
"); | 27 DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required.
"); |
| 27 DEFINE_string(readExpectationsPath, "", "Path to read JSON expectations from."); | 28 DEFINE_string(readExpectationsPath, "", "Path to read JSON expectations from."); |
| 28 DEFINE_string2(writePath, w, "", "Write rendered images into this directory."); | |
| 29 DEFINE_bool(reencode, true, "Reencode the images to test encoding."); | 29 DEFINE_bool(reencode, true, "Reencode the images to test encoding."); |
| 30 DEFINE_bool(testSubsetDecoding, true, "Test decoding subsets of images."); | 30 DEFINE_bool(testSubsetDecoding, true, "Test decoding subsets of images."); |
| 31 DEFINE_string2(writePath, w, "", "Write rendered images into this directory."); |
| 31 | 32 |
| 32 struct Format { | 33 struct Format { |
| 33 SkImageEncoder::Type fType; | 34 SkImageEncoder::Type fType; |
| 34 SkImageDecoder::Format fFormat; | 35 SkImageDecoder::Format fFormat; |
| 35 const char* fSuffix; | 36 const char* fSuffix; |
| 36 }; | 37 }; |
| 37 | 38 |
| 38 static const Format gFormats[] = { | 39 static const Format gFormats[] = { |
| 39 { SkImageEncoder::kBMP_Type, SkImageDecoder::kBMP_Format, ".bmp" }, | 40 { SkImageEncoder::kBMP_Type, SkImageDecoder::kBMP_Format, ".bmp" }, |
| 40 { SkImageEncoder::kGIF_Type, SkImageDecoder::kGIF_Format, ".gif" }, | 41 { SkImageEncoder::kGIF_Type, SkImageDecoder::kGIF_Format, ".gif" }, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 static SkTArray<SkString, false> gDecodeFailures; | 95 static SkTArray<SkString, false> gDecodeFailures; |
| 95 static SkTArray<SkString, false> gEncodeFailures; | 96 static SkTArray<SkString, false> gEncodeFailures; |
| 96 static SkTArray<SkString, false> gSuccessfulDecodes; | 97 static SkTArray<SkString, false> gSuccessfulDecodes; |
| 97 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; | 98 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; |
| 98 static SkTArray<SkString, false> gFailedSubsetDecodes; | 99 static SkTArray<SkString, false> gFailedSubsetDecodes; |
| 99 | 100 |
| 100 // Expections read from a file specified by readExpectationsPath. The expectatio
ns must have been | 101 // Expections read from a file specified by readExpectationsPath. The expectatio
ns must have been |
| 101 // previously written using createExpectationsPath. | 102 // previously written using createExpectationsPath. |
| 102 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; | 103 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; |
| 103 | 104 |
| 104 static bool write_bitmap(const char outName[], SkBitmap* bm) { | 105 static bool write_bitmap(const char outName[], const SkBitmap& bm) { |
| 105 SkBitmap bitmap8888; | 106 return SkImageEncoder::EncodeFile(outName, bm, SkImageEncoder::kPNG_Type, 10
0); |
| 106 if (SkBitmap::kARGB_8888_Config != bm->config()) { | |
| 107 if (!bm->copyTo(&bitmap8888, SkBitmap::kARGB_8888_Config)) { | |
| 108 return false; | |
| 109 } | |
| 110 bm = &bitmap8888; | |
| 111 } | |
| 112 // FIXME: This forces all pixels to be opaque, like the many implementations | |
| 113 // of force_all_opaque. These should be unified if they cannot be eliminated
. | |
| 114 SkAutoLockPixels lock(*bm); | |
| 115 for (int y = 0; y < bm->height(); y++) { | |
| 116 for (int x = 0; x < bm->width(); x++) { | |
| 117 *bm->getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT); | |
| 118 } | |
| 119 } | |
| 120 return SkImageEncoder::EncodeFile(outName, *bm, SkImageEncoder::kPNG_Type, 1
00); | |
| 121 } | 107 } |
| 122 | 108 |
| 123 /** | 109 /** |
| 124 * Return a random SkIRect inside the range specified. | 110 * Return a random SkIRect inside the range specified. |
| 125 * @param rand Random number generator. | 111 * @param rand Random number generator. |
| 126 * @param maxX Exclusive maximum x-coordinate. SkIRect's fLeft and fRight will
be | 112 * @param maxX Exclusive maximum x-coordinate. SkIRect's fLeft and fRight will
be |
| 127 * in the range [0, maxX) | 113 * in the range [0, maxX) |
| 128 * @param maxY Exclusive maximum y-coordinate. SkIRect's fTop and fBottom will
be | 114 * @param maxY Exclusive maximum y-coordinate. SkIRect's fTop and fBottom will
be |
| 129 * in the range [0, maxY) | 115 * in the range [0, maxY) |
| 130 * @return SkIRect Non-empty, non-degenerate rectangle. | 116 * @return SkIRect Non-empty, non-degenerate rectangle. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 gExpectationsToWrite[filename] = value; | 162 gExpectationsToWrite[filename] = value; |
| 177 } | 163 } |
| 178 } | 164 } |
| 179 | 165 |
| 180 /** | 166 /** |
| 181 * Compare against an expectation for this filename, if there is one. | 167 * Compare against an expectation for this filename, if there is one. |
| 182 * @param bitmap SkBitmap to compare to the expected value. | 168 * @param bitmap SkBitmap to compare to the expected value. |
| 183 * @param filename String used to find the expected value. | 169 * @param filename String used to find the expected value. |
| 184 * @return bool True in any of these cases: | 170 * @return bool True in any of these cases: |
| 185 * - the bitmap matches the expectation. | 171 * - the bitmap matches the expectation. |
| 172 * False in any of these cases: |
| 186 * - there is no expectations file. | 173 * - there is no expectations file. |
| 187 * False in any of these cases: | |
| 188 * - there is an expectations file, but no expectation for this
bitmap. | 174 * - there is an expectations file, but no expectation for this
bitmap. |
| 189 * - there is an expectation for this bitmap, but it did not ma
tch. | 175 * - there is an expectation for this bitmap, but it did not ma
tch. |
| 190 * - expectation could not be computed from the bitmap. | 176 * - expectation could not be computed from the bitmap. |
| 191 */ | 177 */ |
| 192 static bool compare_to_expectations_if_necessary(const SkBitmap& bitmap, const c
har* filename, | 178 static bool compare_to_expectations_if_necessary(const SkBitmap& bitmap, const c
har* filename, |
| 193 SkTArray<SkString, false>* fail
ureArray) { | 179 SkTArray<SkString, false>* fail
ureArray) { |
| 180 skiagm::GmResultDigest resultDigest(bitmap); |
| 181 if (!resultDigest.isValid()) { |
| 182 if (failureArray != NULL) { |
| 183 failureArray->push_back().printf("decoded %s, but could not create a
GmResultDigest.", |
| 184 filename); |
| 185 } |
| 186 return false; |
| 187 } |
| 188 |
| 194 if (NULL == gJsonExpectations.get()) { | 189 if (NULL == gJsonExpectations.get()) { |
| 195 return true; | 190 return false; |
| 196 } | 191 } |
| 197 | 192 |
| 198 skiagm::Expectations jsExpectation = gJsonExpectations->get(filename); | 193 skiagm::Expectations jsExpectation = gJsonExpectations->get(filename); |
| 199 if (jsExpectation.empty()) { | 194 if (jsExpectation.empty()) { |
| 200 if (failureArray != NULL) { | 195 if (failureArray != NULL) { |
| 201 failureArray->push_back().printf("decoded %s, but could not find exp
ectation.", | 196 failureArray->push_back().printf("decoded %s, but could not find exp
ectation.", |
| 202 filename); | 197 filename); |
| 203 } | 198 } |
| 204 return false; | 199 return false; |
| 205 } | |
| 206 | |
| 207 skiagm::GmResultDigest resultDigest(bitmap); | |
| 208 if (!resultDigest.isValid()) { | |
| 209 if (failureArray != NULL) { | |
| 210 failureArray->push_back().printf("decoded %s, but could not create a
GmResultDigest.", | |
| 211 filename); | |
| 212 } | |
| 213 return false; | |
| 214 } | 200 } |
| 215 | 201 |
| 216 if (jsExpectation.match(resultDigest)) { | 202 if (jsExpectation.match(resultDigest)) { |
| 217 return true; | 203 return true; |
| 218 } | 204 } |
| 219 | 205 |
| 220 if (failureArray != NULL) { | 206 if (failureArray != NULL) { |
| 221 failureArray->push_back().printf("decoded %s, but the result does not ma
tch " | 207 failureArray->push_back().printf("decoded %s, but the result does not ma
tch " |
| 222 "expectations.", | 208 "expectations.", |
| 223 filename); | 209 filename); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s
, but failed to " | 249 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s
, but failed to " |
| 264 "create a directory to write to.
", subsetDim, | 250 "create a directory to write to.
", subsetDim, |
| 265 filename); | 251 filename); |
| 266 return false; | 252 return false; |
| 267 } | 253 } |
| 268 | 254 |
| 269 // Write the subset to a file whose name includes the dimensions. | 255 // Write the subset to a file whose name includes the dimensions. |
| 270 SkString suffix = SkStringPrintf("_%s.png", subsetDim); | 256 SkString suffix = SkStringPrintf("_%s.png", subsetDim); |
| 271 SkString outPath; | 257 SkString outPath; |
| 272 make_outname(&outPath, dir.c_str(), filename, suffix.c_str()); | 258 make_outname(&outPath, dir.c_str(), filename, suffix.c_str()); |
| 273 SkAssertResult(write_bitmap(outPath.c_str(), bitmapFromDecodeSubset)); | 259 SkAssertResult(write_bitmap(outPath.c_str(), *bitmapFromDecodeSubset)); |
| 274 gSuccessfulSubsetDecodes.push_back().printf("\twrote %s", outPath.c_str()); | 260 gSuccessfulSubsetDecodes.push_back().printf("\twrote %s", outPath.c_str()); |
| 275 | 261 |
| 276 // Also use extractSubset from the original for visual comparison. | 262 // Also use extractSubset from the original for visual comparison. |
| 277 // Write the result to a file in a separate subdirectory. | 263 // Write the result to a file in a separate subdirectory. |
| 278 SkBitmap extractedSubset; | 264 SkBitmap extractedSubset; |
| 279 if (!originalBitmap.extractSubset(&extractedSubset, rect)) { | 265 if (!originalBitmap.extractSubset(&extractedSubset, rect)) { |
| 280 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s
, but failed to " | 266 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s
, but failed to " |
| 281 "extract a similar subset for co
mparison.", | 267 "extract a similar subset for co
mparison.", |
| 282 subsetDim, filename); | 268 subsetDim, filename); |
| 283 return false; | 269 return false; |
| 284 } | 270 } |
| 285 | 271 |
| 286 SkString dirExtracted = SkOSPath::SkPathJoin(writePath, "extracted"); | 272 SkString dirExtracted = SkOSPath::SkPathJoin(writePath, "extracted"); |
| 287 if (!sk_mkdir(dirExtracted.c_str())) { | 273 if (!sk_mkdir(dirExtracted.c_str())) { |
| 288 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s
, but failed to " | 274 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s
, but failed to " |
| 289 "create a directory for extractS
ubset comparison.", | 275 "create a directory for extractS
ubset comparison.", |
| 290 subsetDim, filename); | 276 subsetDim, filename); |
| 291 return false; | 277 return false; |
| 292 } | 278 } |
| 293 | 279 |
| 294 make_outname(&outPath, dirExtracted.c_str(), filename, suffix.c_str()); | 280 make_outname(&outPath, dirExtracted.c_str(), filename, suffix.c_str()); |
| 295 SkAssertResult(write_bitmap(outPath.c_str(), &extractedSubset)); | 281 SkAssertResult(write_bitmap(outPath.c_str(), extractedSubset)); |
| 296 return true; | 282 return true; |
| 297 } | 283 } |
| 298 | 284 |
| 299 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath)
{ | 285 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath)
{ |
| 300 SkBitmap bitmap; | 286 SkBitmap bitmap; |
| 301 SkFILEStream stream(srcPath); | 287 SkFILEStream stream(srcPath); |
| 302 if (!stream.isValid()) { | 288 if (!stream.isValid()) { |
| 303 gInvalidStreams.push_back().set(srcPath); | 289 gInvalidStreams.push_back().set(srcPath); |
| 304 return; | 290 return; |
| 305 } | 291 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 319 return; | 305 return; |
| 320 } | 306 } |
| 321 | 307 |
| 322 // Create a string representing just the filename itself, for use in json ex
pectations. | 308 // Create a string representing just the filename itself, for use in json ex
pectations. |
| 323 SkString basename = SkOSPath::SkBasename(srcPath); | 309 SkString basename = SkOSPath::SkBasename(srcPath); |
| 324 const char* filename = basename.c_str(); | 310 const char* filename = basename.c_str(); |
| 325 | 311 |
| 326 if (compare_to_expectations_if_necessary(bitmap, filename, &gDecodeFailures)
) { | 312 if (compare_to_expectations_if_necessary(bitmap, filename, &gDecodeFailures)
) { |
| 327 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.widt
h(), | 313 gSuccessfulDecodes.push_back().printf("%s [%d %d]", srcPath, bitmap.widt
h(), |
| 328 bitmap.height()); | 314 bitmap.height()); |
| 315 } else if (!FLAGS_mismatchPath.isEmpty()) { |
| 316 SkString outPath; |
| 317 make_outname(&outPath, FLAGS_mismatchPath[0], srcPath, ".png"); |
| 318 if (write_bitmap(outPath.c_str(), bitmap)) { |
| 319 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str()
); |
| 320 } else { |
| 321 gEncodeFailures.push_back().set(outPath); |
| 322 } |
| 323 } |
| 324 |
| 325 if (writePath != NULL) { |
| 326 SkString outPath; |
| 327 make_outname(&outPath, writePath->c_str(), srcPath, ".png"); |
| 328 if (write_bitmap(outPath.c_str(), bitmap)) { |
| 329 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str()
); |
| 330 } else { |
| 331 gEncodeFailures.push_back().set(outPath); |
| 332 } |
| 329 } | 333 } |
| 330 | 334 |
| 331 write_expectations(bitmap, filename); | 335 write_expectations(bitmap, filename); |
| 332 | 336 |
| 333 if (FLAGS_testSubsetDecoding) { | 337 if (FLAGS_testSubsetDecoding) { |
| 334 SkDEBUGCODE(bool couldRewind =) stream.rewind(); | 338 SkDEBUGCODE(bool couldRewind =) stream.rewind(); |
| 335 SkASSERT(couldRewind); | 339 SkASSERT(couldRewind); |
| 336 int width, height; | 340 int width, height; |
| 337 // Build the tile index for decoding subsets. If the image is 1x1, skip
subset | 341 // Build the tile index for decoding subsets. If the image is 1x1, skip
subset |
| 338 // decoding since there are no smaller subsets. | 342 // decoding since there are no smaller subsets. |
| 339 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig
ht > 1) { | 343 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig
ht > 1) { |
| 340 SkASSERT(bitmap.width() == width && bitmap.height() == height); | 344 SkASSERT(bitmap.width() == width && bitmap.height() == height); |
| 341 // Call decodeSubset multiple times: | 345 // Call decodeSubset multiple times: |
| 342 SkRandom rand(0); | 346 SkRandom rand(0); |
| 343 for (int i = 0; i < 5; i++) { | 347 for (int i = 0; i < 5; i++) { |
| 344 SkBitmap bitmapFromDecodeSubset; | 348 SkBitmap bitmapFromDecodeSubset; |
| 345 // FIXME: Come up with a more representative set of rectangles. | 349 // FIXME: Come up with a more representative set of rectangles. |
| 346 SkIRect rect = generate_random_rect(&rand, width, height); | 350 SkIRect rect = generate_random_rect(&rand, width, height); |
| 347 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft,
rect.fTop, | 351 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft,
rect.fTop, |
| 348 rect.fRight, rect.fBottom); | 352 rect.fRight, rect.fBottom); |
| 349 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap:
:kNo_Config)) { | 353 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap:
:kNo_Config)) { |
| 350 SkString subsetName = SkStringPrintf("%s_%s", filename, subs
etDim.c_str()); | 354 SkString subsetName = SkStringPrintf("%s_%s", filename, subs
etDim.c_str()); |
| 351 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub
set, | 355 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub
set, |
| 352 subsetName.c_str(), | 356 subsetName.c_str(), |
| 353 &gFailedSubsetDecod
es)) { | 357 &gFailedSubsetDecod
es)) { |
| 354 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", | 358 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", |
| 355 subsetDim.c_str(),
srcPath); | 359 subsetDim.c_str(),
srcPath); |
| 360 } else if (!FLAGS_mismatchPath.isEmpty()) { |
| 361 write_subset(FLAGS_mismatchPath[0], filename, subsetDim.
c_str(), |
| 362 &bitmapFromDecodeSubset, rect, bitmap); |
| 356 } | 363 } |
| 357 | 364 |
| 358 write_expectations(bitmapFromDecodeSubset, subsetName.c_str(
)); | 365 write_expectations(bitmapFromDecodeSubset, subsetName.c_str(
)); |
| 359 if (writePath != NULL) { | 366 if (writePath != NULL) { |
| 360 write_subset(writePath->c_str(), filename, subsetDim.c_s
tr(), | 367 write_subset(writePath->c_str(), filename, subsetDim.c_s
tr(), |
| 361 &bitmapFromDecodeSubset, rect, bitmap); | 368 &bitmapFromDecodeSubset, rect, bitmap); |
| 362 } | 369 } |
| 363 } else { | 370 } else { |
| 364 gFailedSubsetDecodes.push_back().printf("Failed to decode re
gion %s from %s", | 371 gFailedSubsetDecodes.push_back().printf("Failed to decode re
gion %s from %s", |
| 365 subsetDim.c_str(), s
rcPath); | 372 subsetDim.c_str(), s
rcPath); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 // Encode to a stream. | 411 // Encode to a stream. |
| 405 SkDynamicMemoryWStream wStream; | 412 SkDynamicMemoryWStream wStream; |
| 406 if (!encoder->encodeStream(&wStream, bitmap, 100)) { | 413 if (!encoder->encodeStream(&wStream, bitmap, 100)) { |
| 407 gEncodeFailures.push_back().printf("Failed to reencode %s to type '%
s'", srcPath, | 414 gEncodeFailures.push_back().printf("Failed to reencode %s to type '%
s'", srcPath, |
| 408 suffix_for_type(type)); | 415 suffix_for_type(type)); |
| 409 return; | 416 return; |
| 410 } | 417 } |
| 411 | 418 |
| 412 SkAutoTUnref<SkData> data(wStream.copyToData()); | 419 SkAutoTUnref<SkData> data(wStream.copyToData()); |
| 413 if (writePath != NULL && type != SkImageEncoder::kPNG_Type) { | 420 if (writePath != NULL && type != SkImageEncoder::kPNG_Type) { |
| 414 // Write the encoded data to a file. Do not write to PNG, which will
be written later, | 421 // Write the encoded data to a file. Do not write to PNG, which was
already written. |
| 415 // regardless of the input format. | |
| 416 SkString outPath; | 422 SkString outPath; |
| 417 make_outname(&outPath, writePath->c_str(), srcPath, suffix_for_type(
type)); | 423 make_outname(&outPath, writePath->c_str(), srcPath, suffix_for_type(
type)); |
| 418 SkFILEWStream file(outPath.c_str()); | 424 SkFILEWStream file(outPath.c_str()); |
| 419 if(file.write(data->data(), data->size())) { | 425 if(file.write(data->data(), data->size())) { |
| 420 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_s
tr()); | 426 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_s
tr()); |
| 421 } else { | 427 } else { |
| 422 gEncodeFailures.push_back().printf("Failed to write %s", outPath
.c_str()); | 428 gEncodeFailures.push_back().printf("Failed to write %s", outPath
.c_str()); |
| 423 } | 429 } |
| 424 } | 430 } |
| 425 // Ensure that the reencoded data can still be decoded. | 431 // Ensure that the reencoded data can still be decoded. |
| 426 SkMemoryStream memStream(data); | 432 SkMemoryStream memStream(data); |
| 427 SkBitmap redecodedBitmap; | 433 SkBitmap redecodedBitmap; |
| 428 SkImageDecoder::Format formatOnSecondDecode; | 434 SkImageDecoder::Format formatOnSecondDecode; |
| 429 if (SkImageDecoder::DecodeStream(&memStream, &redecodedBitmap, SkBitmap:
:kNo_Config, | 435 if (SkImageDecoder::DecodeStream(&memStream, &redecodedBitmap, SkBitmap:
:kNo_Config, |
| 430 SkImageDecoder::kDecodePixels_Mode, | 436 SkImageDecoder::kDecodePixels_Mode, |
| 431 &formatOnSecondDecode)) { | 437 &formatOnSecondDecode)) { |
| 432 SkASSERT(format_to_type(formatOnSecondDecode) == type); | 438 SkASSERT(format_to_type(formatOnSecondDecode) == type); |
| 433 } else { | 439 } else { |
| 434 gDecodeFailures.push_back().printf("Failed to redecode %s after reen
coding to '%s'", | 440 gDecodeFailures.push_back().printf("Failed to redecode %s after reen
coding to '%s'", |
| 435 srcPath, suffix_for_type(type)); | 441 srcPath, suffix_for_type(type)); |
| 436 } | 442 } |
| 437 } | 443 } |
| 438 | |
| 439 if (writePath != NULL) { | |
| 440 SkString outPath; | |
| 441 make_outname(&outPath, writePath->c_str(), srcPath, ".png"); | |
| 442 if (write_bitmap(outPath.c_str(), &bitmap)) { | |
| 443 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_str()
); | |
| 444 } else { | |
| 445 gEncodeFailures.push_back().set(outPath); | |
| 446 } | |
| 447 } | |
| 448 } | 444 } |
| 449 | 445 |
| 450 /////////////////////////////////////////////////////////////////////////////// | 446 /////////////////////////////////////////////////////////////////////////////// |
| 451 | 447 |
| 452 // If strings is not empty, print title, followed by each string on its own line
starting | 448 // If strings is not empty, print title, followed by each string on its own line
starting |
| 453 // with a tab. | 449 // with a tab. |
| 454 // @return bool True if strings had at least one entry. | 450 // @return bool True if strings had at least one entry. |
| 455 static bool print_strings(const char* title, const SkTArray<SkString, false>& st
rings) { | 451 static bool print_strings(const char* title, const SkTArray<SkString, false>& st
rings) { |
| 456 if (strings.count() > 0) { | 452 if (strings.count() > 0) { |
| 457 SkDebugf("%s:\n", title); | 453 SkDebugf("%s:\n", title); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 } | 519 } |
| 524 } | 520 } |
| 525 | 521 |
| 526 if (!FLAGS_createExpectationsPath.isEmpty()) { | 522 if (!FLAGS_createExpectationsPath.isEmpty()) { |
| 527 // Use an empty value for everything besides expectations, since the rea
der only cares | 523 // Use an empty value for everything besides expectations, since the rea
der only cares |
| 528 // about the expectations. | 524 // about the expectations. |
| 529 Json::Value nullValue; | 525 Json::Value nullValue; |
| 530 Json::Value root = skiagm::CreateJsonTree(gExpectationsToWrite, nullValu
e, nullValue, | 526 Json::Value root = skiagm::CreateJsonTree(gExpectationsToWrite, nullValu
e, nullValue, |
| 531 nullValue, nullValue); | 527 nullValue, nullValue); |
| 532 std::string jsonStdString = root.toStyledString(); | 528 std::string jsonStdString = root.toStyledString(); |
| 533 SkString path = SkStringPrintf("%s%cresults.json", FLAGS_createExpectati
onsPath[0], | 529 SkFILEWStream stream(FLAGS_createExpectationsPath[0]); |
| 534 SkPATH_SEPARATOR); | |
| 535 SkFILEWStream stream(path.c_str()); | |
| 536 stream.write(jsonStdString.c_str(), jsonStdString.length()); | 530 stream.write(jsonStdString.c_str(), jsonStdString.length()); |
| 537 } | 531 } |
| 538 // Add some space, since codecs may print warnings without newline. | 532 // Add some space, since codecs may print warnings without newline. |
| 539 SkDebugf("\n\n"); | 533 SkDebugf("\n\n"); |
| 540 | 534 |
| 541 bool failed = print_strings("Invalid files", gInvalidStreams); | 535 bool failed = print_strings("Invalid files", gInvalidStreams); |
| 542 failed |= print_strings("Missing codec", gMissingCodecs); | 536 failed |= print_strings("Missing codec", gMissingCodecs); |
| 543 failed |= print_strings("Failed to decode", gDecodeFailures); | 537 failed |= print_strings("Failed to decode", gDecodeFailures); |
| 544 failed |= print_strings("Failed to encode", gEncodeFailures); | 538 failed |= print_strings("Failed to encode", gEncodeFailures); |
| 545 print_strings("Decoded", gSuccessfulDecodes); | 539 print_strings("Decoded", gSuccessfulDecodes); |
| 546 | 540 |
| 547 if (FLAGS_testSubsetDecoding) { | 541 if (FLAGS_testSubsetDecoding) { |
| 548 failed |= print_strings("Failed subset decodes", gFailedSubsetDecodes); | 542 failed |= print_strings("Failed subset decodes", gFailedSubsetDecodes); |
| 549 print_strings("Decoded subsets", gSuccessfulSubsetDecodes); | 543 print_strings("Decoded subsets", gSuccessfulSubsetDecodes); |
| 550 } | 544 } |
| 551 | 545 |
| 552 return failed ? -1 : 0; | 546 return failed ? -1 : 0; |
| 553 } | 547 } |
| 554 | 548 |
| 555 #if !defined SK_BUILD_FOR_IOS | 549 #if !defined SK_BUILD_FOR_IOS |
| 556 int main(int argc, char * const argv[]) { | 550 int main(int argc, char * const argv[]) { |
| 557 return tool_main(argc, (char**) argv); | 551 return tool_main(argc, (char**) argv); |
| 558 } | 552 } |
| 559 #endif | 553 #endif |
| OLD | NEW |