summaryrefslogtreecommitdiff
path: root/camlibs/sonydscf1/sonydscf1.c
diff options
context:
space:
mode:
Diffstat (limited to 'camlibs/sonydscf1/sonydscf1.c')
-rw-r--r--camlibs/sonydscf1/sonydscf1.c455
1 files changed, 454 insertions, 1 deletions
diff --git a/camlibs/sonydscf1/sonydscf1.c b/camlibs/sonydscf1/sonydscf1.c
index 9b90bf68c..bf7478a73 100644
--- a/camlibs/sonydscf1/sonydscf1.c
+++ b/camlibs/sonydscf1/sonydscf1.c
@@ -3,6 +3,7 @@
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <gphoto2/gphoto2.h>
@@ -20,8 +21,460 @@
# define N_(String) (String)
#endif
+#include "common.h"
#include "command.h"
-#include "chotplay.h"
+#include "pmp.h"
+
+#define MAX_PICTURE_NUM 200
+
+static u_char picture_index[MAX_PICTURE_NUM];
+static u_short picture_thumbnail_index[MAX_PICTURE_NUM];
+static u_char picture_protect[MAX_PICTURE_NUM];
+static u_char picture_rotate[MAX_PICTURE_NUM];
+
+static int errflg = 0;
+
+static int
+make_jpeg_comment(u_char *buf, u_char *jpeg_comment)
+{
+ int i, cur = 0;
+ int reso, shutter;
+
+ struct resolution {
+ int reso_val;
+ char *reso_conv;
+ } reso_tab[] = {
+ {PMP_FIN, "fine"},
+ {PMP_STD, "standard"},
+ {PMP_ECM, "economy"},
+ {0, "unknown"},
+ };
+
+ struct sh_speed {
+ int spd_val;
+ char *spd_conv;
+ } sh_speed_tab[] = {
+ {0x0123, "1/7.5"},
+ {0x0187, "1/15"},
+ {0x01eb, "1/30"},
+ {0x024f, "1/60"},
+ {0x0298, "1/100"},
+ {0x031d, "1/250"},
+ {0x0381, "1/500"},
+ {0x03e5, "1/1000"},
+ {0, "unknown"},
+ };
+
+ jpeg_comment[0] = 0xff;
+ jpeg_comment[1] = 0xd8;
+ jpeg_comment[2] = 0xff;
+ jpeg_comment[3] = 0xfe;
+
+ /* resolution */
+ reso = *(buf+PMP_RESOLUTION);
+
+ i = 0;
+ while (1) {
+ if ((reso == reso_tab[i].reso_val) || (reso_tab[i].reso_val == 0)) {
+ cur = 6 + sprintf(&jpeg_comment[6], "Resolution: %s\n",
+ reso_tab[i].reso_conv);
+ break;
+ }
+ i++;
+ }
+
+ /* shutter speed */
+ shutter = (buf[PMP_SPEED]<<8)|buf[PMP_SPEED+1];
+
+ i = 0;
+ while (1) {
+ if ((shutter == sh_speed_tab[i].spd_val) ||
+ (sh_speed_tab[i].spd_val == 0)) {
+ cur = cur + sprintf(&jpeg_comment[cur], "Shutter-speed: %s\n",
+ sh_speed_tab[i].spd_conv);
+ break;
+ }
+ i++;
+ }
+
+ /* PMP comment */
+ if (*(buf+PMP_COMMENT)) {
+ cur = cur + sprintf(&jpeg_comment[cur], "Comment: %s\n",
+ (char *)(buf+PMP_COMMENT));
+ }
+
+ /* taken date */
+ if (*(buf+PMP_TAKE_YEAR) == 0xff) {
+ cur = cur + sprintf(&jpeg_comment[cur],
+ "Date-Taken: ----/--/-- --:--:--\n");
+ }
+ else {
+ cur = cur + sprintf(&jpeg_comment[cur],
+ "Date-Taken: %d/%02d/%02d %02d:%02d:%02d\n",
+ 2000+(*(buf+PMP_TAKE_YEAR)), *(buf+PMP_TAKE_MONTH),
+ *(buf+PMP_TAKE_DATE), *(buf+PMP_TAKE_HOUR), *(buf+PMP_TAKE_MINUTE),
+ *(buf+PMP_TAKE_SECOND));
+ }
+
+ /* edited date */
+ if (*(buf+PMP_EDIT_YEAR) == 0xff) {
+ cur = cur + sprintf(&jpeg_comment[cur],
+ "Date-Edited: ----/--/-- --:--:--\n");
+ }
+ else {
+ cur = cur + sprintf(&jpeg_comment[cur],
+ "Date-Edited: %d/%02d/%02d %02d:%02d:%02d\n",
+ 2000+(*(buf+PMP_EDIT_YEAR)), *(buf+PMP_EDIT_MONTH),
+ *(buf+PMP_EDIT_DATE), *(buf+PMP_EDIT_HOUR), *(buf+PMP_EDIT_MINUTE),
+ *(buf+PMP_EDIT_SECOND));
+ }
+
+ /* use flash? */
+ if (*(buf+PMP_FLASH) != 0) {
+ cur = cur + sprintf(&jpeg_comment[cur], "Flash: on\n");
+ }
+
+ /* insert total jpeg comment length */
+ jpeg_comment[4] = (u_char)((cur - 4) >> 8);
+ jpeg_comment[5] = (u_char)(cur - 4);
+
+ return cur;
+}
+
+static int
+get_picture_information(GPPort *port,int *pmx_num, int outit)
+{
+ u_char buforg[PMF_MAXSIZ];
+ char name[64];
+ long len;
+ int i, n;
+ int j, k;
+ char *buf = (char *) &buforg;
+
+ strcpy(name, "/PIC_CAM/PIC00000/PIC_INF.PMF");
+ F1ok(port);
+ len = F1getdata(port, name, buf, 0);
+
+ n = buf[26] * 256 + buf[27]; /* how many files */
+ *pmx_num = buf[31]; /* ??? */
+
+ if(n ==10)
+ buf++;
+
+ k = 0;
+ for(i = 0 ; i < (int) *pmx_num ; i++){
+ for(j = 0 ; j < buforg[0x20 + 4 * i + 3]; j++){
+ picture_thumbnail_index[k] = (j << 8) | buforg[0x20 + 4 * i] ;
+ k++;
+ }
+ }
+ for(i = 0 ; i < n ; i++){
+ picture_index[i] = buf[0x420 + 0x10 * i + 3];
+ picture_rotate[i] = buf[0x420 + 0x10 * i + 5];
+ picture_protect[i] = buf[0x420 + 0x10 * i + 14];
+ }
+
+ if(outit == 2){
+ fprintf(stdout," No:Internal name:Thumbnail name(Nth):Rotate:Protect\n");
+ for(i = 0 ; i < n ; i++){
+ fprintf(stdout,"%03d:", i + 1);
+ fprintf(stdout," PSN%05d.PMP:", picture_index[i]);
+ fprintf(stdout,"PIDX%03d.PMX(%02d) :",
+ 0xff & picture_thumbnail_index[i],
+ 0xff & (picture_thumbnail_index[i] >> 8));
+ switch(picture_rotate[i]){
+ case 0x00:
+ fprintf(stdout," 0:");
+ break;
+ case 0x04:
+ fprintf(stdout," 270:");
+ break;
+ case 0x08:
+ fprintf(stdout," 180:");
+ break;
+ case 0x0c:
+ fprintf(stdout," 90:");
+ break;
+ default:
+ fprintf(stdout," ???:");
+ break;
+ }
+ if(picture_protect[i])
+ fprintf(stdout,"on");
+ else
+ fprintf(stdout,"off");
+ fprintf(stdout,"\n");
+ }
+ }
+ return(n);
+}
+
+static long
+get_file(GPPort *port,char *name, char **data, int format)
+{
+ u_long filelen;
+ u_long total = 0;
+ long len,memcpylen;
+ char *ptr = NULL;
+ u_char buf[0x400];
+ u_char jpeg_comment[256];
+
+ F1ok(port);
+ F1status(port,0);
+
+ filelen = F1finfo(port,name);
+ if(filelen == 0)
+ return(0);
+
+ if(F1fopen(port,name) != 0)
+ return(0);
+
+ if(format != JPEG)
+ return(0);
+
+ len = F1fread(port, buf, 126);
+ if( len < 126){
+ F1fclose(port);
+ return(0);
+ }
+ memcpylen=make_jpeg_comment(buf, jpeg_comment);
+ ptr = malloc(memcpylen+filelen);
+ *data=ptr;
+ ptr = memcpy(ptr,jpeg_comment,memcpylen);
+ total = 126;
+ ptr +=memcpylen;
+
+ while((len = F1fread(port, buf, 0x0400)) != 0){
+ if(len < 0)
+ return(0);
+ total = total + len;
+/* gp_camera_progress(camera, ((float)total / (float)filelen)); */
+ memcpylen=len;
+ ptr = memcpy(ptr,buf,memcpylen);
+ ptr +=memcpylen;
+
+ }
+ F1fclose(port);
+ return(total);
+}
+
+static long
+get_thumbnail(GPPort *port,char *name, char **data, int format, int n)
+{
+ u_long filelen;
+ u_long total = 0;
+ long len;
+ int i;
+ u_char buf[0x1000];
+ u_char *p;
+ char *ptr;
+ /* printf("name %s,%d\n",name,n); */
+ p = buf;
+
+ F1ok(port);
+ F1status(port,0);
+
+ filelen = F1finfo(port,name);
+ if(filelen == 0)
+ return(0);
+
+ if(F1fopen(port,name) != 0)
+ return(0);
+
+ for( i = 0 ; i < n ; i++)
+ len = F1fseek(port, 0x1000, 1);
+
+ while((len = F1fread(port, p, 0x0400)) != 0){
+ if(len < 0){
+ F1fclose(port);
+ return(0);
+ }
+ total = total + len;
+ p = p + len;
+ if(total >= 0x1000)
+ break;
+ }
+ F1fclose(port);
+
+ filelen = buf[12] * 0x1000000 + buf[13] * 0x10000 +
+ buf[14] * 0x100 + buf[15];
+
+ ptr = malloc(filelen);
+ *data=ptr;
+ ptr = memcpy(ptr,&buf[256],filelen);
+
+ /* write_file(&buf[256], (int) filelen, fp); */
+ return(total);
+}
+
+static void
+get_date_info(GPPort *port, char *name, char *outfilename ,char *newfilename)
+{
+ char *p, *q;
+ int year = 0;
+ int month = 0;
+ int date = 0;
+ int hour = 0;
+ int minute = 0;
+ int second = 0;
+ u_char buf[128];
+
+ F1ok(port);
+ F1status(port,0);
+
+ (void) F1finfo(port, name);
+ if(F1fopen(port, name) ==0){
+ if(F1fread(port, buf, 126) == 126){
+ if(*(buf+PMP_TAKE_YEAR) != 0xff){
+ year = (int) *(buf+PMP_TAKE_YEAR);
+ month = (int) *(buf+PMP_TAKE_MONTH);
+ date = (int) *(buf+PMP_TAKE_DATE);
+ hour = (int) *(buf+PMP_TAKE_HOUR);
+ minute = (int) *(buf+PMP_TAKE_MINUTE);
+ second = (int) *(buf+PMP_TAKE_SECOND);
+ }
+ }
+ F1fclose(port);
+ }
+
+ p = outfilename;
+ q = newfilename;
+ while(*p){
+ if(*p == '%'){
+ p++;
+ switch(*p){
+ case '%':
+ *q = '%';
+ break;
+ case 'H':
+ q = q + sprintf(q, "%02d", hour);
+ break;
+ case 'M':
+ q = q + sprintf(q, "%02d", minute);
+ break;
+ case 'S':
+ q = q + sprintf(q, "%02d", second);
+ break;
+ case 'T':
+#ifdef BINARYFILEMODE
+ q = q + sprintf(q, "%02d%02d%02d", hour, minute, date);
+#else
+ q = q + sprintf(q, "%02d:%02d:%02d", hour, minute, date);
+#endif
+ break;
+ case 'y':
+ q = q + sprintf(q, "%02d", year);
+ break;
+ case 'm':
+ q = q + sprintf(q, "%02d", month);
+ break;
+ case 'd':
+ q = q + sprintf(q, "%02d", date);
+ break;
+ case 'D':
+#ifdef BINARYFILEMODE
+ q = q + sprintf(q, "%02d%02d%02d", year, month, date);
+#else
+ q = q + sprintf(q, "%02d_%02d_%02d", year, month, date);
+#endif
+ break;
+ default:
+ q = q + sprintf(q, "%%%c", *p);
+ break;
+ }
+ p++;
+ }else
+ *q++ = *p++;
+ }
+ *q = 0;
+
+}
+
+static long
+get_picture(GPPort *port, int n, char **data, int format, int ignore, int all_pic_num)
+{
+ long len;
+ char name[64];
+ char name2[64];
+ int i;
+
+ all_pic_num = get_picture_information(port,&i,0);
+
+retry:
+
+ if (all_pic_num < n) {
+ fprintf(stderr, "picture number %d is too large. %d\n",all_pic_num,n);
+ errflg ++;
+ return(GP_ERROR);
+ }
+
+ switch(format){
+ case PMX:
+ sprintf(name, "/PIC_CAM/PIC00000/PIDX%03d.PMX", n - 1);
+ break;
+ case JPEG_T:
+ sprintf(name, "/PIC_CAM/PIC00000/PIDX%03d.PMX",
+ (picture_thumbnail_index[n] & 0xff));
+ break;
+ case JPEG:
+ case PMP:
+ default:
+ if(ignore)
+ sprintf(name, "/PIC_CAM/PIC00000/PSN%05d.PMP", n);
+ else
+ sprintf(name, "/PIC_CAM/PIC00000/PSN%05d.PMP", picture_index[n]);
+ break;
+ }
+ if(ignore)
+ sprintf(name2, "/PIC_CAM/PIC00000/PSN%05d.PMP", n );
+ else
+ sprintf(name2, "/PIC_CAM/PIC00000/PSN%05d.PMP", picture_index[n]);
+
+ /* printf("name %s, name2 %s, %d\n",name,name2,n); */
+
+ if(0)
+ switch(format){
+ case PMX:
+ fprintf(stdout, "pidx%03d.pmx: ", n -1 );
+ break;
+ case JPEG_T:
+ fprintf(stderr, "Thumbnail %03d: ", n);
+ break;
+ case PMP:
+ case JPEG:
+ default:
+ fprintf(stdout, "Picture %03d: ", n);
+ break;
+ }
+
+ if(format == JPEG_T)
+ len = get_thumbnail(port, name, data, format,
+ 0xff & (picture_thumbnail_index[n] >> 8));
+ else
+ len = get_file(port, name, data, format);
+ if(len == 0 ) {
+ goto retry;
+ }
+
+ if (len < 0)
+ errflg ++;
+
+ return(len);
+}
+
+static int
+delete_picture(GPPort *port, int n, int all_pic_num) {
+ if (all_pic_num < n) {
+ gp_log (GP_LOG_ERROR, "delete_picture", "picture number %d is too large. %d",n,all_pic_num);
+ return GP_ERROR;
+ }
+
+ if(picture_protect[n-1] != 0x00){
+ gp_log (GP_LOG_DEBUG, "delete_picture", "picture %d is protected.", n);
+ return GP_ERROR;
+ }
+ return F1deletepicture(port, picture_index[n]);
+}
int camera_id (CameraText *id) {