Skip to content

Commit

Permalink
am a792c80: DO NOT MERGE MTP: Implement GetThumb command
Browse files Browse the repository at this point in the history
* commit 'a792c804025e25eb8a110d1db63f26bbd09e0e6b':
  DO NOT MERGE MTP: Implement GetThumb command
  • Loading branch information
mikeandroid authored and Android Git Automerger committed May 4, 2011
2 parents af964a6 + a792c80 commit df88944
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 2 deletions.
4 changes: 3 additions & 1 deletion media/jni/Android.mk
Expand Up @@ -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 \
Expand Down
63 changes: 63 additions & 0 deletions media/jni/android_mtp_MtpDatabase.cpp
Expand Up @@ -35,6 +35,10 @@
#include "MtpUtils.h"
#include "mtp.h"

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

using namespace android;

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -141,6 +145,8 @@ class MyMtpDatabase : public MtpDatabase {
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,
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 10 additions & 0 deletions media/mtp/MtpDataPacket.cpp
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions media/mtp/MtpDataPacket.h
Expand Up @@ -100,6 +100,7 @@ class MtpDataPacket : public MtpPacket {
// 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
Expand Down
2 changes: 2 additions & 0 deletions media/mtp/MtpDatabase.h
Expand Up @@ -84,6 +84,8 @@ class MtpDatabase {
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,
Expand Down
21 changes: 20 additions & 1 deletion media/mtp/MtpServer.cpp
Expand Up @@ -50,7 +50,7 @@ static const MtpOperationCode kSupportedOperationCodes[] = {
MTP_OPERATION_GET_OBJECT_HANDLES,
MTP_OPERATION_GET_OBJECT_INFO,
MTP_OPERATION_GET_OBJECT,
// MTP_OPERATION_GET_THUMB,
MTP_OPERATION_GET_THUMB,
MTP_OPERATION_DELETE_OBJECT,
MTP_OPERATION_SEND_OBJECT_INFO,
MTP_OPERATION_SEND_OBJECT,
Expand Down Expand Up @@ -370,6 +370,9 @@ bool MtpServer::handleRequest() {
case MTP_OPERATION_GET_OBJECT:
response = doGetObject();
break;
case MTP_OPERATION_GET_THUMB:
response = doGetThumb();
break;
case MTP_OPERATION_GET_PARTIAL_OBJECT:
case MTP_OPERATION_GET_PARTIAL_OBJECT_64:
response = doGetPartialObject(operation);
Expand Down Expand Up @@ -736,6 +739,22 @@ MtpResponseCode MtpServer::doGetObject() {
return MTP_RESPONSE_OK;
}

MtpResponseCode MtpServer::doGetThumb() {
MtpObjectHandle handle = mRequest.getParameter(1);
size_t thumbSize;
void* thumb = mDatabase->getThumbnail(handle, thumbSize);
if (thumb) {
// send data
mData.setOperationCode(mRequest.getOperationCode());
mData.setTransactionID(mRequest.getTransactionID());
mData.writeData(mFD, thumb, thumbSize);
free(thumb);
return MTP_RESPONSE_OK;
} else {
return MTP_RESPONSE_GENERAL_ERROR;
}
}

MtpResponseCode MtpServer::doGetPartialObject(MtpOperationCode operation) {
if (!hasStorage())
return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
Expand Down
1 change: 1 addition & 0 deletions media/mtp/MtpServer.h
Expand Up @@ -133,6 +133,7 @@ class MtpServer {
MtpResponseCode doGetObjectPropList();
MtpResponseCode doGetObjectInfo();
MtpResponseCode doGetObject();
MtpResponseCode doGetThumb();
MtpResponseCode doGetPartialObject(MtpOperationCode operation);
MtpResponseCode doSendObjectInfo();
MtpResponseCode doSendObject();
Expand Down

0 comments on commit df88944

Please sign in to comment.