void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) { // Load the images at the paths SkBitmap baselineBitmap; SkBitmap testBitmap; if (!SkImageDecoder::DecodeFile(baselinePath, &baselineBitmap)) { SkDebugf("Failed to load bitmap \"%s\"\n", baselinePath); return; } if (!SkImageDecoder::DecodeFile(testPath, &testBitmap)) { SkDebugf("Failed to load bitmap \"%s\"\n", testPath); return; } // Setup a record for this diff DiffRecord* newRecord = SkNEW(DiffRecord); newRecord->fBaselinePath = baselinePath; newRecord->fTestPath = testPath; newRecord->fNext = fRecords; fRecords = newRecord; // Perform each diff for (int differIndex = 0; differIndex < fDifferCount; differIndex++) { SkImageDiffer* differ = fDiffers[differIndex]; int diffID = differ->queueDiff(&baselineBitmap, &testBitmap); if (diffID >= 0) { // Copy the results into data for this record DiffData& diffData = newRecord->fDiffs.push_back(); diffData.fDiffName = differ->getName(); diffData.fResult = differ->getResult(diffID); int poiCount = differ->getPointsOfInterestCount(diffID); SkIPoint* poi = differ->getPointsOfInterest(diffID); diffData.fPointsOfInterest.append(poiCount, poi); // Because we are doing everything synchronously for now, we are done with the diff // after reading it. differ->deleteDiff(diffID); } } }
void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) { // Load the images at the paths SkBitmap baselineBitmap; SkBitmap testBitmap; if (!SkImageDecoder::DecodeFile(baselinePath, &baselineBitmap)) { SkDebugf("Failed to load bitmap \"%s\"\n", baselinePath); return; } if (!SkImageDecoder::DecodeFile(testPath, &testBitmap)) { SkDebugf("Failed to load bitmap \"%s\"\n", testPath); return; } // Setup a record for this diff fRecordMutex.acquire(); DiffRecord* newRecord = fRecords.addToHead(DiffRecord()); fRecordMutex.release(); // compute the common name SkString baseName = SkOSPath::Basename(baselinePath); SkString testName = SkOSPath::Basename(testPath); if (longNames) { newRecord->fCommonName = get_combined_name(baseName, testName); } else { newRecord->fCommonName = get_common_prefix(baseName, testName); } newRecord->fCommonName.append(".png"); newRecord->fBaselinePath = baselinePath; newRecord->fTestPath = testPath; newRecord->fSize = SkISize::Make(baselineBitmap.width(), baselineBitmap.height()); // only generate diff images if we have a place to store them SkImageDiffer::BitmapsToCreate bitmapsToCreate; bitmapsToCreate.alphaMask = !fAlphaMaskDir.isEmpty(); bitmapsToCreate.rgbDiff = !fRgbDiffDir.isEmpty(); bitmapsToCreate.whiteDiff = !fWhiteDiffDir.isEmpty(); // Perform each diff for (int differIndex = 0; differIndex < fDifferCount; differIndex++) { SkImageDiffer* differ = fDiffers[differIndex]; // Copy the results into data for this record DiffData& diffData = newRecord->fDiffs.push_back(); diffData.fDiffName = differ->getName(); if (!differ->diff(&baselineBitmap, &testBitmap, bitmapsToCreate, &diffData.fResult)) { // if the diff failed, record -1 as the result // TODO(djsollen): Record more detailed information about exactly what failed. // (Image dimension mismatch? etc.) See http://skbug.com/2710 ('make skpdiff // report more detail when it fails to compare two images') diffData.fResult.result = -1; continue; } if (bitmapsToCreate.alphaMask && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result && !diffData.fResult.poiAlphaMask.empty() && !newRecord->fCommonName.isEmpty()) { newRecord->fAlphaMaskPath = SkOSPath::Join(fAlphaMaskDir.c_str(), newRecord->fCommonName.c_str()); // compute the image diff and output it SkBitmap copy; diffData.fResult.poiAlphaMask.copyTo(©, kN32_SkColorType); SkImageEncoder::EncodeFile(newRecord->fAlphaMaskPath.c_str(), copy, SkImageEncoder::kPNG_Type, 100); // cleanup the existing bitmap to free up resources; diffData.fResult.poiAlphaMask.reset(); bitmapsToCreate.alphaMask = false; } if (bitmapsToCreate.rgbDiff && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result && !diffData.fResult.rgbDiffBitmap.empty() && !newRecord->fCommonName.isEmpty()) { // TODO(djsollen): Rather than taking the max r/g/b diffs that come back from // a particular differ and storing them as toplevel fields within // newRecord, we should extend outputRecords() to report optional // fields for each differ (not just "result" and "pointsOfInterest"). // See http://skbug.com/2712 ('allow skpdiff to report different sets // of result fields for different comparison algorithms') newRecord->fMaxRedDiff = diffData.fResult.maxRedDiff; newRecord->fMaxGreenDiff = diffData.fResult.maxGreenDiff; newRecord->fMaxBlueDiff = diffData.fResult.maxBlueDiff; newRecord->fRgbDiffPath = SkOSPath::Join(fRgbDiffDir.c_str(), newRecord->fCommonName.c_str()); SkImageEncoder::EncodeFile(newRecord->fRgbDiffPath.c_str(), diffData.fResult.rgbDiffBitmap, SkImageEncoder::kPNG_Type, 100); diffData.fResult.rgbDiffBitmap.reset(); bitmapsToCreate.rgbDiff = false; } if (bitmapsToCreate.whiteDiff && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result && !diffData.fResult.whiteDiffBitmap.empty() && !newRecord->fCommonName.isEmpty()) { newRecord->fWhiteDiffPath = SkOSPath::Join(fWhiteDiffDir.c_str(), newRecord->fCommonName.c_str()); SkImageEncoder::EncodeFile(newRecord->fWhiteDiffPath.c_str(), diffData.fResult.whiteDiffBitmap, SkImageEncoder::kPNG_Type, 100); diffData.fResult.whiteDiffBitmap.reset(); bitmapsToCreate.whiteDiff = false; } } }