OSDN Git Service

画像表示画面のタイトルをファイル名にした。
[gokigen/PKRemote.git] / app / src / main / java / net / osdn / gokigen / pkremote / camera / vendor / ptpip / wrapper / playback / CanonFullImageReceiver.java
1 package net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.playback;
2
3 import android.app.Activity;
4 import android.util.Log;
5
6 import androidx.annotation.NonNull;
7
8 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IDownloadContentCallback;
9 import net.osdn.gokigen.pkremote.camera.interfaces.playback.IProgressEvent;
10 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandCallback;
11 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.IPtpIpCommandPublisher;
12 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandCanonGetPartialObject;
13 import net.osdn.gokigen.pkremote.camera.vendor.ptpip.wrapper.command.messages.PtpIpCommandGeneric;
14
15 import java.io.ByteArrayOutputStream;
16
17 public class CanonFullImageReceiver implements IPtpIpCommandCallback
18 {
19     private static final String TAG = CanonFullImageReceiver.class.getSimpleName();
20
21     private final Activity activity;
22     private final IPtpIpCommandPublisher publisher;
23     private IDownloadContentCallback callback = null;
24
25     private boolean isReceiveMulti = true;
26     private int objectId = 0;
27
28     private int received_total_bytes = 0;
29     private int received_remain_bytes = 0;
30
31     private int target_image_size = 0;
32     private boolean receivedFirstData = false;
33
34     CanonFullImageReceiver(@NonNull Activity activity, @NonNull IPtpIpCommandPublisher publisher)
35     {
36         this.activity = activity;
37         this.publisher = publisher;
38     }
39
40     void issueCommand(int objectId, int imageSize, IDownloadContentCallback callback)
41     {
42         if (this.objectId != 0)
43         {
44             // already issued
45             Log.v(TAG, " COMMAND IS ALREADY ISSUED. : " + objectId);
46             return;
47         }
48         this.callback = callback;
49         this.objectId = objectId;
50         this.target_image_size = imageSize;
51         this.isReceiveMulti = true;
52         this.receivedFirstData = false;
53
54         Log.v(TAG, " getPartialObject (id : " + objectId + ", size:" + imageSize + ")");
55         publisher.enqueueCommand(new PtpIpCommandCanonGetPartialObject(this, (objectId + 1), false, objectId, objectId, 0x00, imageSize, imageSize)); // 0x9107 : GetPartialObject
56     }
57
58     @Override
59     public void receivedMessage(int id, byte[] rx_body)
60     {
61         try
62         {
63             if (id == objectId + 1)
64             {
65                 getPartialObjectFinished();
66             }
67             else if (id == objectId + 2)
68             {
69                 Log.v(TAG, " TransferComplete() RECEIVED  : " + id + " (" + objectId + ") size : " + target_image_size);
70
71                 // end of receive sequence.
72                 callback.onCompleted();
73                 receivedFirstData = false;
74                 received_remain_bytes = 0;
75                 received_total_bytes = 0;
76                 target_image_size = 0;
77                 objectId = 0;
78                 callback = null;
79                 System.gc();
80             }
81             else
82             {
83                 Log.v(TAG, " RECEIVED UNKNOWN ID : " + id);
84             }
85         }
86         catch (Exception e)
87         {
88             e.printStackTrace();
89             {
90                 callback.onErrorOccurred(e);
91             }
92         }
93     }
94
95     @Override
96     public void onReceiveProgress(final int currentBytes, final int totalBytes, byte[] rx_body)
97     {
98         // 受信したデータから、通信のヘッダ部分を削除する
99         byte[] body = cutHeader(rx_body);
100         int length = (body == null) ? 0 : body.length;
101         Log.v(TAG, " onReceiveProgress() " + currentBytes + "/" + totalBytes + " (" + length + " bytes.)");
102         callback.onProgress(body, length, new IProgressEvent() {
103             @Override
104             public float getProgress() {
105                 return ((float) currentBytes / (float) target_image_size);
106             }
107
108             @Override
109             public boolean isCancellable() {
110                 return (false);
111             }
112
113             @Override
114             public void requestCancellation() { }
115         });
116     }
117
118     private byte[] cutHeader(byte[] rx_body)
119     {
120         if (rx_body == null)
121         {
122             return (null);
123         }
124         int length = rx_body.length;
125         int data_position = 0;
126         ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
127         if (!receivedFirstData)
128         {
129             // データを最初に読んだとき。ヘッダ部分を読み飛ばす
130             receivedFirstData = true;
131             data_position = (int) rx_body[0] & (0xff);
132             Log.v(TAG, " FIRST DATA POS. : " + data_position);
133             //SimpleLogDumper.dump_bytes(" [sss]", Arrays.copyOfRange(rx_body, 0, (64)));
134         }
135         else if (received_remain_bytes > 0)
136         {
137             // データの読み込みが途中だった場合...
138             if (length < received_remain_bytes)
139             {
140                 // 全部コピーする、足りないバイト数は残す
141                 received_remain_bytes = received_remain_bytes - length;
142                 received_total_bytes = received_total_bytes + rx_body.length;
143                 return (rx_body);
144             }
145             else
146             {
147                 byteStream.write(rx_body, data_position, received_remain_bytes);
148                 data_position = received_remain_bytes;
149                 received_remain_bytes = 0;
150             }
151         }
152
153         while (data_position <= (length - 12))
154         {
155             int body_size =  (rx_body[data_position] & 0xff) + ((rx_body[data_position + 1]  & 0xff) << 8) +
156                     ((rx_body[data_position + 2] & 0xff) << 16) + ((rx_body[data_position + 3] & 0xff) << 24);
157             if (body_size <= 12)
158             {
159                 Log.v(TAG, " --- BODY SIZE IS SMALL : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] " + rx_body.length + "  (" + target_image_size + ")");
160                 //int startpos = (data_position > 48) ? (data_position - 48) : 0;
161                 //SimpleLogDumper.dump_bytes(" [xxx]", Arrays.copyOfRange(rx_body, startpos, (data_position + 48)));
162                 break;
163             }
164
165             // 受信データ(のヘッダ部分)をダンプする
166             //Log.v(TAG, " RX DATA : " + data_position + " (" + body_size + ") [" + received_remain_bytes + "] (" + received_total_bytes + ")");
167             //SimpleLogDumper.dump_bytes(" [zzz] " + data_position + ": ", Arrays.copyOfRange(rx_body, data_position, (data_position + 48)));
168
169             if ((data_position + body_size) > length)
170             {
171                 // データがすべてバッファ内になかったときは、バッファすべてコピーして残ったサイズを記憶しておく。
172                 int copysize = (length - ((data_position + 12)));
173                 byteStream.write(rx_body, (data_position + 12), copysize);
174                 received_remain_bytes = body_size - copysize - 12;  // マイナス12は、ヘッダ分
175                 received_total_bytes = received_total_bytes + copysize;
176                 //Log.v(TAG, " ----- copy : " + (data_position + 12) + " " + copysize + " remain : " + received_remain_bytes + "  body size : " + body_size);
177                 break;
178             }
179             try
180             {
181                 byteStream.write(rx_body, (data_position + 12), (body_size - 12));
182                 data_position = data_position + body_size;
183                 received_total_bytes = received_total_bytes + 12;
184                 //Log.v(TAG, " --- COPY : " + (data_position + 12) + " " + (body_size - 12) + " remain : " + received_remain_bytes);
185
186             }
187             catch (Exception e)
188             {
189                 Log.v(TAG, "  pos : " + data_position + "  size : " + body_size + " length : " + length);
190                 e.printStackTrace();
191             }
192         }
193         return (byteStream.toByteArray());
194     }
195
196     @Override
197     public boolean isReceiveMulti()
198     {
199         return (isReceiveMulti);
200     }
201
202     private void getPartialObjectFinished()
203     {
204         try
205         {
206             //   すべてのデータを受信した後に...終わりを送信する
207             Log.v(TAG, " getPartialObjectFinished(), id : " + objectId + " (size : " + target_image_size + ")");
208             isReceiveMulti = false;
209             publisher.enqueueCommand(new PtpIpCommandGeneric(this,  (objectId + 2), false, objectId, 0x9117, 4,0x01));  // 0x9117 : TransferComplete
210         }
211         catch (Throwable t)
212         {
213             t.printStackTrace();
214             System.gc();
215         }
216     }
217 }