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:
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user