diff options
53 files changed, 3070 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/AUTHORS diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..e0d4f1bf6 --- /dev/null +++ b/COPYING @@ -0,0 +1 @@ +insert copy of "LGPL" here diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ChangeLog diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/INSTALL diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..ee07add25 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to generate a GNU Makefile + +SUBDIRS = include libgphoto2 camlibs frontends @@ -0,0 +1,2 @@ +* CameraFile's must be created using gp_file_new() +* gp_file_clean/free do 2 different things diff --git a/OVERVIEW b/OVERVIEW new file mode 100644 index 000000000..a4bfa5684 --- /dev/null +++ b/OVERVIEW @@ -0,0 +1,191 @@ +Notes +========================================================================= + + * When the cache is turned on, the front-end should + not manipulate images directly. use the gp_image_ functions to do + manipulation. the gp_image_ functions return the changed image. + Saving images is done through gp_file_save. + +Program Flow +========================================================================= +Here is the program flow (covering most everything hopefully): + +[FE] - Front-end +[GC] - gPhoto core +[LI] - gPhoto camera library + +Choosing a Camera +------------------------------------------------------------------------ +User selects "Choose Camera" + +[FE] Calls "gp_camera_count" to retrieve the number of available cameras + \ + [GC] open the library directory. opens each library + supported-camera file ("libraryname.supported"). + A master list is generated and sorted. Total number + of support cameras is returned. + / +[FE] Retrieve each camera name by calling "gp_camera_name". + \ + [GC] returns the camera name from the master list. + / +[FE] Presents the camera list to the user. They choose. "gp_camera_set" +is then called + \ + [GC] Camera library is loaded based on camera_number. + library functions are loaded. "init" is called. + \ + [LI] Does whatever it needs to do to initialize + / + [GC] sits here and looks pretty + / +[FE] Calls "gp_camera_abilities" to get the abilities of the selected +camera. + \ + [GC] calls "abilities" + \ + [LI] returns the cameras abilities + / + [GC] doh dee doh + / +[FE] Configure GUI/settings according to the camera abilities (black +out "preview" if it doesn't support it, etc...) + + +Getting an Index +------------------------------------------------------------------------ +User selects "Get Index" + +[FE] calls "gp_folder_count" + \ + [GC] calls "folder_count" + \ + [LI] returns the number of folders on the camera. + If folder don't exist (only 1 place to keep images), + returns 1. + / + [GC] returns the number of folders + / +[FE] if the number of folders is > 1, calls "gp_folder_name" for each +folder. + \ + [GC] calls "folder_name" + \ + [LI] returns the name of a particular folder + / + [GC] ... + / +[FE] presents user with a folder list. user selects which folder. +"gp_folder_set" is called + \ + [GC] if another folder is open already, calls "folder_close" + \ + [LI] does stuff to close the current folder + / + [GC] "folder_set" is called. + \ + [LI] does stuff to set the current folder + / + [GC] "folder_open" is called + \ + [LI] does stuff to open the current folder + / + [GC] uhhh.. + / +[FE] calls "gp_file_count" to retrieve the number of pictures in the +current folder. + \ + [GC] calls "file_count" + \ + [LI] returns the number of files. + / + [GC] nothing. + / +[FE] calls "gp_file_get_preview" for each picture to get the thumbnail index. + \ + [GC] "file_get_preview" is called + \ + [LI] retrieves the preview + / + [GC] Caches the preview file. returns the file data + / +[FE] displays the index + +Getting a picture/sound/etc... +------------------------------------------------------------------------ +User select "Get Picture/Sound/etc..." + +[FE] calls "gp_file_get" + \ + [GC] calls "file_get" + \ + [LI] retrieves the file + / + [GC] caches the file. returns the file information. + / +[FE] displays the file + +Manipulating Images (rotate/flip) +------------------------------------------------------------------------ +User selects "Rotate/Flip Image" (either full-size image, or thumbnail) + +[FE] Calls gp_image_(flip_v | flip_h | rotate) + or gp_image_preview_(flip_v | flip_h | rotate) + \ + [GC] Rotates image in cache. returns altered image. + / +[FE] Displays new image + +Saving Images +------------------------------------------------------------------------ +User selects "Save (Image | Sound | whatever...)" + +[FE] Calls "gp_file_save" + \ + [GC] If file exists, calls gp_confirm. If return == GP_OK, + then overwrites the file. If return == GP_ERROR, then just + returns. + / +[FE] Says "File saved as ...". + +Retrieving library information (summary, manual, about) +------------------------------------------------------------------------ +User wants to know something about the camera/library. + +[FE] calls "gp_(summary | manual | about" + \ + [GC] calls (summary | manual | about ) + \ + [LI] returns the appropriate information + / + [GC] ... + / +[FE] displays the information + +Files needed by each camera library +----------------------------------- + * library itself + "libgphoto_name.so" + ex: "libgphoto_casio.so" + + * supported camera list + "libgphoto_name.supported" + ex: "libgphoto_casio.supported" + + contents are a list of cameras, each on a separate + line, that that library supports. + ex: + Casio QV10 + Casio QV100 + Casio QV39483 + and so on. this makes it easy to add cameras to + gPhoto when they are confirmed to work. + + * configuration specification + "libgphoto_name.config" + ex: "libgphoto_casio.config" + + contents are the spcification for the configuration + interface. this format needs to be defined. check + the gphoto.h file for a proposal. this makes it easy + to change the configuration interface. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 000000000..e01c61dc6 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +# This was lifted from the Gimp, and adapted slightly by +# Raph Levien . + +DIE=0 + +PROJECT=gphoto2 + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $PROJECT." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(libtool --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have libtool installed to compile $PROJECT." + echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have automake installed to compile $PROJECT." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +test -f include/gphoto2.h || { + echo "You must run this script in the top-level gphoto2 directory" + exit 1 +} + +if test -z "$*"; then + echo "I am going to run ./configure with no arguments - if you wish " + echo "to pass any to it, please specify them on the $0 command line." +fi + + +case $CC in +*xlc | *xlc\ * | *lcc | *lcc\ *) am_opt=--include-deps;; +esac + +for dir in . +do + echo processing $dir + (cd $dir; \ + libtoolize --copy --force; \ + aclocalinclude="$ACLOCAL_FLAGS"; \ + aclocal $aclocalinclude; \ + autoheader; automake --add-missing --gnu $am_opt; autoconf) +done + +./configure "$@" + +echo +echo "Now type 'make' to compile $PROJECT." diff --git a/camlibs/Makefile.am b/camlibs/Makefile.am new file mode 100644 index 000000000..bee3ddd6f --- /dev/null +++ b/camlibs/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to generate a GNU Makefile + +SUBDIRS = directory fujitsu barbie diff --git a/camlibs/barbie/Makefile.am b/camlibs/barbie/Makefile.am new file mode 100644 index 000000000..6d760c9a0 --- /dev/null +++ b/camlibs/barbie/Makefile.am @@ -0,0 +1,10 @@ +camlibdir = $(prefix)/lib/gphoto2 +camlib_LTLIBRARIES = libgphoto2_barbie.la + +CFLAGS = @CFLAGS@ `gpio-config --cflags` +LDFLAGS = @LDFLAGS@ `gpio-config --libs` +INCLUDES = -I$(top_srcdir)/include + +libgphoto2_barbie_la_SOURCES = barbie.c barbie.h + +libgphoto2_barbie_la_LDFLAGS = -version-info 0:0:0 diff --git a/camlibs/barbie/README b/camlibs/barbie/README new file mode 100644 index 000000000..1bfd3ae70 --- /dev/null +++ b/camlibs/barbie/README @@ -0,0 +1,5 @@ +To compile stand-alone, libgpio needs to be installed. If it is, run: + + ./compile + +the resulting binary, named "barbie" can be put anywhere. diff --git a/camlibs/barbie/barbie.c b/camlibs/barbie/barbie.c new file mode 100644 index 000000000..346a392d1 --- /dev/null +++ b/camlibs/barbie/barbie.c @@ -0,0 +1,470 @@ +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <gphoto2.h> +#include <gpio.h> +#include "barbie.h" + +gpio_device *dev=NULL; +gpio_device_settings settings; + +/* packet headers/footers */ +char packet_header[3] = {0x02, 0x01}; +char packet_header_data[6] = {0x02, 0x01, 0x01, 0x01, 0x01}; +char packet_header_firmware[4] = {0x02, 'V', 0x01}; +char packet_footer[2] = {0x03}; + +/* Some simple packet templates */ +char packet_1[4] = {0x02, 0x01, 0x01, 0x03}; +char packet_2[5] = {0x02, 0x01, 0x01, 0x01, 0x03}; + +/* Utility Functions + ======================================================================= +*/ + +void barbie_packet_dump(int direction, char *buf, int size) { + int x; + + if (direction == 0) + printf("\tRead Packet (%i): ", size); + else + printf("\tWrite Packet (%i): ", size); + for (x=0; x<size; x++) { + if (isalpha(buf[x])) + printf("[ '%c' ] ", (unsigned char)buf[x]); + else + printf("[ x%02x ] ", (unsigned char)buf[x]); + } + printf("\n"); +} + +int barbie_write_command(char *command, int size) { + + int x; + + barbie_packet_dump(1, command, size); + x=gpio_write(dev, command, size); + return (x == GPIO_OK); +} + +int barbie_read_response(char *response, int size) { + + int x; + char ack = 0; + + /* Read the ACK */ + x=gpio_read(dev, &ack, 1); +#ifdef BARBIE_DEBUG + barbie_packet_dump(0, &ack, 1); +#endif + if ((ack != ACK)||(x<0)) + return (0); + + /* Read the Response */ + memset(response, 0, size); + x=gpio_read(dev,response, size); +#ifdef BARBIE_DEBUG + barbie_packet_dump(0, response, x); +#endif + return (x > 0); +} + +int barbie_exchange (char *cmd, int cmd_size, char *resp, int resp_size) { + + int count = 0; + + while (count++ < 10) { + if (barbie_write_command(cmd, cmd_size) != 1) + return (0); + if (barbie_read_response(resp, resp_size) != 1) + return (0); + /* if it's not busy, return */ + if (resp[RESPONSE_BYTE] != '!') + return (1); + /* if busy, sleep 2 seconds */ + sleep(2); + } + + return (0); +} + +int barbie_ping() { + + char cmd[4], resp[4]; + +#ifdef BARBIE_DEBUG + printf("Pinging the camera\n"); +#endif + + memcpy(cmd, packet_1, 4); + cmd[COMMAND_BYTE] = 'E'; + cmd[DATA1_BYTE] = 'x'; + + if (barbie_exchange(cmd, 4, resp, 4) == 0) + return (0); + + if (resp[DATA1_BYTE] != 'x') + return (0); +printf("ping answered!\n"); + return (1); +} + +char *barbie_read_firmware() { + + char cmd[4]; + int x; + + memcpy(cmd, packet_1, 4); + cmd[COMMAND_BYTE] = 'V'; + cmd[DATA1_BYTE] = '0'; + + return (barbie_read_data(cmd, 4, BARBIE_DATA_FIRMWARE, &x)); +} + +char *barbie_read_picture(int picture_number, int get_thumbnail, int *size) { + + char cmd[4], resp[4]; + + memcpy(cmd, packet_1, 4); + cmd[COMMAND_BYTE] = 'A'; + cmd[DATA1_BYTE] = picture_number; + + if (barbie_exchange(cmd, 4, resp, 4) != 1) + return (NULL); + + memcpy(cmd, packet_1, 4); + if (get_thumbnail) + cmd[COMMAND_BYTE] = 'M'; + else + cmd[COMMAND_BYTE] = 'U'; + + cmd[DATA1_BYTE] = 0; + + return (barbie_read_data(cmd, 4, BARBIE_DATA_PICTURE, size)); +} + +char *barbie_read_data (char *cmd, int cmd_size, int data_type, int *size) { + + char c, resp[4]; + int n1, n2, n3, n4, x, y, z; + unsigned char r, g, b; + char *s = NULL, *us = NULL, *rg = NULL; + char *ppmhead_t = "P6\n# test.ppm\n%i %i\n255\n"; + char ppmhead[64]; + + if (barbie_exchange(cmd, cmd_size, resp, 4) != 1) + return (0); + switch (data_type) { + case BARBIE_DATA_FIRMWARE: +printf("Getting Firmware\n"); + /* we're getting the firmware revision */ + *size = resp[2]; + s = (char *)malloc(sizeof(char)*(*size)); + memset(s, 0, *size); + s[0] = resp[3]; + if (gpio_read(dev, &s[1], (*size)-1) < 0) { + free(s); + return (NULL); + } + break; + case BARBIE_DATA_PICTURE: +printf("Getting Picture\n"); + /* we're getting a picture */ + n1 = (unsigned char)resp[2]; + n2 = (unsigned char)resp[3]; + if (gpio_read(dev, &c, 1) < 0) + return (NULL); + n3 = (unsigned char)c; + if (gpio_read(dev, &c, 1) < 0) + return (NULL); + n4 = (unsigned char)c; + *size = PICTURE_SIZE(n1, n2, n3, n4); +printf("\tn1=%i n2=%i n3=%i n4=%i size=%i\n", n1, n2 ,n3, n4, *size); + sprintf(ppmhead, ppmhead_t, n1-1, (n2+n3-1)); + us = (char *)malloc(sizeof(char)*(*size)); + rg = (char *)malloc(sizeof(char)*(*size)); + s = (char *)malloc(sizeof(char)*(n1-1)*(n2+n3-1)*3+strlen(ppmhead)); + memset(us, 0, *size); + memset(rg, 0, *size); + memset(s , 0, *size+strlen(ppmhead)); + if (gpio_read(dev, us, *size)<0) { + free(us); + free(rg); + free(s); + return (NULL); + } + /* Unshuffle the data */ + *size = *size - 16; + for (x=0; x<(n2+n3); x++) { + for (y=0; y<n1; y++) { + z = x*n1 + y/2 + y%2*(n1/2+2); + rg[x*n1+y] = us[z]; + } + } + /* Camera uses Bayen array: + * bg bg ... + * gr gr ... + */ + strcpy(s, ppmhead); + z = strlen(s); + for (x=0; x<(n2+n3-1); x++) { + for (y=0; y<(n1-1); y++) { + b = (unsigned char)rg[x*n1+y]; + g = (((unsigned char)rg[(x+1)*n1+y] + + (unsigned char)rg[x*n1+y+1]) / 2); + r = (unsigned char)rg[(x+1)*n1+y+1]; + s[z++] = r; + s[z++] = g; + s[z++] = b; + } + } + *size = z; +printf("size=%i\n", *size); + break; + case BARBIE_DATA_THUMBNAIL: + break; + default: + break; + } + /* read the footer */ + if (gpio_read(dev, &c, 1) < 0) { + free(us); + free(rg); + free(s); + return (0); + } + free(us); + free(rg); + return(s); +} + +/* gPhoto Functions + ======================================================================= +*/ + +int camera_abilities (CameraAbilities *abilities) { + + /* What models do we support? */ + abilities->model[0] = strdup("Barbie Cam"); + abilities->model[1] = strdup("WWF Cam"); + abilities->model[2] = NULL; + + /* Port options */ + abilities->serial = 1; + abilities->serial_baud[0] = 57600; + abilities->serial_baud[1] = 0; + + /* Misc options */ + abilities->cancel = 0; + abilities->capture = 1; + abilities->config = 0; + abilities->delete_file = 0; + abilities->file_preview = 1; + abilities->lock = 0; + abilities->reset = 0; + abilities->sleep = 1; +} + +int camera_init(CameraInit *init) { + +#ifdef BARBIE_DEBUG + printf("Initializing the camera\n"); +#endif + + if (dev) { + gpio_free(dev); + gpio_close(dev); + } + dev = gpio_new(GPIO_DEVICE_SERIAL); + gpio_set_timeout(dev, 5000); + + strcpy(settings.serial.port, init->port_settings.serial_port); + + settings.serial.speed = init->port_settings.serial_baud; + settings.serial.bits = 8; + settings.serial.parity = 0; + settings.serial.stopbits= 1; + + gpio_set_settings(dev, settings); + + gpio_open(dev); + + return (barbie_ping()); +} + +int camera_exit() { + + return GP_OK; +} + +int camera_open() { + + return GP_OK; +} + +int camera_close() { + + return GP_OK; +} + +int camera_folder_count () { + + return 0; +} + +int camera_folder_name (int folder_number, char *folder_name) { + + folder_name[0] = 0; + + return GP_OK; +} + +int camera_folder_set (int folder_number) { + + return GP_OK; +} + +int camera_file_count () { + char cmd[4], resp[4]; +#ifdef BARBIE_DEBUG + printf("Getting the number of pictures\n"); +#endif + memcpy(cmd, packet_1, 4); + + cmd[COMMAND_BYTE] = 'I'; + cmd[DATA1_BYTE] = 0; + + if (barbie_exchange(cmd, 4, resp, 4) != 1) + return (0); + + return (resp[DATA1_BYTE]); +} + +int camera_file_get (int file_number, CameraFile *file) { + + int size; + char *name; +#ifdef BARBIE_DEBUG + printf("Getting a picture\n"); +#endif + name = strdup("barbie0.ppm"); + name[6] = '0' + file_number; + + gp_update_progress(0.00); + + file->type = GP_FILE_PPM; + file->data = barbie_read_picture(file_number, 0, &size);; + if (!file->data) + return GP_ERROR; + file->size = size; + file->name = name; + + return GP_OK; +} + +int camera_file_get_preview (int file_number, CameraFile *file) { + + int size; + char *name; +#ifdef BARBIE_DEBUG + printf("Getting a preview\n"); +#endif + name = strdup("barbie0thumb.ppm"); + name[6] = '0' + file_number; + + gp_update_progress(0.00); + + file->type = GP_FILE_PPM; + file->data = barbie_read_picture(file_number, 1, &size);; + if (!file->data) + return GP_ERROR; + file->size = size; + file->name = name; + + return GP_OK; +} + +int camera_file_delete (int file_number) { + + return GP_ERROR; +} + + +int camera_file_lock (int file_number) { + + return GP_ERROR; +} + +int camera_file_unlock (int file_number) { + + return GP_ERROR; +} + +int camera_config_set (CameraConfig *conf) { + + return GP_OK; +} + +int camera_capture (int type) { + + char cmd[4], resp[4]; +#ifdef BARBIE_DEBUG + printf("Taking a picture\n"); +#endif + memcpy(cmd, packet_1, 4); + + /* Initiated the grab */ + cmd[COMMAND_BYTE] = 'G'; + cmd[DATA1_BYTE] = 0x40; + if (barbie_exchange(cmd, 4, resp, 4) == 0) + return (0); + + /* Get the response (error code) to the grab */ + cmd[COMMAND_BYTE] = 'Y'; + cmd[DATA1_BYTE] = 0; + if (barbie_exchange(cmd, 4, resp, 4) == 0) + return (0); + + return(resp[DATA1_BYTE] == 0? GP_OK: GP_ERROR); +} + +int camera_summary (char *summary) { + + int num; + char *firm; + + num = camera_file_count(); + firm = barbie_read_firmware(); + + sprintf(summary, +"Number of pictures: %i +Firmware Version: %s", num,firm); + + free(firm); + + return GP_OK; +} + +int camera_manual (char *manual) { + + strcpy(manual, "No manual available."); + + return GP_OK; +} +int camera_about (char *about) { + + strcpy(about, +"Barbie/HotWheels/WWF +Scott Fritzinger <scottf@unr.edu> +Andreas Meyer <ahm@spies.com> +Pete Zaitcev <zaitcev@metabyte.com> + +Reverse engineering of image data by: +Jeff Laing <jeffl@SPATIALinfo.com> + +Implemented using documents found on +the web. Permission given by Vision."); + return GP_OK; +} diff --git a/camlibs/barbie/barbie.h b/camlibs/barbie/barbie.h new file mode 100644 index 000000000..9c9721caa --- /dev/null +++ b/camlibs/barbie/barbie.h @@ -0,0 +1,130 @@ +/* Protocol Notes + ========================================================== + +* PC is the host (always) + +* 6 images MAXIMUM on the camera, 128k of memory + +* Camera has an image counter that designates current image to do something with. + (yes, there is better wording, but hey... :) + +* ACK = 0x06, NAK = 0x15 + - No ack/nak means bad connection/faulty cable/no camera + +* Camera always answers ACK to sent command + +* Most COMMAND's have a matching RESPONSE + +* Command Packet structure is: + [0x02] [COMMAND] [DATA] [DATA] [...] [0x03] + +* Response Packet structure is: + [0x02] [RESPONSE] [DATA] [DATA] [...] [0x03] + +* Image transfer Packet Structure is: + [0x02] [RESPONSE] [N1] [N2] [N3] [N4] [DATA] [DATA] [...] [0x03] + + N1 = number of columns in the image + N2 = number of black lines + N3 = number of visible lines + N4 = number of status bytes + + Number of data bytes = N1 * (N2 + N3) + N4 + +* Firmware version transfer Packet Structure is: + [0x02] [RESPONSE] [SIZE] [CHAR] [CHAR] [...] [NULL] [0x03] + + - On error: + [0x02] [RESPONSE] [0] [0x03] + +* Camera sends response packets to host after it sends ACK. + (NAK gets no response of course) + + - Command/Response codes + (note: COMMAND is upper case, RESPONSE is lower case of same letter) + + CMD CMD DATA BYTES RESP DATA BYTES Description + --- ----------------------- --------------------- ----------------------- + A 1 (index #) 1 (0) move to image index # + B 2 (duration, num times) 1 (0) beep (duration*50ms) + E 1 (test char) 1 (test char) echo (test or wake up camera) + G 1 (delay & retry flags) 1 (0, use grab image grab image - increments counter, + result for error lower nibble = self timer delay, + upper nibble = retry numbers + 0,16,32,64(force),112 + I 1 (0) 1 (image index) get image counter + (use reset first to get # pics) + J 2 (value: LSB, MSB) 2 (error, value) increment counter + (0 lets current ram be read) + K 1 (value) 1 (error) write rambyte + (counter incremented after) + L 1 (0) 1 (0) go idle + M 1 (0) hdr+pixel data+info upload thumbnail (increments + image counter & image index) + P 1 (new port value) 1 (old port value) set port value + Q 1 (video mode) 1 (0) video mode (!!) + (requires capture card) + R 1 (register index) 1 (register value) read register value + (error = 0xFF) + T 2 (min, max) 1 (0) set exposure threshold + U 1 (0) hdr+pixel data+info upload image + V 1 (0) version string get version information + W 2 (register index, value) 1 (0 = OK, 0xFF = ERR) write register value + X 1 (0) 2 (min, max) get exposure threshold + Y 1 (0) 1 (grab result code) get grab result code + 0x00 = successful + 0x80 = memory full + 0x81 = failed exposure + Z 1 (0) 1 (0) quit self test + +* If camera is busy when command is issued, camera responds with a BUSY packet + [0x02] [BUSY] [BUSYCODE] [0x03] + + - BUSY = '!' + - Busy codes: + 0x20 BUSY_TIMER camera waiting + 0x21 BUSY_EXPOSURE waiting for exposure after grab started + 0x22 BUSY_VIDEO camera in continuous video mode (self test)(yummy!!!!) :) + 0x23 BUSY_SHUTTER waiting for shutter to come up + 0x24 BUSY_COMMAND waiting for command completion + 0x25 BUSY_COUNTER counter being reset (to nonzero value) + +*/ + +#define MAX_PICTURES 6 + +#define ACK 0x06 +#define NAK 0x15 + +#define COMMAND_BYTE 1 +#define RESPONSE_BYTE 1 +#define DATA1_BYTE 2 +#define DATA2_BYTE 3 + +#define BARBIE_DATA_FIRMWARE 0 +#define BARBIE_DATA_THUMBNAIL 1 +#define BARBIE_DATA_PICTURE 2 + +#define PICTURE_SIZE(n1, n2, n3, n4) (n1*(n2+n3)+n4) + +/* Utility functions */ +void barbie_packet_dump(int direction, char *buf, int size); +int barbie_write_command(char *command, int size); +int barbie_read_response(char *response, int size); +char* barbie_read_data(char *cmd, int cmd_size, int get_firmware, int *size); + +char* barbie_read_firmware(); +char* barbie_read_picture(int picture_number, int get_thumbnail, int *size); + +int barbie_exchange (char *cmd, int cmd_size, char *resp, int resp_size); +int barbie_ping(); + +/* Required gPhoto functions */ +int barbie_initialize(void); +struct Image* barbie_get_preview(void); +int barbie_delete_picture(int index); +int barbie_take_picture(void); +int barbie_number_of_pictures(void); +int barbie_configure(void); +char* barbie_summary(void); +char* barbie_description(void); diff --git a/camlibs/barbie/compile b/camlibs/barbie/compile new file mode 100755 index 000000000..1aa9d3c2a --- /dev/null +++ b/camlibs/barbie/compile @@ -0,0 +1,2 @@ +#!/bin/sh +gcc -g -Wall -DBARBIE_DEBUG -DBUILD_PROGRAM -lgpio barbie.c main.c -o barbie diff --git a/camlibs/barbie/main.c b/camlibs/barbie/main.c new file mode 100644 index 000000000..0da28ea6f --- /dev/null +++ b/camlibs/barbie/main.c @@ -0,0 +1,54 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "barbie.h" + +char serial_port[32]; + +int main (int argc, char *argv[]) { + + int size, x; + char *s; + char fname[16]; + FILE *fp; + sprintf(serial_port, "/dev/ttyS0"); + + if (barbie_initialize() != 1) + printf("initialization failed\n"); + else + printf("initialization succeeded\n"); + + for (x=3; x<=3; x++) { + s = barbie_read_picture(x, 0,&size); + if (s) { + sprintf(fname, "temp-%i.ppm", x); + fp = fopen(fname, "w"); + fwrite(s, size, 1, fp); + fclose(fp); + free(s); + } else { + printf("error!\n"); + } + } + + +/* display number of pictures + printf("%i\n", barbie_number_of_pictures()); +*/ + +/* take a picture + printf("%i\n", barbie_take_picture()); +*/ + +/* firmware revision + s = barbie_read_firmware(); + if (s) { + printf("%s\n", s); + free(s); + } else { + printf("0\n"); + } +*/ + return (0); +} diff --git a/camlibs/directory/Makefile.am b/camlibs/directory/Makefile.am new file mode 100644 index 000000000..ce9264ad3 --- /dev/null +++ b/camlibs/directory/Makefile.am @@ -0,0 +1,8 @@ +camlibdir = $(prefix)/lib/gphoto2 +camlib_LTLIBRARIES = libgphoto2_directory.la + +INCLUDES = -I$(top_srcdir)/include + +libgphoto2_directory_la_SOURCES = directory.c directory.h + +libgphoto2_directory_la_LDFLAGS = -version-info 0:0:0 diff --git a/camlibs/directory/directory.c b/camlibs/directory/directory.c new file mode 100644 index 000000000..dea06eb21 --- /dev/null +++ b/camlibs/directory/directory.c @@ -0,0 +1,227 @@ +/* Notes: + * only supports jpegs/gifs right now + * uses the setting value of "dir_directory" to open as the directory + (interfaces will want to set this when they choose to "open" a + directory.) +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <dirent.h> +#include <sys/stat.h> +#include <unistd.h> +#include <gphoto2.h> + +char dir_directory[1024]; +char dir_images[1024][1024]; +int dir_num_images; +int dir_get_index; + +int camera_abilities (CameraAbilities *abilities) { + + abilities->model[0] = strdup("Browse a directory"); + abilities->model[1] = NULL; + + abilities->file_preview = 1; + abilities->delete_file = 0; + abilities->capture = 0; + abilities->config = 0; + abilities->lock = 1; + abilities->reset = 0; + abilities->cancel = 0; + + return (GP_OK); +} + +int camera_init (CameraInit *init) { + + int i=0; + + dir_num_images = 0; + + for (i=0; i<1024; i++) + strcpy(dir_images[i], ""); + + strcpy(dir_directory, init->port_settings.directory_path); + if (strlen(dir_directory)==0) { + gp_set_setting("dir_directory", getenv("HOME")); + strcpy(dir_directory, getenv("HOME")); + } + + return (GP_OK); +} + +int camera_exit () { + + return (GP_OK); +} + +int camera_open () { + + gp_get_setting("dir_directory", dir_directory); + + return (GP_OK); +} + +int camera_close () { + + return (GP_OK); +} + +int camera_folder_count (int *count) { + + return (1); +} + +int camera_folder_name(int folder_number, char *folder_name) { + + gp_get_setting("dir_directory", dir_directory); + strcpy(folder_name, dir_directory); + + return (GP_OK); +} + +int camera_folder_set(int folder_number) { + + DIR *dir; + struct dirent *de; + struct stat s; + char *dot, fname[1024]; + + gp_get_setting("dir_directory", dir_directory); + dir = opendir(dir_directory); + if (!dir) { + perror("directory: folder_set"); + return (GP_ERROR); + } + de = readdir(dir); + while (de) { + gp_update_progress(-1); + sprintf(fname, "%s/%s", dir_directory, de->d_name); + stat(fname, &s); + /* If it's a file ...*/ + if (S_ISREG(s.st_mode)) { + dot = strrchr(de->d_name, '.'); + if ( + (strcasecmp(dot, ".gif")==0)|| + (strcasecmp(dot, ".jpg")==0)|| + (strcasecmp(dot, ".jpeg")==0)) { + strcpy(dir_images[dir_num_images++], + de->d_name); +#ifdef DEBUG + printf("directory: found \"%s\"\n", de->d_name); +#endif + } + } + de = readdir(dir); + } + closedir(dir); + + return (GP_OK); +} + +int camera_file_count () { + + return (dir_num_images); +} + +int camera_file_get (int file_number, CameraFile *file) { + + /**********************************/ + /* file_number now starts at 0!!! */ + /**********************************/ + + FILE *fp; + long imagesize; + char filename[1024]; + + sprintf(filename, "%s%s", dir_directory, + dir_images[file_number]); + fp = fopen(filename, "r"); + fseek(fp, 0, SEEK_END); + imagesize = ftell(fp); + rewind(fp); + file->data = (char *)malloc(sizeof(char)*imagesize); + fread(file->data, (size_t)imagesize, (size_t)sizeof(char), fp); + fclose(fp); + + file->name = strdup(dir_images[file_number]); + file->type = GP_FILE_JPEG; + file->size = imagesize; + return (GP_OK); +} + +int camera_file_get_preview (int file_number, CameraFile *preview) { + + /**********************************/ + /* file_number now starts at 0!!! */ + /**********************************/ + + char filename[1024]; + FILE *fp; + long int imagesize; + sprintf(filename, "%s/%s", dir_directory, + dir_images[file_number]); + fp = fopen(filename, "r"); + fseek(fp, 0, SEEK_END); + imagesize = ftell(fp); + rewind(fp); + preview->data = (char *)malloc(sizeof(char)*imagesize); + fread(preview->data, (size_t)imagesize, (size_t)sizeof(char),fp); + fclose(fp); + preview->type = GP_FILE_JPEG; + preview->size = imagesize; + +// gp_file_image_scale(preview, 80, 60, preview); + + return (GP_OK); +} + +int camera_file_delete (int file_number) { + + return (GP_ERROR); +} + +int camera_file_lock (int file_number) { + + return (GP_ERROR); +} + +int camera_file_unlock (int file_number) { + + return (GP_ERROR); +} + +int camera_config_set (CameraConfig *conf) { + + return (GP_ERROR); +} + +int camera_capture (int type) { + + return (GP_ERROR); +} + +int camera_summary (char *summary) { + + strcpy(summary, "Summary Not Available"); + + return (GP_OK); +} + +int camera_manual (char *manual) { + + strcpy(manual, "Manual Not Available"); + + return (GP_OK); +} + +int camera_about (char *about) { + + strcpy(about, +"Directory Browse Mode +by Scott Fritzinger <scottf@unr.edu>"); + + return (GP_OK); +} diff --git a/camlibs/directory/directory.h b/camlibs/directory/directory.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/camlibs/directory/directory.h diff --git a/camlibs/fujitsu/Makefile.am b/camlibs/fujitsu/Makefile.am new file mode 100644 index 000000000..67daa7794 --- /dev/null +++ b/camlibs/fujitsu/Makefile.am @@ -0,0 +1,10 @@ +camlibdir = $(prefix)/lib/gphoto2 +camlib_LTLIBRARIES = libgphoto2_fujitsu.la + +CFLAGS = @CFLAGS@ `gpio-config --cflags` +LDFLAGS = @LDFLAGS@ `gpio-config --libs` +INCLUDES = -I$(top_srcdir)/include + +libgphoto2_fujitsu_la_SOURCES = fujitsu.c fujitsu.h + +libgphoto2_fujitsu_la_LDFLAGS = -version-info 0:0:0 `gpio-config --libs` diff --git a/camlibs/fujitsu/README b/camlibs/fujitsu/README new file mode 100644 index 000000000..2641f4d5a --- /dev/null +++ b/camlibs/fujitsu/README @@ -0,0 +1,3 @@ +This is just a shell of the fujitsu library so far. + +i will be developing it in a day or so after the core is introduced. diff --git a/camlibs/fujitsu/fujitsu.c b/camlibs/fujitsu/fujitsu.c new file mode 100644 index 000000000..8e4154aa3 --- /dev/null +++ b/camlibs/fujitsu/fujitsu.c @@ -0,0 +1,136 @@ +#include <string.h> +#include <gphoto2.h> +#include <gpio.h> + +int camera_abilities (CameraAbilities *abilities) { + + abilities->model[0] = strdup("Olympus D-220L"); + abilities->model[1] = strdup("Olympus D-320L"); + abilities->model[2] = strdup("Olympus D-620L"); + abilities->model[3] = NULL; + + abilities->serial = 1; + abilities->serial_baud[0] = 19200; + abilities->serial_baud[1] = 38400; + abilities->serial_baud[2] = 57600; + abilities->serial_baud[3] = 115200; + abilities->serial_baud[4] = 0; + + abilities->cancel = 0; + abilities->capture = 1; + abilities->config = 1; + abilities->delete_file = 1; + abilities->file_preview = 1; + abilities->reset = 1; + abilities->sleep = 1; + + return (GP_OK); +} + +int camera_init (CameraInit *init) { + + return (GP_OK); +} + +int camera_exit () { + + return (GP_OK); +} + +int camera_open () { + + return (GP_OK); +} + +int camera_close () { + + return (GP_OK); +} + +int camera_folder_count (int *count) { + + return (0); +} + +int camera_folder_name(int folder_number, char *folder_name) { + + return (GP_OK); +} + +int camera_folder_set(int folder_number) { + + return (GP_OK); +} + +int camera_file_count () { + + return (0); +} + +int camera_file_get (int file_number, CameraFile *file) { + + /**********************************/ + /* file_number now starts at 0!!! */ + /**********************************/ + + return (GP_OK); +} + +int camera_file_get_preview (int file_number, CameraFile *preview) { + + /**********************************/ + /* file_number now starts at 0!!! */ + /**********************************/ + + return (GP_OK); +} + +int camera_file_delete (int file_number) { + + return (GP_ERROR); +} + +int camera_file_lock (int file_number) { + + return (GP_ERROR); +} + +int camera_file_unlock (int file_number) { + + return (GP_ERROR); +} + +int camera_config_set (CameraConfig *conf) { + + return (GP_ERROR); +} + +int camera_capture (int type) { + + return (GP_ERROR); +} + +int camera_summary (char *summary) { + + strcpy(summary, "Summary Not Available"); + + return (GP_OK); +} + +int camera_manual (char *manual) { + + strcpy(manual, "Manual Not Available"); + + return (GP_OK); +} + +int camera_about (char *about) { + + strcpy(about, +"Scott Fritzinger <scottf@unr.edu> +Support for Fujitsu-based digital cameras +including Olympus, Nikon, Epson, and a few +others."); + + return (GP_OK); +} diff --git a/camlibs/fujitsu/fujitsu.h b/camlibs/fujitsu/fujitsu.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/camlibs/fujitsu/fujitsu.h diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..33cfc3bf1 --- /dev/null +++ b/configure.in @@ -0,0 +1,44 @@ +dnl Process this file with autoconf to produce a configure script. + +PACKAGE=gphoto2 +VERSION=1.90 +libdir=${prefix}/lib/gphoto2 + +AC_INIT(include/gphoto2.h) +AM_CONFIG_HEADER(config.h) +AM_INIT_AUTOMAKE(gphoto2, 1.90) +AM_MAINTAINER_MODE + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CPP +AM_PROG_LIBTOOL + +dnl Checks for libraries. +dnl Replace `main' with a function in -ldl: +AC_CHECK_LIB(dl, main) +dnl Replace `main' with a function in -libs: +AC_CHECK_LIB(ibs, main) + +dnl Checks for header files. +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_CHECK_HEADERS(fcntl.h unistd.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_SIZE_T + +dnl Checks for library functions. +AC_CHECK_FUNCS(mkdir strdup) + +AC_OUTPUT(\ +Makefile +camlibs/Makefile +camlibs/barbie/Makefile +camlibs/fujitsu/Makefile +camlibs/directory/Makefile +frontends/Makefile +frontends/command-line/Makefile +include/Makefile +libgphoto2/Makefile \ +) diff --git a/frontends/Makefile.am b/frontends/Makefile.am new file mode 100644 index 000000000..7abaa7cfb --- /dev/null +++ b/frontends/Makefile.am @@ -0,0 +1,3 @@ +## Process this file with automake to generate a GNU Makefile + +SUBDIRS = command-line diff --git a/frontends/command-line/Makefile.am b/frontends/command-line/Makefile.am new file mode 100644 index 000000000..dd884b2aa --- /dev/null +++ b/frontends/command-line/Makefile.am @@ -0,0 +1,10 @@ +## Process this file with automake to create a GNU Makefile + +bin_PROGRAMS = gphoto2 + +CFLAGS = @CFLAGS@ -I$(top_srcdir)/include + +gphoto2_SOURCES = main.c main.h \ + interface.c interface.h + +gphoto2_LDADD = ../../libgphoto2/libgphoto2.la diff --git a/frontends/command-line/gphoto2 b/frontends/command-line/gphoto2 new file mode 100755 index 000000000..e8ecb8483 --- /dev/null +++ b/frontends/command-line/gphoto2 @@ -0,0 +1,120 @@ +#! /bin/sh + +# gphoto2 - temporary wrapper script for .libs/gphoto2 +# Generated by ltmain.sh - GNU libtool 1.3.3 (1.385.2.181 1999/07/02 15:49:11) +# +# The gphoto2 program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +relink_command="gcc -g -O2 -I../../include -o \$progdir/\$file main.o interface.o ../../libgphoto2/.libs/libgphoto2.so -ldl -ldl -Wl,--rpath -Wl,/home/scottf/gphoto2/libgphoto2/.libs -Wl,--rpath -Wl,/opt/gphoto2/lib" + +# This environment variable determines our operation mode. +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then + # install mode needs the following variable: + link_against_libtool_libs=' ../../libgphoto2/libgphoto2.la' +else + # When we are sourced in execute mode, $file and $echo are already set. + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + echo="echo" + file="$0" + # Make sure echo works. + if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : + else + # Restart under the correct shell, and then maybe $echo will work. + exec /bin/sh "$0" --no-reexec ${1+"$@"} + fi + fi + + # Find the directory that this script lives in. + thisdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "x$thisdir" = "x$file" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=`ls -ld "$file" | sed -n 's/.*-> //p'` + while test -n "$file"; do + destdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + + # If there was a directory component, then change thisdir. + if test "x$destdir" != "x$file"; then + case "$destdir" in + [\/]* | [A-Za-z]:[\/]*) thisdir="$destdir" ;; + *) thisdir="$thisdir/$destdir" ;; + esac + fi + + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + file=`ls -ld "$thisdir/$file" | sed -n 's/.*-> //p'` + done + + # Try to get the absolute directory name. + absdir=`cd "$thisdir" && pwd` + test -n "$absdir" && thisdir="$absdir" + + program=lt-'gphoto2' + progdir="$thisdir/.libs" + + if test ! -f "$progdir/$program" || \ + { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | sed 1q`; \ + test "X$file" != "X$progdir/$program"; }; then + + file="$$-$program" + + if test ! -d "$progdir"; then + mkdir "$progdir" + else + rm -f "$progdir/$file" + fi + + # relink executable if necessary + if test -n "$relink_command"; then + if (cd "$thisdir" && eval $relink_command); then : + else + rm -f "$progdir/$file" + exit 1 + fi + fi + + mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null || + { rm -f "$progdir/$program"; + mv -f "$progdir/$file" "$progdir/$program"; } + rm -f "$progdir/$file" + fi + + if test -f "$progdir/$program"; then + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + # Run the actual program with our arguments. + + # Export the path to the program. + PATH="$progdir:$PATH" + export PATH + + exec $program ${1+"$@"} + + $echo "$0: cannot exec $program ${1+"$@"}" + exit 1 + fi + else + # The program doesn't exist. + $echo "$0: error: $progdir/$program does not exist" 1>&2 + $echo "This script is just a wrapper for $program." 1>&2 + echo "See the libtool documentation for more information." 1>&2 + exit 1 + fi +fi diff --git a/frontends/command-line/interface.c b/frontends/command-line/interface.c new file mode 100644 index 000000000..4c53706aa --- /dev/null +++ b/frontends/command-line/interface.c @@ -0,0 +1,34 @@ +#include <stdio.h> +#include <stdlib.h> + +#include <gphoto2.h> + +int interface_update_status (char *status) { + + printf("Status: %s\n", status); + return (GP_OK); +} + +int interface_message (char *message) { + + printf("Message: %s\n", message); + return (GP_OK); +} + +int interface_confirm (char *message) { + + char c; + + printf("%s [y/n] ", message); + fflush(stdout); + c = getchar(); + fflush(stdin); + return ((c=='y') || (c=='Y')); +} + +int interface_update_progress (float percentage) { + + if (percentage >= 0) + printf("Percent completed: %f\n", percentage); + return (GP_OK); +} diff --git a/frontends/command-line/interface.h b/frontends/command-line/interface.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/frontends/command-line/interface.h diff --git a/frontends/command-line/main.c b/frontends/command-line/main.c new file mode 100644 index 000000000..87310303e --- /dev/null +++ b/frontends/command-line/main.c @@ -0,0 +1,135 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <gphoto2.h> + +#define DEBUG + +int main (int argc, char **argv) { + + CameraAbilities a; + CameraPortSettings s; + CameraFile *f; + char buf[1024]; + int x, m, n, camnum; + + /* ----------------------------- */ + /* Initialize the gPhoto library */ + /* ----------------------------- */ + gp_init(); + + strcpy(s.serial_port, "/dev/ttyS0"); + s.serial_baud = 57600; + gp_port_set(s); + + /* ---------------------------------------- */ + /* Retrieve the number of cameras available */ + /* ---------------------------------------- */ + if ((n = gp_camera_count())==GP_ERROR) + printf("cli: camera_count error!\n"); +#ifdef DEBUG + printf("cli: Number of cameras: %i\n", n); +#endif + /* ----------------------------------- */ + /* Display a list of available cameras */ + /* ----------------------------------- */ + for (x=0; x<n; x++) { + if (gp_camera_name(x, buf)==GP_ERROR) + printf("cli: (ERROR) camera_name error! (%i)\n", x); + +#ifdef DEBUG + printf("cli: Camera #%i name: %s\n", x, buf); +#endif + } + + /* -------------------------- */ + /* Choose which camera to use */ + /* -------------------------- */ + printf("Camera number to use? "); + fflush(stdout); + fgets(buf, 1023, stdin); + camnum = atoi(buf); +#ifdef DEBUG + printf("cli: Setting camera #%i active\n", camnum); +#endif + /* ---------------------------------------------- */ + /* Set the camera they chose as the active camera */ + /* ---------------------------------------------- */ + if (gp_camera_set(camnum) == GP_ERROR) + printf("cli: (ERROR) camera_set error!\n"); + + /* ------------------------------- */ + /* Retrieve the camera's abilities */ + /* ------------------------------- */ + if (gp_camera_abilities(&a) == GP_ERROR) + printf("cli: (ERROR) camera_abilities error!\n"); + + /* --------------------------------------- */ + /* Get the number of folders on the camera */ + /* --------------------------------------- */ + n = gp_folder_count(); + if (n == GP_ERROR) + printf("cli: (ERROR) folder_count error!\n"); +#ifdef DEBUG + printf("cli: Number of folders: %i\n", n); +#endif + + /* ------------------------------------ */ + /* Get the names of each of the folders */ + /* ------------------------------------ */ + for (x=0; x<n; x++) { + gp_folder_name(x, buf); +#ifdef DEBUG + printf("cli: Folder #%i name: %s\n", x, buf); +#endif + } + /* ------------------------------- */ + /* Set the currently active folder */ + /* ------------------------------- */ + if (gp_folder_set(0) == GP_ERROR) + printf("Can't set folder!\n"); + + /* ----------------------------------------- */ + /* Get the number of pictures in that folder */ + /* ----------------------------------------- */ + m=gp_file_count(); + if (m == GP_ERROR) + printf("cli: (ERROR) file_count error!\n"); +#ifdef DEBUG + printf("cli: Number of files in folder #%i: %i\n", n, m); +#endif + + /* ------------------------------- */ + /* Get a thumbnail from the camera */ + /* ------------------------------- */ + f = gp_file_new(); + + printf("cli: Getting preview 0\n"); + gp_file_get_preview(0, f); + printf("cli: done!\n"); + + gp_file_save(0, "/home/scottf/test.jpg"); + + /* ---------------------------------- */ + /* Display camera/library information */ + /* ---------------------------------- */ + if (gp_summary(buf) == GP_ERROR) + printf("cli: (ERROR) summary error!\n"); + printf("cli: Summary:\n%s\n", buf); + + if (gp_manual(buf) == GP_ERROR) + printf("cli: (ERROR) manual error!\n"); + printf("cli: Manual:\n%s\n", buf); + + if (gp_about(buf) == GP_ERROR) + printf("cli: (ERROR) about error!\n"); + printf("cli: About:\n%s\n", buf); + + /* ---------------------------- */ + /* Close out the gPhoto library */ + /* ---------------------------- */ + gp_exit(); + + return (0); +} diff --git a/frontends/command-line/main.h b/frontends/command-line/main.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/frontends/command-line/main.h diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 000000000..b3cfeac3c --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,4 @@ +## Process this file with automake to generate a GNU Makefile + +gphotoheaddir = $(prefix)/include/gphoto2 +gphotohead_HEADERS= gphoto2.h gphoto-core.h gphoto-datatypes.h gphoto-interface.h gphoto-library.h diff --git a/include/gphoto-core.h b/include/gphoto-core.h new file mode 100644 index 000000000..5474d767d --- /dev/null +++ b/include/gphoto-core.h @@ -0,0 +1,161 @@ +/* Header file for gPhoto 0.5-Dev + + Author: Scott Fritzinger <scottf@unr.edu> + + This library is covered by the LGPL. +*/ + + +/* Save/retrieve library or front-end configuration data. */ + int gp_get_setting (char *key, char *value); + int gp_set_setting (char *key, char *value); + + +/* Functions for the front-ends + ---------------------------------------------------------------- */ + +/* Initialize/Quit the gPhoto library */ + int gp_init(); + int gp_exit(); + +/* Camera port operations */ + int gp_port_set (CameraPortSettings settings); + +/* Camera operations */ + /* Retrieve number of cameras */ + int gp_camera_count (); + + /* Retrieve camera name */ + int gp_camera_name (int camera_number, char *camera_name); + + /* Set the current camera library */ + int gp_camera_set (int camera_number); + + /* Retrieve the camera abilities */ + int gp_camera_abilities (CameraAbilities *abilities); + + /* Init/Exit, Open or close a camera */ + int gp_camera_init (CameraInit *init); + int gp_camera_exit (); + + int gp_camera_open (); + int gp_camera_close (); + +/* Folder operations */ + /* Retrieve the number of folders on the camera */ + int gp_folder_count (); + + /* Retrieve the name of a particular folder */ + int gp_folder_name (int folder_number, char *folder_name); + + /* Set the current folder */ + int gp_folder_set (int folder_number); + +/* File operations */ + /* Retrieve the number of files in the current folder */ + int gp_file_count (); + + /* Download a file or a preview from the camera from the current folder*/ + int gp_file_get (int file_number, CameraFile *file); + int gp_file_get_preview (int file_number, CameraFile *preview); + + /* Delete a file from the current folder */ + int gp_file_delete (int file_number); + + /* Saves image to "filename" (full path and filename) */ + int gp_file_save (int file_number, char *filename); + + /* ---- These next 2 are just utilities ---- */ + + /* Allocates a new CameraFile */ + CameraFile* gp_file_new (); + + /* Frees a CameraFile's components */ + int gp_file_clean (CameraFile *file); + + /* Frees a CameraFile from memory */ + int gp_file_free (CameraFile *file); + +/* Camera configuration operations */ + /* Retrieve and set configuration options for the camera */ + int gp_config_get (char *config_dialog_filename); + + /* The config dialog will be stored in a plainttext file. The filename is + returned to the gphoto-core, which will pass it to the front-end. + The format is still under discussion. XML leads the way though intpotential + formats. we need a draft though. + + Something like (note: my XML is awful, so no standards here) : + <page name="Port/Speed"> + <menu name="Port" value="/dev/ttyS0"> + <menu name="Port" value="/dev/ttyS1"> + <menu name="Port" value="/dev/ttyS2"> + <menu name="Port" value="/dev/ttyS3"> + - or - + <text name="Other Port"> + </page> + <page name="General"> + <text name="Camera Name"> + <label value="Quality"> + <radio name="Quality" value="High"> + <radio name="Quality" value="Normal"> + <radio name="Quality" value="Low"> + </page> + <page name="Flash/Lens"> + <label value="Lens Mode"> + <radio name="Mode" value="Macro"> + <radio name="Mode" value="Normal"> + <group name="Flash"> + <radio name="Flash" value="Flash"> + <radio name="Flash" value="No Flash"> + <checkbox name="Red-eye Reduction"> + </group> + </page> + */ + + /* Send "key=value" pairs to the library, delimited by '\n' */ + int gp_config_set (char *config_settings); + +/* Miscellaneous functions */ + /* Captures the current view. Basically, it takes a picture */ + int gp_capture (int type); + + /* Retrieves camera status (number of pictures, charge, etc...) */ + int gp_summary (char *summary); + + /* Retrieves usage of the camera library (config settings, problems, etc) */ + int gp_manual (char *manual); + + /* Retrieves information about the camera library (author, version, etc) */ + int gp_about (char *about); + +/* Image Manipulation Functions */ + int gp_image_preview_rotate (int file_number, int degrees, CameraFile *new_file); + int gp_image_preview_flip_h (int file_number, CameraFile *new_file); + int gp_image_preview_flip_v (int file_number, CameraFile *new_file); + + int gp_image_rotate (int file_number, int degrees, CameraFile *new_file); + int gp_image_scale (int file_number, int width, int height, CameraFile *new_file); + int gp_image_flip_h (int file_number, CameraFile *new_file); + int gp_image_flip_v (int file_number, CameraFile *new_file); + + +/* Utility functions for libraries + ---------------------------------------------------------------- */ +/* Image manipulation for in-memory images */ + int gp_file_image_rotate (CameraFile *old_file, int degrees, CameraFile *new_file); + int gp_file_image_scale (CameraFile *old_file, int width, int height, CameraFile *new_file); + int gp_file_image_flip_h (CameraFile *old_file, CameraFile *new_file); + int gp_file_image_flip_v (CameraFile *old_file, CameraFile *new_file); + +/* Displays the current status on an operation in the camera */ + int gp_update_status (char *status); + +/* Displays a percentage done in the current operation */ + int gp_update_progress (float percentage); + +/* Displays a message (error, very important info) */ + int gp_message (char *message); + +/* Displays a configuration */ + int gp_confirm (char *message); diff --git a/include/gphoto-datatypes.h b/include/gphoto-datatypes.h new file mode 100644 index 000000000..7a9a9ba60 --- /dev/null +++ b/include/gphoto-datatypes.h @@ -0,0 +1,119 @@ +/* Header file for gPhoto 0.5-Dev + + Author: Scott Fritzinger <scottf@unr.edu> + + This library is covered by the LGPL. +*/ + +/* Data Structures + ---------------------------------------------------------------- */ + +/* Return Values */ +#define GP_OK 0 +#define GP_ERROR -1 +#define GP_ERROR_CRITICAL -2 + +/* File Types */ +typedef enum { + GP_FILE_UNKNOWN, + GP_FILE_JPEG, + GP_FILE_TIFF, + GP_FILE_FLASHPIX, + GP_FILE_PPM, + GP_FILE_WAV, + GP_FILE_MPEG, + GP_FILE_QUICKTIME +} CameraFileType; + +/* Physical Connection Types */ +typedef enum { + GP_PORT_DIRECTORY, + GP_PORT_SERIAL, + GP_PORT_USB, + GP_PORT_PARALLEL, + GP_PORT_IRDA +} CameraConnectType; + +typedef struct { + CameraConnectType type; + /* What kind of connection is it? */ + + char serial_port[128]; + /* path to serial port device */ + + int serial_baud; + /* Baud rate for serial port camera */ + + int usb_node; + /* dummy for now. need way to specify which USB device */ + + char directory_path[128]; + /* path for directory lib to index */ +} CameraPortSettings; + +typedef struct { + char *model[128]; + + /* can the library support the following: */ + int serial : 1; + int usb : 1; + int parallel : 1; + int ieee1394 : 1; + + int serial_baud[64]; + /* if serial==1, baud rates that this camera */ + /* supports. terminate list with a zero */ + + int cancel : 1; + /* Camera operation can be cancelled in progress */ + + int capture : 1; + /* Camera can do a capture (take picture) */ + + int config : 1; + /* Camera can be configures remotely */ + + int delete_file : 1; + /* Camera can delete files */ + + int file_preview : 1; + /* Camera can get file previews (thumbnails) */ + + int lock : 1; + /* Camera can lock (protect) pictures */ + + int reset : 1; + /* Camera can be reset during transfer */ + + int sleep : 1; + /* Camera can be turned off (sleep) */ +} CameraAbilities; + + + +typedef struct { + char model[128]; /* Name of the camera */ + + CameraPortSettings port_settings; /* Port settings */ +} CameraInit; + +typedef struct { + CameraFileType type; + /* Type of file (GP_FILE_JPEG, GP_FILE_TIFF, ..) */ + + char* name; + /* Suggested name for the file */ + + long int size; + /* Size of the image data*/ + + char* data; + /* Image data */ + +} CameraFile; + +typedef struct { + char *name; + char *value; +} CameraConfig; + diff --git a/include/gphoto-interface.h b/include/gphoto-interface.h new file mode 100644 index 000000000..0b4dd270a --- /dev/null +++ b/include/gphoto-interface.h @@ -0,0 +1,24 @@ +/* Header file for gPhoto 0.5-Dev + + Author: Scott Fritzinger <scottf@unr.edu> + + This library is covered by the LGPL. +*/ + + +/* Functions provided by the front-end interface + ---------------------------------------------------------------- */ + +/* Displays the current status on an operation in the camera */ + int interface_update_status (char *status); + +/* Displays a percentage done in the current operation */ + int interface_update_progress (float percentage); + +/* Displays a message (error, very important info) */ + int interface_message (char *message); + +/* Displays a configuration */ + int interface_confirm (char *message); + + diff --git a/include/gphoto-library.h b/include/gphoto-library.h new file mode 100644 index 000000000..d358c3b82 --- /dev/null +++ b/include/gphoto-library.h @@ -0,0 +1,25 @@ +int camera_abilities (CameraAbilities *abilities); + +int camera_init (CameraInit *init); +int camera_exit (); + +int camera_open (); +int camera_close (); + +int camera_folder_count (); +int camera_folder_name(int folder_number, char *folder_name); +int camera_folder_set(int folder_number); + +int camera_file_count (); +int camera_file_get (int file_number, CameraFile *file); +int camera_file_get_preview (int file_number, CameraFile *preview); +int camera_file_delete (int file_number); + +int camera_file_lock (int file_number); +int camera_file_unlock (int file_number); + +int camera_config_set (CameraConfig *conf); +int camera_capture (int type); +int camera_summary (char *summary); +int camera_manual (char *manual); +int camera_about (char *about); diff --git a/include/gphoto2.h b/include/gphoto2.h new file mode 100644 index 000000000..7efafb702 --- /dev/null +++ b/include/gphoto2.h @@ -0,0 +1,11 @@ +/* Header file for gPhoto 0.5-Dev + + Author: Scott Fritzinger <scottf@unr.edu> + + This library is covered by the LGPL. +*/ + +#include <gphoto-datatypes.h> +#include <gphoto-core.h> +#include <gphoto-library.h> +#include <gphoto-interface.h> diff --git a/libgphoto2/Makefile.am b/libgphoto2/Makefile.am new file mode 100644 index 000000000..b96fcb205 --- /dev/null +++ b/libgphoto2/Makefile.am @@ -0,0 +1,14 @@ +lib_LTLIBRARIES = libgphoto2.la + +CFLAGS= @CFLAGS@ \ + -Wall \ + -I$(top_srcdir)/include \ + -DCAMLIBS=\"$(pkglibdir)\" + +libgphoto2_la_LDFLAGS = -version-info 0:0:0 +libgphoto2_la_SOURCES = cache.c cache.h \ + core.c core.h \ + helpers.c helpers.h \ + library.c library.h \ + settings.c settings.h \ + util.c util.h diff --git a/libgphoto2/TODO b/libgphoto2/TODO new file mode 100644 index 000000000..60d54a57a --- /dev/null +++ b/libgphoto2/TODO @@ -0,0 +1 @@ +* ltdl diff --git a/libgphoto2/cache.c b/libgphoto2/cache.c new file mode 100644 index 000000000..1a117aade --- /dev/null +++ b/libgphoto2/cache.c @@ -0,0 +1,184 @@ +#include <dirent.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <gphoto2.h> + +#include "cache.h" + +int cache_put (int camera_number, int folder_number, int file_number, CameraFile *file) { + + FILE *fp; + char buf[1024]; + + sprintf(buf, "%s/.gphoto/cache/%i-%i-%i.%i", getenv("HOME"), + camera_number, folder_number, file_number, file->type); +#ifdef DEBUG + printf("cache: putting \"%s\"... ", buf); + fflush(stdout); +#endif + fp = fopen(buf, "w"); + fwrite(file->data, (size_t)sizeof(char), (size_t)file->size, fp); + fclose(fp); + +#ifdef DEBUG + printf("done!\n"); +#endif + return (GP_OK); +} + +int cache_get (int camera_number, int folder_number, int file_number, CameraFile *file) { + + FILE *fp; + DIR *d; + struct dirent *de; + long int s; + int camn, foldn, filen, filet; + char buf[1024], cachedir[1024]; + + sprintf(cachedir, "%s/.gphoto/cache", getenv("HOME")); + d = opendir(cachedir); +#ifdef DEBUG + printf("cache: getting (%i, %i, %i)... ", + camera_number, folder_number, file_number); + fflush(stdout); +#endif + + do { + camn = -1; + foldn = -1; + filen = -1; + /* Read each entry */ + de = readdir(d); + if (de) { + sscanf(de->d_name, "%i-%i-%i.%i", + &camn, &foldn, &filen, &filet); + if ((camn == camera_number) && + (foldn == folder_number) && + (filen == file_number)) { + sprintf(buf, "%s/%s", cachedir, de->d_name); +#ifdef DEBUG + printf("found! (%s)\n", de->d_name); +#endif + fp = fopen(buf, "w"); + fseek(fp, 0, SEEK_END); + s = ftell(fp); + rewind(fp); + file->data = (char*)malloc(sizeof(char)*s); + fread(file->data, (size_t)sizeof(char), + (size_t)file->size, fp); + fclose(fp); + file->size = s; + file->type = filet; + return (GP_OK); + } + } + } while (de); +#ifdef DEBUG + printf("error! didn't exist!\n"); +#endif + return (GP_ERROR); +} + +int cache_delete (int camera_number, int folder_number, int file_number) { + + /* if file_number == -1, all the files in the folder get deleted */ + /* if folder_number == -1, all the folders for camera get deleted */ + /* if camera_number == -1, ALL the camera's files get delete */ + + DIR *d; + struct dirent *de; + int camn, foldn, filen, filet; + char buf[1024], cachedir[1024]; + +#ifdef DEBUG + printf("cache: Deleting (%i, %i, %i)...\n", + camera_number, folder_number, file_number); + fflush(stdout); +#endif + sprintf(cachedir, "%s/.gphoto/cache", getenv("HOME")); + d = opendir(cachedir); + do { + camn = -2; + foldn = -2; + filen = -2; + /* Read each entry */ + de = readdir(d); + if (de) { + sscanf(de->d_name, "%i-%i-%i.%i", + &camn, &foldn, &filen, &filet); + if ((camn>=0)&&(foldn>=0)&&(filen>=0)) { + sprintf(buf, "%s/%s", cachedir, de->d_name); + if (((camn == camera_number) && + (foldn == folder_number) && + (filen == file_number)) + || + ((camn == camera_number) && + (foldn == folder_number) && + (file_number == -1)) + || + ((camn == camera_number) && + (folder_number == -1)) + || + (camera_number == -1)) { +#ifdef DEBUG + printf("cache: Removing %s\n", buf); +#endif + unlink(buf); + } else { +#ifdef DEBUG + printf("cache: Leaving %s\n", buf); +#endif + } + + } + + } + } while (de); + + return (GP_OK); +} + +int cache_exists (int camera_number, int folder_number, int file_number) { + + DIR *d; + struct dirent *de; + int camn, foldn, filen, filet; + char cachedir[1024]; + +#ifdef DEBUG + printf("cache: looking for (%i, %i, %i)... ", + camera_number, folder_number, file_number); + fflush(stdout); +#endif + + sprintf(cachedir, "%s/.gphoto/cache", getenv("HOME")); + d = opendir(cachedir); + do { + camn = -1; + foldn = -1; + filen = -1; + /* Read each entry */ + de = readdir(d); + if (de) { + sscanf(de->d_name, "%i-%i-%i.%i", + &camn, &foldn, &filen, &filet); + if ((camn == camera_number) && + (foldn == folder_number) && + (filen == file_number)) { +#ifdef DEBUG + printf("found! (%s)\n", de->d_name); +#endif + return (GP_OK); + } + } + } while (de); + +#ifdef DEBUG + printf("missing!\n"); +#endif + + return (GP_ERROR); +} diff --git a/libgphoto2/cache.h b/libgphoto2/cache.h new file mode 100644 index 000000000..7426cd5b8 --- /dev/null +++ b/libgphoto2/cache.h @@ -0,0 +1,5 @@ +int cache_put (int camera_number, int folder_number, int file_number, CameraFile *file); +int cache_get (int camera_number, int folder_number, int file_number, CameraFile *file); +int cache_exists (int camera_number, int folder_number, int file_number); +int cache_delete (int camera_number, int folder_number, int file_number); + diff --git a/libgphoto2/core.c b/libgphoto2/core.c new file mode 100644 index 000000000..f9e546c07 --- /dev/null +++ b/libgphoto2/core.c @@ -0,0 +1,556 @@ +#include <dlfcn.h> +#include <dirent.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <gphoto2.h> + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "core.h" +#include "cache.h" +#include "library.h" +#include "settings.h" + +#define DEBUG + +/* Some local globals + ---------------------------------------------------------------- */ + + CameraPortSettings glob_port_settings; + + int glob_folder_number; /* currently selected folder number */ + int glob_camera_number; /* currently selected camera number */ + + /* Camera List */ + int glob_camera_count; /* total cameras found */ + CameraChoice glob_camera[512]; /* camera/library list */ + + /* Currently loaded settings */ + int glob_setting_count; /* number of settings found */ + Setting glob_setting[512]; /* setting key/value list */ + + + /* Current loaded library's handle */ + void *glob_library_handle; /* current library handle */ + Camera glob_c; /* pointer to current camera function set */ + +/* Core functions (for front-ends) + ---------------------------------------------------------------- */ + +int gp_init () { + + DIR *d; + struct dirent *de; + char buf[1024]; + + /* Initialize the globals */ + glob_camera_number = 0; + glob_camera_count = 0; + glob_setting_count = 0; + glob_library_handle = NULL; + glob_folder_number = 0; + +#ifdef DEBUG + printf(" > Debug Mode On < \n"); + printf("core: Creating $HOME/.gphoto and $HOME/.gphoto/cache\n"); +#endif + /* Make sure the directories are created */ + sprintf(buf, "%s/.gphoto", getenv("HOME")); + (void)mkdir(buf, 0700); + sprintf(buf, "%s/.gphoto/cache", getenv("HOME")); + (void)mkdir(buf, 0700); + +#ifdef DEBUG + printf("core: Camera library dir: %s\n", CAMLIBS); + printf("core: Trying to load libraries:\n"); +#endif + /* Load settings */ + load_settings(); + + /* Look for available camera libraries */ + d = opendir(CAMLIBS); + do { + /* Read each entry */ + de = readdir(d); + if (de) { +#ifdef DEBUG + printf("core:\tis %s a library? ", de->d_name); +#endif + /* try to open the library */ + if (is_library(de->d_name) == GP_OK) { +#ifdef DEBUG + printf("yes\n"); +#endif + glob_camera_count += load_camera_list(de->d_name, glob_camera, glob_camera_count); +#ifdef DEBUG + } else { + printf("no\n"); +#endif + } + } + } while (de); + +#ifdef DEBUG + { + int x; + printf("core: List of cameras found:\n"); + for (x=0; x<glob_camera_count; x++) + printf("core:\t\"%s\" uses %s\n", + glob_camera[x].name, glob_camera[x].library); + if (glob_camera_count == 0) + printf("core:\tNone\n"); + } +#endif + cache_delete(-1, -1, -1); /* wipe all the cache clean */ + if (gp_get_setting("camera", buf) == GP_OK) + return (load_library(buf)); + return (GP_OK); +} + +int gp_exit () { + + cache_delete(-1, -1, -1); /* wipe all the cache clean */ + + gp_camera_exit(); + return (GP_OK); +} + +int gp_port_set (CameraPortSettings port_settings) { + + memcpy(&glob_port_settings, &port_settings, sizeof(glob_port_settings)); + + return (GP_OK); +} + +int gp_camera_count () { + + return(glob_camera_count); +} + +int gp_camera_name (int camera_number, char *camera_name) { + + if (camera_number > glob_camera_count) + return (GP_ERROR); + + strcpy(camera_name, glob_camera[camera_number].name); + return (GP_OK); +} + +int gp_camera_set (int camera_number) { + + CameraInit ci; + + if (camera_number >= glob_camera_count) + return (GP_ERROR); + + if (glob_library_handle != NULL) + dlclose(glob_library_handle); + glob_library_handle = NULL; + if (load_library(glob_camera[camera_number].name)==GP_ERROR) + return (GP_ERROR); + glob_camera_number = camera_number; + +#ifdef DEBUG + printf("core: Initializing \"%s\" (%s)...\n", + glob_camera[camera_number].name, + glob_camera[camera_number].library); +#endif + strcpy(ci.model, glob_camera[camera_number].name); + memcpy(&ci.port_settings, &glob_port_settings, sizeof(glob_port_settings)); + gp_camera_init(&ci); + return(GP_OK); +} + +int gp_camera_abilities (CameraAbilities *abilities) { + + if (glob_c.abilities == NULL) + return(GP_ERROR); + + return(glob_c.abilities(abilities)); +} + +int gp_camera_init (CameraInit *init) { + + if (glob_c.init == NULL) + return(GP_ERROR); + + return(glob_c.init(init)); +} + +int gp_camera_exit () { + + if (glob_c.exit == NULL) + return(GP_ERROR); + + return(glob_c.exit()); +} + +int gp_camera_open () { + + if (glob_c.open == NULL) + return(GP_ERROR); + + return(glob_c.open()); +} + +int gp_camera_close () { + + if (glob_c.close == NULL) + return(GP_ERROR); + + return(glob_c.close()); +} + +int gp_folder_count () { + + if (glob_c.folder_count == NULL) + return(GP_ERROR); + + return(glob_c.folder_count()); +} + +int gp_folder_name (int folder_number, char *folder_name) { + + if (glob_c.folder_name == NULL) + return (GP_ERROR); + + return(glob_c.folder_name(folder_number, folder_name)); +} + +int gp_folder_set (int folder_number) { + + if (glob_c.folder_set == NULL) + return (GP_ERROR); + + if (glob_c.folder_set(folder_number) == GP_ERROR) + return (GP_ERROR); + glob_folder_number = folder_number; + return(GP_OK); +} + +int gp_file_count () { + + if (glob_c.file_count == NULL) + return (GP_ERROR); + + return(glob_c.file_count()); +} + +int gp_file_get (int file_number, CameraFile *file) { + + if (glob_c.file_get == NULL) + return (GP_ERROR); + + if (cache_exists(glob_camera_number, glob_folder_number, file_number) == GP_OK) + return (cache_get(glob_camera_number, glob_folder_number, file_number, file)); + + gp_file_clean(file); + glob_c.file_get(file_number, file); + cache_put(glob_camera_number, glob_folder_number, file_number, file); + + return (GP_OK); +} + +int gp_file_get_preview (int file_number, CameraFile *preview) { + + if (glob_c.file_get_preview == NULL) + return (GP_ERROR); + if (cache_exists(glob_camera_number, glob_folder_number, file_number)==GP_OK) + return (cache_get(glob_camera_number, glob_folder_number, file_number, preview)); + + gp_file_clean(preview); + glob_c.file_get_preview(file_number, preview); + + cache_put(glob_camera_number, glob_folder_number, file_number, preview); + + return(GP_OK); +} + +int gp_file_delete (int file_number) { + + /* + if (glob_c.file_delete == NULL) + return (GP_ERROR); + glob_c.file_delete(file_number) + Remove from the cache + update cache itself (picture number shifting) + */ + + return(GP_OK); +} + +int gp_file_lock (int file_number) { + + return (GP_ERROR); +} + +int gp_file_unlock (int file_number) { + + return (GP_ERROR); +} + +int gp_file_save_to_disk (CameraFile *file, char *filename) { + + FILE *fp; + + if ((fp = fopen(filename, "w"))==NULL) + return (GP_ERROR); + fwrite(file->data, (size_t)sizeof(char), (size_t)file->size, fp); + fclose(fp); + + return (GP_OK); +} + +int gp_file_save (int file_number, char *filename) { + + /* + write image data to disk as "filename" + */ + + CameraFile *f; + + f = gp_file_new(); + if (cache_exists(glob_camera_number,glob_folder_number,file_number) + == GP_ERROR) + return (GP_ERROR); + cache_get(glob_camera_number,glob_folder_number,file_number,f); + + return (gp_file_save_to_disk(f, filename)); +} + + +CameraFile* gp_file_new () { + + /* + Allocates a new CameraFile + */ + + CameraFile *f; + + f = (CameraFile*)malloc(sizeof(CameraFile)); + f->type = GP_FILE_UNKNOWN; + f->name = NULL; + f->data = NULL; + f->size = 0; + + return(f); +} + +int gp_file_clean (CameraFile *file) { + + /* + frees a CameraFile's components + */ + + if (file->name) + free(file->name); + if (file->data) + free(file->data); + file->name = NULL; + file->data = NULL; + file->size = 0; + return(GP_OK); +} + + +int gp_file_free (CameraFile *file) { + + /* + frees a CameraFile from memory + */ + + gp_file_clean(file); + free(file); + return(GP_OK); +} + + +int gp_config_get (char *config_dialog_filename) { + + /* + strcpy(config_dialog_name, LIB/library_name.config); + */ + + return(GP_OK); +} + +int gp_config_set (char *config_settings) { + + if (glob_c.config_set == NULL) + return (GP_ERROR); + + return(glob_c.config_set(config_settings)); +} + +int gp_capture (int type) { + + if (glob_c.capture == NULL) + return (GP_ERROR); + + return(glob_c.capture(type)); +} + +int gp_summary (char *summary) { + + if (glob_c.summary == NULL) + return (GP_ERROR); + + return(glob_c.summary(summary)); +} + +int gp_manual (char *manual) { + + if (glob_c.manual == NULL) + return (GP_ERROR); + + return(glob_c.manual(manual)); +} + +int gp_about (char *about) { + + if (glob_c.about == NULL) + return (GP_ERROR); + + return(glob_c.about(about)); +} + +/* Utility (helper) functions for Front-ends + ---------------------------------------------------------------------------- */ + +/* Image previews */ +int gp_image_preview_rotate (int file_number, int degrees, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_image_preview_scale (int file_number, int width, int height, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_image_preview_flip_h (int file_number, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_image_preview_flip_v (int file_number, CameraFile *new_file) { + + return(GP_OK); +} + +/* Full-size images */ +int gp_image_rotate (int file_number, int degrees, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_image_scale (int file_number, int width, int height, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_image_flip_h (int file_number, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_image_flip_v (int file_number, CameraFile *new_file) { + + return(GP_OK); +} + + +/* Utility (helper) functions for libraries + ---------------------------------------------------------------------------- */ + +int gp_file_image_rotate (CameraFile *old_file, int degrees, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_file_image_scale (CameraFile *old_file, int width, int height, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_file_image_flip_h (CameraFile *old_file, CameraFile *new_file) { + + return(GP_OK); +} + +int gp_file_image_flip_v (CameraFile *old_file, CameraFile *new_file) { + + return(GP_OK); +} + +/* Configuration file functions (for front-ends and libraries) + ---------------------------------------------------------------------------- */ + +int gp_get_setting (char *key, char *value) { + + int x; + + for (x=0; x<glob_setting_count; x++) { + if (strcmp(glob_setting[x].key, key)==0) { + strcpy(value, glob_setting[x].value); + return (GP_OK); + } + } + strcpy(value, ""); + return(GP_ERROR); +} + +int gp_set_setting (char *key, char *value) { + + int x; + +#ifdef DEBUG + printf("core: Setting key \"%s\" to value \"%s\"\n",key,value); +#endif + + for (x=0; x<glob_setting_count; x++) { + if (strcmp(glob_setting[x].key, key)==0) { + strcpy(glob_setting[x].value, value); + save_settings(glob_setting, glob_setting_count); + return (GP_OK); + } + } + strcpy(glob_setting[glob_setting_count].key, key); + strcpy(glob_setting[glob_setting_count++].value, value); + save_settings(glob_setting, glob_setting_count); + + return(GP_OK); +} + + +/* Front-end interaction functions + ---------------------------------------------------------------------------- */ + +int gp_update_status (char *status) { + + interface_update_status(status); + return(GP_OK); +} + +int gp_update_progress (float percentage) { + + interface_update_progress(percentage); + return(GP_OK); +} + +int gp_message (char *message) { + + interface_message(message); + return(GP_OK); +} + +int gp_confirm (char *message) { + + return(interface_confirm(message)); +} diff --git a/libgphoto2/core.h b/libgphoto2/core.h new file mode 100644 index 000000000..a8577b6d7 --- /dev/null +++ b/libgphoto2/core.h @@ -0,0 +1,58 @@ +/* Data types +---------------------------------------------------------------- */ +typedef struct { + /* The name of the camera ("Olympus D-220L") */ + char name[128]; + /* The filename of the camera library. */ + char library[128]; +} CameraChoice; + +typedef struct { + /* key = value settings */ + char key[256]; + char value[256]; +} Setting; + +typedef int (*c_abilities) (CameraAbilities*); +typedef int (*c_init) (); +typedef int (*c_exit) (); +typedef int (*c_open) (); +typedef int (*c_close) (); +typedef int (*c_folder_count) (); +typedef int (*c_folder_name) (int, char*); +typedef int (*c_folder_set) (int); +typedef int (*c_file_count) (); +typedef int (*c_file_get) (int, CameraFile*); +typedef int (*c_file_get_preview)(int, CameraFile*); +typedef int (*c_file_delete) (int); +typedef int (*c_file_lock) (int); +typedef int (*c_file_unlock) (int); +typedef int (*c_config_set) (char*); +typedef int (*c_capture) (int); +typedef int (*c_summary) (char*); +typedef int (*c_manual) (char*); +typedef int (*c_about) (char*); + + +/* Function pointers to the current library functions */ +typedef struct { + c_abilities abilities; + c_init init; + c_exit exit; + c_open open; + c_close close; + c_folder_count folder_count; + c_folder_name folder_name; + c_folder_set folder_set; + c_file_count file_count; + c_file_get file_get; + c_file_get_preview file_get_preview; + c_file_delete file_delete; + c_file_lock file_lock; + c_file_unlock file_unlock; + c_config_set config_set; + c_capture capture; + c_summary summary; + c_manual manual; + c_about about; +} Camera; diff --git a/libgphoto2/helpers.c b/libgphoto2/helpers.c new file mode 100644 index 000000000..62e85ba85 --- /dev/null +++ b/libgphoto2/helpers.c @@ -0,0 +1,17 @@ +/* + Contains the command-lines for altering various image types + + +JPEG | JPG + flip_h + jpegtran -copy all -flip horizontal %s + + flip_v + jpegtran -copy all -flip vertical %s + + rotate + jpegtran -copy all -rotate %i %s + + scale + ??? +*/ diff --git a/libgphoto2/helpers.h b/libgphoto2/helpers.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/libgphoto2/helpers.h diff --git a/libgphoto2/library.c b/libgphoto2/library.c new file mode 100644 index 000000000..cd9ad0bba --- /dev/null +++ b/libgphoto2/library.c @@ -0,0 +1,119 @@ +#include <dlfcn.h> +#include <stdio.h> +#include <gphoto2.h> + +#include "core.h" +#include "library.h" +#include "util.h" + +extern CameraChoice glob_camera[]; +extern int glob_camera_count; +extern void *glob_library_handle; +extern Camera glob_c; + +int is_library(char *library_filename) { + + char buf[1024]; + void *lh; + + sprintf(buf, "%s/%s", CAMLIBS, library_filename); + + if ((lh = dlopen(buf, RTLD_LAZY))==NULL) { + perror("load_library"); + return (GP_ERROR); + } + + dlclose(lh); + + return (GP_OK); +} + +int load_library (char *camera_name) { + + char buf[1024]; + void *lh; + int x; + for (x=0; x<glob_camera_count; x++) { + if (strcmp(glob_camera[x].name, camera_name)==0) { + sprintf(buf, "%s/%s", CAMLIBS, glob_camera[x].library); + if ((lh = dlopen(buf, RTLD_LAZY))==NULL) { + perror("load_library"); + return (GP_ERROR); + } + glob_c.abilities = dlsym(lh, "camera_abilities"); + glob_c.init = dlsym(lh, "camera_init"); + glob_c.exit = dlsym(lh, "camera_exit"); + glob_c.open = dlsym(lh, "camera_open"); + glob_c.close = dlsym(lh, "camera_close"); + glob_c.folder_count = dlsym(lh, "camera_folder_count"); + glob_c.folder_name = dlsym(lh, "camera_folder_name"); + glob_c.folder_set = dlsym(lh, "camera_folder_set"); + glob_c.file_count = dlsym(lh, "camera_file_count"); + glob_c.file_get = dlsym(lh, "camera_file_get"); + glob_c.file_get_preview = dlsym(lh, "camera_file_get_preview"); + glob_c.file_delete = dlsym(lh, "camera_file_delete"); + glob_c.file_lock = dlsym(lh, "camera_file_lock"); + glob_c.file_unlock = dlsym(lh, "camera_file_unlock"); + glob_c.config_set = dlsym(lh, "camera_config_set"); + glob_c.capture = dlsym(lh, "camera_capture"); + glob_c.summary = dlsym(lh, "camera_summary"); + glob_c.manual = dlsym(lh, "camera_manual"); + glob_c.about = dlsym(lh, "camera_about"); + glob_library_handle = lh; + + return (GP_OK); + } + } + + return (GP_ERROR); +} + +int load_camera_list (char *library_filename, CameraChoice *camera, int index) { + /* Returns the number of cameras added to the CameraChoice list */ + /* 0 implies an error occurred */ + + char buf[1024]; + void *lh; + c_abilities load_camera_abilities; + CameraAbilities a; + int x; + + sprintf(buf, "%s/%s", CAMLIBS, library_filename); + + /* try to open the library */ + if ((lh = dlopen(buf, RTLD_LAZY))==NULL) { + perror("load_library"); + return 0; + } + + /* load in the camera_abilities function */ + load_camera_abilities = dlsym(lh, "camera_abilities"); + if (load_camera_abilities(&a) == GP_ERROR) { + dlclose(lh); + return 0; + } + + /* check to see if this library has been loaded */ + for (x=0; x<index; x++) { + if (strcmp(camera[x].name, a.model[0])==0) { + dlclose(lh); + return (0); + } + } + + /* read in the supported camera list */ + x=0; + while (a.model[x]) { + printf("camera model: %s\n", a.model[x]); + strcpy(camera[x+index].name, a.model[x]); + strcpy(camera[x+index].library, library_filename); + x++; + } + + /* clean up */ + gp_free_abilities(&a); + + dlclose(lh); + + return (x); +} diff --git a/libgphoto2/library.h b/libgphoto2/library.h new file mode 100644 index 000000000..0ee70f62d --- /dev/null +++ b/libgphoto2/library.h @@ -0,0 +1,3 @@ +int is_library (char *library_filename); +int load_library (char *camera_name); +int load_camera_list(char *library_filename, CameraChoice *camera, int index); diff --git a/libgphoto2/settings.c b/libgphoto2/settings.c new file mode 100644 index 000000000..1e500096c --- /dev/null +++ b/libgphoto2/settings.c @@ -0,0 +1,85 @@ +#include <gphoto2.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "core.h" +#include "settings.h" + +extern Setting glob_setting[]; +extern int glob_setting_count; + +int load_settings () { + + FILE *f; + char buf[1024], *c; + + glob_setting_count = 0; + + sprintf(buf, "%s/.gphoto/settings", getenv("HOME")); +#ifdef DEBUG + printf("core: Loading settings from file \"%s\"\n", buf); +#endif + if ((f=fopen(buf, "a+"))==NULL) { + perror("Loading Settings"); + return(0); + } + rewind(f); + while (!feof(f)) { + strcpy(buf, ""); + fgets(buf, 1023, f); + if (strlen(buf)>3) { + buf[strlen(buf)-1] = '\0'; + c = strtok(buf, "="); + strcpy(glob_setting[glob_setting_count].key, c); + c = strtok(NULL, "="); + strcpy(glob_setting[glob_setting_count++].value, c); + } + } +#ifdef DEBUG + dump_settings(); +#endif + + return (GP_OK); +} + + +int save_settings () { + + FILE *f; + char buf[1024]; + int x=0; + + sprintf(buf, "%s/.gphoto/settings", getenv("HOME")); +#ifdef DEBUG + printf("core: Saving settings to file \"%s\"\n", buf); +#endif + if ((f=fopen(buf, "w+"))==NULL) { + perror("Loading Settings"); + return(0); + } + rewind(f); + while (x < glob_setting_count) { + fwrite(glob_setting[x].key, strlen(glob_setting[x].key),1,f); + fputc('=', f); + fwrite(glob_setting[x].value, strlen(glob_setting[x].value),1,f); + fputc('\n', f); + x++; + } + fclose(f); + + return (GP_OK); +} + +int dump_settings () { + + int x; + printf("core: All settings:\n"); + for (x=0; x<glob_setting_count; x++) + printf("core:\t\"%s\" = \"%s\"\n", + glob_setting[x].key,glob_setting[x].value); + if (glob_setting_count == 0) + printf("core:\tNone\n"); + printf("core: Total settings: %i\n", glob_setting_count); + + return (GP_OK); +} diff --git a/libgphoto2/settings.h b/libgphoto2/settings.h new file mode 100644 index 000000000..684148d85 --- /dev/null +++ b/libgphoto2/settings.h @@ -0,0 +1,3 @@ +int save_settings (); +int load_settings (); +int dump_settings (); diff --git a/libgphoto2/util.c b/libgphoto2/util.c new file mode 100644 index 000000000..51ac175b1 --- /dev/null +++ b/libgphoto2/util.c @@ -0,0 +1,13 @@ +#include <stdlib.h> +#include <gphoto2.h> +#include "util.h" + +int gp_free_abilities (CameraAbilities *abilities) { + + int x=0; + + while (abilities->model[x]) + free(abilities->model[x++]); + + return GP_OK; +} diff --git a/libgphoto2/util.h b/libgphoto2/util.h new file mode 100644 index 000000000..45bc4d345 --- /dev/null +++ b/libgphoto2/util.h @@ -0,0 +1 @@ +int gp_free_abilities (CameraAbilities *abilities); |