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 "SkBitmapHasher.h" | 10 #include "SkBitmapHasher.h" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 | 63 |
64 static SkImageDecoder::Format guess_format_from_suffix(const char suffix[]) { | 64 static SkImageDecoder::Format guess_format_from_suffix(const char suffix[]) { |
65 for (size_t i = 0; i < SK_ARRAY_COUNT(gFormats); i++) { | 65 for (size_t i = 0; i < SK_ARRAY_COUNT(gFormats); i++) { |
66 if (strcmp(suffix, gFormats[i].fSuffix) == 0) { | 66 if (strcmp(suffix, gFormats[i].fSuffix) == 0) { |
67 return gFormats[i].fFormat; | 67 return gFormats[i].fFormat; |
68 } | 68 } |
69 } | 69 } |
70 return SkImageDecoder::kUnknown_Format; | 70 return SkImageDecoder::kUnknown_Format; |
71 } | 71 } |
72 | 72 |
73 /** | |
74 * Return the name of the file, ignoring the directory structure. | |
75 * Does not create a new string. | |
76 * @param fullPath Full path to the file. | |
77 * @return string The basename of the file - anything beyond the final slash, o r the full name | |
78 * if there is no slash. | |
79 * TODO: Might this be useful as a utility function in SkOSFile? Would it be mo re appropriate to | |
80 * create a new string? | |
81 */ | |
82 static const char* SkBasename(const char* fullPath) { | |
83 const char* filename = strrchr(fullPath, SkPATH_SEPARATOR); | |
84 if (NULL == filename || ++filename == '\0') { | |
epoger
2013/05/15 15:42:01
should be *++filename ?
When we move this into Sk
scroggo
2013/05/15 18:08:24
Done.
| |
85 filename = fullPath; | |
86 } | |
87 return filename; | |
88 } | |
89 | |
73 static void make_outname(SkString* dst, const char outDir[], const char src[], | 90 static void make_outname(SkString* dst, const char outDir[], const char src[], |
74 const char suffix[]) { | 91 const char suffix[]) { |
75 dst->set(outDir); | 92 const char* basename = SkBasename(src); |
76 const char* start = strrchr(src, '/'); | 93 dst->set(skiagm::SkPathJoin(outDir, basename)); |
77 if (start) { | |
78 start += 1; // skip the actual last '/' | |
79 } else { | |
80 start = src; | |
81 } | |
82 dst->append(start); | |
83 if (!dst->endsWith(suffix)) { | 94 if (!dst->endsWith(suffix)) { |
84 const char* cstyleDst = dst->c_str(); | 95 const char* cstyleDst = dst->c_str(); |
85 const char* dot = strrchr(cstyleDst, '.'); | 96 const char* dot = strrchr(cstyleDst, '.'); |
86 if (dot != NULL) { | 97 if (dot != NULL) { |
87 int32_t index = SkToS32(dot - cstyleDst); | 98 int32_t index = SkToS32(dot - cstyleDst); |
88 dst->remove(index, dst->size() - index); | 99 dst->remove(index, dst->size() - index); |
89 } | 100 } |
90 dst->append(suffix); | 101 dst->append(suffix); |
91 } | 102 } |
92 } | 103 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 static void write_expectations(const SkBitmap& bitmap, const char* filename) { | 186 static void write_expectations(const SkBitmap& bitmap, const char* filename) { |
176 if (!FLAGS_createExpectationsPath.isEmpty()) { | 187 if (!FLAGS_createExpectationsPath.isEmpty()) { |
177 // Creates an Expectations object, and add it to the list to write. | 188 // Creates an Expectations object, and add it to the list to write. |
178 skiagm::Expectations expectation(bitmap); | 189 skiagm::Expectations expectation(bitmap); |
179 Json::Value value = expectation.asJsonValue(); | 190 Json::Value value = expectation.asJsonValue(); |
180 gExpectationsToWrite[filename] = value; | 191 gExpectationsToWrite[filename] = value; |
181 } | 192 } |
182 } | 193 } |
183 | 194 |
184 /** | 195 /** |
185 * Return the name of the file, ignoring the directory structure. | |
186 * Does not create a new string. | |
187 * @param fullPath Full path to the file. | |
188 * @return string The basename of the file - anything beyond the final slash, o r the full name | |
189 * if there is no slash. | |
190 * TODO: Might this be useful as a utility function in SkOSFile? Would it be mo re appropriate to | |
191 * create a new string? | |
192 */ | |
193 static const char* SkBasename(const char* fullPath) { | |
194 const char* filename = strrchr(fullPath, SkPATH_SEPARATOR); | |
195 if (NULL == filename || ++filename == '\0') { | |
196 filename = fullPath; | |
197 } | |
198 return filename; | |
199 } | |
200 | |
201 /** | |
202 * Compare against an expectation for this filename, if there is one. | 196 * Compare against an expectation for this filename, if there is one. |
203 * @param bitmap SkBitmap to compare to the expected value. | 197 * @param bitmap SkBitmap to compare to the expected value. |
204 * @param filename String used to find the expected value. | 198 * @param filename String used to find the expected value. |
205 * @return bool True in any of these cases: | 199 * @return bool True in any of these cases: |
206 * - the bitmap matches the expectation. | 200 * - the bitmap matches the expectation. |
207 * - there is no expectations file. | 201 * - there is no expectations file. |
208 * False in any of these cases: | 202 * False in any of these cases: |
209 * - there is an expectations file, but no expectation for this bitmap. | 203 * - there is an expectations file, but no expectation for this bitmap. |
210 * - there is an expectation for this bitmap, but it did not ma tch. | 204 * - there is an expectation for this bitmap, but it did not ma tch. |
211 * - expectation could not be computed from the bitmap. | 205 * - expectation could not be computed from the bitmap. |
(...skipping 27 matching lines...) Expand all Loading... | |
239 } | 233 } |
240 | 234 |
241 if (failureArray != NULL) { | 235 if (failureArray != NULL) { |
242 failureArray->push_back().printf("decoded %s, but the result does not ma tch " | 236 failureArray->push_back().printf("decoded %s, but the result does not ma tch " |
243 "expectations.", | 237 "expectations.", |
244 filename); | 238 filename); |
245 } | 239 } |
246 return false; | 240 return false; |
247 } | 241 } |
248 | 242 |
243 /** | |
244 * Helper function to write a bitmap subset to a file. Only called if subsets w ere created | |
245 * and a writePath was provided. Creates a subdirectory called 'subsets' and wr ites a PNG to | |
246 * that directory. Also creates a subdirectory called 'extracted' and writes a bitmap created | |
247 * using extractSubset to a PNG in that directory. Both files will represent th e same | |
248 * subrectangle and have the same name for comparison. | |
249 * @param writePath Parent directory to hold the folders for the PNG files to w rite. Must | |
250 * not be NULL. | |
251 * @param filename Basename of the original file. Used to name the new files. M ust not be | |
252 * NULL. | |
253 * @param subsetDim String representing the dimensions of the subset. Used to n ame the new | |
254 * files. Must not be NULL. | |
255 * @param bitmapFromDecodeSubset Pointer to SkBitmap created by SkImageDecoder: :DecodeSubset, | |
256 * using rect as the area to decode. | |
257 * @param rect Rectangle of the area decoded into bitmapFromDecodeSubset. Used to call | |
258 * extractSubset on originalBitmap to create a bitmap with the same dimensi ons/pixels as | |
259 * bitmapFromDecodeSubset (assuming decodeSubset worked properly). | |
260 * @param originalBitmap SkBitmap decoded from the same stream as bitmapFromDec odeSubset, | |
261 * using SkImageDecoder::decode to get the entire image. Used to create a P NG file for | |
262 * comparison to the PNG created by bitmapFromDecodeSubset. | |
263 */ | |
264 static void write_subset(const char* writePath, const char* filename, const char * subsetDim, | |
epoger
2013/05/15 15:42:01
Seems like this function may as well return a bool
scroggo
2013/05/15 18:08:24
Done.
| |
265 SkBitmap* bitmapFromDecodeSubset, SkIRect rect, | |
266 const SkBitmap& originalBitmap) { | |
267 // All parameters must be valid. | |
268 SkASSERT(writePath != NULL); | |
epoger
2013/05/15 15:42:01
I like the precondition checks!
| |
269 SkASSERT(filename != NULL); | |
270 SkASSERT(subsetDim != NULL); | |
271 SkASSERT(bitmapFromDecodeSubset != NULL); | |
272 // Create a subdirectory to hold the results of decodeSubset. | |
epoger
2013/05/15 15:42:01
IMHO, newlines before each comment-delimited block
scroggo
2013/05/15 18:08:24
Done.
| |
273 // TODO: Move SkPathJoin into SkOSFile.h | |
274 SkString dir = skiagm::SkPathJoin(writePath, "subsets"); | |
275 if (!sk_mkdir(dir.c_str())) { | |
276 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s , but failed to " | |
277 "create a directory to write to. ", subsetDim, | |
278 filename); | |
279 return; | |
280 } | |
281 // Write the subset to a file whose name includes the dimensions. | |
282 SkString suffix = SkStringPrintf("_%s.png", subsetDim); | |
283 SkString outPath; | |
284 make_outname(&outPath, dir.c_str(), filename, suffix.c_str()); | |
285 SkAssertResult(write_bitmap(outPath.c_str(), bitmapFromDecodeSubset)); | |
286 gSuccessfulSubsetDecodes.push_back().printf("\twrote %s", outPath.c_str()); | |
287 // Also use extractSubset from the original for visual comparison. | |
288 // Write the result to a file in a separate subdirectory. | |
289 SkBitmap extractedSubset; | |
290 if (!originalBitmap.extractSubset(&extractedSubset, rect)) { | |
291 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s , but failed to " | |
292 "extract a similar subset for co mparison.", | |
293 subsetDim, filename); | |
294 return; | |
295 } | |
296 SkString dirExtracted = skiagm::SkPathJoin(writePath, "extracted"); | |
297 if (!sk_mkdir(dirExtracted.c_str())) { | |
298 gFailedSubsetDecodes.push_back().printf("Successfully decoded %s from %s , but failed to " | |
299 "create a directory for extractS ubset comparison.", | |
300 subsetDim, filename); | |
301 return; | |
302 } | |
303 make_outname(&outPath, dirExtracted.c_str(), filename, suffix.c_str()); | |
304 SkAssertResult(write_bitmap(outPath.c_str(), &extractedSubset)); | |
305 } | |
306 | |
249 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) { | 307 static void decodeFileAndWrite(const char srcPath[], const SkString* writePath) { |
250 SkBitmap bitmap; | 308 SkBitmap bitmap; |
251 SkFILEStream stream(srcPath); | 309 SkFILEStream stream(srcPath); |
252 if (!stream.isValid()) { | 310 if (!stream.isValid()) { |
253 gInvalidStreams.push_back().set(srcPath); | 311 gInvalidStreams.push_back().set(srcPath); |
254 return; | 312 return; |
255 } | 313 } |
256 | 314 |
257 SkImageDecoder* codec = SkImageDecoder::Factory(&stream); | 315 SkImageDecoder* codec = SkImageDecoder::Factory(&stream); |
258 if (NULL == codec) { | 316 if (NULL == codec) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap: :kNo_Config)) { | 356 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap: :kNo_Config)) { |
299 SkString subsetName = SkStringPrintf("%s_%s", filename, subs etDim.c_str()); | 357 SkString subsetName = SkStringPrintf("%s_%s", filename, subs etDim.c_str()); |
300 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub set, | 358 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub set, |
301 subsetName.c_str(), | 359 subsetName.c_str(), |
302 &gFailedSubsetDecod es)) { | 360 &gFailedSubsetDecod es)) { |
303 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub set %s from %s", | 361 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub set %s from %s", |
304 subsetDim.c_str(), srcPath); | 362 subsetDim.c_str(), srcPath); |
305 } | 363 } |
306 | 364 |
307 write_expectations(bitmapFromDecodeSubset, subsetName.c_str( )); | 365 write_expectations(bitmapFromDecodeSubset, subsetName.c_str( )); |
308 | |
309 if (writePath != NULL) { | 366 if (writePath != NULL) { |
310 // Write the region to a file whose name includes the di mensions. | 367 write_subset(writePath->c_str(), filename, subsetDim.c_s tr(), |
311 SkString suffix = SkStringPrintf("_%s.png", subsetDim.c_ str()); | 368 &bitmapFromDecodeSubset, rect, bitmap); |
312 SkString outPath; | |
313 make_outname(&outPath, writePath->c_str(), srcPath, suff ix.c_str()); | |
314 SkDEBUGCODE(bool success =) | |
315 write_bitmap(outPath.c_str(), &bitmapFromDecodeSubset); | |
316 SkASSERT(success); | |
317 gSuccessfulSubsetDecodes.push_back().printf("\twrote %s" , outPath.c_str()); | |
318 // Also use extractSubset from the original for visual c omparison. | |
319 SkBitmap extractedSubset; | |
320 if (bitmap.extractSubset(&extractedSubset, rect)) { | |
321 suffix.printf("_%s_extracted.png", subsetDim.c_str() ); | |
322 make_outname(&outPath, writePath->c_str(), srcPath, suffix.c_str()); | |
323 SkDEBUGCODE(success =) write_bitmap(outPath.c_str(), &extractedSubset); | |
324 SkASSERT(success); | |
325 } | |
326 } | 369 } |
327 } else { | 370 } else { |
328 gFailedSubsetDecodes.push_back().printf("Failed to decode re gion %s from %s\n", | 371 gFailedSubsetDecodes.push_back().printf("Failed to decode re gion %s from %s", |
329 subsetDim.c_str(), s rcPath); | 372 subsetDim.c_str(), s rcPath); |
330 } | 373 } |
331 } | 374 } |
332 } | 375 } |
333 } | 376 } |
377 | |
334 if (FLAGS_reencode) { | 378 if (FLAGS_reencode) { |
335 // Encode to the format the file was originally in, or PNG if the encode r for the same | 379 // Encode to the format the file was originally in, or PNG if the encode r for the same |
336 // format is unavailable. | 380 // format is unavailable. |
337 SkImageDecoder::Format format = codec->getFormat(); | 381 SkImageDecoder::Format format = codec->getFormat(); |
338 if (SkImageDecoder::kUnknown_Format == format) { | 382 if (SkImageDecoder::kUnknown_Format == format) { |
339 if (stream.rewind()) { | 383 if (stream.rewind()) { |
340 format = SkImageDecoder::GetStreamFormat(&stream); | 384 format = SkImageDecoder::GetStreamFormat(&stream); |
341 } | 385 } |
342 if (SkImageDecoder::kUnknown_Format == format) { | 386 if (SkImageDecoder::kUnknown_Format == format) { |
343 const char* dot = strrchr(srcPath, '.'); | 387 const char* dot = strrchr(srcPath, '.'); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
513 } | 557 } |
514 | 558 |
515 return failed ? -1 : 0; | 559 return failed ? -1 : 0; |
516 } | 560 } |
517 | 561 |
518 #if !defined SK_BUILD_FOR_IOS | 562 #if !defined SK_BUILD_FOR_IOS |
519 int main(int argc, char * const argv[]) { | 563 int main(int argc, char * const argv[]) { |
520 return tool_main(argc, (char**) argv); | 564 return tool_main(argc, (char**) argv); |
521 } | 565 } |
522 #endif | 566 #endif |
OLD | NEW |