/// If outputDir.isEmpty(), don't write out diff files. static void create_diff_images (DiffMetricProc dmp, const int colorThreshold, const SkString& baseFile, const SkString& comparisonFile, const SkString& outputDir, const SkString& outputFilename, DiffRecord* drp) { SkASSERT(!baseFile.isEmpty()); SkASSERT(!comparisonFile.isEmpty()); drp->fBase.fFilename = baseFile; drp->fBase.fFullPath = baseFile; drp->fBase.fStatus = DiffResource::kSpecified_Status; drp->fComparison.fFilename = comparisonFile; drp->fComparison.fFullPath = comparisonFile; drp->fComparison.fStatus = DiffResource::kSpecified_Status; SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str())); if (baseFileBits) { drp->fBase.fStatus = DiffResource::kRead_Status; } SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str())); if (comparisonFileBits) { drp->fComparison.fStatus = DiffResource::kRead_Status; } if (nullptr == baseFileBits || nullptr == comparisonFileBits) { if (nullptr == baseFileBits) { drp->fBase.fStatus = DiffResource::kCouldNotRead_Status; } if (nullptr == comparisonFileBits) { drp->fComparison.fStatus = DiffResource::kCouldNotRead_Status; } drp->fResult = DiffRecord::kCouldNotCompare_Result; return; } if (are_buffers_equal(baseFileBits, comparisonFileBits)) { drp->fResult = DiffRecord::kEqualBits_Result; return; } get_bitmap(baseFileBits, drp->fBase, SkImageDecoder::kDecodePixels_Mode); get_bitmap(comparisonFileBits, drp->fComparison, SkImageDecoder::kDecodePixels_Mode); if (DiffResource::kDecoded_Status != drp->fBase.fStatus || DiffResource::kDecoded_Status != drp->fComparison.fStatus) { drp->fResult = DiffRecord::kCouldNotCompare_Result; return; } create_and_write_diff_image(drp, dmp, colorThreshold, outputDir, outputFilename); //TODO: copy fBase.fFilename and fComparison.fFilename to outputDir // svn and git often present tmp files to diff tools which are promptly deleted //TODO: serialize drp to outputDir // write a tool to deserialize them and call print_diff_page SkASSERT(DiffRecord::kUnknown_Result != drp->fResult); }
/// Creates difference images, returns the number that have a 0 metric. /// If outputDir.isEmpty(), don't write out diff files. static void create_diff_images (DiffMetricProc dmp, const int colorThreshold, RecordArray* differences, const SkString& baseDir, const SkString& comparisonDir, const SkString& outputDir, const StringArray& matchSubstrings, const StringArray& nomatchSubstrings, bool recurseIntoSubdirs, bool getBounds, bool verbose, DiffSummary* summary) { SkASSERT(!baseDir.isEmpty()); SkASSERT(!comparisonDir.isEmpty()); FileArray baseFiles; FileArray comparisonFiles; get_file_list(baseDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &baseFiles); get_file_list(comparisonDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &comparisonFiles); if (!baseFiles.isEmpty()) { qsort(baseFiles.begin(), baseFiles.count(), sizeof(SkString*), SkCastForQSort(compare_file_name_metrics)); } if (!comparisonFiles.isEmpty()) { qsort(comparisonFiles.begin(), comparisonFiles.count(), sizeof(SkString*), SkCastForQSort(compare_file_name_metrics)); } int i = 0; int j = 0; while (i < baseFiles.count() && j < comparisonFiles.count()) { SkString basePath(baseDir); SkString comparisonPath(comparisonDir); DiffRecord *drp = new DiffRecord; int v = strcmp(baseFiles[i]->c_str(), comparisonFiles[j]->c_str()); if (v < 0) { // in baseDir, but not in comparisonDir drp->fResult = DiffRecord::kCouldNotCompare_Result; basePath.append(*baseFiles[i]); comparisonPath.append(*baseFiles[i]); drp->fBase.fFilename = *baseFiles[i]; drp->fBase.fFullPath = basePath; drp->fBase.fStatus = DiffResource::kExists_Status; drp->fComparison.fFilename = *baseFiles[i]; drp->fComparison.fFullPath = comparisonPath; drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status; VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, baseFiles[i]); ++i; } else if (v > 0) { // in comparisonDir, but not in baseDir drp->fResult = DiffRecord::kCouldNotCompare_Result; basePath.append(*comparisonFiles[j]); comparisonPath.append(*comparisonFiles[j]); drp->fBase.fFilename = *comparisonFiles[j]; drp->fBase.fFullPath = basePath; drp->fBase.fStatus = DiffResource::kDoesNotExist_Status; drp->fComparison.fFilename = *comparisonFiles[j]; drp->fComparison.fFullPath = comparisonPath; drp->fComparison.fStatus = DiffResource::kExists_Status; VERBOSE_STATUS("MISSING", ANSI_COLOR_YELLOW, comparisonFiles[j]); ++j; } else { // Found the same filename in both baseDir and comparisonDir. SkASSERT(DiffRecord::kUnknown_Result == drp->fResult); basePath.append(*baseFiles[i]); comparisonPath.append(*comparisonFiles[j]); drp->fBase.fFilename = *baseFiles[i]; drp->fBase.fFullPath = basePath; drp->fBase.fStatus = DiffResource::kExists_Status; drp->fComparison.fFilename = *comparisonFiles[j]; drp->fComparison.fFullPath = comparisonPath; drp->fComparison.fStatus = DiffResource::kExists_Status; SkAutoDataUnref baseFileBits(read_file(drp->fBase.fFullPath.c_str())); if (baseFileBits) { drp->fBase.fStatus = DiffResource::kRead_Status; } SkAutoDataUnref comparisonFileBits(read_file(drp->fComparison.fFullPath.c_str())); if (comparisonFileBits) { drp->fComparison.fStatus = DiffResource::kRead_Status; } if (NULL == baseFileBits || NULL == comparisonFileBits) { if (NULL == baseFileBits) { drp->fBase.fStatus = DiffResource::kCouldNotRead_Status; VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, baseFiles[i]); } if (NULL == comparisonFileBits) { drp->fComparison.fStatus = DiffResource::kCouldNotRead_Status; VERBOSE_STATUS("READ FAIL", ANSI_COLOR_RED, comparisonFiles[j]); } drp->fResult = DiffRecord::kCouldNotCompare_Result; } else if (are_buffers_equal(baseFileBits, comparisonFileBits)) { drp->fResult = DiffRecord::kEqualBits_Result; VERBOSE_STATUS("MATCH", ANSI_COLOR_GREEN, baseFiles[i]); } else { AutoReleasePixels arp(drp); get_bitmap(baseFileBits, drp->fBase, SkImageDecoder::kDecodePixels_Mode); get_bitmap(comparisonFileBits, drp->fComparison, SkImageDecoder::kDecodePixels_Mode); VERBOSE_STATUS("DIFFERENT", ANSI_COLOR_RED, baseFiles[i]); if (DiffResource::kDecoded_Status == drp->fBase.fStatus && DiffResource::kDecoded_Status == drp->fComparison.fStatus) { create_and_write_diff_image(drp, dmp, colorThreshold, outputDir, drp->fBase.fFilename); } else { drp->fResult = DiffRecord::kCouldNotCompare_Result; } } ++i; ++j; } if (getBounds) { get_bounds(*drp); } SkASSERT(DiffRecord::kUnknown_Result != drp->fResult); differences->push(drp); summary->add(drp); } for (; i < baseFiles.count(); ++i) { // files only in baseDir DiffRecord *drp = new DiffRecord(); drp->fBase.fFilename = *baseFiles[i]; drp->fBase.fFullPath = baseDir; drp->fBase.fFullPath.append(drp->fBase.fFilename); drp->fBase.fStatus = DiffResource::kExists_Status; drp->fComparison.fFilename = *baseFiles[i]; drp->fComparison.fFullPath = comparisonDir; drp->fComparison.fFullPath.append(drp->fComparison.fFilename); drp->fComparison.fStatus = DiffResource::kDoesNotExist_Status; drp->fResult = DiffRecord::kCouldNotCompare_Result; if (getBounds) { get_bounds(*drp); } differences->push(drp); summary->add(drp); } for (; j < comparisonFiles.count(); ++j) { // files only in comparisonDir DiffRecord *drp = new DiffRecord(); drp->fBase.fFilename = *comparisonFiles[j]; drp->fBase.fFullPath = baseDir; drp->fBase.fFullPath.append(drp->fBase.fFilename); drp->fBase.fStatus = DiffResource::kDoesNotExist_Status; drp->fComparison.fFilename = *comparisonFiles[j]; drp->fComparison.fFullPath = comparisonDir; drp->fComparison.fFullPath.append(drp->fComparison.fFilename); drp->fComparison.fStatus = DiffResource::kExists_Status; drp->fResult = DiffRecord::kCouldNotCompare_Result; if (getBounds) { get_bounds(*drp); } differences->push(drp); summary->add(drp); } release_file_list(&baseFiles); release_file_list(&comparisonFiles); }