diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | camlibs/jamcam/README | 14 | ||||
-rw-r--r-- | camlibs/jamcam/jamcam.c | 77 | ||||
-rw-r--r-- | camlibs/jamcam/library.c | 110 | ||||
-rw-r--r-- | camlibs/jamcam/library.h | 13 |
5 files changed, 167 insertions, 53 deletions
@@ -1,3 +1,9 @@ +2001-09-23 Chris Pinkham <cpinkham@infi.net> + + * camlibs/jamcam/jamcam.c + camlibs/jamcam/library.h + camlibs/jamcam/library.c: Added support for low-res images. + 2001-09-22 Lutz Müller <urc8@rz.uni-karlsruhe.de> * libgphoto2/filesys.c: Fix two small bugs. diff --git a/camlibs/jamcam/README b/camlibs/jamcam/README new file mode 100644 index 000000000..9a7f6746f --- /dev/null +++ b/camlibs/jamcam/README @@ -0,0 +1,14 @@ +KBGear JamCam v3.0 + +This driver is based upon protocol reverse-engineered +using Portmon and sniffusb under Windows 98. + +For questions/comments, email the library author: + + Chris Pinkham + cpinkham@infi.net + + +TODO List +--------- + diff --git a/camlibs/jamcam/jamcam.c b/camlibs/jamcam/jamcam.c index 032ece1de..839cd1b50 100644 --- a/camlibs/jamcam/jamcam.c +++ b/camlibs/jamcam/jamcam.c @@ -46,10 +46,9 @@ #include "library.h" #define TIMEOUT 2000 -#define DEFAULT_SPEED 9600 -#define JAMCAM_VERSION "0.1" -#define JAMCAM_LAST_MOD "09/09/2001 21:00 EST" +#define JAMCAM_VERSION "0.3" +#define JAMCAM_LAST_MOD "09/23/2001 20:53 EST" /* define what cameras we support */ static struct { @@ -90,7 +89,6 @@ int camera_abilities (CameraAbilitiesList *list) a->operations = GP_OPERATION_NONE; a->file_operations = GP_FILE_OPERATION_PREVIEW; - /* fixme, believe supports GP_FOLDER_PUT_FILE */ a->folder_operations = GP_FOLDER_OPERATION_NONE; a->usb_vendor = models[x].usb_vendor; @@ -100,7 +98,6 @@ int camera_abilities (CameraAbilitiesList *list) ptr = models[++x].model; } - fprintf( stderr, "and there\n" ); return (GP_OK); } @@ -125,6 +122,7 @@ static int get_info_func (CameraFilesystem *fs, const char *folder, { Camera *camera = data; int n; + struct jamcam_file *jc_file; gp_debug_printf (GP_DEBUG_LOW, "jamcam", "* get_info_func"); gp_debug_printf (GP_DEBUG_LOW, "jamcam", "*** folder: %s", folder); @@ -133,12 +131,18 @@ static int get_info_func (CameraFilesystem *fs, const char *folder, /* Get the file number from the CameraFileSystem */ CHECK (n = gp_filesystem_number (camera->fs, folder, filename)); + jc_file = jamcam_file_info( camera, n ); + /* fixme, get file size also */ info->file.fields = GP_FILE_INFO_TYPE; - strcpy (info->file.type, GP_MIME_JPEG ); + strcpy (info->file.type, GP_MIME_PPM); + info->file.width = jc_file->width; + info->file.height = jc_file->height; info->preview.fields = GP_FILE_INFO_TYPE; - strcpy (info->preview.type, GP_MIME_JPEG); + strcpy (info->preview.type, GP_MIME_PPM); + info->preview.width = 80; + info->preview.height = 60; return (GP_OK); } @@ -160,58 +164,62 @@ static int camera_file_get (Camera *camera, const char *folder, unsigned char gtable[256]; char *ptr; int size = 0, n = 0; - int length, width; + int width, height; + struct jamcam_file *jc_file; gp_debug_printf (GP_DEBUG_LOW, "jamcam", "* camera_file_get"); gp_debug_printf (GP_DEBUG_LOW, "jamcam", "*** folder: %s", folder); gp_debug_printf (GP_DEBUG_LOW, "jamcam", "*** filename: %s",filename); gp_debug_printf (GP_DEBUG_LOW, "jamcam", "*** type: %d", type); - /* - * Get the file number from the CameraFileSystem (and increment - * because we need numbers starting with 1) - */ CHECK (n = gp_filesystem_number (camera->fs, folder, filename)); - n++; switch (type) { case GP_FILE_TYPE_PREVIEW: CHECK (jamcam_request_thumbnail (camera, raw, &size, n)); - CHECK (gp_file_set_mime_type (file, GP_MIME_RAW)); - strcpy( tmp_filename, "thumb_" ); - strcat( tmp_filename, filename ); - tmp_filename[strlen(tmp_filename)-3] = 'r'; - tmp_filename[strlen(tmp_filename)-2] = 'a'; - tmp_filename[strlen(tmp_filename)-1] = 'w'; - CHECK (gp_file_set_name (file, tmp_filename)); + width = 80; + height = 60; + + sprintf( ppm, + "P6\n" + "# CREATOR: gphoto2, jamcam library\n" + "%d %d\n" + "255\n", width, height ); + + ptr = ppm + strlen( ppm ); + + size = strlen( ppm ) + ( height * width * 3 ); + + gp_bayer_decode( width, height, raw, ptr, BAYER_TILE_GBRG ); + gp_create_gamma_table( gtable, 0.5 ); + gp_gamma_correct_single( ptr, height * width, gtable ); + + CHECK (gp_file_set_mime_type (file, GP_MIME_PPM)); + CHECK (gp_file_set_name (file, filename)); CHECK (gp_file_append (file, ppm, size)); break; case GP_FILE_TYPE_NORMAL: CHECK (jamcam_request_image (camera, raw, &size, n)); - if ( size == 261600 ) { - length = 436; - width = 600; - } else { - length = 218; - width = 300; - } + jc_file = jamcam_file_info (camera, n); sprintf( ppm, "P6\n" - "# CREATOR: gphoto2, panasonic coolshot library\n" + "# CREATOR: gphoto2, jamcam library\n" "%d %d\n" - "255\n", width, length ); + "255\n", jc_file->width, jc_file->height ); ptr = ppm + strlen( ppm ); - size = strlen( ppm ) + ( length * width * 3 ); + size = strlen( ppm ) + ( jc_file->width * jc_file->height * 3 ); - gp_bayer_decode( width, length, raw, ptr, BAYER_TILE_GBRG ); + gp_bayer_decode( jc_file->width, jc_file->height, raw, ptr, + BAYER_TILE_GBRG ); gp_create_gamma_table( gtable, 0.5 ); - gp_gamma_correct_single( ptr, length * width, gtable ); + gp_gamma_correct_single( ptr, jc_file->width * jc_file->height, + gtable ); CHECK (gp_file_set_mime_type (file, GP_MIME_PPM)); CHECK (gp_file_set_name (file, filename)); @@ -284,7 +292,7 @@ int camera_init (Camera *camera) /* First, set up all the function pointers */ camera->functions->exit = camera_exit; - camera->functions->file_get = camera_file_get; + camera->functions->file_get = camera_file_get; camera->functions->summary = camera_summary; camera->functions->manual = camera_manual; camera->functions->about = camera_about; @@ -314,9 +322,6 @@ int camera_init (Camera *camera) CHECK (gp_port_settings_set (camera->port, settings)); CHECK (gp_port_timeout_set (camera->port, TIMEOUT)); - /* - CHECK (gp_port_open( camera->port )); - */ /* check to see if camera is really there */ CHECK (jamcam_enq (camera)); diff --git a/camlibs/jamcam/library.c b/camlibs/jamcam/library.c index 61fbecdf8..c609fd42d 100644 --- a/camlibs/jamcam/library.c +++ b/camlibs/jamcam/library.c @@ -32,6 +32,9 @@ #include "library.h" +struct jamcam_file jamcam_files[1024]; +static int jamcam_count = 0; + static int jamcam_set_usb_mem_pointer( Camera *camera, int position ) { char reply[4]; @@ -56,12 +59,16 @@ static int jamcam_set_usb_mem_pointer( Camera *camera, int position ) { int jamcam_file_count (Camera *camera) { char buf[16]; - char reply[16]; + unsigned char reply[16]; int position = 0; - int count = 0; + int data_incr; + int width; + int height; gp_debug_printf (GP_DEBUG_LOW, "jamcam", "* jamcam_file_count"); + jamcam_count = 0; + memset( buf, 0, sizeof( buf )); switch( camera->port->type ) { @@ -76,10 +83,24 @@ int jamcam_file_count (Camera *camera) { jamcam_read_packet( camera, reply, 16 ); - while((unsigned char)reply[0] != 0xff ) { - count++; + while( reply[0] != 0xff ) { + width = (reply[5] * 256) + reply[4]; + height = (reply[7] * 256) + reply[6]; + + data_incr = 0; + data_incr += reply[8]; + data_incr += reply[9] * 256; + data_incr += reply[10] * 256 * 256; + data_incr += reply[11] * 256 * 256 * 256; - position += DATA_INCR; + jamcam_files[jamcam_count].position = position; + jamcam_files[jamcam_count].width = width; + jamcam_files[jamcam_count].height = height; + jamcam_files[jamcam_count].data_incr = data_incr; + + jamcam_count++; + + position += data_incr; buf[4] = ( position ) & 0xff; buf[5] = ( position >> 8 ) & 0xff; @@ -96,19 +117,35 @@ int jamcam_file_count (Camera *camera) { gp_port_read (camera->port, reply, 0x10 ); + width = (reply[13] * 256) + reply[12]; + height = (reply[15] * 256) + reply[14]; + jamcam_set_usb_mem_pointer( camera, position + 8 ); gp_port_read (camera->port, reply, 0x10 ); while((unsigned char)reply[0] != 0xff ) { - count++; + data_incr = 0; + data_incr += reply[0]; + data_incr += reply[1] * 256; + data_incr += reply[2] * 256 * 256; + data_incr += reply[3] * 256 * 256 * 256; - position += DATA_INCR; + jamcam_files[jamcam_count].position = position; + jamcam_files[jamcam_count].width = width; + jamcam_files[jamcam_count].height = height; + jamcam_files[jamcam_count].data_incr = data_incr; + jamcam_count++; + + position += data_incr; jamcam_set_usb_mem_pointer( camera, position ); gp_port_read (camera->port, reply, 0x10 ); + width = (reply[13] * 256) + reply[12]; + height = (reply[15] * 256) + reply[14]; + jamcam_set_usb_mem_pointer( camera, position + 8 ); gp_port_read (camera->port, reply, 0x10 ); @@ -116,7 +153,9 @@ int jamcam_file_count (Camera *camera) { break; } - return( count ); + gp_debug_printf (GP_DEBUG_LOW, "jamcam", + "*** returning jamcam_count = %d", jamcam_count); + return( jamcam_count ); } int jamcam_fetch_memory( Camera *camera, char *data, int start, int length ) { @@ -188,30 +227,69 @@ int jamcam_request_image( Camera *camera, char *buf, int *len, int number ) { *len = DATA_SIZE; - position = ( DATA_INCR * ( number - 1 )) + 0x10; + position = jamcam_files[number].position + 0x10; + *len = jamcam_files[number].width * jamcam_files[number].height; - jamcam_set_usb_mem_pointer( camera, position ); - gp_port_read (camera->port, buf, 120 ); + if ( camera->port->type == GP_PORT_USB ) { + jamcam_set_usb_mem_pointer( camera, position ); + gp_port_read (camera->port, buf, 120 ); - if ( camera->port->type == GP_PORT_USB ) position += 8; + } return( jamcam_fetch_memory( camera, buf, position, *len )); } +struct jamcam_file *jamcam_file_info(Camera *camera, int number) +{ + return( &jamcam_files[number] ); +} + int jamcam_request_thumbnail( Camera *camera, char *buf, int *len, int number ) { + char line[600]; char packet[16]; int position; + int x, y; + char *ptr; gp_debug_printf (GP_DEBUG_LOW, "jamcam", "* jamcam_request_thumbnail"); memset( packet, 0, sizeof( packet )); - position = ( DATA_INCR * ( number - 1 )) + 0x10; + position = jamcam_files[number].position + 0x10; + + *len = 4800; - *len = 600; + ptr = buf; - return( jamcam_fetch_memory( camera, buf, position, 600 )); + /* fetch thumbnail lines and build the thumbnail */ + position += 10 * jamcam_files[number].width; + for( y = 0 ; y < 60 ; y++ ) { + jamcam_fetch_memory( camera, line, position, + jamcam_files[number].width ); + + if ( jamcam_files[number].width == 600 ) { + for( x = 22; x < 578 ; x += 7 ) { + *(ptr++) = line[x]; + } + position += 7 * 600; + } else { + for( x = 0; x < 320 ; ) { + *(ptr++) = line[x]; + x += 3; + *(ptr++) = line[x]; + x += 5; + } + + if ( y % 2 ) { + position += 5 * 320; + } else { + position += 3 * 320; + } + } + } + + return( GP_OK ); } int jamcam_write_packet (Camera *camera, char *packet, int length) { @@ -299,8 +377,6 @@ int jamcam_enq (Camera *camera) gp_port_read( camera->port, (char *)buf, 0x0c ); - fprintf( stderr, "buf = %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3] ); - if ( !strncmp( (char *)buf, "KB00", 4 )) { return (GP_OK); } else if (( buf[0] == 0xf0 ) && diff --git a/camlibs/jamcam/library.h b/camlibs/jamcam/library.h index 849c2da9a..e3193e30b 100644 --- a/camlibs/jamcam/library.h +++ b/camlibs/jamcam/library.h @@ -23,6 +23,9 @@ /* Boston, MA 02111-1307, USA. */ /****************************************************************/ +#ifndef __LIBRARY_H__ +#define __LIBRARY_H__ + #define RETRIES 10 #define SER_PKT_SIZE 2048 @@ -33,11 +36,19 @@ #define CHECK(result) {int res; res = result; if (res < 0) return (res);} +struct jamcam_file { + int position; + int width; + int height; + int data_incr; +}; + int jamcam_enq(Camera *camera); int jamcam_who_knows(Camera *camera); int jamcam_write_packet(Camera *camera, char *packet, int length); int jamcam_read_packet(Camera *camera, char *packet, int length); int jamcam_file_count(Camera *camera); +struct jamcam_file *jamcam_file_info(Camera *camera, int number); int jamcam_fetch_memory(Camera *camera, char *data, int start, int length ); int jamcam_request_image(Camera *camera, char *buf, int *len, int number); int jamcam_request_thumbnail(Camera *camera, char *buf, int *len, int number ); @@ -60,3 +71,5 @@ int gp_gamma_correct_single( unsigned char *data, int pixels, int gp_bayer_decode(int w, int h, unsigned char *input, unsigned char *output, int tile); + +#endif __LIBRARY_H__ |