/* * Jenopt JD11 Camera Driver * Copyright 1999-2001 Marcus Meissner * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ #define _DEFAULT_SOURCE #include "config.h" #include #include #include #include #include #include #include #include "serial.h" #include "decomp.h" #ifdef ENABLE_NLS # include # undef _ # define _(String) dgettext (GETTEXT_PACKAGE, String) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else # define textdomain(String) (String) # define gettext(String) (String) # define dgettext(Domain,Message) (Message) # define dcgettext(Domain,Message,Type) (Message) # define bindtextdomain(Domain,Directory) (Domain) # define _(String) (String) # define N_(String) (String) #endif #if 0 static int dread(GPPort *port, caddr_t buf, int xsize) { int i; int ret = gp_port_read(port,buf,xsize); if (ret == -1) { perror("dread"); return -1; } fprintf(stderr,"dread[%d]:",ret); for (i=0;i>8; buf[1] = cmd&0xff; return WRITE(port,buf,2); } static int _read_cmd(GPPort *port,unsigned short *xcmd) { unsigned char buf[2]; int i = 0,ret; *xcmd = 0x4242; do { if (1==(ret=READ(port,buf,1))) { if (buf[0]==0xff) { if (1==READ(port,buf+1,1)) { *xcmd = (buf[0] << 8)| buf[1]; return GP_OK; } } } else { return ret; } } while (i++<10); return GP_ERROR_IO; } #if 0 static void _dump_buf(unsigned char *buf,int size) { int i; fprintf(stderr,"["); for (i=0;i>8; buf[1] = cmd&0xff; ret = WRITE(port,buf,2); do { if (1==(ret=READ(port,buf,1))) { if (buf[0]==0xff) { if (1==READ(port,buf+1,1)) { *xcmd = (buf[0] << 8)| buf[1]; return GP_OK; } } } else { return ret; } } while (i++<3); } return GP_ERROR_IO; } int jd11_ping(GPPort *port) { unsigned short xcmd; char buf[1]; int ret,tries = 3; while (tries--) { ret = GP_ERROR_IO; while (1==READ(port,buf,1)) /* drain input queue before PING */; ret=_send_cmd_2(port,0xff08,&xcmd); if ((ret>=GP_OK) && (xcmd==0xfff1)) return GP_OK; } return ret; } int jd11_get_rgb(GPPort *port,float *red, float *green, float *blue) { char buf[10]; int ret=GP_OK,tries=0,curread=0; _send_cmd(port,0xffa7); while ((curread<10) && (tries++<30)) { ret=READ(port,buf+curread,sizeof(buf)-curread); if (ret < 0) continue; if (ret == 0) break; curread+=ret; } if(curread<10) { fprintf(stderr,"%d returned bytes on float query.\n",ret); return GP_ERROR_IO; } /*_dump_buf(buf,10);*/ *green = buf[1]+buf[2]*0.1+buf[3]*0.01; *red = buf[4]+buf[5]*0.1+buf[6]*0.01; *blue = buf[7]+buf[8]*0.1+buf[9]*0.01; return GP_OK; } int jd11_set_rgb(GPPort *port,float red, float green, float blue) { unsigned char buf[20]; _send_cmd(port,0xffa7); buf[0] = 0xff; buf[1] = (int)green; buf[2] = ((int)(green*10))%10; buf[3] = ((int)(green*100))%10; buf[4] = (int)red; buf[5] = ((int)(red*10))%10; buf[6] = ((int)(red*100))%10; buf[7] = (int)blue; buf[8] = ((int)(blue*10))%10; buf[9] = ((int)(blue*100))%10; /*_dump_buf(buf,10);*/ return WRITE(port,buf,10); } int jd11_select_index(GPPort *port) { /* select index */ unsigned short xcmd; int ret; ret = _send_cmd_2(port,0xffa4,&xcmd); if (ret < GP_OK) return ret; if (xcmd!=0xff01) return GP_ERROR_IO; return GP_OK; } int jd11_select_image(GPPort *port,int nr) { /* select image */ unsigned short xcmd; _send_cmd(port,0xffa1); _send_cmd(port,0xff00|nr); _read_cmd(port,&xcmd); if (xcmd != 0xff01) return GP_ERROR_IO; return GP_OK; } int jd11_set_bulb_exposure(GPPort *port,int i) { unsigned short xcmd; if ((i<1) || (i>9)) return GP_ERROR_BAD_PARAMETERS; _send_cmd(port,0xffa9); _send_cmd(port,0xff00|i); _read_cmd(port,&xcmd); return GP_OK; } #if 0 static void jd11_TestADC(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff75); _read_cmd(port,&xcmd); fprintf(stderr,"TestADC: done, xcmd=%x\n",xcmd); } static void cmd_TestDRAM(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff72); _read_cmd(port,&xcmd); fprintf(stderr,"TestDRAM: done.\n"); } /* doesn't actually flash */ static void cmd_TestFLASH(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff73); _read_cmd(port,&xcmd); fprintf(stderr,"TestFLASH: xcmd = %x.\n",xcmd); } /* some kind of selftest ... shuts the shutters, beeps... only stops by * powercycle. */ static void cmd_79(GPPort *port) { unsigned short xcmd; _send_cmd(port,0xff79); _read_cmd(port,&xcmd); fprintf(stderr,"79: done, xcmd =%x\n",xcmd); } #endif static int jd11_imgsize(GPPort *port) { char buf[20]; int ret; int i=0,curread=0; _send_cmd(port,0xfff0); do { ret=READ(port,&buf[curread],10-curread); if (ret>0) curread+=ret; usleep(1000); } while ((i++<20) && (curread<10)); /*_dump_buf(buf,curread);*/ if (!curread) /* We get 0 bytes return for 0 images. */ return 0; ret=strtol(&buf[2],NULL,16); return ret; } static int getpacket(GPPort *port,unsigned char *buf, int expect) { int curread = 0, csum = 0; int tries = 0; if (expect == 200) expect++; while (tries++<5) { int i=0,ret; do { ret=READ(port,buf+curread,expect-curread); if (ret>0) { curread+=ret; i=0; continue; } usleep(100); } while ((i++<2) && (curread200) readsize = 200; ret=getpacket(port,indexbuf+curread,readsize); if (ret==0) break; curread+=ret; if (ret<200) break; gp_context_progress_update (context, id, curread); if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { /* What to do...Just free the stuff we allocated for now.*/ free(indexbuf); return GP_ERROR_CANCEL; } _send_cmd(port,0xfff1); } gp_context_progress_stop (context, id); for (i=0;iport; unsigned int id; jd11_select_image(port,nr); *imagebufs = (unsigned char**)malloc(3*sizeof(unsigned char*)); for (picnum=0;picnum<3;picnum++) { curread=0; sizes[picnum] = jd11_imgsize(port); (*imagebufs)[picnum]=(unsigned char*)malloc(sizes[picnum]+400); _send_cmd(port,0xfff1); id = gp_context_progress_start (context, sizes[picnum], _("Downloading data...")); while (curread 200) readsize = 200; ret=getpacket(port,(*imagebufs)[picnum]+curread,readsize); if (ret==0) break; curread+=ret; if (ret<200) break; gp_context_progress_update (context, id, curread); if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { int j; /* What to do ... Just free the stuff we allocated for now. */ for (j=0;jright mirrored */ for (h=480;h--;) { int w; for (w=320;w--;) { if (h&1) { /* G B G B G B G B G */ *s++ = uncomp[0][h*320+w]; *s++ = uncomp[2][(h/2)*320+w]; } else { /* R G R G R G R G R */ *s++ = uncomp[1][(h/2)*320+w]; *s++ = uncomp[0][h*320+w]; } } } /*gp_bayer_decode(bayerpre,640,480,data,BAYER_TILE_GRBG);*/ gp_ahd_decode(bayerpre,640,480,data,BAYER_TILE_GRBG); free(bayerpre); } else { s=data; for (h=480;h--;) { /* upside down */ int w; for (w=640;w--;) { /* right to left */ /* and images are in green red blue */ *s++=uncomp[1][(h/2)*320+(w/2)]; *s++=uncomp[0][h*320+(w/2)]; *s++=uncomp[2][(h/2)*320+(w/2)]; } } } free(uncomp[0]);free(uncomp[1]);free(uncomp[2]); free(imagebufs[0]);free(imagebufs[1]);free(imagebufs[2]);free(imagebufs); gp_file_append(file, (char*)data, 640*480*3); free(data); return GP_OK; }