in analyzer/src/main/java/com/android/tools/sizereduction/analyzer/suggesters/binaryfiles/WebpSuggester.java [76:136]
private ImmutableList<Suggestion> processFileEntry(Context context, FileData fileData) {
if (context.getMinSdkVersion() < MIN_SDK_VERSION_SUPPORTING_LOSSLESS_WEBP) {
return ImmutableList.of();
}
if (!SUPPORTED_FILE_TYPES.contains(getFileExtension(fileData))) {
return ImmutableList.of();
}
String lowercasePath = Ascii.toLowerCase(fileData.getPathWithinRoot().toString());
if (lowercasePath.endsWith(".9.png")) {
// 9patch images must be in PNG format
return ImmutableList.of();
}
try (InputStream inputStream = fileData.getInputStream()) {
CountingInputStream countingStream = new CountingInputStream(inputStream);
BufferedImage bufferedImage = safelyParseImage(countingStream);
long oldSize = countingStream.getCount();
byte[] webpBytes = webpConverter.encodeLosslessWebp(bufferedImage);
long newSize = webpBytes.length;
long reduction = oldSize - newSize;
if (reduction >= SIZE_REDUCTION_THRESHOLD_BYTES) {
// We must round off the estimate to account for slight differences between different
// versions of the webp tools (cwebp uses a higher effort factor by default than libwebp,
// and we have no way of controlling it given this API).
// We don't want to seem to promise a specific size reduction so we round down to the
// nearest
// round number.
long estimate = reduction - (reduction % ESTIMATE_PRECISION);
WebpAutoFix autoFix = null;
if (fileData instanceof SystemFileData) {
autoFix = new WebpAutoFix(((SystemFileData) fileData).getSystemPath());
}
return ImmutableList.of(
Suggestion.create(
Suggestion.IssueType.WEBP,
Suggestion.Category.WEBP,
Payload.newBuilder()
.setWebpData(
WebpData.newBuilder()
.setFile(
FileEntryData.newBuilder()
.setFilePath(fileData.getPathWithinRoot().toString())))
.build(),
"Convert " + fileData.getPathWithinRoot() + " to webp with lossless encoding",
estimate,
autoFix));
} else {
return ImmutableList.of();
}
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (ImageReadException e) {
// We shouldn't crash if we can't read the image.
return ImmutableList.of();
}
}