camera_capture_preview works with all tested cameras in camlibs/digigr8 and delete_all_func works with one of them.

git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@10442 67ed7778-7388-44ab-90cf-0a291f65f57c
This commit is contained in:
Theodore Kilgore
2007-07-17 01:53:50 +00:00
parent 12c0dd7a79
commit a85bb71b9f
5 changed files with 179 additions and 24 deletions

View File

@@ -1,3 +1,10 @@
2007-07-16 Theodore Kilgore <kilgota@auburn.edu>
* library.c: "Disney pix micro" camera supports "delete all."
Also, digigr8 cameras will do capture_preview. These two functions added.
0x9050 cameras need to be distinguished from 0x905C cameras.
* digigr8.c: camera functions to support deletion and capture.
* digigr8.h: necessary changes.
2007-07-12 Theodore Kilgore <kilgota@auburn.edu>
* library.c: "Disney pix micro" camera, 0x2770:0x9050, works
with this driver. Added it.

View File

@@ -51,6 +51,7 @@ WHAT FEATURES DO THESE CAMERAS HAVE, AND WHAT DOES THIS DRIVER SUPPORT?
-- Ability to download the first k pictures, where
k is less than the number on the camera Y
-- Ability to download individual photos Y (faked, but works)
-- Shoot a frame and save image to computer Y
-- Internal battery, which recharges through the USB port (some models)
-------------------------------------------------------------------------
@@ -74,12 +75,17 @@ The following things can be done with button-pushes on the camera:
Notes:
One camera has been discovered, in July 2007, to which the above list does
not correspond. See the section "More concerning the newly discovered
0x2770:0x9050 camera".
The only known cameras supported by the camlibs/digigr8 have a 640x480
high-resolution setting and a 320x240 low-resolution setting. If your
0x2770:0x905c camera uses another resolution setting, then it might still
work. There is some similarity with the sq905 cameras, and I kept that part
of the code here. Specifically, if the camera has 352x288 and 176x144
resolution settings, these might work but are not tested. If your camera does
resolution settings, these might work but are not tested (Note added July 2007:
the code for 352x288 _does_ continue to work; see below). If your camera does
not work due to unknown resolution settings, then the new resolution settings
need to be listed in digigr8.c in digi_get_picture_width (). Please report any
such problem. I will ask you to run a gphoto2 command in debug mode and we can
@@ -190,11 +196,17 @@ the compression algorithm is the same as that in the 0x905C cameras, this new
camera is quite usable, for what it is. Resolution for this camera is fixed at
352x288 and can not be adjusted. In fact, the only thing on the camera which
can be controlled at all, aside from snapping photos one at a time, is to
delete photos one at a time, starting from the last one (one has to press the
delete button on the camera and the shutter button on the camera to delete one
picture). No clip option, no delayed-shooting option, no multiple frames for AVI
images. In summary, this is a very rudimentary camera, even more so than other
SQ cameras.
delete photos one at a time or to delete all. To delete one photo with the
delete button on the camera, press the button. To delete all, hold it down
longer. The camera has no clip option, no delayed-shooting option, and no
multi-frame clips intended for AVI images. However, the camera will do
software deletion of all photos using the option gphoto2 -D, while for the
other cameras supported in camlibs/digigr8 the gphoto2 -D option does nothing
at all. However:
The USB command to delete is the same as the command to shoot a frame
(gphoto2 option is --capture-preview). If you shoot a frame with the Disney
pix micro, it will deledte whatever photos are on the camera !!!
@@ -218,4 +230,4 @@ WARRANTY?
Theodore Kilgore
12/05/05
(revised 12/29/05, 03/28/07, 06/25/07, 07/12/07)
(revised 12/29/05, 03/28/07, 06/25/07, 07/16/07)

View File

