--- /dev/null
+package net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.playback;
+
+import android.util.Log;
+
+import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent;
+
+import java.util.Date;
+
+class NikonImageContentInfo implements ICameraContent
+{
+ private final String TAG = toString();
+ private Date date;
+ private String contentName = "";
+ private boolean isDateValid = false;
+ private boolean isContentNameValid = false;
+ private int contentSize = 0;
+
+
+ private final int storageId;
+ private final int subDirectoryId;
+ private final int objectId;
+
+ NikonImageContentInfo(int storageId, int subDirectoryId, int objectId)
+ {
+ this.storageId = storageId;
+ this.subDirectoryId = subDirectoryId;
+ this.objectId = objectId;
+ this.date = new Date();
+
+ //String dumpLog = String.format(" ST: 0x%08x SD: 0x%08x OBJ: 0x%08x", storageId, subDirectoryId, objectId);
+ //Log.v(TAG, " NikonImageContentInfo " + dumpLog);
+ }
+
+ int getStorageId()
+ {
+ return (storageId);
+ }
+
+ int getSubdirectoryId()
+ {
+ return (subDirectoryId);
+ }
+
+ int getObjectId()
+ {
+ return (objectId);
+ }
+
+ int getOriginalSize()
+ {
+ return (contentSize);
+ }
+
+ @Override
+ public String getCameraId()
+ {
+ return "";
+ }
+
+ @Override
+ public String getCardId()
+ {
+ return (String.format("0x%08x", storageId));
+ }
+
+ @Override
+ public String getContentPath()
+ {
+ return (String.format("0x%08x", subDirectoryId));
+ }
+
+ @Override
+ public String getContentName()
+ {
+ if (isContentNameValid)
+ {
+ return (contentName);
+ }
+ return (String.format("0x%08x.JPG", objectId));
+ }
+
+ @Override
+ public boolean isDateValid()
+ {
+ return (isDateValid);
+ }
+
+ @Override
+ public Date getCapturedDate()
+ {
+ return (date);
+ }
+
+ @Override
+ public void setCapturedDate(Date date)
+ {
+ Log.v(TAG, "setCapturedDate()");
+ this.date = date;
+ isDateValid = true;
+ }
+
+ public void setContentName(String contentName)
+ {
+ Log.v(TAG, "setContentName() : " + contentName);
+ this.contentName = contentName;
+ isContentNameValid = true;
+ }
+
+ public void setOriginalSize(int size)
+ {
+ this.contentSize = size;
+ }
+}
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
-import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback.PtpIpImageContentInfo;
import java.util.ArrayList;
import java.util.List;
-import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX_2;
-import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX_3;
import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_ID;
-import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_STORAGE_INFO;
-import static net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpMessages.GET_OBJECT_INFO_EX;
public class NikonImageObjectReceiver implements IPtpIpCommandCallback, NikonStorageContentHolder.ImageObjectReceivedCallback
{
private final String TAG = toString();
private final NikonInterfaceProvider provider;
private boolean isDumpLog = true;
- private List<ICameraContent> imageObjectList;
- private List<PtpIpImageContentInfo> ptpIpImageObjectList;
private ICameraContentListCallback callback = null;
- private int subDirectoriesCount = -1;
- private int receivedSubDirectoriesCount = -1;
private SparseArray<NikonStorageContentHolder> storageIdList;
NikonImageObjectReceiver(NikonInterfaceProvider provider)
{
this.provider = provider;
- this.imageObjectList = new ArrayList<>();
- this.ptpIpImageObjectList = new ArrayList<>();
-
this.storageIdList = new SparseArray<>();
}
{
try
{
- IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
- //SimpleLogDumper.dump_bytes(" [RX] ", rx_body);
- switch (id)
+ if (id == GET_STORAGE_ID)
{
- case GET_STORAGE_ID:
- // ストレージID一覧を解析する
- parseStorageId(rx_body);
- for(int index = 0; index < storageIdList.size(); index++)
- {
- int key = storageIdList.keyAt(index);
- NikonStorageContentHolder contentHolder = storageIdList.get(key);
- contentHolder.getContents();
- }
- subDirectoriesCount = -1; // ここから画像取得シーケンスに入るので、、、
- break;
-
- case GET_STORAGE_INFO:
- // TODO: (要検討) ストレージの情報を取得しているが、本当に使わなくてもよい?
- publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX, isDumpLog, 0, 0x9109, 12, 0x00010001, 0xffffffff, 0x00200000));
- break;
-
- case GET_OBJECT_INFO_EX:
- List<PtpIpImageContentInfo> directries = parseContentSubdirectories(rx_body, 32);
- {
- // サブディレクトリの情報を拾う
- for (PtpIpImageContentInfo contentInfo : directries)
- {
- publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX_2, isDumpLog, 0, 0x9109, 12, 0x00010001, contentInfo.getId(), 0x00200000));
- }
- }
- break;
-
- case GET_OBJECT_INFO_EX_2:
- List<PtpIpImageContentInfo> subDirectries = parseContentSubdirectories(rx_body, 32);
- {
- // 画像の情報を拾う
- for (PtpIpImageContentInfo contentInfo : subDirectries)
- {
- publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_OBJECT_INFO_EX_3, isDumpLog, 0, 0x9109, 12, 0x00010001, contentInfo.getId(), 0x00200000));
- }
- subDirectoriesCount = subDirectries.size();
- receivedSubDirectoriesCount = 0;
- if (subDirectoriesCount <= 0)
- {
- // カメラの画像コンテンツが見つからなかった(サブディレクトリがなかった)...ここで画像解析終了の報告をする
- callback.onCompleted(imageObjectList);
- }
- }
- break;
-
- case GET_OBJECT_INFO_EX_3:
- if (isDumpLog)
- {
- Log.v(TAG, " --- CONTENT ---");
- }
- List<PtpIpImageContentInfo> objects = parseContentSubdirectories(rx_body, 32);
- if (objects.size() > 0)
- {
- imageObjectList.addAll(objects);
- ptpIpImageObjectList.addAll(objects);
- }
- receivedSubDirectoriesCount++;
- if (receivedSubDirectoriesCount >= subDirectoriesCount)
- {
- // 全コンテンツの受信成功
- if(this.callback != null)
- {
- callback.onCompleted(imageObjectList);
- }
- }
- break;
-
- default:
-/*
- if ((id & 0xff) == GET_STORAGE_HANDLE1)
- {
- }
-*/
- break;
+ // ストレージID一覧を解析する
+ parseStorageId(rx_body);
+ for(int index = 0; index < storageIdList.size(); index++)
+ {
+ int key = storageIdList.keyAt(index);
+ NikonStorageContentHolder contentHolder = storageIdList.get(key);
+ contentHolder.getContents();
+ }
}
}
catch (Exception e)
}
}
+/*
private List<PtpIpImageContentInfo> parseContentSubdirectories(byte[] rx_body, int offset)
{
List<PtpIpImageContentInfo> result = new ArrayList<>();
}
return (result);
}
+*/
@Override
public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
return (false);
}
- PtpIpImageContentInfo getContentObject(String fileName)
+ NikonImageContentInfo getContentObject(String fileName)
{
- for (PtpIpImageContentInfo contentInfo : ptpIpImageObjectList)
+ for(int index = 0; index < storageIdList.size(); index++)
{
-
- if (fileName.matches(contentInfo.getContentName()))
+ int key = storageIdList.keyAt(index);
+ NikonStorageContentHolder contentHolder = storageIdList.get(key);
+ SparseArray<NikonImageContentInfo> objectArray = contentHolder.getObjectIdList();
+ int objectId = Integer.parseInt(fileName.substring(fileName.indexOf("/") + 3, fileName.indexOf(".")), 16);
+ NikonImageContentInfo content = objectArray.get(objectId);
+ if (content != null)
{
- return (contentInfo);
+ return (content);
}
}
return (null);
}
- public void getCameraContents(ICameraContentListCallback callback)
+ void getCameraContents(ICameraContentListCallback callback)
{
this.callback = null;
try
if (publisher != null)
{
// オブジェクト一覧をクリアする
- this.imageObjectList.clear();
- this.ptpIpImageObjectList.clear();
-
publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_ID, isDumpLog, 0, 0x1004)); // GetStorageIDs
this.callback = callback;
}
public void onReceived(int storageId)
{
Log.v(TAG, " ----- STORAGE ID : " + storageId + " -----");
-
- List<Integer> objectList = new ArrayList<>();
+ List<ICameraContent> objectList = new ArrayList<>();
for(int index = 0; index < storageIdList.size(); index++)
{
int key = storageIdList.keyAt(index);
{
return;
}
- objectList.addAll(contentHolder.getObjectIdList());
+ SparseArray<NikonImageContentInfo> objectArray = contentHolder.getObjectIdList();
+ for (int objectIndex = 0; objectIndex < objectArray.size(); objectIndex++)
+ {
+ objectList.add(objectArray.valueAt(objectIndex));
+ }
}
+
// すべてのStorageで Object Id の取得が終わった!
- Log.v(TAG," ----- RECEIVED ALL IMAGE OBJECT ID count : " + objectList.size() + "-----");
- for (int id : objectList)
- {
- Log.v(TAG, " OBJECT ID : " + id);
- }
- Log.v(TAG, " --------------------");
+ Log.v(TAG," ----- RECEIVED ALL IMAGE OBJECT ID count : " + objectList.size() + " -----");
+ callback.onCompleted(objectList);
}
@Override
public void onError(Exception e)
{
Log.v(TAG, "onError : " + e.getLocalizedMessage());
-
}
}
start = 1;
}
final String indexStr = path.substring(start);
- PtpIpImageContentInfo content = nikonImageObjectReceiver.getContentObject(indexStr);
+ NikonImageContentInfo content = nikonImageObjectReceiver.getContentObject(indexStr);
if (content != null)
{
IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
//int storageId = content.getStorageId();
- int objectId = content.getId();
+ int objectId = content.getObjectId();
// 画像表示中...のメッセージを表示する
IInformationReceiver display = provider.getInformationReceiver();
// 画像を取得する
PtpIpScreennailImageReceiver receiver = new PtpIpScreennailImageReceiver(activity, objectId, publisher, callback);
- publisher.enqueueCommand(new CanonRequestInnerDevelopStart(receiver, objectId, true, objectId, objectId)); // 0x9141 : RequestInnerDevelopStart
+ publisher.enqueueCommand(new PtpIpCommandGeneric(new PtpIpThumbnailImageReceiver(activity, callback), objectId, false, 0, 0x90c4, 4, objectId));
}
}
catch (Exception e)
}
//String indexStr = path.substring(start, path.indexOf("."));
final String indexStr = path.substring(start);
- //Log.v(TAG, "downloadContentThumbnail() : [" + path + "] " + indexStr);
+ Log.v(TAG, "downloadContentThumbnail() : [" + path + "] " + indexStr);
- PtpIpImageContentInfo content = nikonImageObjectReceiver.getContentObject(indexStr);
+ NikonImageContentInfo content = nikonImageObjectReceiver.getContentObject(indexStr);
if (content != null)
{
IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
- //int storageId = content.getStorageId();
- int objectId = content.getId();
+ int objectId = content.getObjectId();
// Log.v(TAG, "downloadContentThumbnail() " + indexStr + " [" + objectId + "] (" + storageId + ")");
- publisher.enqueueCommand(new PtpIpCommandGeneric(new PtpIpThumbnailImageReceiver(activity, callback), objectId, false, 0, 0x910a, 8, objectId, 0x00032000));
+ publisher.enqueueCommand(new PtpIpCommandGeneric(new PtpIpThumbnailImageReceiver(activity, callback), objectId, false, 0, 0x100a, 4, objectId));
}
}
catch (Exception e)
start = 1;
}
final String indexStr = path.substring(start);
- PtpIpImageContentInfo content = nikonImageObjectReceiver.getContentObject(indexStr);
+ NikonImageContentInfo content = nikonImageObjectReceiver.getContentObject(indexStr);
if (content != null)
{
if (isSmallSize)
{
// スモールサイズの画像取得コマンド(シーケンス)を発行する
- smallImageReciever.issueCommand(content.getId(), callback);
+ smallImageReciever.issueCommand(content.getObjectId(), callback);
}
else
{
// オリジナル画像の取得コマンド(シーケンス)を発行する
- fullImageReceiver.issueCommand(content.getId(), content.getOriginalSize(), callback);
+ fullImageReceiver.issueCommand(content.getObjectId(), content.getOriginalSize(), callback);
}
}
}
e.printStackTrace();
}
}
-
}
package net.osdn.gokigen.pkremote.camera.vendor.nikon.wrapper.playback;
import android.util.Log;
+import android.util.SparseArray;
import androidx.annotation.NonNull;
private final NikonInterfaceProvider provider;
private final ImageObjectReceivedCallback callback;
private boolean isDumpLog = true;
- private List<Integer> objectList;
private int subDirectoryCount = 0;
private int receivedDirectoryCount = 0;
private boolean isObjectReceived = false;
+ private SparseArray<NikonImageContentInfo> imageObjectList;
NikonStorageContentHolder(@NonNull NikonInterfaceProvider provider, int storageId, @NonNull ImageObjectReceivedCallback callback)
{
this.provider = provider;
this.storageId = storageId;
this.callback = callback;
- this.objectList = new ArrayList<>();
+ this.imageObjectList = new SparseArray<>();
}
void getContents()
isObjectReceived = false;
IPtpIpCommandPublisher publisher = provider.getCommandPublisher();
publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_HANDLE1, isDumpLog, 0, 0x1007, 12, storageId, 0x00003001, 0xffffffff));
- objectList.clear();
+ imageObjectList.clear();
}
catch (Exception e)
{
{
int checkBytes = rx_body[0];
int readPosition = checkBytes + 12;
- int nofSubDirectories = ((int) rx_body[readPosition]) +
- ((int) rx_body[readPosition + 1] << 8) +
- ((int) rx_body[readPosition + 2] << 16) +
- ((int) rx_body[readPosition + 3] << 24);
+ int nofSubDirectories = ((int) rx_body[readPosition] & 0x000000ff) +
+ (((int) rx_body[readPosition + 1] & 0x000000ff) << 8) +
+ (((int) rx_body[readPosition + 2] & 0x000000ff) << 16) +
+ (((int) rx_body[readPosition + 3] & 0x000000ff) << 24);
for (int index = 0; index < nofSubDirectories; index++)
{
readPosition = readPosition + 4;
- int directoryId = ((int) rx_body[readPosition]) +
- ((int) rx_body[readPosition + 1] << 8) +
- ((int) rx_body[readPosition + 2] << 16) +
- ((int) rx_body[readPosition + 3] << 24);
- directoryList.add(directoryId);
+ byte data0 = rx_body[readPosition];
+ byte data1 = rx_body[readPosition + 1];
+ byte data2 = rx_body[readPosition + 2];
+ byte data3 = rx_body[readPosition + 3];
+ int objectId = ((int) data0 & 0x000000ff) + (((int) data1 & 0x000000ff) << 8) + (((int) data2 & 0x000000ff) << 16)+ (((int) data3 & 0x000000ff) << 24);
+ directoryList.add(objectId);
}
}
catch (Exception e)
// サブディレクトリの一覧を受信した
subDirectoryCount = 0;
receivedDirectoryCount = 0;
- List<Integer> subDirectoriesList = parseObjects(rx_body);
- for (int subDirectory : subDirectoriesList)
+ final List<Integer> subDirectoriesList = parseObjects(rx_body);
+ for (final int subDirectory : subDirectoriesList)
{
Log.v(TAG, " STORAGE ID : " + storageId + " DIRECTORY ID : " + subDirectory);
- publisher.enqueueCommand(new PtpIpCommandGeneric(this, GET_STORAGE_HANDLE3, isDumpLog, 0, 0x1007, 12, storageId, 0x00000000, subDirectory)); //
+
+ publisher.enqueueCommand(new PtpIpCommandGeneric(new IPtpIpCommandCallback() {
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ // OBJECT IDリストを受信した!
+ List<Integer> objectsList = parseObjects(rx_body);
+ for (int objectId : objectsList)
+ {
+ imageObjectList.append(objectId, new NikonImageContentInfo(storageId, subDirectory, objectId));
+ }
+ receivedDirectoryCount++;
+ if (subDirectoryCount <= receivedDirectoryCount)
+ {
+ // 送信要求したメッセージの応答をすべて受信した!
+ isObjectReceived = true;
+ callback.onReceived(storageId);
+ }
+ }
+
+ @Override
+ public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
+ {
+ //
+ }
+
+ @Override
+ public boolean isReceiveMulti() {
+ return false;
+ }
+ }, GET_STORAGE_HANDLE3, isDumpLog, 0, 0x1007, 12, storageId, 0x00000000, subDirectory));
+
+/*
+ // ストレージ名称。。。ここでは利用できない
+ publisher.enqueueCommand(new PtpIpCommandGeneric(new IPtpIpCommandCallback() {
+ @Override
+ public void receivedMessage(int id, byte[] rx_body)
+ {
+ try
+ {
+ // ストレージIDの情報を取得 (名称、作成日時、更新日時)
+ String directoryName = parse2ByteCharacters(rx_body, ((int) rx_body[0] + 12 + 16 * 3 + 4));
+ String createTime =parse2ByteCharacters(rx_body, ((int) rx_body[0] + 12 + 16 * 4 + 7));
+ String modifyTime = parse2ByteCharacters(rx_body, ((int) rx_body[0] + 12 + 16 * 6 + 8));
+ Log.v(TAG, " ST: " + storageId + " SD : " + subDirectory + " " + directoryName + " " + createTime + " " + modifyTime);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
+ {
+ // なにもしない
+ }
+
+ @Override
+ public boolean isReceiveMulti()
+ {
+ return (false);
+ }
+ }, GET_FOLDER_INFO, isDumpLog, 0, 0x1008, 4, subDirectory));
+*/
subDirectoryCount++;
}
- return;
}
- if (id == GET_STORAGE_HANDLE3)
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ callback.onError(e);
+ }
+ }
+
+/*
+ private String parse2ByteCharacters(byte[] rx_body, int startPosition)
+ {
+ int length = (int) rx_body[startPosition] - 1;
+ startPosition++;
+
+ String value = "";
+ try
+ {
+ byte[] data = new byte[length];
+ for (int index = 0; index < length; index++)
{
- // OBJECT IDリストを受信した!
- List<Integer> objectsList = parseObjects(rx_body);
- objectList.addAll(objectsList);
- receivedDirectoryCount++;
- if (subDirectoryCount <= receivedDirectoryCount)
- {
- // 送信要求したメッセージの応答をすべて受信した!
- isObjectReceived = true;
- callback.onReceived(storageId);
- }
+ data[index] = rx_body[startPosition + index * 2];
}
+ value = new String(data);
}
catch (Exception e)
{
e.printStackTrace();
- callback.onError(e);
}
+ return (value);
}
+*/
- List<Integer> getObjectIdList()
+ SparseArray<NikonImageContentInfo> getObjectIdList()
{
- return (objectList);
+ return (imageObjectList);
}
boolean isObjectIdReceived()
@Override
public void onReceiveProgress(int currentBytes, int totalBytes, byte[] rx_body)
{
-
+ //
}
@Override
int GET_STORAGE_HANDLE1 = 110;
int GET_STORAGE_HANDLE2 = 111;
int GET_STORAGE_HANDLE3 = 112;
+ int GET_FOLDER_INFO = 113;
/*
private static final String PENTAX_RAW_PEF_SUFFIX = ".pef";
private static final String PANASONIC_RAW_SUFFIX = ".rw2";
private static final String SONY_RAW_SUFFIX = ".arw";
+ private static final String NIKON_RAW_SUFFIX = ".nef";
private static final String CANON_RAW_SUFFIX = ".crw";
private static final String CANON_RAW_SUFFIX2 = ".cr2";
private static final String CANON_RAW_SUFFIX3 = ".cr3";
{
contentItems.add(new CameraContentEx(item, true, CANON_RAW_SUFFIX3));
}
+ else if (path.endsWith(NIKON_RAW_SUFFIX))
+ {
+ contentItems.add(new CameraContentEx(item, true, NIKON_RAW_SUFFIX));
+ }
}
for (CameraContentEx item : contentItems)
android:title="@string/pref_nikon_host_ip"
android:defaultValue="192.168.1.1"
android:summary="@string/pref_summary_nikon_host_ip" />
-
+<!--
<CheckBoxPreference
android:key="ble_wifi_on"
android:title="@string/pref_ble_wifi_on"
android:summary="@string/pref_summary_ble_wifi_on"/>
-
+-->
</PreferenceCategory>
<PreferenceCategory