From 1f1f81e0d15dd2130dd2a806e6943b0063a5e9ea Mon Sep 17 00:00:00 2001 From: James Wei Date: Mon, 22 Mar 2021 13:17:01 +0800 Subject: [PATCH] MTP: Add thumbnail generation for JPG Add thumbnail generation support for JPG image format Instead of retrieving thumbnail from EXIF header Bug: 178726106 Test: atest MtpTests Test: manual test on Windows 10 file explorer Test: manual test on Linux nautilus file browser Change-Id: I29ad89835a8a27204a2e6dbd97b994209a813424 --- media/java/android/mtp/MtpDatabase.java | 18 +++++++++++++++--- .../tests/MtpTests/res/raw/test_bad_thumb.jpg | Bin 0 -> 8610 bytes .../src/android/mtp/MtpDatabaseTest.java | 5 +++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java index ed56b4398c226..9fe700a41ab24 100755 --- a/media/java/android/mtp/MtpDatabase.java +++ b/media/java/android/mtp/MtpDatabase.java @@ -821,8 +821,10 @@ public class MtpDatabase implements AutoCloseable { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream); - if (byteStream.size() > MAX_THUMB_SIZE) + if (byteStream.size() > MAX_THUMB_SIZE) { + Log.w(TAG, "getThumbnailProcess: size=" + byteStream.size()); return null; + } byte[] byteArray = byteStream.toByteArray(); @@ -852,7 +854,15 @@ public class MtpDatabase implements AutoCloseable { outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0; outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0); outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_DIMENSION, 0); - return true; + if (exif.getThumbnailRange() != null) { + if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) { + Log.d(TAG, "getThumbnailInfo: check thumb info:" + + thumbOffsetAndSize[0] + "," + thumbOffsetAndSize[1] + + "," + outLongs[1] + "," + outLongs[2]); + } + + return true; + } } catch (IOException e) { // ignore and fall through } @@ -885,7 +895,9 @@ public class MtpDatabase implements AutoCloseable { case MtpConstants.FORMAT_JFIF: try { ExifInterface exif = new ExifInterface(path); - return exif.getThumbnail(); + + if (exif.getThumbnailRange() != null) + return exif.getThumbnail(); } catch (IOException e) { // ignore and fall through } diff --git a/media/tests/MtpTests/res/raw/test_bad_thumb.jpg b/media/tests/MtpTests/res/raw/test_bad_thumb.jpg index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..78ac703850a1e1365dac6ffb7e8c35e98b8e7bb2 100644 GIT binary patch literal 8610 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 FzW_a&cRc_A literal 0 HcmV?d00001 diff --git a/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java index e2e8ff4946e01..0bf99cfd9dd1d 100644 --- a/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java +++ b/media/tests/MtpTests/src/android/mtp/MtpDatabaseTest.java @@ -271,9 +271,10 @@ public class MtpDatabaseTest { Log.d(TAG, "testMtpDatabaseThumbnail: Test bad JPG"); - testThumbnail(handleJpgBadThumb, jpgfileBadThumb, false); +// Now we support to generate thumbnail if embedded thumbnail is corrupted or not existed + testThumbnail(handleJpgBadThumb, jpgfileBadThumb, true); - testThumbnail(handleJpgNoThumb, jpgFileNoThumb, false); + testThumbnail(handleJpgNoThumb, jpgFileNoThumb, true); testThumbnail(handleJpgBad, jpgfileBad, false);