Files
libgphoto2/camlibs/sipix/web2.c
Arnaud Launay b9d58ca88b replace (c) and (C) by �
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@5969 67ed7778-7388-44ab-90cf-0a291f65f57c
2002-12-15 11:45:10 +00:00

474 lines
12 KiB
C

/* library.c
*
* Copyright © 2002 Marcus Meissner <marcus@jet.franken.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <gphoto2-library.h>
#include <gphoto2-result.h>
#include "web2.h"
#ifdef ENABLE_NLS
# include <libintl.h>
# undef _
# define _(String) dgettext (GETTEXT_PACKAGE, String)
# ifdef gettext_noop
# define N_(String) gettext_noop (String)
# else
# define N_(String) (String)
# endif
#else
# define _(String) (String)
# define N_(String) (String)
#endif
#define WEB2_SELECT_PICTURE 0xb2
#define WEB2_GET_NUMPICS 0xb6
#define WEB2_OPEN_CAMERA 0xd7
#define WEB2_CLOSE_CAMERA 0xd8
#define WEB2_GET_EXIF 0xe5
#define WEB2_GET_IMAGE 0x93
#define WEB2_GET_THUMBNAIL 0x9b
#define WEB2_GET_DIRENTRY 0xb9
#define WEB2_GET_PICINFO 0xad
static int
web2_command(
GPPort *port, int iswrite, int cmd, int param, int index, char *data, int datasize
) {
int ret;
if (iswrite)
ret = gp_port_usb_msg_write(port,0,(cmd<<8)|param,index,data,datasize);
else
ret = gp_port_usb_msg_read(port,0,(cmd<<8)|param,index,data,datasize);
#if 0
fprintf(stderr,"cmd %x, param %d, ret is %d\n",cmd, param, ret);
if ((ret > 0) && data) {
for (i=0;i<datasize;i++) { fprintf(stderr,"%02x ",data[i]); }
fprintf(stderr,"\n");
}
#endif
if (ret>=GP_OK)
ret=GP_OK;
return ret;
}
int
web2_init(GPPort *port, GPContext *context) {
return web2_command(port, 1, WEB2_OPEN_CAMERA, 1, 0, NULL, 0);
}
int
web2_exit(GPPort *port, GPContext *context) {
return web2_command(port, 1, WEB2_CLOSE_CAMERA, 0, 0, NULL, 0);
}
int
web2_select_picture(GPPort *port, GPContext *context, int picnum) {
char cmdbuf[2];
picnum++;
cmdbuf[0] = picnum & 0xff;
cmdbuf[1] = (picnum>>8) & 0xff;
return web2_command(port, 1, WEB2_SELECT_PICTURE, 0, 0, cmdbuf, 2);
}
static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
int
web2_getexif(GPPort *port, GPContext *context, CameraFile *file)
{
int ret, i;
char xbuf[16384];
ret = web2_command(port, 1, WEB2_GET_EXIF, 0x00, 0, NULL, 0);
if (ret!=GP_OK)
return ret;
gp_file_append(file, ExifHeader, sizeof(ExifHeader));
ret = gp_port_read(port, xbuf, sizeof(xbuf));
if (ret < GP_OK) {
gp_file_clean(file);
return ret;
}
for (i=0;i<ret;i+=2) {
unsigned char tmp = xbuf[i];
xbuf[i] = xbuf[i+1];
xbuf[i+1] = tmp;
}
gp_file_append(file, xbuf, ret);
return GP_OK;
}
int
web2_getthumb(GPPort *port, GPContext *context, CameraFile *file)
{
int ret, i;
unsigned char buf[16384];
ret = web2_command(port, 1, WEB2_GET_THUMBNAIL, 0x00, 0, NULL, 0);
if (ret!=GP_OK)
return ret;
ret = gp_port_read(port, buf, sizeof(buf));
if (ret < GP_OK)
return ret;
for (i=0;i<ret;i+=2) {
unsigned char tmp = buf[i];
buf[i] = buf[i+1];
buf[i+1] = tmp;
}
gp_file_append(file, buf, ret);
return GP_OK;
}
int
web2_getpicture(GPPort *port, GPContext *context, CameraFile *file)
{
char xbuf[8192];
int wascanceled = 0, id, ret, curread = 0, size;
char fn[20];
ret = web2_get_file_info(port, context, fn, &size);
if (ret!=GP_OK)
return ret;
id = gp_context_progress_start(context, size, _("Downloading image..."));
size++; /* sometimes we need to read a byte more to settle the camera */
/* can be called with 0x10 and 0x1 flag. But what do these do? */
ret = web2_command(port, 1, WEB2_GET_IMAGE, 0, 0, 0, 0);
if (ret!=GP_OK)
return ret;
while (curread < size) {
int toread = size-curread;
if (toread > sizeof(xbuf))
toread = sizeof(xbuf);
ret = gp_port_read(port, xbuf, toread);
if (ret < GP_OK)
return ret;
gp_file_append(file,xbuf,ret);
curread+=ret;
gp_context_progress_update(context, id, curread);
if (toread!=ret)
break;
if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
/* We need to read the rest too or the communication is in
* an undefined state. */
wascanceled = 1;
}
}
gp_context_progress_stop(context, id);
if (wascanceled)
return GP_ERROR_CANCEL;
return GP_OK;
}
int
web2_get_picture_info(
GPPort *port, GPContext *context,
int picnum,
int *perc, int *incamera, int *flags, int *unk
) {
char cmdbuf[8];
int ret;
/* picnum is not in param, but in the control message index! */
ret = web2_command(port, 0, WEB2_GET_PICINFO, 0, picnum+1, cmdbuf, 8);
if (ret != GP_OK)
return ret;
*perc = cmdbuf[0] | (cmdbuf[1] << 8);
*incamera = cmdbuf[2] | (cmdbuf[3] << 8);
*flags = cmdbuf[4] | (cmdbuf[5] << 8);
*unk = cmdbuf[6] | (cmdbuf[7] << 8);
return GP_OK;
}
int
web2_get_file_info(GPPort *port, GPContext *context, char *name, int *filesize) {
unsigned char cmdbuf[26];
int i, hmm, ret;
ret = web2_command(port, 0, WEB2_GET_DIRENTRY, 0, 0, cmdbuf, 26);
/* 0 usually? */
hmm = cmdbuf[0] | (cmdbuf[1] << 8);
/* flip filename bytes to be in correct order */
for (i=2;i<16;i++)
name[i-2] = cmdbuf[i^1];
*filesize = (cmdbuf[18] ) | (cmdbuf[19] << 8) | \
(cmdbuf[20] << 16) | (cmdbuf[21] << 24);
/* 22-25 unused? */
return ret;
}
/********************** Unknown and/or incomplete ******************/
/* Called after 0xad and 0xb2 , with 0, 1, 2, or similar x values
* Seems to global, not picture based. (Select storage? Select camera access
* mode?) Not clear. You need to set it correctly before download or delete
* thought
*/
int
web2_set_xx_mode(GPPort *port, GPContext *context, int mode) {
char cmdbuf[2];
cmdbuf[0] = mode & 0xff;
cmdbuf[1] = (mode>>8) & 0xff;
return web2_command(port, 1, 0xae, 0, 0, cmdbuf, 2);
}
int
web2_getnumpics(
GPPort *port, GPContext *context,
int *x1, int *numpics, int *x3, int *freemem
) {
char cmdbuf[10];
int ret;
ret = web2_command(port, 0, WEB2_GET_NUMPICS, 0x00, 0, cmdbuf, 10);
if (ret!=GP_OK)
return ret;
*x1 = cmdbuf[0] | (cmdbuf[1] << 8); /* unclear */
*numpics = cmdbuf[2] | (cmdbuf[3] << 8);
*x3 = cmdbuf[4] | (cmdbuf[5] << 8); /* unclear */
/* sometimes looks like mem, sometimes it doesn't */
*freemem = cmdbuf[6] | (cmdbuf[7] << 8) | (cmdbuf[8] << 16) | (cmdbuf[9] << 24);
return GP_OK;
}
/* called with 0x00, 0x20, or 0x40 */
/* 0x40 is 'delete selected picture' */
/* the others are unknown */
int
web2_set_picture_attribute(GPPort *port, GPContext *context, int x, int *y) {
char cmdbuf[2];
int ret;
ret = web2_command(port, 0, 0xba, x, 0, cmdbuf, 2);
if (ret!=GP_OK)
return ret;
*y = cmdbuf[0] | (cmdbuf[1] << 8);
return GP_OK;
}
/* gets 7 shorts */
int
_cmd_e6(GPPort *port, GPContext *context, short *arr) {
char cmdbuf[14];
int i;
int ret;
ret = web2_command(port, 0, 0xe6, 0, 0, cmdbuf, 14);
if (ret!=GP_OK)
return ret;
for (i=0;i<7;i++)
arr[i] = cmdbuf[2*i+0] | (cmdbuf[2*i+1]<<8);
return GP_OK;
}
#if 0
int
_cmd_d0(GPPort *port, GPContext *context, int flag, short *retval) {
char buf[4];
int ret;
ret = web2_command(port, 0, 0xd0, 0, 0, buf, 4);
if (ret < 0)
return GP_ERROR_IO;
*retval = buf[flag*2] | (buf[flag*2+1]<<8);
return GP_OK;
}
int /* change mode? args are 30,40,50 ... they will appear in d0 later */
_cmd_1f(GPPort *port, GPContext *context, int x) {
return web2_command(port, 1, 0x1f, x, 0, NULL, 0);
}
int
_cmd_07(GPPort *port, GPContext *context, int *x) {
char cmdbuf[2];
int ret;
ret = web2_command(port, 0, 0x07, 0, 0, cmdbuf, 2);
if (ret < 0)
return GP_ERROR_IO;
*x = cmdbuf[0] | (cmdbuf[1]<<8);
return GP_OK;
}
int
_cmd_0a(GPPort *port, GPContext *context, int x1, int x2) {
char buf[80], cmdbuf[2];
int ret, i;
cmdbuf[0] = x2&0xff;
cmdbuf[1] = (x2>>8)&0xff;
ret = web2_command(port, 1, 0x0a, x1, 0, cmdbuf, 2);
if (ret < 0) {
fprintf(stderr,"0a failed\n");
return GP_ERROR_IO;
}
ret = gp_port_read(port, buf, 80);
if (ret<80)
return ret;
for (i=0;i<sizeof(buf);i++) { fprintf(stderr,"%02x ",buf[i]); }
fprintf(stderr,"\n");
return GP_OK;
}
/* similar to 0a, writes the 80 byte table */
int
_cmd_0b(GPPort *port, GPContext *context, int x1, int x2) {
char cmdbuf[2];
int ret;
cmdbuf[0] = x2&0xff;
cmdbuf[1] = (x2>>8)&0xff;
ret = web2_command(port, 1, 0x0b, x1, 0, cmdbuf, 2);
if (ret < 0)
return GP_ERROR_IO;
/* Bulk writes stuff */
return GP_OK;
}
int
_cmd_eb(GPPort *port, GPContext *context, int x) {
char cmdbuf[2];
cmdbuf[0] = x & 0xff;
cmdbuf[1] = (x>>8) & 0xff;
/* Only 1 is passed as param, and x appears to be a BOOL */
return web2_command(port, 1, 0xeb, 1, 0, cmdbuf, 2);
}
int
_cmd_11(GPPort *port, GPContext *context, int x) {
return web2_command(port, 1, 0x11, x|0x20, 0, NULL, 0);
}
/* gets 1 shorts */
int
_cmd_bf(GPPort *port, GPContext *context, int x, short *val) {
char cmdbuf[2];
int ret;
ret = web2_command(port, 0, 0xbf, x, 0, cmdbuf, 2);
if (ret!=GP_OK)
return ret;
*val = cmdbuf[0] | (cmdbuf[1]<<8);
return GP_OK;
}
int
_cmd_20(GPPort *port, GPContext *context, int x) {
return web2_command(port, 1, 0x20, x, 0, NULL, 0);
}
int
_cmd_60(GPPort *port, GPContext *context, int x) {
return web2_command(port, 1, 0x60, x, 0, NULL, 0);
}
int
_cmd_20_0(GPPort *port, GPContext *context) {
return _cmd_20(port,context,0);
}
int
_cmd_e1(GPPort *port, GPContext *context, int x) {
switch (x) {
case 0: /* keep 0 */
break;
case 1: x = 0xe;
break;
default: x = 0xe + 0x19;
break;
}
return web2_command(port, 1, 0xe1, x, 0, NULL, 0);
}
static short xshort[3];
int
_cmd_26(GPPort *port, GPContext *context, int x) {
char cmdbuf[6];
int i;
switch (x) {
case 0:
for (i=0;i<3;i++) {
cmdbuf[2*i+0] = xshort[i] & 0xff;
cmdbuf[2*i+1] = (xshort[i] >> 8) & 0xff;
}
return web2_command(port, 1, 0x26, 0x10, 0, cmdbuf, 6);
case 1: xshort[0] = 364; /* 16c */
xshort[1] = 256; /* 100 */
xshort[2] = 596; /* 254 */
break;
case 2: xshort[0] = 998; /* 3e6 */
xshort[1] = 256; /* 100 */
xshort[2] = 259; /* 103 */
break;
default: xshort[0] = 625; /* 271 */
xshort[1] = 256; /* 100 */
xshort[2] = 607; /* 25f */
break;
}
for (i=0;i<3;i++) {
cmdbuf[2*i+0] = xshort[i] & 0xff;
cmdbuf[2*i+1] = (xshort[i] >> 8) & 0xff;
}
return web2_command(port, 1, 0x26, 0x00, 0, cmdbuf, 6);
}
int
_cmd_75(GPPort *port, GPContext *context, int x) {
switch (x) {
case 0: x = 1;break;
case 1: x = 2;break;
case 2: x = 0;break;
default:x = 1;break;
}
return web2_command(port, 1, 0x75, x, 0, NULL, 0);
}
int
_cmd_fb(GPPort *port, GPContext *context, int *y) {
char cmdbuf[2];
int ret;
ret = web2_command(port, 0, 0xfb, 0, 0xa2b8, cmdbuf, 2);
if (ret != GP_OK)
return ret;
*y = cmdbuf[0] | (cmdbuf[1] << 8);
return GP_OK;
}
#endif