? ID ? camera.txt ? photopc ? epinfo ? jscan.diff ? photopc.patches ? pix Index: Makefile =================================================================== RCS file: /u/cvsroot/photopc/Makefile,v retrieving revision 1.1.1.1 retrieving revision 1.3 diff -u -r1.1.1.1 -r1.3 --- Makefile 1997/10/20 07:01:33 1.1.1.1 +++ Makefile 1997/10/20 16:57:02 1.3 @@ -1,3 +1,4 @@ +# $Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $ # Makefile for Epson PhotoPC manipulation tool # Copyright (c) 1997 Eugene G. Crosser @@ -25,20 +26,22 @@ # system call. On others, you don't and you cannot. Look if there is # a file "/usr/include/sys/select.h" and define accordingly. +PREFIX=/usr/local + # This one is good for Linux: OPTS = -DINT16=short -DHAVE_CFMAKERAW # This one is good for Solaris 2.x: #OPTS = -DINT16=short -DHAVE_SELECT_H -BINDEST = /usr/local/bin -LIBDEST = /usr/local/lib -INCDEST = /usr/local/include -MANDEST = /usr/local/man +BINDEST = ${PREFIX}/bin +LIBDEST = ${PREFIX}/lib +INCDEST = ${PREFIX}/include +MANDEST = ${PREFIX}/man MANEXT = 1 CC = gcc -CFLAGS = -O2 -Wall +CFLAGS = -O2 -Wall -g LD = gcc LDFLAGS = AR = ar @@ -73,7 +76,7 @@ install: all ${INSTALL} -m 755 photopc ${BINDEST} ${INSTALL} -m 755 epinfo ${BINDEST} - ${INSTALL} -d -m 755 ${MANDEST}/man${MANEXT} +# ${INSTALL} -d -m 755 ${MANDEST}/man${MANEXT} ${INSTALL} -m 644 photopc.man ${MANDEST}/man${MANEXT}/photopc.${MANEXT} ${INSTALL} -m 644 epinfo.man ${MANDEST}/man${MANEXT}/epinfo.${MANEXT} Index: eph_open.c =================================================================== RCS file: /u/cvsroot/photopc/eph_open.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- eph_open.c 1997/10/20 07:01:33 1.1.1.1 +++ eph_open.c 1997/10/20 16:57:02 1.2 @@ -1,3 +1,8 @@ +/* $Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $ */ + +#ifndef lint +static char vcid[] = "$Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $"; +#endif /* lint */ /* Copyright (c) 1997 Eugene G. Crosser @@ -20,7 +25,9 @@ #include #include -#define DEFSPEED B19200 +#define INITIALSPEED B19200 /* the intial com port speed of the camera */ +#define DEFSPEED B115200 /* the default speed we'd like the program + to use */ int eph_open(eph_iob *iob,char *devname,long speed) { struct termios tios; @@ -29,8 +36,11 @@ int rc; int count=0; + if (speed == 0){ + speed = DEFSPEED; + } + switch (speed) { - case 0: tspeed=B19200; ephspeed=2; speed=19200; break; case 9600: tspeed=B9600; ephspeed=1; break; case 19200: tspeed=B19200; ephspeed=2; break; case 38400: tspeed=B38400; ephspeed=3; break; @@ -66,8 +76,8 @@ tios.c_oflag=0; tios.c_lflag=0; #endif - cfsetospeed(&tios,DEFSPEED); - cfsetispeed(&tios,DEFSPEED); + cfsetospeed(&tios,INITIALSPEED); + cfsetispeed(&tios,INITIALSPEED); #ifdef USE_VMIN_AND_VTIME tios.c_cc[VMIN]=127; tios.c_cc[VTIME]=1; @@ -118,7 +128,7 @@ close(iob->fd); return -1; } - if (tspeed != DEFSPEED) usleep(SPEEDCHGDELAY); + if (tspeed != INITIALSPEED) usleep(SPEEDCHGDELAY); return 0; } Index: jscan.c =================================================================== RCS file: /u/cvsroot/photopc/jscan.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- jscan.c 1997/10/20 07:01:33 1.1.1.1 +++ jscan.c 1997/10/20 07:10:27 1.2 @@ -1,3 +1,8 @@ +/* $Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $ */ + +#ifndef lint +static char vcid[] = "$Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $"; +#endif /* lint */ /* Copyright (c) 1997 Eugene G. Crosser @@ -29,6 +34,12 @@ p+=strlen("SanyoElectricDSC"); length-=3; length-=strlen("SanyoElectricDSC"); + break; + } else if ((*p == 0xec) && (strcmp(p+3,"OLYMPUS OPTICAL CO.,LTD. ") == 0)){ + p+=4; + p+=strlen("OLYMPUS OPTICAL CO.,LTD. "); + length-=3; + length-=strlen("OLYMPUS OPTICAL CO.,LTD. "); break; } p+=length; Index: photopc.c =================================================================== RCS file: /u/cvsroot/photopc/photopc.c,v retrieving revision 1.1.1.1 retrieving revision 1.6 diff -u -r1.1.1.1 -r1.6 --- photopc.c 1997/10/20 07:01:33 1.1.1.1 +++ photopc.c 1997/10/31 00:20:55 1.6 @@ -1,3 +1,10 @@ +#define TIME_FILENAMES +/* $Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $ */ + +#ifndef lint +static char vcid[] = "$Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $"; +#endif /* lint */ + /* Copyright (c) 1997 Eugene G. Crosser @@ -36,8 +43,12 @@ int setclock(eph_iob *iob,int argc,char *argv[]) { time_t now,new; + struct tm *tm; (void)time(&now); + tm = localtime(&now); + + now += tm->tm_gmtoff; if (eph_setint(iob,2,now)) return -1; if (eph_getint(iob,2,&new)) return -1; @@ -213,6 +224,130 @@ static char *flashval[] = {"Auto","Force","Off","AntiRedeye"}; +char *resnames[] = {"Normal", "HQ", "HQ2"}; +char *flashnames[] = {"Auto", "Force On", "Off", "Redeye"}; +char *lensnames[] = {"Macro", "Normal"}; + +struct camreg { + int regnum; /* register number */ + char *regname; /* ascii name of register */ + enum { IREG, VREG } type; /* type integer or string */ + int lbvalname; /* lower bound of names */ + int ubvalname; /* upper bound of names */ + char **valname; +} camreg[] = { + { 1, "Resolution", IREG, 1, 4, resnames }, + { 2, "Time", IREG, 0, 0, NULL }, + { 3, "Shutter Speed", IREG, 0, 0, NULL }, + { 4, "Current Frame Number", IREG, 0, 0, NULL }, + { 5, "Unknown #5", IREG, 0, 0, NULL }, + { 6, "Unknown #6", IREG, 0, 0, NULL }, + { 7, "Flash Mode", IREG, 1, 5, flashnames }, + { 8, "Unknown #8", IREG, 0, 0, NULL }, + { 9, "Unknown #9", IREG, 0, 0, NULL }, + { 10, "Frames Taken", IREG, 0, 0, NULL }, + { 11, "Frames Left", IREG, 0, 0, NULL }, + { 12, "Curr Frame Len", IREG, 0, 0, NULL }, + { 13, "Curr Thumb Len", IREG, 0, 0, NULL }, +#if 0 + { 14, "Curr Frame Data", VREG, 0, 0, NULL }, + { 15, "Curr Thumb Data", VREG, 0, 0, NULL }, +#endif + { 16, "Battery %", IREG, 0, 0, NULL }, + /* { 17, "Baud", IREG, 0, 0, NULL }, */ + { 18, "Unknown #18", IREG, 0, 0, NULL }, + /* + * 19, 20, 21 + */ + { 22, "ID", VREG, 0, 0, NULL }, + { 23, "Power timer host", IREG, 0, 0, NULL }, + { 24, "Power timer field", IREG, 0, 0, NULL }, + { 25, "Serial #", VREG, 0, 0, NULL }, + { 26, "Version #", VREG, 0, 0, NULL }, + { 27, "Model #", VREG, 0, 0, NULL }, + { 28, "Memory Left", IREG, 0, 0, NULL }, + /* { 29, "Unknown #29", IREG, 0, 0, NULL }, */ + /* { 30, "Unknown #30", IREG, 0, 0, NULL }, */ + /* { 31, "Unknown #31", IREG, 0, 0, NULL }, */ + { 32, "Unknown #32", IREG, 0, 0, NULL }, + { 33, "Lens", IREG, 1, 3, lensnames}, + { 34, "Unknown #34", IREG, 0, 0, NULL }, + { 35, "Unknown #35", IREG, 0, 0, NULL }, + { 36, "Unknown #36", IREG, 0, 0, NULL }, + { 36, "Unknown #36", IREG, 0, 0, NULL }, + /* { 37, "Unknown #37", IREG, 0, 0, NULL }, */ + { 38, "Unknown #38", IREG, 0, 0, NULL }, + { 39, "Unknown #39", IREG, 0, 0, NULL }, + + { 40, "Last frame", IREG, 0, 0, NULL }, + { 41, "LCD Brightness", IREG, 0, 0, NULL }, + { 42, "Unknown #42", IREG, 0, 0, NULL }, + { 43, "Unknown #43", IREG, 0, 0, NULL }, + { 44, "Unknown #44", IREG, 0, 0, NULL }, + { 45, "Unknown #45", IREG, 0, 0, NULL }, + { 46, "Unknown #46", IREG, 0, 0, NULL }, + { 47, "Unknown #47", IREG, 0, 0, NULL }, + { 48, "Unknown #48", IREG, 0, 0, NULL }, + { 49, "Unknown #49", IREG, 0, 0, NULL }, + + { 50, "Unknown #50", IREG, 0, 0, NULL }, + { 51, "Unknown #51", IREG, 0, 0, NULL }, + { 52, "Unknown #52", IREG, 0, 0, NULL }, + { 53, "Unknown #53", IREG, 0, 0, NULL }, + { 54, "Unknown #54", IREG, 0, 0, NULL }, + { 55, "Unknown #55", IREG, 0, 0, NULL }, + { 56, "Unknown #56", IREG, 0, 0, NULL }, + { 57, "Unknown #57", IREG, 0, 0, NULL }, + { 58, "Unknown #58", IREG, 0, 0, NULL }, + { 59, "Unknown #59", IREG, 0, 0, NULL }, + + { 60, "Unknown #60", IREG, 0, 0, NULL }, + { 61, "Unknown #61", IREG, 0, 0, NULL }, + { 62, "Unknown #62", IREG, 0, 0, NULL }, + { 63, "Unknown #63", IREG, 0, 0, NULL }, + { 64, "Unknown #64", IREG, 0, 0, NULL }, + + { 0, NULL, 0, NULL, 0 } +}; + + +int query2(eph_iob *iob,int argc,char *argv[]) { + unsigned long result; + char *buffer; + int bufsize; + struct camreg *camregp; + + buffer=malloc(2048); + + for (camregp = camreg ; camregp->regnum ; camregp++){ + if (camregp->type == IREG){ + result = -1; + if (eph_getint(iob,camregp->regnum,&result)) { + printf("%20s: ???\n", camregp->regname); + } else if ((camregp->lbvalname <= result) && + (result < camregp->ubvalname)) { + printf("%20s: %s\n", camregp->regname, + camregp->valname[result - camregp->lbvalname]); + } else { + printf("%20s: %ld\n", camregp->regname, result); + } + } else if (camregp->type == VREG){ + bufsize=2048; buffer[0]='\0'; + if (eph_getvar(iob,camregp->regnum,&buffer,&bufsize)) { + printf("%20s: \"???\"\n", camregp->regname); + } else { + printf("%20s: \"%s\"\n", camregp->regname, buffer); + } + } + } + + printf("\n"); + + free(buffer); + return 0; +} + + int query(eph_iob *iob,int argc,char *argv[]) { unsigned long result; char *buffer; @@ -228,7 +363,15 @@ if ((result == 0L) || (result == (unsigned long)-1L)) { printf("Camera time: not set (%ld)",result); } else { + struct tm *tm; + time_t now; + + tm = localtime (&result); + result -= tm->tm_gmtoff; + (void)time(&now); + printf("Camera time: %s",asctime(localtime((time_t*)&result))); + printf("Time drift: %ld sec\n", (time_t) result - now); } if (eph_getint(iob,3,&result)) return -1; @@ -365,9 +508,23 @@ } filesize=length; got=bufsize; - if (eph_getvar(iob,thumbnail?0x0f:0x0e,&buffer,&got)) return -1; + { + struct timeval tvstart, tvend; + double start, end; + + gettimeofday(&tvstart, NULL); + if (eph_getvar(iob,thumbnail?0x0f:0x0e,&buffer,&got)) return -1; + gettimeofday(&tvend, NULL); + + start = (tvstart.tv_usec * 1e-6) + tvstart.tv_sec; + end = (tvend.tv_usec * 1e-6) + tvend.tv_sec; + + printf("\n%0.1f KBytes in %0.1f sec (%0.2f KBytes/sec)\n", + got / 1e3, end - start, got / ((end - start) * 1e3)); + + } filesize=0L; - printf("\n"); + /* printf("\n"); */ res=buffer; ressize=bufsize; jscan(&res,&ressize); @@ -375,6 +532,9 @@ if (p && (*p != '-')) { sscanf(p,"%lu",&pictime); pictm=localtime(&pictime); + + pictime -= pictm->tm_gmtoff; + pictm=localtime(&pictime); } else { pictime=(time_t)0; pictm=&_pictm; @@ -384,6 +544,7 @@ if (!quite) { printf("taken %s",asctime(pictm)); } +#ifndef TIME_FILENAMES if ((stat(filenm,&st) == 0) && (S_ISDIR(st.st_mode))) { int count; @@ -406,6 +567,26 @@ if (fname == NULL) return -1; strcpy(fname,filenm); } +#else /* TIME_FILENAMES */ + fname=malloc(strlen(filenm)+15); + if (fname == NULL) return -1; + sprintf(fname,"%s/%s%04d%02d%02d_%02d%02d%02d.jpg", + filenm, + thumbnail?"thm":"pic", + pictm->tm_year + 1900, /* tm_year is year since 1900 */ + pictm->tm_mon+1, + pictm->tm_mday, + + pictm->tm_hour, + pictm->tm_min, + pictm->tm_sec + ); + if ((stat(fname,&st) < 0) && (errno == ENOENT)) { + if (!quite) printf("file \"%s\"\n",fname); + } else { /* already got this one */ + return -2; + } +#endif if ((fp=fopen(fname,"w")) == NULL) { perror(fname); return -1; @@ -433,18 +614,32 @@ if (!quite) printf("Retreiving %ld frames\n",top); } else if (sscanf(argv[1],"%ld-%ld",&bot,&top) == 2) { /* do nothing */ ; + } else if (sscanf(argv[1],"%ld-all",&bot) == 1) { + if (eph_getint(iob,0x0a,&top)) { + fprintf(stderr,"could not get number of frames\n"); + return -1; + } + if (!quite) printf("Retreiving frames %ld - %ld\n", bot, top); } else if (sscanf(argv[1],"%ld",&bot) == 1) { top=bot; } else { fprintf(stderr,"bad frmes interval \"%s\"\n",argv[1]); return -1; } - if ((top != bot) && (stat(argv[2],&st) == 0) && !S_ISDIR(st.st_mode)) { + if ( +#ifndef TIME_FILENAMES + (top != bot) && +#endif + (stat(argv[2],&st) == 0) && !S_ISDIR(st.st_mode)) { fprintf(stderr,"target must be directory for interval\n"); return -1; } for (i=bot;i<=top;i++) { - if ((rc=retrfile(iob,thumbnail,i,argv[2]))) return rc; + if ((rc=retrfile(iob,thumbnail,i,argv[2]))) { + /* "got it" already code */ + if (rc != -2) + return rc; + } } return 0; } @@ -467,6 +662,7 @@ } cmdlist[] = { {"", 0, NULL, "== Query parameters ==" }, {"query", 0, query, "" }, + {"query2", 0, query2, "" }, {"count", 0, count, "" }, {"geti", 1, geti, "-" }, {"getv", 1, getv, "-" }, @@ -504,7 +700,7 @@ printf("\t-v\t- increase debugging verbosity\n"); printf("\t-q\t- do not show running download indicator\n"); printf("\t-s baud\t- set port speed to 9600,19200,38400,57600 or 115200\n"); - printf("\t\t\tdefault is 19200\n"); + printf("\t\t\tdefault is 115200\n"); printf("\t-l dev\t- use device name instead of default %s\n\n",device); printf("Commands:\n"); for (i=0;cmdlist[i].cmd;i++) { Index: photopc.man =================================================================== RCS file: /u/cvsroot/photopc/photopc.man,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- photopc.man 1997/10/20 07:01:33 1.1.1.1 +++ photopc.man 1997/10/20 16:57:03 1.2 @@ -1,3 +1,4 @@ +.\" $Id: photopc-diff.txt,v 1.1 1997/12/14 09:11:12 wolfgang Exp $ .TH PHOTOPC 1 "24 May 1997" "PhotoPC manipulation tool" "User Commands" .SH NAME @@ -33,8 +34,8 @@ .TP 0.5i .B -s speed This option allows setting the data rate to use when communicating -with the camera. Valid rates are 9600, 19200 (the default), 38400, -57600 and 115200. +with the camera. Valid rates are 9600, 19200, 38400, +57600 and 115200 (the default). .TP 0.5i .B -l device Index: protocol.html =================================================================== RCS file: /u/cvsroot/photopc/protocol.html,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- protocol.html 1997/10/20 07:01:33 1.1.1.1 +++ protocol.html 1997/10/24 08:05:01 1.2 @@ -1,11 +1,19 @@ + Epson PhotoPC protocol +Nota Bene: The following text refers to to the "Epson" +protocol. I believe that this is essentially the same protocol that +is used in the Agfa, Epson, Olympus and Sanyo digital cameras. +-wolfgang + +
+

Disclaimer: This description is completely unofficial, Epson even does not know about its existance. All informaion presented -here is discovered by me, +here is discovered by me, Eugene Crosser, while snooping the serial line and by trial and error. I never had an official protocol description, have never seen any related software source code, and have never done reverse @@ -16,12 +24,12 @@

Epson PhotoPC Protocol

-Epson +Epson PhotoPC 500 is a digital camera that uses a serial (RS232) interface for communication with the host. Follows the description of the high-level protocol it uses over the serial line. I think that the same protocol is used with vanilla -PhotoPC +PhotoPC model.

Protocol Basics

@@ -222,7 +230,7 @@ Some information taken from `camediaplay' package by Jun-ichiro Itoh - +<itojun@itojun.org>

Please mail your corrections/additions to