summaryrefslogtreecommitdiff
path: root/camlibs/agfa-cl20
diff options
context:
space:
mode:
authorMarcus Meissner <marcus@jet.franken.de>2003-05-12 07:59:14 +0000
committerMarcus Meissner <marcus@jet.franken.de>2003-05-12 07:59:14 +0000
commitd1afce8e654ad3858b0525a8288f5dc528d8585c (patch)
treea5c6b74e32a23c2da338ba163f6a192b493fe6ad /camlibs/agfa-cl20
parent370f8cacff3ffc1785d563181c5b02f2741d4961 (diff)
downloadlibgphoto2-d1afce8e654ad3858b0525a8288f5dc528d8585c.tar.gz
* from cl20.poeml.de, see Changelog.
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@6382 67ed7778-7388-44ab-90cf-0a291f65f57c
Diffstat (limited to 'camlibs/agfa-cl20')
-rw-r--r--camlibs/agfa-cl20/ChangeLog10
-rw-r--r--camlibs/agfa-cl20/RANDOM60
-rw-r--r--camlibs/agfa-cl20/README14
-rw-r--r--camlibs/agfa-cl20/STATUS9
-rw-r--r--camlibs/agfa-cl20/agfa_cl20.c682
-rw-r--r--camlibs/agfa-cl20/commands.txt68
-rw-r--r--camlibs/agfa-cl20/pic-header.txt19
-rw-r--r--camlibs/agfa-cl20/protocol.txt352
-rw-r--r--camlibs/agfa-cl20/protocol2.txt266
9 files changed, 1480 insertions, 0 deletions
diff --git a/camlibs/agfa-cl20/ChangeLog b/camlibs/agfa-cl20/ChangeLog
new file mode 100644
index 000000000..743612f3f
--- /dev/null
+++ b/camlibs/agfa-cl20/ChangeLog
@@ -0,0 +1,10 @@
+2003-05-12 Marcus Meissner <meissner@suse.de>
+
+ * agfa-cl20.c: Made it compile without warnings.
+
+2003-05-12 Marcus Meissner <meissner@suse.de>
+
+ * Makefile.am, README, STATUS, *.txt, agfa-cl20.c:
+ Imported from http://cl20.poeml.de
+
+ Written by Dennis Poeml et.al.
diff --git a/camlibs/agfa-cl20/RANDOM b/camlibs/agfa-cl20/RANDOM
new file mode 100644
index 000000000..2d9c01ad8
--- /dev/null
+++ b/camlibs/agfa-cl20/RANDOM
@@ -0,0 +1,60 @@
+$Id$
+
+Just some random ramblings :-)
+
+
+-------------------
+
+Why does the damn windows software poll the camera so often?
+Answer: Because of the stupid "print" button on the camera!
+It does not use an interrupt or anything, but you have to send:
+
+usb_control_msg( cl20_dev, 0xC1, 0x00, 0x0000, 0x8985, data, 1, 5000);
+ which is: C1 00 00 00 85 89 00 01
+
+If *data now contains "0", nothing happend.
+If *data is now "8", the user is PRESSING the button.
+
+Notice I say "PRESSING" :-) it has no memory, if you miss the moment the
+user presses the button, you do not see it!
+
+-------------------
+
+If you have a low quality picture on the camera, downloading the
+thumbnail is the same transaction as downloading the whole picture.
+Even worse, it's only 16k! So it's quite low resolution :-)
+
+-------------------
+
+If you are using the compactflash card, data download is a proper
+JPEG file, ready to use.
+
+If you are NOT using the compactflash card, data download is a so
+far meaningless heap of garbage !! You can get the picture, no
+problem, but you have to know how to process it for it to be useful!
+
+-------------------
+
+There are only a few different USB commands used, with slightly different
+parameters. I have good hopes for this camera :-)
+
+-------------------
+
+For the first time (for me) USB snoopy actually saw the USB transactions
+used when using the CL20 as a webcam (in streaming mode).
+
+-------------------
+
+Camera has 1 configuration, which is set as 1 (so do not start counting at 0!)
+Camera has 2 interfaces, "dmesg" should show you all info you could ever need
+, and it shows interface 1 (which is 0) only has Iso endpoints, whereas
+interface 2 (which is 1) has a bulk endpoint. Iso's are used for streaming
+video, and bulk is used for downloading picture data. It should be possible
+(the latest Agfa windows driver claims this) to use interface 1 and 2 at
+the same time, i.e. downloading pictures while also streaming video.
+#TODO verify this, it was late when I read it, could be wrong :-)
+
+-------------------
+
+When the camera erases all pictures, my guess is it is actually just sending
+the command to delete the last picture until there are no pictures left :)
diff --git a/camlibs/agfa-cl20/README b/camlibs/agfa-cl20/README
new file mode 100644
index 000000000..221d52684
--- /dev/null
+++ b/camlibs/agfa-cl20/README
@@ -0,0 +1,14 @@
+How to install this camlib:
+
+Copy the agfa-cl20 directory to ...../libgphoto2/camlibs
+
+Then, edit the file configure.in (in the libgphoto2 directory) on lines:
+148, and
+160
+to include "agfa-cl20" in the list of driver names.
+
+THEN you can run "sh autoconf.sh"
+./configure --prefix=/usr --with-drivers=agfa-cl20
+make
+make install
+
diff --git a/camlibs/agfa-cl20/STATUS b/camlibs/agfa-cl20/STATUS
new file mode 100644
index 000000000..44734d838
--- /dev/null
+++ b/camlibs/agfa-cl20/STATUS
@@ -0,0 +1,9 @@
+Thumbnail and full image support for all resolutions.
+
+Deleting files not yet supported.
+
+Need to experiment more what happens with huge number of pictures.
+Send me a corrupted image if you find any!
+Use gphoto2 to extract the raw data also
+
+
diff --git a/camlibs/agfa-cl20/agfa_cl20.c b/camlibs/agfa-cl20/agfa_cl20.c
new file mode 100644
index 000000000..061a19dfe
--- /dev/null
+++ b/camlibs/agfa-cl20/agfa_cl20.c
@@ -0,0 +1,682 @@
+/* agfa-cl20.c
+ *
+ * Copyright (C) 2002-2003 by Dennis Poeml, http://cl20.poeml.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 <string.h>
+#include <gphoto2.h>
+#include <gphoto2-library.h>
+#include <gphoto2-result.h>
+
+#ifdef ENABLE_NLS
+# include <libintl.h>
+# undef _
+# define _(String) dgettext (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 GP_MODULE
+
+static struct {
+ char *model;
+ int usb_vendor;
+ int usb_product;
+} models[] = {
+ { "Agfa ePhoto CL20", 0x06bd, 0x0404 },
+ { NULL, 0, 0 }
+};
+
+
+static int to_camera(int a)
+{
+ int b = a / 10;
+ int c = a % 10;
+ return ((b * 16) + c);
+}
+
+static int from_camera(int a)
+{
+ int b = a / 16;
+ int c = a % 16;
+ return ((b * 10) + c);
+}
+
+int
+camera_id (CameraText *id)
+{
+ strcpy(id->text, "agfa_cl20");
+
+ return (GP_OK);
+}
+
+int
+camera_abilities (CameraAbilitiesList *list)
+{
+ CameraAbilities a;
+ char *ptr;
+ int x = 0;
+
+ GP_DEBUG(" * camera_abilities()");
+
+ ptr = models[x].model;
+ while (ptr) {
+ memset(&a, 0, sizeof(a));
+ strcpy(a.model, ptr);
+ a.status = GP_DRIVER_STATUS_EXPERIMENTAL;
+ a.port = GP_PORT_USB;
+ // a.speed[0] = 0;
+ a.operations = GP_OPERATION_NONE;
+ a.file_operations = GP_FILE_OPERATION_DELETE | GP_FILE_OPERATION_PREVIEW;
+ a.folder_operations = GP_FOLDER_OPERATION_DELETE_ALL;
+
+ a.usb_vendor = models[x].usb_vendor;
+ a.usb_product = models[x].usb_product;
+
+ gp_abilities_list_append(list, a);
+
+ ptr = models[++x].model;
+ }
+
+ return (GP_OK);
+}
+
+static int
+camera_exit (Camera *camera, GPContext *context)
+{
+ GP_DEBUG(" * camera_exit()");
+ return (GP_OK);
+}
+
+static int
+get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
+ CameraFileType type, CameraFile *file, void *data,
+ GPContext *context)
+{
+ Camera *camera = data;
+ int n = -1;
+ char raw[ 500000 ];
+ char ppm[ 500000 ];
+ int size = -1;
+ unsigned char hb, lb;
+ unsigned long j;
+ unsigned int app1len = -1;
+ unsigned char resolution;
+
+ //unsigned char last, next;
+
+ GP_DEBUG(" * get_file_func()");
+
+ /*
+ * Get the file from the camera. Use gp_file_set_mime_type,
+ * gp_file_set_data_and_size, etc.
+ */
+
+ n = gp_filesystem_number(camera->fs, folder, filename, context) + 1;
+
+ switch(type) {
+ case GP_FILE_TYPE_PREVIEW:
+ GP_DEBUG(" * REQUEST FOR A PREVIEW");
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n),0x0008,NULL,0x0);
+ gp_port_read(camera->port, raw, 0x100);
+
+ hb = (unsigned char)*(raw + 0x06);
+ lb = (unsigned char)*(raw + 0x05);
+ size = (unsigned int)(hb * 256) + (unsigned int)(lb);
+
+ resolution = (unsigned char)*(raw + 0x11);
+ if (resolution == 1) {
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n),0x000A,NULL,0x0);
+ for (j = 0; j < size; j++)
+ gp_port_read(camera->port, raw+(j*0x100), 0x100);
+ printf("Done reading image!\n");
+ GP_DEBUG(" *DONE READING IMAGE!");
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ size = size * 0x100;
+
+ lb = (unsigned char)*(raw + 0x05);
+ hb = (unsigned char)*(raw + 0x04);
+ app1len = (unsigned int)(hb * 256) + (unsigned int)(lb);
+
+ printf("App1 Length is 0x%x\n", app1len);
+
+ printf("Setting JFIF header\n");
+
+ raw[3] = 0xe0;
+ raw[4] = 0x00;
+ raw[5] = 0x10;
+ raw[6] = 'J';
+ raw[7] = 'F';
+ raw[8] = 'I';
+ raw[9] = 'F';
+ raw[10] = 0x00;
+ raw[11] = 0x01;
+ raw[12] = 0x01;
+ raw[13] = 0x00;
+ raw[14] = 0x00;
+ raw[15] = 0x01;
+ raw[16] = 0x00;
+ raw[17] = 0x01;
+ raw[18] = 0x00;
+ raw[19] = 0x00;
+
+ printf("Doing memmove\n");
+
+ memmove(&raw[20],
+ &raw[app1len + 4],
+ (unsigned int)(size - app1len - 2));
+
+ size = size - app1len + 24;
+
+ printf("Done!!\n");
+
+ gp_file_set_mime_type(file, GP_MIME_JPEG);
+ gp_file_set_name(file, filename);
+ gp_file_append(file, raw, size);
+
+ break;
+
+ } else {
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ printf("Reading %d blocks\n", size);
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n),0x000B,NULL,0x0);
+ if (size < 100) {
+ for (j = 0; j < size; j++)
+ gp_port_read(camera->port, raw + (j * 0x100), 0x100);
+ } else {
+ for (j = 0; j < 100; j++)
+ gp_port_read(camera->port, raw + (j * 0x100), 0x100);
+ }
+ GP_DEBUG(" *DONE READING IMAGE!");
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ size = size * 0x100;
+
+ {
+ unsigned int thumb_start = 9 + 0x1a0;
+ unsigned char temp1, temp2, temp3, temp4;
+ unsigned char Y, Cb, Cr;
+ signed int R, G, B;
+ unsigned int pixel_count = 0;
+ unsigned int offset = 0;
+
+ sprintf(ppm, "P3\n128 96\n255\n");
+ offset = offset + 14;
+
+ temp1 = raw[ thumb_start + pixel_count ];
+ printf("First victim is %d 0x%x\n", temp1, temp1);
+
+ while (pixel_count < (128*96*2)) {
+ temp1 = raw[ thumb_start + pixel_count ];
+ temp2 = raw[ thumb_start + pixel_count + 1 ];
+ temp3 = raw[ thumb_start + pixel_count + 2 ];
+ temp4 = raw[ thumb_start + pixel_count + 3 ];
+ pixel_count = pixel_count + 4;
+
+ Y = temp1 + 128;
+ Cb = temp3 + 128;
+ Cr = temp4 + 128;
+
+ R = Y + (1.402 * (Cr-128));
+ G = Y - (0.34414 * (Cb-128)) - (0.71414 * (Cr-128));
+ B = Y + (1.772 * (Cb-128));
+ if (R > 255) R = 255;
+ if (R < 0) R = 0;
+ if (G > 255) G = 255;
+ if (G < 0) G = 0;
+ if (B > 255) B = 255;
+ if (B < 0) B = 0;
+
+ sprintf(ppm + offset , "%03d %03d %03d\n", R, G, B);
+ offset = offset + 4 + 4 + 4;
+
+
+ Y = temp2 + 128;
+
+ R = Y + (1.402 * (Cr-128));
+ G = Y - (0.34414 * (Cb-128)) - (0.71414 * (Cr-128));
+ B = Y + (1.772 * (Cb-128));
+ if (R > 255) R = 255;
+ if (R < 0) R = 0;
+ if (G > 255) G = 255;
+ if (G < 0) G = 0;
+ if (B > 255) B = 255;
+ if (B < 0) B = 0;
+
+ sprintf(ppm + offset, "%03d %03d %03d\n", R,G,B);
+ offset = offset + 4 + 4 + 4;
+ }
+
+ size = offset;
+
+ gp_file_set_mime_type(file, GP_MIME_PPM);
+ gp_file_set_name(file, filename);
+ gp_file_append(file, ppm, size);
+ }
+
+ break;
+ }
+ case GP_FILE_TYPE_RAW:
+ GP_DEBUG(" * REQUEST FOR RAW IMAGE");
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n),0x0008,NULL,0x0);
+ gp_port_read(camera->port, raw, 0x100);
+
+ hb = (unsigned char)*(raw + 0x06);
+ lb = (unsigned char)*(raw + 0x05);
+ size = (unsigned int)(hb * 256) + (unsigned int)(lb);
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n),0x000A,NULL,0x0);
+ for (j = 0; j < size; j++) {
+ gp_port_read(camera->port, raw + (j * 0x100), 0x100);
+ }
+ GP_DEBUG(" *DONE READING IMAGE!");
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ size = size * 0x100;
+
+ printf("Done!!\n");
+
+ gp_file_set_mime_type(file, GP_MIME_RAW);
+ gp_file_set_name(file, filename);
+ gp_file_append(file, raw, size);
+
+ break;
+ case GP_FILE_TYPE_NORMAL:
+ GP_DEBUG(" * REQUEST FOR NORMAL IMAGE");
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n),0x0008,NULL,0x0);
+ gp_port_read(camera->port, raw, 0x100);
+
+ hb = (unsigned char)*(raw + 0x06);
+ lb = (unsigned char)*(raw + 0x05);
+ size = (unsigned int)(hb * 256) + (unsigned int)(lb);
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n),0x000A,NULL,0x0);
+ for (j = 0; j < size; j++) {
+ gp_port_read(camera->port, raw + (j * 0x100), 0x100);
+ }
+ printf("Done reading image!\n");
+ GP_DEBUG(" *DONE READING IMAGE!");
+
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&lb,0x0001);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&lb,0x0001);
+
+ size = size * 0x100;
+
+ lb = (unsigned char)*(raw + 0x05);
+ hb = (unsigned char)*(raw + 0x04);
+ app1len = (unsigned int)(hb * 256) + (unsigned int)(lb);
+
+ printf("App1 Length is 0x%x\n", app1len);
+
+ printf("Setting JFIF header\n");
+
+ raw[3] = 0xe0;
+ raw[4] = 0x00;
+ raw[5] = 0x10;
+ raw[6] = 'J';
+ raw[7] = 'F';
+ raw[8] = 'I';
+ raw[9] = 'F';
+ raw[10] = 0x00;
+ raw[11] = 0x01;
+ raw[12] = 0x01;
+ raw[13] = 0x00;
+ raw[14] = 0x00;
+ raw[15] = 0x01;
+ raw[16] = 0x00;
+ raw[17] = 0x01;
+ raw[18] = 0x00;
+ raw[19] = 0x00;
+#if 0
+ if (n == 1) {
+ unsigned int loop = 0;
+ int done = -1;
+ unsigned int first_c4 = 0;
+ unsigned int second_c4 = 0;
+
+ printf("First picture, always problematic\n");
+
+ loop = app1len + 5;
+ last = raw[ loop ];
+ next = raw[ loop + 1];
+ while (done < 1) {
+ last = raw[ loop ];
+ next = raw[ loop + 1];
+ while ((last != 0xff) && (next != 0xc4)) {
+ last = next;
+ loop++;
+ next = raw[ loop ];
+ printf("Comparing 0x%x and 0x%x\n", last, next);
+ }
+ if (done == -1)
+ first_c4 = loop;
+ else
+ second_c4 = loop;
+ done++;
+ loop++;
+ }
+
+ memmove(&raw[first_c4], &raw[second_c4],
+ (unsigned int)(size - (second_c4 - first_c4)));
+ raw[first_c4 + 3] = 0x00;
+ }
+#endif
+ printf("Doing memmove\n");
+
+ memmove(&raw[20],
+ &raw[app1len + 4],
+ (unsigned int)(size - app1len - 2));
+
+ size = size - app1len + 24;
+
+ printf("Done!!\n");
+
+ gp_file_set_mime_type(file, GP_MIME_JPEG);
+ gp_file_set_name(file, filename);
+ gp_file_append(file, raw, size);
+
+ break;
+ default:
+ GP_DEBUG(" * NOT SUPPORTED");
+ return GP_ERROR_NOT_SUPPORTED;
+ }
+
+
+ return (GP_OK);
+}
+
+#if 0
+static int
+delete_file_func (CameraFilesystem *fs, const char *folder,
+ const char *filename, void *data, GPContext *context)
+{
+ Camera *camera = data;
+
+ GP_DEBUG(" * delete_file_func()");
+
+ /* Delete the file from the camera. */
+
+ return (GP_OK);
+}
+
+static int
+delete_all_func (CameraFilesystem *fs, const char *folder, void *data,
+ GPContext *context)
+{
+ Camera *camera = data;
+
+ GP_DEBUG(" * delete_all_func()");
+
+ /*
+ * Delete all files in the given folder. If your camera doesn't have
+ * such a functionality, just don't implement this function.
+ */
+
+ return (GP_OK);
+}
+
+static int
+camera_capture_preview (Camera *camera, CameraFile *file, GPContext *context)
+{
+ /*
+ * Capture a preview and return the data in the given file (again,
+ * use gp_file_set_data_and_size, gp_file_set_mime_type, etc.).
+ * libgphoto2 assumes that previews are NOT stored on the camera's
+ * disk. If your camera does, please delete it from the camera.
+ */
+
+ return (GP_OK);
+}
+
+static int
+camera_capture (Camera *camera, CameraCaptureType type, CameraFilePath *path,
+ GPContext *context)
+{
+ /*
+ * Capture an image and tell libgphoto2 where to find it by filling
+ * out the path.
+ */
+
+ return (GP_OK);
+}
+#endif
+
+static int
+camera_summary (Camera *camera, CameraText *summary, GPContext *context)
+{
+ /*
+ * Fill out the summary with some information about the current
+ * state of the camera (like pictures taken, etc.).
+ */
+
+ char * indata = calloc(1, 0x100);
+ int count = -10;
+ int cf = 0;
+
+ gp_port_usb_msg_write(camera->port,0x02, 0x0000, 0x0007, NULL, 0x0000 );
+ gp_port_usb_msg_write(camera->port,0x0A, 0x0000, 0x0000, NULL, 0x0000 );
+ gp_port_usb_msg_write(camera->port,0x02, 0x0000, 0x0007, NULL, 0x0000 );
+ gp_port_usb_msg_write(camera->port,0x0A, 0x0000, 0x0001, NULL, 0x0000 );
+ gp_port_read( camera->port, indata, 0x100 );
+
+ count = (int)(*(indata + 0x10));
+ if (count == 0xFFFFFFFF)
+ cf = -1;
+ else
+ cf = 1;
+
+ count = ((int)(*(indata + 0x16)) - 1);
+ count = from_camera( count );
+
+ if (cf == 1)
+ sprintf(summary->text, "Camera is using CompactFlash and has taken %d pictures", count);
+ return (GP_OK);
+}
+
+static int
+camera_manual (Camera *camera, CameraText *manual, GPContext *context)
+{
+ /*
+ * If you would like to tell the user some information about how
+ * to use the camera or the driver, this is the place to do.
+ */
+
+ GP_DEBUG(" * camera_manual()");
+
+ return (GP_OK);
+}
+
+static int
+camera_about (Camera *camera, CameraText *about, GPContext *context)
+{
+ strcpy (about->text, _("agfa_cl20\n"
+ "The Agfa CL20 Linux Driver People!\n"
+ " Email us at cl20@poeml.de \n"
+ " Visit us at http://cl20.poeml.de "));
+
+ return (GP_OK);
+}
+
+static int
+get_info_func (CameraFilesystem *fs, const char *folder, const char *filename,
+ CameraFileInfo *info, void *data, GPContext *context)
+{
+ Camera *camera = data;
+ int n;
+ unsigned short resolution;
+ char sbr;
+ char * indata = calloc(1, 0x100);
+
+ GP_DEBUG(" * get_info_func()");
+
+ /* Get the file info here and write it into <info> */
+
+ n = gp_filesystem_number( camera->fs, folder, filename, context);
+
+ info->file.fields = GP_FILE_INFO_TYPE;
+ strcpy( info->file.type, GP_MIME_JPEG );
+
+ gp_port_usb_msg_write(camera->port,0x0A,to_camera(n+1),0x0008,NULL,0x0);
+ gp_port_read(camera->port, indata, 0x100);
+
+ resolution = (unsigned short)*(indata + 0x11);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x0521,&sbr,1);
+ gp_port_usb_msg_read(camera->port,0x00,0x0000,0x8000,&sbr,1);
+
+ if (resolution == 1) {
+ info->file.width = 512;
+ info->file.height = 384;
+ info->preview.fields = GP_FILE_INFO_TYPE;
+ strcpy( info->preview.type, GP_MIME_JPEG);
+ info->preview.width = 512;
+ info->preview.height = 384;
+ } else if (resolution == 3) {
+ info->file.width = 1024;
+ info->file.height = 768;
+ info->preview.fields = GP_FILE_INFO_TYPE;
+ strcpy( info->preview.type, GP_MIME_PPM);
+ info->preview.width = 128;
+ info->preview.height = 96;
+ } else if (resolution == 5) {
+ info->preview.fields = GP_FILE_INFO_TYPE;
+ strcpy( info->preview.type, GP_MIME_PPM);
+ info->preview.width = 128;
+ info->preview.height = 96;
+ info->file.width = 1024;
+ info->file.height = 768;
+ }
+
+ return (GP_OK);
+}
+
+static int
+file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
+ void *data, GPContext *context)
+{
+ Camera * camera = data;
+ char * indata = calloc(1, 0x100);
+ int count = -10;
+
+ gp_port_usb_msg_write(camera->port,0x02, 0x0000, 0x0007, NULL, 0x0000 );
+ gp_port_usb_msg_write(camera->port,0x0A, 0x0000, 0x0000, NULL, 0x0000 );
+ gp_port_usb_msg_write(camera->port,0x02, 0x0000, 0x0007, NULL, 0x0000 );
+ gp_port_usb_msg_write(camera->port,0x0A, 0x0000, 0x0001, NULL, 0x0000 );
+ gp_port_read( camera->port, indata, 0x100 );
+
+ count = ((int)(*(indata + 0x16)) - 1);
+ count = from_camera( count );
+
+ gp_list_populate( list, "pic_%04i.jpg", count);
+ free(indata);
+
+ return (GP_OK);
+}
+
+int
+camera_init (Camera *camera, GPContext *context)
+{
+ GPPortSettings settings;
+ char single_byte_return = 'X';
+
+ GP_DEBUG(" * camera_init()");
+
+ /* First, set up all the function pointers */
+ camera->functions->exit = camera_exit;
+ camera->functions->summary = camera_summary;
+ camera->functions->manual = camera_manual;
+ camera->functions->about = camera_about;
+
+ /* Now, tell the filesystem where to get lists, files and info */
+ gp_filesystem_set_list_funcs (camera->fs, file_list_func,
+ NULL, camera);
+ gp_filesystem_set_info_funcs (camera->fs, get_info_func, NULL,
+ camera);
+ gp_filesystem_set_file_funcs (camera->fs, get_file_func,
+ NULL, camera);
+ gp_filesystem_set_folder_funcs (camera->fs, NULL,
+ NULL, NULL, NULL, camera);
+
+ /*
+ * The port is already provided with camera->port (and
+ * already open). You just have to use functions like
+ * gp_port_timeout_set, gp_port_settings_get, gp_port_settings_set.
+ */
+
+ gp_port_get_settings( camera->port, &settings );
+ switch (camera->port->type) {
+ case GP_PORT_SERIAL:
+ return ( GP_ERROR );
+ case GP_PORT_USB:
+ settings.usb.config = 1;
+ settings.usb.interface = 1;
+ settings.usb.inep = 2;
+ break;
+ default:
+ return ( GP_ERROR );
+ }
+
+ gp_port_set_settings(camera->port, settings );
+
+ /* Camera should return either 0x00 or 0x08, depending on
+ * wether the PRINT button is depressed. Either way, it
+ * should NOT stay 'X'
+ */
+
+ gp_port_usb_msg_read( camera->port,
+ 0x00,
+ 0x0000,
+ 0x8985,
+ &single_byte_return, 1 );
+
+ if ((single_byte_return == 0) || (single_byte_return == 8))
+ return (GP_OK);
+ else
+ return (GP_ERROR_MODEL_NOT_FOUND);
+}
diff --git a/camlibs/agfa-cl20/commands.txt b/camlibs/agfa-cl20/commands.txt
new file mode 100644
index 000000000..8167f22d8
--- /dev/null
+++ b/camlibs/agfa-cl20/commands.txt
@@ -0,0 +1,68 @@
+general commands, same for flash card or NON flash card,
+I don't know what they do exactly.
+
+c1 00 00 00 21 05 01 00
+
+c1 00 00 00 20 05 01 00 This one appeares only right after issuing any delete command
+ 41 0a 01 00 0d 00 00 00 (for pic 01). It appears after every
+ delete comand. I dont't know what
+ it does. The camera answers as usual with a "00" Byte.
+
+41 02 00 00 07 00 00 00 This appears after the
+ 41 0a 0x 00 0d 00 00 00
+ c1 00 00 00 20 05 01 00
+ sequence.
+ It also appears before these two basic commands:
+ 41 0a 00 00 00 00 00 00
+ 41 0a 00 00 01 00 00 00
+
+41 0a 00 00 00 00 00 00 This I believe to be a reset command. It is issued in the very
+ beginning and for example after dleting all the pictures, just
+ before the directory is reread with the
+ 41 0a 00 00 01 00 00 00
+ command.
+
+c1 00 00 00 00 80 01 00 This appears before every 41 0a command. And usually after a
+ c1 00 00 00 21 05 01 00. But not always.
+
+c1 00 00 00 85 89 01 00 After a long transfer and after al the picture info transfers
+ this is sent until something else happens.
+ To me it looks like a "keepalive"
+ Every other minute (?) this is interuppted by a combination
+ of:
+ c1 00 00 00 21 05 01 00
+ c1 00 00 00 00 80 01 00
+ c1 00 00 00 21 05 01 00
+ c1 00 00 00 00 80 01 00
+ Then it continues.
+
+ UPDATE: dennis 09.09.02
+ The command "c1 00 00 00 85 89 01 00" is a polling command to query the status of the
+ "print" button on the camera. It appears whenever nothing else is happening, and is
+ needed to catch the user pressing the print button. Keepalive is not necessary with
+ USB.
+
+
+
+Using a compact flash card:
+
+41 0a 00 00 01 00 00 00 Send the basic directory info
+
+41 0a 03 00 08 00 00 00 send infos for picture number 03
+
+41 0a 03 00 00 0a 00 00 Send picture number 03
+
+41 0a 03 00 00 0d 00 00 Delete picture number 03
+
+
+WITHOUT a compact flash card:
+
+41 0a 00 00 01 00 00 00 Send the basic directory info
+
+41 03 ff 0f 00 00 00 00 send infos for the first picture
+41 03 fe 0f 00 00 00 00 send infos for the second picture
+41 03 fd 0f 00 00 00 00 guess what? :))
+
+41 03 ff 0f 08 00 00 00 send the first picture
+41 03 fe 0f 08 00 00 00 send the second picture
+41 03 fd 0f 08 00 00 00 you know what...
diff --git a/camlibs/agfa-cl20/pic-header.txt b/camlibs/agfa-cl20/pic-header.txt
new file mode 100644
index 000000000..fc62acff2
--- /dev/null
+++ b/camlibs/agfa-cl20/pic-header.txt
@@ -0,0 +1,19 @@
+00000000 01 00 00 10 00 04 02 00 00 31 2e 31 36 00 00 00 |.........1.16...|
+ -----
+ 0x0204 is the number of bulk transfers to be read.
+
+00000010 00 05 00 00 00 08 05 00 00 02 00 00 00 00 00 00 |................|
+ -- --
+ I 0x05 is the number of pictures on the camera plus 1.
+ I so 4 in this case.
+ --
+ is the resolution.
+ 01 lowest
+ 03 medium
+ 05 highest
+
+00000020 02 78 01 67 02 23 06 50 01 e0 00 60 00 6c 05 00 |.x.g.#.P.à.`.l..|
+ -- --
+ this sometimes changes, but I don't know why...
+
+
diff --git a/camlibs/agfa-cl20/protocol.txt b/camlibs/agfa-cl20/protocol.txt
new file mode 100644
index 000000000..d15c99447
--- /dev/null
+++ b/camlibs/agfa-cl20/protocol.txt
@@ -0,0 +1,352 @@
+Okay, let's tell something about the protocoll:
+
+Everything can be looked up in the USB 1.1 secification!
+http://www.usb.org/developers/data/usbspec.zip
+
+That's where I have everything from.
+
+All the communication consists of three usb command types:
+It seems that all the packages have a little endian byte order (least significant byte first?)
+I always confuse that. Well, If I have 0x0001 then it sends 01 00, so turned around.
+
+1. control packages with direction "in"
+2. control packages with direction "out"
+3. bulk transfers with direction "in"
+
+1. These control packages are always 8 Bytes long. The first
+ Byte is the reqest Type. this is always 0xc1 for direction "in".
+ The c1 is a Bitmap:
+7 1 means that the direction is device to host
+6 1 Bits 6 and 5 mean that the "Type" is "Vendor"
+5 0
+4 0 the first 5 Bits (0-4) define the recipient. In this case an "Interface"
+3 0
+2 0
+1 0
+0 1
+
+the last two Bytes are always 01 00 the length of the camera reply, so 0x0001 - one Byte.
+The camera always replys with 0x00.
+
+
+2. Similar to 1. just the direction is "out".
+ The first byte is always 0x41 (just changing the last bit to 0 - direction "out")
+ The last two bytes are 00 00, because we don't await an answer of the camera.
+
+
+3. these semm to be standard bulk transfers. you just open one, and the camera sends data.
+ The direction of this transfer is "in".
+ The trnsfer buffer length is always 0x100.
+
+
+
+-----------------
+
+
+So, what happens now on the bus:
+
+First we send a standard USB Device request, to get the device descriptor:
+direction is "in" (80) length of answer is 0x0012 (12 00)
+
+SetupPacket : 80 06 00 01 00 00 12 00
+
+We get as an answer the device descriptor:
+
+ 0000:
+ 12 01 00 01 00 00 00 08 bd 06 04 04 90 00 00 00
+ 0010:
+ 00 01
+
+What this means is in the USB specs.
+
+
+Then we want the "configuration descriptor" from the device. I think this is done by sending:
+
+SetupPacket : 80 06 00 02 00 00 09 02
+
+
+As answer we should get:
+ 0000:
+09 02 27 00 01 01 00 80 fa 09 04 01 00 03 ff 00
+ 0010:
+00 00 07 05 82 02 40 00 00 07 05 03 02 40 00 00
+ 0020:
+07 05 84 03 01 00 08
+
+
+Now it's time to choose a configuration. I believe the camera just has one, but without setting it exlicitly, the camera does nothing!
+
+So we choose configuration 0x01.
+
+I think this is done by sending:
+
+SetupPacket : 00 09 01 00 00 00 00 00
+Note, that the direction is "out" now (00) and the length 0x0000 (00 00).
+
+
+That was the setup process. Now the camera should talk to us.
+
+
+***************
+* Here I had one picture on the camera. I plugged the camera in,
+* got the thumbnail and deleted it. Then I switched the camera
+* off.
+*
+* In further experiemnts we have to try out, where our magic numbers
+* are: Like: How many pictures are on the camera, which one is going
+* to be downloaded...
+*****************************
+
+SetupPacket : c1 00 00 00 21 05 01 00
+ answer: 00
+SetupPacket : 41 02 00 00 07 00 00 00
+SetupPacket : 41 0a 00 00 00 00 00 00
+SetupPacket : 41 02 00 00 07 00 00 00
+SetupPacket : 41 0a 00 00 01 00 00 00
+
+Bulk Transfer "in":
+
+ 0000: 1 . 1 6 I think this is something
+01 00 00 10 00 00 00 00 00 31 2e 31 36 00 00 00 like a directory... No idea, what
+ 0010: the 1.16 means. Could be either a
+00 00 00 00 00 00 02 00 00 02 00 00 00 00 06 0a protocol or firmware version.
+ 0020:
+1e 79 01 69 02 28 06 50 01 e0 00 60 00 c0 0f 00
+ 0030:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0040:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0050:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0060:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0070:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0080:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0090:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00a0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00b0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00c0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00d0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00e0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00f0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+SetupPacket : c1 00 00 00 21 05 01 00
+ answer: 00
+SetupPacket : c1 00 00 00 00 80 01 00
+ answer: 00
+SetupPacket : 41 0a 01 00 08 00 00 00
+Bulk Transfer "in":
+ 0000: 1 . 1 6
+01 00 00 10 00 14 00 00 00 31 2e 31 36 00 00 00 The 14 is new. No idea, what it means...
+ 0010:
+00 01 00 00 00 00 02 00 00 02 00 00 00 00 06 0a The 01 could be one of the magic
+ 0020: numbers, since there was ONE pic
+1e 79 01 69 02 28 06 50 01 e0 00 60 00 c0 0f 00 on the camera...
+ 0030:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0040:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0050:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0060:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0070:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0080:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0090:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00a0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00b0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00c0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00d0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00e0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00f0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+**************************
+* I just got an idea: The camera has internal AND a flash card as memory.
+* When we have a flash card, the internal memory is not going to
+* be used. Maybe the first "directory" is the internal one, with zero pics.
+* Maybe the second one is the flash card directory with the one pic.
+* Maybe I'm completely wrong... ;-)
+***************************
+
+
+SetupPacket : c1 00 00 00 85 89 01 00
+ answer: 00
+SetupPacket : c1 00 00 00 21 05 01 00
+ answer: 00
+SetupPacket : c1 00 00 00 00 80 01 00
+ answer: 00
+SetupPacket : c1 00 00 00 21 05 01 00
+ answer: 00
+SetupPacket : c1 00 00 00 00 80 01 00
+ answer: 00
+SetupPacket : 41 0a 01 00 0a 00 00 00
+Bulk Transfer "in":
+ 0000: E x i f M M *
+ff d8 ff e1 01 a5 45 78 69 66 00 00 4d 4d 00 2a
+ 0010:
+00 00 00 08 00 07 01 1a 00 05 00 00 00 01 00 00
+ 0020: (
+01 0e 01 1b 00 05 00 00 00 01 00 00 01 16 01 28
+ 0030:
+00 03 00 00 00 01 00 02 00 00 02 13 00 03 00 00
+ 0040:
+P I C T 0 0 0 1 J P G <sp>
+50 49 43 54 30 30 30 31 4a 50 47 20 00 00 00 00
+ 0050:
+00 00 00 00 00 00 00 00 00 00 02 00 00 14 00 00
+ 0060: D 0 ^ @ c
+00 04 00 00 00 01 00 00 00 44 00 00 30 5e 40 63
+ 0070:
+@ , A f
+40 00 01 2c 41 66 00 00 00 00 00 00 00 00 00 00
+ 0080:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0090:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00a0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00b0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00c0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00d0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00e0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00f0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+Bulk transfer "in":
+ 0000:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0010:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0020:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0030:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0040:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0050:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0060: 0 2 1 0
+0b 90 00 00 07 00 00 00 04 30 32 31 30 91 01 00
+ 0070:
+07 00 00 00 04 01 02 03 00 a0 00 00 07 00 00 00
+ 0080:
+04 00 00 00 00 a0 01 00 03 00 00 00 01 00 01 00
+ 0090:
+00 a0 02 00 04 00 00 00 01 00 00 02 00 a0 03 00
+ 00a0:
+04 00 00 00 01 00 00 01 80 ff db 00 84 00 10 0b
+ 00b0: (
+0c 0e 0c 0a 10 0e 0d 0e 12 11 10 13 18 28 1a 18
+ 00c0: 1 # % ( : 3 = < 9 3 8 7
+16 16 18 31 23 25 1d 28 3a 33 3d 3c 39 33 38 37
+ 00d0:
+@ H \ N @ D W E 7 8 P m Q W _ b
+40 48 5c 4e 40 44 57 45 37 38 50 6d 51 57 5f 62
+ 00e0:
+67 68 67 3e 4d 71 79 70 64 78 5c 65 67 63 01 11
+ 00f0:
+12 12 18 15 18 2f 1a 1a 2f 63 42 38 42 63 63 63
+
+
+Then 18 further bulk "in" transfers, probably containing the data of the picture/thumbnail.
+
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+plenty of these more for wuite a while.
+SetupPacket : c1 00 00 00 21 05 01 00
+SetupPacket : c1 00 00 00 00 80 01 00
+SetupPacket : c1 00 00 00 21 05 01 00
+SetupPacket : c1 00 00 00 00 80 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+and so on...
+SetupPacket : c1 00 00 00 21 05 01 00
+SetupPacket : c1 00 00 00 00 80 01 00
+SetupPacket : 41 0a 01 00 0d 00 00 00
+SetupPacket : c1 00 00 00 20 05 01 00 Somewhere here I deleted
+SetupPacket : 41 02 00 00 07 00 00 00 a thumbnail...
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : 41 0a 01 00 00 00 00 00
+SetupPacket : c1 00 00 00 21 05 01 00
+SetupPacket : 41 02 00 00 07 00 00 00
+SetupPacket : 41 0a 00 00 00 00 00 00
+SetupPacket : 41 02 00 00 07 00 00 00
+SetupPacket : 41 0a 00 00 01 00 00 00
+Bult transfer "in":
+ 0000: 1 . 1 6 Maybe this is something like
+01 00 00 10 00 00 00 00 00 31 2e 31 36 00 00 00 the directory... So, after deleting
+ 0010: a thumbnail, it re-reads the directory
+00 00 00 00 00 00 01 00 00 02 00 00 00 00 06 0a
+ 0020:
+1e 79 01 69 02 28 06 50 01 e0 00 60 00 c0 0f 00
+ 0030:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0040:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0050:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0060:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0070:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0080:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0090:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00a0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00b0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00c0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00d0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00e0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00f0:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+SetupPacket : c1 00 00 00 85 89 01 00
+etc. pp.
+SetupPacket : 41 0a 01 00 00 00 00 00 Somewhere here I just switched off
+SetupPacket : c1 00 00 00 21 05 01 00 the camera... It just dies then
+SetupPacket : c1 00 00 00 21 05 01 00 We don't have to do something
+ special...
+
diff --git a/camlibs/agfa-cl20/protocol2.txt b/camlibs/agfa-cl20/protocol2.txt
new file mode 100644
index 000000000..1031a1d47
--- /dev/null
+++ b/camlibs/agfa-cl20/protocol2.txt
@@ -0,0 +1,266 @@
+Okay,
+
+this is the second approach for the Protocol.
+
+What I believe the "commands" are, I have put in a list in the file "commands.txt".
+
+There seem to be fundamental differecs in the data and command set, when using a flash card or no flash card.
+When the pictures are saved on the internal camera memory, they come over in a strange format, from which I have no idea, what it is. Additionally the commands used to retrieve pictures are different.
+
+I will now try to specify the commands used for the basic operation of the camera.
+
+When using a Flash Card, the pictures are coming over in EXIF Format. EXIF is a JPEG format developed for DSC (digital still cameras).
+
+---------------
+Digital Still Camera Image File Format Standard (Exchangeable image file format for Digital Still Cameras: Exif) Version 2.1
+----------------
+
+The specs can be found here:
+http://www.pima.net/standards/it10/PIMA15740/Exif_2-1.PDF
+
+This is a special format which INCLUDES THUMBNAILS. This means, that the picture and the thmbnail are ONE file.
+So what basicallly happens in the windows driver:
+
+It retrieves the EXIF File complete, for example 173kb. I calcualted it. It fits. I had 685 Bulk Transfers, 256Bytes each, which makes a total of 175360 Bytes --> my picture (Exif=Thumbnail+picture).
+The Windows driver then extracts the Thumbnail out of the Exif, saves i as JFIF (JPEG) and displays it in the thumbnail overview.
+
+So, if you have the Exif you automatically have the Thumbnail AND the picture. So there is only one transfer for both.
+
+Interesting is also, that the actual picture, the Exif File, comes in BIG ENDIAN Format. you can see this from the 4d 4d (MM) in the EXIF header.
+
+
+Okay, let's tell something about the protocoll:
+
+Everything can be looked up in the USB 1.1 secification!
+That's where I have everything from.
+
+All the communication consists of three usb command types:
+It seems that all the packages have a little endian byte order (least significant byte first?)
+I always cofuse that. Well, If I have 0x0001 then it sends 01 00, so turned around.
+
+1. control packages with direction "in"
+2. control packages with direction "out"
+3. bulk transfers with direction "in"
+
+1. These control packages are always 8 Bytes long. The first
+ Byte is the reqest Type. this is always 0xc1 for direction "in".
+ The c1 is a Bitmap:
+7 1 means that the direction is device to host
+6 1 Bits 6 and 5 mean that the "Type" is "Vendor"
+5 0
+4 0 the first 5 Bits (0-4) define the recipient. In this case an "Interface"
+3 0
+2 0
+1 0
+0 1
+
+the last two Bytes are always 01 00 the length of the camera reply, so 0x0001 - one Byte.
+The camera always replys with 0x00.
+
+
+2. Similar to 1. just the direction is "out".
+ The first byte is always 0x41 (just changing the last bit to 0 - direction "out")
+ The last two bytes are 00 00, because we don't await an answer of the camera.
+
+
+3. these semm to be standard bulk transfers. you just open one, and the camera sends data.
+ The direction of this transfer is "in".
+ The trnsfer buffer length is always 0x100.
+
+
+
+-----------------
+
+
+So, what happens now on the bus:
+
+First we send a standard USB Device request, to get the device descriptor:
+direction is "in" (80) length of answer is 0x0012 (12 00)
+
+SetupPacket : 80 06 00 01 00 00 12 00
+
+We get as an answer the device descriptor:
+
+ 0000:
+ 12 01 00 01 00 00 00 08 bd 06 04 04 90 00 00 00
+ 0010:
+ 00 01
+
+What this means is in the USB specs.
+
+
+Then we want the "configuration descriptor" from the device. I think this is done by sending:
+
+SetupPacket : 80 06 00 02 00 00 09 02
+
+
+As answer we should get:
+ 0000:
+09 02 27 00 01 01 00 80 fa 09 04 01 00 03 ff 00
+ 0010:
+00 00 07 05 82 02 40 00 00 07 05 03 02 40 00 00
+ 0020:
+07 05 84 03 01 00 08
+
+
+Now it's time to choose a configuration. I believe the camera just has one, but without setting it exlicitly, the camera does not
+hing!
+
+So we choose configuration 0x01.
+
+I think this is done by sending:
+
+SetupPacket : 00 09 01 00 00 00 00 00
+Note, that the direction is "out" now (00) and the length 0x0000 (00 00).
+
+
+That was the setup process. Now the camera should talk to us.
+
+
+
+SetupPacket : c1 00 00 00 21 05 01 00
+ answer: 00
+SetupPacket : 41 02 00 00 07 00 00 00
+SetupPacket : 41 0a 00 00 00 00 00 00
+SetupPacket : 41 02 00 00 07 00 00 00
+SetupPacket : 41 0a 00 00 01 00 00 00 This is the command for getting
+ a basic directory
+
+Bulk Transfer "in":
+***********************************************************************8
+this output is very different if you use a flash card or not.
+These are the first rows with a flash card:
+
+
+ 0000: 1 . 1 6
+01 00 00 10 00 00 00 00 00 31 2e 31 36 00 00 00
+ 0010:
+00 00 00 00 00 00 02 00 00 02 00 00 00 00 06 0a The first 02 is the number of
+ 0020: pictures plus one. In this case
+1e 79 01 69 02 28 06 50 01 e0 00 60 00 c0 0f 00 one piture.
+ 0030:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 0040:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+
+These are the first rows without a flash card:
+
+ 0000:
+00 00 00 10 00 ff ff ff ff 31 2e 31 36 ff ff ff
+ 0010:
+ff ff ff ff 00 03 00 00 00 02 00 00 ff ff 05 09 Maybe the 03 is the nubmer of pictures, but I don't
+ 0020: think so..
+1b 00 00 00 00 00 00 50 01 e0 00 60 00 17 0f 00
+ 0030:
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ UPDATE: dennis, 09.09.02
+ The 03 IS the number of pictures. I have tried it several times and it always represents the
+ number of pictures. Funny how you don't have to subtract 1 here!
+
+
+
+Next thing that happens is to get information on the picture. This is done for EACH picture.
+
+So, if I have 5 pictures I will get 5 commands:
+
+ flash-card no flash card
+SetupPacket : 41 0a 01 00 08 00 00 00 41 03 ff 0f 00 00 00 00
+SetupPacket : 41 0a 02 00 08 00 00 00 41 03 fe 0f 00 00 00 00
+SetupPacket : 41 0a 03 00 08 00 00 00 41 03 fd 0f 00 00 00 00
+SetupPacket : 41 0a 04 00 08 00 00 00 41 03 fc 0f 00 00 00 00
+SetupPacket : 41 0a 05 00 08 00 00 00 41 03 fb 0f 00 00 00 00
+
+Each time I get back a picture information package, looing like (for pic 4 for ex)
+
+ 0000:
+01 00 00 10 00 90 01 01 05 31 2e 31 36 01 08 01 01 74 00 ff ff 35 00 02 20 18 90 78 34 00 00 00
+ 0010:
+09 05 0a 01 00 03 06 00 00 02 00 00 0f 01 05 09 1b 01 00 00 17 0f 00 5c 66 40 3c ff ff ff ff ff
+ 0020:
+1b 74 01 62 02 11 06 50 01 e0 00 60 00 17 0f 01 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
+ 0030:
+19 01 1a 01 1b 01 1c 01 1d 01 1e 01 1f 01 20 01 and mor ffs...
+ 0040:
+21 01 22 01 23 01 24 01 25 01 26 01 27 01 28 01
+ 0050:
+29 01 2a 01 2b 01 2c 01 2d 01 2e 01 2f 01 30 01
+ 0060:
+31 01 32 01 33 01 34 01 35 01 36 01 37 01 38 01
+ 0070:
+39 01 3a 01 3b 01 3c 01 3d 01 3e 01 3f 01 40 01
+ 0080:
+41 01 42 01 43 01 44 01 45 01 46 01 47 01 48 01
+ 0090:
+49 01 ff ff 4b 01 4c 01 4d 01 4e 01 4f 01 50 01
+ 00a0:
+51 01 52 01 53 01 54 01 55 01 56 01 57 01 58 01
+ 00b0:
+59 01 5a 01 5b 01 5c 01 5d 01 5e 01 5f 01 60 01
+ 00c0:
+61 01 62 01 63 01 64 01 65 01 66 01 67 01 68 01
+ 00d0:
+69 01 6a 01 6b 01 6c 01 6d 01 6e 01 6f 01 70 01
+ 00e0:
+71 01 72 01 73 01 74 01 75 01 76 01 77 01 78 01
+ 00f0:
+79 01 7a 01 7b 01 7c 01 7d 01 7e 01 7f 01 80 01
+
+I don't know yet, what information is in there, and what it is used for.
+Also a clear difference between the flash card and the non flash card.
+
+
+
+
+Then, the Exif files (in case of the flash card - in non flash card mode I don't know, what is going to be transferred)
+are transferred, one after the other. In order.
+
+
+ flash card non flash card
+SetupPacket : 41 0a 01 00 0a 00 00 00 41 03 ff 0f 08 00 00 00
+
+
+ 0000:
+ff d8 ff e1 61 a5 45 78 69 66 00 00 4d 4d 00 2a ef a8 a2 8a 00 28 a2 8a 00 28 a2 8a 00 28 a2 8a
+ 0010:
+00 00 00 08 00 07 01 1a 00 05 00 00 00 01 00 00 00 28 a2 8a 00 28 a2 8a 00 28 a2 8a 00 28 a2 8a
+ 0020:
+01 0e 01 1b 00 05 00 00 00 01 00 00 01 16 01 28 00 28 a2 8a 00 28 a2 8a 00 28 a2 8a 00 28 a4 a5
+ 0030:
+00 03 00 00 00 01 00 02 00 00 02 13 00 03 00 00 a0 02 8a 28 a0 02 8a 28 a0 02 8a 28 a0 02 8a 28
+ 0040:
+50 49 43 54 30 30 30 31 4a 50 47 20 00 00 00 00 and so on....
+ 0050:
+00 00 00 00 00 00 00 00 00 00 02 00 00 ac 02 00
+ 0060:
+50 49 43 54 30 30 30 32 4a 50 47 20 00 00 00 00
+ 0070:
+00 00 00 00 00 00 00 00 00 00 ad 00 00 74 02 00
+ 0080:
+50 49 43 54 30 30 30 33 4a 50 47 20 00 00 00 00
+ 0090:
+00 00 00 00 00 00 00 00 00 00 4a 01 00 60 03 00
+ 00a0:
+50 49 43 54 30 30 30 34 4a 50 47 20 00 00 00 00
+ 00b0:
+00 00 00 00 00 00 00 00 00 00 22 02 00 90 01 00
+ 00c0:
+50 49 43 54 30 30 30 35 4a 50 47 20 00 00 00 00
+ 00d0:
+00 00 00 00 00 00 00 00 00 00 86 02 00 c0 02 00
+ 00e0:
+02 00 04 00 00 00 01 00 00 04 00 a0 03 00 04 00
+ 00f0:
+00 00 01 00 00 03 00 00 00 00 00 00 0e 01 00 00
+
+
+This is an exif File. It has a clear header, This I don't know what it is. I cannot
+and conforms to the spec. I reckon, you can just find a header nor other readable characters.
+save it and use it. Maybe it is just compressed jpg data.
+ I don't know.
+
+
+-------------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------------
+