1 /* Sony DSC-F55 & MSAC-SR1 - gPhoto2 camera library
2 * Copyright 2001, 2002, 2004 Raymond Penners <raymond@dotsphinx.com>
3 * Copyright 2000 Mark Davies <mdavies@dial.pipex.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
19 */
20
21 #define _DEFAULT_SOURCE
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include <gphoto2/gphoto2.h>
30 #include "sony.h"
31
32 #define GP_MODULE "sony55"
33
34 /**
35 * Constants
36 */
37 #define SONY_CONVERSE_RETRY 5
38
39 #define SONY_INVALID_CHECKSUM 0x40
40 #define SONY_INVALID_SEQUENCE 0x41
41 #define SONY_RESET_SEQUENCE 0x42
42 #define SONY_RESEND_PACKET 0x43
43
44 #define SONY_ESCAPE_CHAR 0x7d
45 #define SONY_START_CHAR 0xc0
46 #define SONY_END_CHAR 0xc1
47
48
49 static const unsigned char START_PACKET = 192;
50 static const unsigned char END_PACKET = 193;
51
52 static const char ESC_START_STRING[] = { 0x7d, 0xe0 };
53 static const char ESC_END_STRING[] = { 0x7d, 0xe1 };
54 static const char ESC_ESC_STRING[] = { 0x7d, 0x5d };
55
56 static const unsigned char PacketCodes[2] = { 192, 193 };
57
58
59 #if defined(USE_ALL_TYPES)
60 static unsigned char EmailImage[] =
61 { 0, 2, 2, 0, 16, '/', 'M', 'S', 'S', 'O', 'N', 'Y', '/', 'I', 'M',
62 'C',
63 'I', 'F', '1', '0', '0'
64 };
65 #endif
66
67
68 static unsigned char IdentString[] =
69 { 0, 1, 1, 'S', 'O', 'N', 'Y', ' ', ' ', ' ', ' ', ' ' };
70 static unsigned char EmptyPacket[] = { 0 }; /* null packet */
71 static unsigned char SetTransferRate[] = { 0, 1, 3, 0 };
72 static unsigned char SendImageCount[] = { 0, 2, 1 };
73 static unsigned char StillImage[] =
74 { 0, 2, 2, 0, 14, '/', 'D', 'C', 'I', 'M', '/', '1', '0', '0', 'M',
75 'S',
76 'D', 'C', 'F'
77 };
78 static unsigned char MpegImage[] =
79 { 0, 2, 2, 0, 16, '/', 'M', 'S', 'S', 'O', 'N', 'Y', '/', 'M', 'O',
80 'M',
81 'L', '0', '0', '0', '1'
82 };
83 static unsigned char SelectImage[] = { 0, 2, 48, 0, 0, 0, 0 };
84 static unsigned char SendImage[] = { 0, 2, '1', 0, 1, 0, 0 };
85 static unsigned char SendNextImagePacket[] = { 0, 2, '1', 0 };
86 static unsigned char SendThumbnail[] = { 0, 2, '0', 0 };
87
88 #if 0
89 static unsigned char SelectCamera[] = { 0, 1, 2 };
90 static unsigned char DownloadComplete[] = { 0, 2, '0', 255 };
91 static unsigned char X10Camera[] = { 0, 1, 5 };
92
93 static unsigned char X5Camera[] = { 0, 2, 1 };
94 static unsigned char X13Camera[] = { 0, 2, 18 };
95
96 #endif
97
98
99 /*
100 * This array contains the expected packet sequence code to be applied/
101 * checked for.
102 */
103 static const unsigned char sony_sequence[] =
104 { 14, 0, 32, 34, 66, 68, 100, 102, 134, 136, 168, 170, 202, 204, 236,
105 238,
106 255
107 };
108
109
110 #ifdef __linux__
111 static const int baud_rate = 115200;
112 #else
113 # ifdef __sun__
114 static const int baud_rate = 38400;
115 # else
116 static const int baud_rate = 9600;
117 # endif
118 #endif
119
120
121
122
123
124 /**
125 * Returns transfer rate ID
126 */
127 static int
sony_baud_to_id(long baud)128 sony_baud_to_id(long baud)
129 {
130 int r;
131
132 switch (baud) {
133 case 115200:
134 r = 4;
135 break;
136 case 57600:
137 r = 3;
138 break; /* FIXME ??? */
139 case 38400:
140 r = 2;
141 break; /* works on sun */
142 case 19200:
143 r = 1;
144 break; /* works on sun */
145 default:
146 case 9600:
147 r = 0;
148 break; /* works on sun */
149 }
150 return r;
151 }
152
153
154 /**
155 * Reads a byte
156 */
157 static int
sony_read_byte(Camera * camera,unsigned char * b)158 sony_read_byte(Camera * camera, unsigned char *b)
159 {
160 int n = gp_port_read(camera->port, (char *)b, 1);
161 if (n != 1)
162 return GP_ERROR;
163 else
164 return GP_OK;
165 }
166
167
168
169 /**
170 * Returns the checksum for a packet
171 */
172 static unsigned char
sony_packet_checksum(Packet * p)173 sony_packet_checksum(Packet * p)
174 {
175 unsigned short int o = 0;
176 unsigned long int sum = 0;
177
178 sum = 0;
179
180 while (o < p->length)
181 sum += p->buffer[o++];
182
183 return 256 - (sum & 255);
184 }
185
186 /**
187 * Returns TRUE iff the packet is valid
188 */
189 static int
sony_packet_validate(Camera * camera,Packet * p)190 sony_packet_validate(Camera * camera, Packet * p)
191 {
192 unsigned char c = sony_packet_checksum(p);
193
194 if (c != p->checksum) {
195 GP_DEBUG(
196 "sony_packet_validate: invalid checksum");
197 return SONY_INVALID_CHECKSUM;
198 }
199
200 if (129 == p->buffer[0]) {
201 GP_DEBUG(
202 "sony_packet_validate: resend packet");
203 return SONY_RESEND_PACKET;
204 }
205
206 if (sony_sequence[camera->pl->sequence_id] != p->buffer[0]) {
207 GP_DEBUG(
208 "sony_packet_validate: invalid sequence");
209 return SONY_INVALID_SEQUENCE;
210 }
211
212 return GP_OK;
213 }
214
215 /**
216 * Constructs a packet.
217 */
218 static int
sony_packet_make(Camera * camera,Packet * p,unsigned char * buffer,unsigned short int length)219 sony_packet_make(Camera * camera, Packet * p, unsigned char *buffer,
220 unsigned short int length)
221 {
222 p->length = 0;
223
224 while (length--)
225 p->buffer[p->length++] = *(buffer++);
226
227 if (255 == sony_sequence[++(camera->pl->sequence_id)])
228 camera->pl->sequence_id = 0;
229
230 p->buffer[0] = sony_sequence[camera->pl->sequence_id++];
231
232 if (255 == sony_sequence[camera->pl->sequence_id])
233 camera->pl->sequence_id = 0;
234
235 p->checksum = sony_packet_checksum(p);
236
237 return TRUE;
238 }
239
240 /**
241 * Reads a packet.
242 */
sony_packet_read(Camera * camera,Packet * pack)243 static int sony_packet_read(Camera * camera, Packet * pack)
244 {
245 unsigned int n;
246 unsigned char byte = 0;
247 static Packet p;
248
249 GP_DEBUG(
250 "sony_packet_read()");
251 p.length = 0;
252
253 for (n = 0; n < 2; n++) {
254 for (byte = 0; byte != (unsigned char) PacketCodes[n];) {
255 if (sony_read_byte(camera, &byte) == GP_ERROR) {
256 return FALSE;
257 }
258
259 if (n > 0) {
260 if (SONY_ESCAPE_CHAR == byte) {
261 unsigned char extra;
262
263 sony_read_byte(camera, &extra);
264
265 switch (extra) {
266 case 1:
267 case 7:
268 case 0xe1:
269 case 0xe0:
270 extra &= 0xcf;
271 p.buffer[p.length++] =
272 extra;
273 continue;
274 case 0x5d:
275 p.buffer[p.length++] =
276 byte;
277 continue;
278 default:
279 p.buffer[p.length++] =
280 byte;
281 p.buffer[p.length++] =
282 extra;
283 continue;
284 }
285 } else
286 p.buffer[p.length++] = byte;
287 }
288 }
289 }
290
291 p.length -= 2;
292 p.checksum = p.buffer[p.length];
293
294 memcpy(pack, &p, sizeof(Packet));
295 return TRUE;
296 }
297
298 /**
299 * Sends a packet
300 */
301 static int
sony_packet_write(Camera * camera,Packet * p)302 sony_packet_write(Camera * camera, Packet * p)
303 {
304 unsigned short int count;
305 int rc;
306
307 GP_DEBUG(
308 "sony_packet_write()");
309
310 /**
311 * This usleep is necessary when using (relatively) fast CPUs,
312 * as P4 2Ghz. Without it gphoto2 stops with a segmentation fault
313 * and the --debug message sony_packet_validate: invalid sequence
314 * Failed to read packet during transfer. The delay is somewhat
315 * arbitrary. (alberto-g@(remove_me)inventati.org)
316 **/
317 usleep(10000);
318
319 rc = gp_port_write(camera->port, (char *)&START_PACKET, 1);
320
321 p->buffer[p->length] = p->checksum;
322
323 for (count = 0; count < p->length + 1 && rc != GP_ERROR; count++) {
324 switch ((unsigned char) p->buffer[count]) {
325 case SONY_ESCAPE_CHAR:
326 rc = gp_port_write(camera->port, ESC_ESC_STRING, 2);
327 break;
328
329 case SONY_START_CHAR:
330 rc = gp_port_write(camera->port, ESC_START_STRING, 2);
331 break;
332
333 case SONY_END_CHAR:
334 rc = gp_port_write(camera->port, ESC_END_STRING, 2);
335 break;
336
337 default:
338 rc = gp_port_write(camera->port,
339 (char *) &p->buffer[count], 1);
340 break;
341 }
342 }
343 if (rc != GP_ERROR)
344 rc = gp_port_write(camera->port, (char *) &END_PACKET, 1);
345 return rc;
346 }
347
348 /**
349 * Communicates packets
350 */
351 static int
sony_converse(Camera * camera,Packet * out,unsigned char * str,int len)352 sony_converse(Camera * camera, Packet * out, unsigned char *str, int len)
353 {
354 Packet ps;
355 char old_sequence = 33;
356 int sequence_count = 0;
357 int invalid_sequence = 0;
358 int count;
359 int rc;
360
361 GP_DEBUG( "sony_converse()");
362 sony_packet_make(camera, &ps, str, len);
363
364 for (count = 0; count < SONY_CONVERSE_RETRY; count++) {
365 rc = sony_packet_write(camera, &ps);
366
367 if (rc == GP_OK) {
368 if (sony_packet_read(camera, out)) {
369 switch (sony_packet_validate(camera, out)) {
370 case SONY_INVALID_CHECKSUM:
371 if (invalid_sequence) {
372 sony_packet_make(camera,
373 &ps, str,
374 len);
375 break;
376 }
377
378 GP_DEBUG ("Checksum invalid");
379 ps.buffer[0] = 129;
380 ps.checksum =
381 sony_packet_checksum(&ps);
382 break;
383
384 case SONY_INVALID_SEQUENCE:
385 if (camera->pl->model
386 != SONY_MODEL_DSC_F55) {
387 invalid_sequence = 1;
388 sony_packet_make(camera,
389 &ps, str,
390 len);
391 break;
392 }
393
394 if (old_sequence == out->buffer[0])
395 sequence_count++;
396 else if (0 == sequence_count)
397 old_sequence =
398 out->buffer[0];
399
400 if (sequence_count == 4) {
401 GP_DEBUG ("Attempting to reset sequence id - image may be corrupt.");
402 camera->pl->sequence_id = 0;
403
404 while (sony_sequence
405 [camera->pl->
406 sequence_id] !=
407 old_sequence)
408 camera->pl->
409 sequence_id++;
410
411 return GP_OK;
412 }
413 GP_DEBUG ("Invalid Sequence");
414 ps.buffer[0] = 129;
415 ps.checksum =
416 sony_packet_checksum(&ps);
417 break;
418
419 case SONY_RESET_SEQUENCE:
420 camera->pl->sequence_id = 0;
421 return GP_OK;
422
423 case SONY_RESEND_PACKET:
424 GP_DEBUG ("Resending Packet");
425 break;
426
427 case GP_OK:
428 return GP_OK;
429
430 default:
431 GP_DEBUG ("Unknown Error");
432 break;
433 }
434 } else {
435 /* printf("Incomplete packet\n"); */
436 ps.buffer[0] = 129;
437 ps.checksum = sony_packet_checksum(&ps);
438 }
439 }
440 }
441
442 GP_DEBUG(
443 "Failed to read packet during transfer.");
444
445 return GP_ERROR;
446 }
447
448
449 /**
450 * Sets baud rate
451 */
452 static int
sony_baud_port_set(Camera * camera,long baud)453 sony_baud_port_set(Camera * camera, long baud)
454 {
455 gp_port_settings settings;
456
457 gp_port_get_settings(camera->port, &settings);
458 settings.serial.speed = baud;
459 gp_port_set_settings(camera->port, settings);
460
461 usleep(70000);
462
463 return GP_OK;
464 }
465
466 /**
467 * Sets baud rate
468 */
469 static int
sony_baud_set(Camera * camera,long baud)470 sony_baud_set(Camera * camera, long baud)
471 {
472 Packet dp;
473 int rc;
474
475 GP_DEBUG( "sony_baud_set(%ld)",
476 baud);
477
478 if (camera->pl->current_baud_rate != baud) {
479 /* FIXME */
480 SetTransferRate[3] = sony_baud_to_id(baud);
481
482 rc = sony_converse(camera, &dp, SetTransferRate, 4);
483 if (rc == GP_OK) {
484 sony_baud_port_set(camera, baud);
485 rc = sony_converse(camera, &dp, EmptyPacket, 1);
486 if (rc == GP_OK) {
487 camera->pl->current_baud_rate = baud;
488 }
489 usleep(100000); /* 50000 was good too, jw */
490
491 }
492 }
493 else {
494 rc = GP_OK;
495 }
496 return rc;
497 }
498
499 /**
500 * Port initialisation
501 */
502 static int
sony_init_port(Camera * camera)503 sony_init_port (Camera *camera)
504 {
505 gp_port_settings settings;
506 int rc;
507
508 rc = gp_port_set_timeout (camera->port, 5000);
509 if (rc == GP_OK) {
510
511 gp_port_get_settings(camera->port, &settings);
512
513 settings.serial.speed = 9600;
514 settings.serial.bits = 8;
515 settings.serial.parity = 0;
516 settings.serial.stopbits = 1;
517
518 rc = gp_port_set_settings(camera->port, settings);
519 if (rc == GP_OK) {
520 rc = gp_port_flush(camera->port, 0);
521 }
522 }
523 return rc;
524 }
525
526 /**
527 * Establish first contact (remember the prime directive? :)
528 */
529 static int
sony_init_first_contact(Camera * camera)530 sony_init_first_contact (Camera *camera)
531 {
532 int count = 0;
533 Packet dp;
534 int rc = GP_ERROR;
535
536 for (count = 0; count < 3; count++) {
537 camera->pl->sequence_id = 0;
538
539 rc = sony_converse(camera, &dp, IdentString, 12);
540 if (rc == GP_OK) {
541 GP_DEBUG(
542 "Init OK");
543 break;
544 }
545 usleep(2000);
546 GP_DEBUG(
547 "Init - Fail %u", count + 1);
548 }
549 return rc;
550 }
551
552 /**
553 * Device supports MPEG?
554 */
555 static int
sony_is_mpeg_supported(Camera * camera)556 sony_is_mpeg_supported (Camera * camera)
557 {
558 return camera->pl->model == SONY_MODEL_DSC_F55;
559 }
560
561 /**
562 * Initialises camera
563 */
564 int
sony_init(Camera * camera,SonyModel model)565 sony_init (Camera * camera, SonyModel model)
566 {
567 int rc;
568 camera->pl->model = model;
569 camera->pl->current_baud_rate = -1;
570 camera->pl->current_mpeg_mode = -1;
571
572 rc = sony_init_port (camera);
573 if (rc == GP_OK)
574 rc = sony_init_first_contact (camera);
575
576 return rc;
577 }
578
579 /**
580 * Reset the camera sequence count and baud rate.
581 */
582 int
sony_exit(Camera * camera)583 sony_exit(Camera * camera)
584 {
585 Packet dp;
586 int rc = GP_ERROR;
587
588 rc = sony_baud_set(camera, 9600);
589 while (rc == GP_OK && camera->pl->sequence_id > 0) {
590 rc = sony_converse(camera, &dp, EmptyPacket, 1);
591 }
592
593 return rc;
594 }
595
596
597 static int
sony_set_file_mode(Camera * camera,SonyFileType file_type)598 sony_set_file_mode(Camera * camera, SonyFileType file_type)
599 {
600 int rc = GP_OK;
601 Packet dp;
602 if (file_type == SONY_FILE_MPEG) {
603 if (camera->pl->current_mpeg_mode != 1) {
604 rc = sony_converse(camera, &dp, MpegImage, 21);
605 if (rc == GP_OK) {
606 camera->pl->current_mpeg_mode = 1;
607 }
608 }
609 }
610 else {
611 if (camera->pl->current_mpeg_mode != 0) {
612 rc = sony_converse(camera, &dp, StillImage, 19);
613 if (rc == GP_OK) {
614 camera->pl->current_mpeg_mode = 0;
615 }
616 }
617 }
618 return rc;
619 }
620
621
622 /**
623 * Return count of images taken.
624 */
625 int
sony_file_count(Camera * camera,SonyFileType file_type,int * count)626 sony_file_count(Camera * camera, SonyFileType file_type, int *count)
627 {
628 Packet dp;
629 int rc, nr;
630
631 GP_DEBUG( "sony_file_count()");
632 if (file_type == SONY_FILE_MPEG && (! sony_is_mpeg_supported(camera))) {
633 *count = 0;
634 return GP_OK;
635 }
636 *count = -1;
637 rc = sony_converse(camera, &dp, SetTransferRate, 4);
638 if (rc != GP_OK)
639 return rc;
640 rc = sony_set_file_mode(camera, file_type);
641 if (rc != GP_OK)
642 return rc;
643 rc = sony_converse(camera, &dp, SendImageCount, 3);
644 if (rc != GP_OK)
645 return rc;
646 nr = dp.buffer[5] | (dp.buffer[4]<<8);
647 GP_DEBUG ("count = %d", nr);
648 *count = nr;
649 return GP_OK;
650 }
651
652
653
654 /**
655 * Fetches file name.
656 */
657 int
sony_file_name_get(Camera * camera,int imageid,SonyFileType mpeg,char buf[13])658 sony_file_name_get(Camera *camera, int imageid, SonyFileType mpeg, char buf[13])
659 {
660 Packet dp;
661 int rc;
662
663 GP_DEBUG( "sony_file_name_get()");
664 rc = sony_set_file_mode(camera, mpeg);
665 if (rc != GP_OK)
666 return rc;
667 sony_baud_set(camera, baud_rate);
668 /* FIXME: Not nice, changing global data like this. */
669 SelectImage[3] = (imageid >> 8);
670 SelectImage[4] = imageid & 0xff;
671 rc = sony_converse(camera, &dp, SelectImage, 7);
672 if (rc != GP_OK)
673 return rc;
674 memcpy(buf, &dp.buffer[5], 8);
675 buf[8] = '.';
676 memcpy(buf+9, &dp.buffer[5+8], 3);
677 buf[12] = 0;
678 return rc;
679 }
680
681
682 /**
683 * Is it an MPEG file?
684 */
685 int
sony_is_mpeg_file_name(const char * file_name)686 sony_is_mpeg_file_name(const char * file_name)
687 {
688 return strncmp(file_name,"MOV",3)==0;
689 }
690
691
692
693 /**
694 * Fetches an image.
695 */
696 static int
sony_file_get(Camera * camera,int imageid,int file_type,CameraFile * file,GPContext * context)697 sony_file_get(Camera * camera, int imageid, int file_type,
698 CameraFile * file, GPContext *context)
699 {
700 int sc; /* count of bytes to skip at start of packet */
701 Packet dp;
702 int rc;
703 char buffer[128];
704
705 GP_DEBUG( "sony_file_get()");
706
707 rc = sony_set_file_mode(camera, file_type);
708 if (rc != GP_OK) {
709 return rc;
710 }
711
712 if (gp_context_cancel(context) == GP_CONTEXT_FEEDBACK_CANCEL) {
713 return GP_ERROR_CANCEL;
714 }
715
716 rc = gp_file_clean(file);
717 if (rc == GP_OK) {
718 gp_file_set_mime_type (file, GP_MIME_JPEG);
719 /* The file name we specify here is not important,
720 * since the calling function, gp_filesystem_get_file_impl,
721 * overwrites it with the correct one.
722 */
723 sprintf(buffer, SONY_FILE_NAME_FMT, imageid);
724
725 sony_baud_set(camera, baud_rate);
726
727 rc = sony_set_file_mode(camera, file_type);
728 if (rc == GP_OK) {
729 if (file_type == SONY_FILE_THUMBNAIL) {
730 sc = 0x247;
731 SelectImage[3] = (imageid >> 8);
732 SelectImage[4] = imageid & 0xff;
733 sony_converse(camera, &dp, SelectImage, 7);
734
735 if (camera->pl->model
736 != SONY_MODEL_DSC_F55) {
737 gp_file_append(file,
738 "\xff\xd8\xff", 3);
739 }
740
741 for (;;) {
742 if (gp_context_cancel(context)
743 == GP_CONTEXT_FEEDBACK_CANCEL) {
744
745 rc = GP_ERROR_CANCEL;
746 break;
747 }
748 gp_context_idle(context);
749
750 sony_converse(camera, &dp,
751 SendThumbnail, 4);
752
753 gp_file_append(file,
754 (char *) dp.buffer +
755 sc, dp.length - sc);
756 sc = 7;
757
758 if (3 == dp.buffer[4])
759 break;
760 }
761 } else {
762 sc = 11;
763
764 SendImage[3] = (imageid >> 8);
765 SendImage[4] = imageid;
766 sony_converse(camera, &dp, SendImage, 7);
767
768 for (;;) {
769 if (gp_context_cancel(context)
770 == GP_CONTEXT_FEEDBACK_CANCEL) {
771
772 rc = GP_ERROR_CANCEL;
773 break;
774 }
775 gp_context_idle(context);
776
777 gp_file_append(file,
778 (char *) dp.buffer +
779 sc, dp.length - sc);
780
781 if (file_type == SONY_FILE_EXIF) {
782 const char *fdata;
783 unsigned long fsize;
784
785 gp_file_get_data_and_size
786 (file, &fdata, &fsize);
787 /* FIXME: 4096 is a rather */
788 /* arbitrary value */
789 if (fsize > 4096)
790 break;
791 }
792
793 sc = 7;
794
795 if (3 == dp.buffer[4])
796 break;
797
798 sony_converse(camera, &dp,
799 SendNextImagePacket,
800 4);
801 }
802 }
803 }
804 sony_baud_set(camera, 9600);
805
806 if (rc != GP_OK) {
807 gp_file_clean(file);
808 }
809 }
810 return rc;
811 }
812
813 /**
814 * Fetches a thumbnail image.
815 */
816 int
sony_thumbnail_get(Camera * camera,int imageid,CameraFile * file,GPContext * context)817 sony_thumbnail_get(Camera * camera, int imageid, CameraFile * file, GPContext *context)
818 {
819 return sony_file_get(camera, imageid, SONY_FILE_THUMBNAIL, file, context);
820 }
821
822 /**
823 * Fetches an image.
824 */
825 int
sony_image_get(Camera * camera,int imageid,CameraFile * file,GPContext * context)826 sony_image_get(Camera * camera, int imageid, CameraFile * file, GPContext *context)
827 {
828 return sony_file_get(camera, imageid, SONY_FILE_IMAGE, file, context);
829 }
830
831 /**
832 * Fetches EXIF information.
833 */
834 int
sony_exif_get(Camera * camera,int imageid,CameraFile * file,GPContext * context)835 sony_exif_get(Camera * camera, int imageid, CameraFile * file, GPContext *context)
836 {
837 return sony_file_get(camera, imageid, SONY_FILE_EXIF, file, context);
838 }
839
840 /**
841 * Fetches an Mpeg.
842 */
843 int
sony_mpeg_get(Camera * camera,int imageid,CameraFile * file,GPContext * context)844 sony_mpeg_get(Camera * camera, int imageid, CameraFile * file, GPContext *context)
845 {
846 return sony_file_get(camera, imageid, SONY_FILE_MPEG, file, context);
847 }
848
849
850 /**
851 * Fetches image details.
852 */
853 int
sony_image_info(Camera * camera,int imageid,SonyFileType file_type,CameraFileInfo * info,GPContext * context)854 sony_image_info(Camera * camera, int imageid, SonyFileType file_type,
855 CameraFileInfo * info, GPContext *context)
856 {
857 unsigned int l = 0;
858 int rc;
859 Packet dp;
860
861 rc = sony_set_file_mode(camera, file_type);
862 if (rc != GP_OK) {
863 return rc;
864 }
865
866 if (gp_context_cancel(context) == GP_CONTEXT_FEEDBACK_CANCEL) {
867 return GP_ERROR_CANCEL;
868 }
869
870 SelectImage[3] = (imageid >> 8);
871 SelectImage[4] = imageid & 0xff;
872 rc = sony_converse(camera, &dp, SelectImage, 7);
873 if (rc == GP_OK) {
874 l = (l << 8) | dp.buffer[16];
875 l = (l << 8) | dp.buffer[17];
876 l = (l << 8) | dp.buffer[18];
877 l = (l << 8) | dp.buffer[19];
878
879 info->file.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_TYPE;
880 info->file.size = l;
881
882 info->preview.fields = GP_FILE_INFO_TYPE;
883
884 if (file_type == SONY_FILE_MPEG) {
885 strcpy (info->file.type, GP_MIME_AVI);
886 }
887 else {
888 strcpy (info->file.type, GP_MIME_JPEG);
889 }
890 }
891 return rc;
892 }
893
894
895
896 /*
897 * Local Variables:
898 * c-file-style:"linux"
899 * indent-tabs-mode:t
900 * End:
901 */
902