Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 710a2064 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

DO NOT MERGE MTP: Implement GetThumb command



This allows the PC to access thumbnails in JPEG files over MTP/PTP

Bug: 3219495

Change-Id: Id61f353ba70e896fae9a47338bf7871c0f185d3e
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 7fc3bebb
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -27,9 +27,11 @@ LOCAL_SHARED_LIBRARIES := \
    libcamera_client \
    libsqlite \
    libmtp \
    libusbhost
    libusbhost \
    libexif

LOCAL_C_INCLUDES += \
    external/jhead \
    external/tremor/Tremor \
    frameworks/base/core/jni \
    frameworks/base/media/libmedia \
+63 −0
Original line number Diff line number Diff line
@@ -35,6 +35,10 @@
#include "MtpUtils.h"
#include "mtp.h"

extern "C" {
#include "jhead.h"
}

using namespace android;

// ----------------------------------------------------------------------------
@@ -141,6 +145,8 @@ public:
    virtual MtpResponseCode         getObjectInfo(MtpObjectHandle handle,
                                            MtpObjectInfo& info);

    virtual void*                   getThumbnail(MtpObjectHandle handle, size_t& outThumbSize);

    virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
                                            MtpString& outFilePath,
                                            int64_t& outFileLength,
@@ -778,10 +784,67 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
    info.mName = strdup((const char *)temp);
    env->ReleaseCharArrayElements(mStringBuffer, str, 0);

    // read EXIF data for thumbnail information
    if (info.mFormat == MTP_FORMAT_EXIF_JPEG || info.mFormat == MTP_FORMAT_JFIF) {
        MtpString path;
        int64_t length;
        MtpObjectFormat format;
        if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK) {
            ResetJpgfile();
             // Start with an empty image information structure.
            memset(&ImageInfo, 0, sizeof(ImageInfo));
            ImageInfo.FlashUsed = -1;
            ImageInfo.MeteringMode = -1;
            ImageInfo.Whitebalance = -1;
            strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
            if (ReadJpegFile((const char*)path, READ_METADATA)) {
                Section_t* section = FindSection(M_EXIF);
                if (section) {
                    info.mThumbCompressedSize = ImageInfo.ThumbnailSize;
                    info.mThumbFormat = MTP_FORMAT_EXIF_JPEG;
                    info.mImagePixWidth = ImageInfo.Width;
                    info.mImagePixHeight = ImageInfo.Height;
                }
            }
            DiscardData();
        }
    }

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return MTP_RESPONSE_OK;
}

void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) {
    MtpString path;
    int64_t length;
    MtpObjectFormat format;
    void* result = NULL;
    outThumbSize = 0;

    if (getObjectFilePath(handle, path, length, format) == MTP_RESPONSE_OK
            && (format == MTP_FORMAT_EXIF_JPEG || format == MTP_FORMAT_JFIF)) {
        ResetJpgfile();
         // Start with an empty image information structure.
        memset(&ImageInfo, 0, sizeof(ImageInfo));
        ImageInfo.FlashUsed = -1;
        ImageInfo.MeteringMode = -1;
        ImageInfo.Whitebalance = -1;
        strncpy(ImageInfo.FileName, (const char *)path, PATH_MAX);
        if (ReadJpegFile((const char*)path, READ_METADATA)) {
            Section_t* section = FindSection(M_EXIF);
            if (section) {
                outThumbSize = ImageInfo.ThumbnailSize;
                result = malloc(outThumbSize);
                if (result)
                    memcpy(result, section->Data + ImageInfo.ThumbnailOffset + 8, outThumbSize);
            }
            DiscardData();
        }
    }

    return result;
}

MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle,
                                            MtpString& outFilePath,
                                            int64_t& outFileLength,
+10 −0
Original line number Diff line number Diff line
@@ -388,6 +388,16 @@ int MtpDataPacket::writeDataHeader(int fd, uint32_t length) {
    int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
    return (ret < 0 ? ret : 0);
}

int MtpDataPacket::writeData(int fd, void* data, uint32_t length) {
    MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length + MTP_CONTAINER_HEADER_SIZE);
    MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
    int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
    if (ret == MTP_CONTAINER_HEADER_SIZE)
        ret = ::write(fd, data, length);
    return (ret < 0 ? ret : 0);
}

#endif // MTP_DEVICE

#ifdef MTP_HOST
+1 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ public:
    // write our data to the given file descriptor
    int                 write(int fd);
    int                 writeDataHeader(int fd, uint32_t length);
    int                 writeData(int fd, void* data, uint32_t length);
#endif

#ifdef MTP_HOST
+2 −0
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ public:
    virtual MtpResponseCode         getObjectInfo(MtpObjectHandle handle,
                                            MtpObjectInfo& info) = 0;

    virtual void*                   getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) = 0;

    virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
                                            MtpString& outFilePath,
                                            int64_t& outFileLength,
Loading