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 |