@@ -75,7 +75,7 @@ digi_init (GPPort *port, CameraPrivateLibrary *priv)
}
unsigned char
int
digi_get_comp_ratio (CameraPrivateLibrary *priv, int entry)
{
switch (priv->catalog[16*entry]) {
@@ -156,7 +156,8 @@ digi_reset (GPPort *port)
return GP_OK;
}
unsigned char *
int
digi_read_picture_data (GPPort *port, unsigned char *data, int size, int n )
{
@@ -174,3 +175,48 @@ digi_read_picture_data (GPPort *port, unsigned char *data, int size, int n )
return GP_OK;
}
int digi_delete_all (GPPort *port, CameraPrivateLibrary *priv)
{
int i;
int size;
int num_pics;
unsigned char *get_size;
unsigned char *junk=NULL;
get_size=malloc(0x50);
if(!get_size)
return GP_ERROR_NO_MEMORY;
num_pics = priv->nb_entries;
GP_DEBUG("number of entries is %i\n", num_pics);
digi_reset (port);
digi_reset (port);
if(!num_pics) {
GP_DEBUG("Camera is already empty!\n");
return GP_OK;
}
SQWRITE (port, 0x0c, 0x1440, 0x110f, NULL, 0);
i=0;
while (i < 19) {
gp_port_read(port, (char *)get_size, 0x50);
GP_DEBUG("get_size[0x40] = 0x%x\n", get_size[0x40]);
size = get_size[0x40]+(get_size[0x41]*0x100);
GP_DEBUG("size = 0x%x\n", size);
if(size <= 0xff) {
free(get_size);
GP_DEBUG("Size not read. Downloading to clear camera not needed.\n");
digi_reset(port);
return GP_OK;
}
junk = malloc(size);
if(! junk) {
GP_DEBUG("allocation of junk space failed\n");
return GP_ERROR_NO_MEMORY;
}
gp_port_read(port, (char *)junk, size);
free(junk);
i ++;
}
digi_reset (port);
return GP_OK;
}

View File

@@ -22,19 +22,19 @@ struct _CameraPrivateLibrary {
unsigned char *catalog;
int nb_entries;
int last_fetched_entry;
int delete_all;
};
int digi_reset (GPPort *);
int digi_init (GPPort *, CameraPrivateLibrary *);
int digi_rewind (GPPort *port, CameraPrivateLibrary *priv);
unsigned char *digi_read_picture_data (GPPort *, unsigned char *data,
int digi_read_picture_data (GPPort *, unsigned char *data,
int size, int n);
/* Those functions don't need data transfer with the camera */
int digi_get_num_frames (CameraPrivateLibrary *, int entry);
unsigned
char digi_get_comp_ratio (CameraPrivateLibrary *, int entry);
int digi_get_comp_ratio (CameraPrivateLibrary *, int entry);
int digi_get_data_size (CameraPrivateLibrary *, int entry);
int digi_get_picture_width (CameraPrivateLibrary *, int entry);
int digi_is_clip (CameraPrivateLibrary *, int entry);
@@ -43,5 +43,6 @@ int digi_decompress (unsigned char *out_data, unsigned char *data,
int digi_postprocess (CameraPrivateLibrary *priv,
int width, int height,
unsigned char* rgb, int n);
int digi_delete_all (GPPort *, CameraPrivateLibrary *priv);
#endif

View File

@@ -94,8 +94,9 @@ camera_abilities (CameraAbilitiesList *list)
a.operations = GP_OPERATION_NONE;
else
a.operations = GP_OPERATION_CAPTURE_PREVIEW;
a.folder_operations = GP_FOLDER_OPERATION_NONE;
a.file_operations = GP_FILE_OPERATION_PREVIEW + GP_FILE_OPERATION_RAW;
a.folder_operations = GP_FOLDER_OPERATION_DELETE_ALL;
a.file_operations = GP_FILE_OPERATION_PREVIEW
+ GP_FILE_OPERATION_RAW;
gp_abilities_list_append (list, a);
}
@@ -105,7 +106,7 @@ camera_abilities (CameraAbilitiesList *list)
static int
camera_summary (Camera *camera, CameraText *summary, GPContext *context)
{
sprintf (summary->text,_("Your USB camera has an SQ905C chipset.\n"
sprintf (summary->text,_("Your USB camera seems to have an SQ905C chipset.\n"
"The total number of pictures in it is %i\n"
),
@@ -119,13 +120,12 @@ static int camera_manual (Camera *camera, CameraText *manual, GPContext *context
strcpy(manual->text,
_(
"For cameras with SQ905C Technologies chip.\n"
"Should work with gtkam. Photos will be saved in PPM format.\n\n"
"IMPORTANT: CAMERA DOES NOT SUPPORT PHOTO SELECTION!\n"
"YOU MUST DOWNLOAD ALL PHOTOS AND CULL THEM LATER !!!\n"
"These cameras do not allow deletion of all photos.\n"
"Uploading of data to the camera is not supported.\n"
"Compression mode is UNSUPPORTED. A compressed photo\n"
"is guaranteed to download as pure junk.\n"
"Photos will be saved in PPM format.\n\n"
"Some of these cameras allow software deletion of all photos.\n"
"Others do not, depending on the chip revision. \n"
"If deletion does work, then gphoto2 -- capture image will \n"
"have the side-effect that it also deletes what is on the camera.\n"
"Uploading of data to the camera not supported by hardware.\n"
));
return (GP_OK);
@@ -269,6 +269,79 @@ get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
return status;
}
static int
delete_all_func (CameraFilesystem *fs, const char *folder, void *data,
GPContext *context)
{
Camera *camera = data;
if(!camera->pl->delete_all)
return GP_ERROR_NOT_SUPPORTED;
digi_delete_all (camera->port, camera->pl);
return GP_OK;
}
static int
camera_capture_preview (Camera *camera, CameraFile *file, GPContext *context)
{
unsigned char get_size[0x50];
unsigned char *raw_data;
unsigned char *frame_data;
unsigned char *ppm, *ptr;
unsigned char gtable[256];
char filename[14] = "digi_cap.ppm";
int size;
int w = 320;
int h = 240;
int b;
digi_reset (camera->port);
gp_port_usb_msg_write (camera->port, 0x0c, 0x1440, 0x110f, NULL, 0);
gp_port_read(camera->port, (char *)get_size, 0x50);
GP_DEBUG("get_size[0x40] = 0x%x\n", get_size[0x40]);
b = get_size[0x40]+(get_size[0x41]*0x100);
GP_DEBUG("b = 0x%x\n", b);
raw_data = malloc(b);
if(!raw_data) {
free(raw_data);
return GP_ERROR_NO_MEMORY;
}
gp_port_read(camera->port, (char *)raw_data, b);
frame_data = malloc(w*h);
if (!frame_data) {
free(frame_data);
return GP_ERROR_NO_MEMORY;
}
digi_decompress (frame_data, raw_data, w, h);
/* Now put the data into a PPM image file. */
ppm = malloc (w * h * 3 + 256);
if (!ppm) { return GP_ERROR_NO_MEMORY; }
sprintf ((char *)ppm,
"P6\n"
"# CREATOR: gphoto2, SQ905C library\n"
"%d %d\n"
"255\n", w, h);
ptr = ppm + strlen ((char*)ppm);
size = strlen ((char*)ppm) + (w * h * 3);
GP_DEBUG ("size = %i\n", size);
gp_bayer_decode (frame_data, w , h , ptr, BAYER_TILE_BGGR);
gp_gamma_fill_table (gtable, .5);
gp_gamma_correct_single (gtable, ptr, w * h);
gp_file_set_mime_type (file, GP_MIME_PPM);
gp_file_set_name (file, filename);
gp_file_set_data_and_size (file, (char *)ppm, size);
digi_reset(camera->port);
return (GP_OK);
}
/*************** Exit and Initialization Functions ******************/
static int
@@ -288,19 +361,27 @@ camera_exit (Camera *camera, GPContext *context)
static CameraFilesystemFuncs fsfuncs = {
.file_list_func = file_list_func,
.get_file_func = get_file_func
.get_file_func = get_file_func,
.delete_all_func = delete_all_func
};
int
camera_init(Camera *camera, GPContext *context)
{
GPPortSettings settings;
CameraAbilities abilities;
int ret = 0;
/* First, set up all the function pointers */
ret = gp_camera_get_abilities(camera,&abilities);
if (ret < 0) return ret;
GP_DEBUG("product number is 0x%x\n", abilities.usb_product);
/* Now, set up all the function pointers */
camera->functions->summary = camera_summary;
camera->functions->manual = camera_manual;
camera->functions->about = camera_about;
camera->functions->capture_preview
= camera_capture_preview;
camera->functions->exit = camera_exit;
GP_DEBUG ("Initializing the camera\n");
@@ -317,6 +398,14 @@ camera_init(Camera *camera, GPContext *context)
if (!camera->pl) return GP_ERROR_NO_MEMORY;
camera->pl->catalog = NULL;
camera->pl->nb_entries = 0;
switch (abilities.usb_product) {
case 0x9050:
camera->pl->delete_all = 1;
break;
default:
camera->pl->delete_all = 0;
}
/* Connect to the camera */
ret = digi_init (camera->port, camera->pl);