Logo Search packages:      
Sourcecode: libgphoto2 version File versions  Download package

jamcam.c

/****************************************************************/
/* jamcam.c - Gphoto2 library for the KBGear JamCam v2 and v3   */
/*                                                              */
/* Copyright  2001 Chris Pinkham                             */
/*                                                              */
/* Author: Chris Pinkham <cpinkham@infi.net>                    */
/*                                                              */
/* This library is free software; you can redistribute it       */
/* and/or modify it under the terms of the GNU Library 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 Library General Public License for     */
/* more details.                                                */
/*                                                              */
/* You should have received a copy of the GNU Library 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 <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <gphoto2/gphoto2.h>
#include <bayer.h>
#include <gamma.h>

#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (GETTEXT_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

#include "library.h"

#define GP_MODULE "jamcam"
#define TIMEOUT         2000

#define JAMCAM_VERSION "0.6"
#define JAMCAM_LAST_MOD "11/28/2001 14:51 EST"

/* define what cameras we support */
static const struct {
      char *model;
      int usb_vendor;
      int usb_product;
} models[] = {
      { "KBGear:JamCam", 0x084E, 0x0001 },
      { NULL, 0, 0 }
};


int camera_id (CameraText *id)
{
      /* GP_DEBUG ("* camera_id"); */

      strcpy (id->text, "jamcam");

      return (GP_OK);
}

int camera_abilities (CameraAbilitiesList *list)
{
      int x = 0;
      char *ptr;
      CameraAbilities a;

      /* GP_DEBUG ("* camera_abilities"); */

      ptr = models[x].model;
      while (ptr) {
            memset(&a, 0, sizeof(a));
            strcpy (a.model, ptr );
            a.status = GP_DRIVER_STATUS_PRODUCTION;
            a.port     = GP_PORT_SERIAL | GP_PORT_USB;
            a.speed[0] = 57600;
            a.speed[1] = 0;

            /* fixme, need to set these operations lists to correct values */
            a.operations        =   GP_OPERATION_NONE;
            a.file_operations   =   GP_FILE_OPERATION_PREVIEW;

            a.folder_operations =   GP_FOLDER_OPERATION_NONE;

            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 file_list_func (CameraFilesystem *fs, const char *folder,
                     CameraList *list, void *data, GPContext *context)
{
      Camera *camera = data;
      int count;

      GP_DEBUG ("* file_list_func");
      GP_DEBUG ("*** folder: %s", folder);

      CHECK (count = jamcam_file_count (camera));
      CHECK (gp_list_populate (list, "pic_%04i.ppm", count));

      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;
      struct jamcam_file *jc_file;

      GP_DEBUG ("* get_info_func");
      GP_DEBUG ("*** folder: %s", folder);
      GP_DEBUG ("*** filename: %s",filename);

      /* Get the file number from the CameraFileSystem */
      CHECK (n = gp_filesystem_number (camera->fs, folder,
                               filename, context));

      jc_file = jamcam_file_info( camera, n );

      /* fixme, get file size also */
      info->file.fields = GP_FILE_INFO_TYPE;
      strcpy (info->file.type, GP_MIME_PPM);
      info->file.width = jc_file->width;
      info->file.height = jc_file->height;

      info->preview.fields = GP_FILE_INFO_TYPE;
      strcpy (info->preview.type, GP_MIME_PPM);
      info->preview.width = 80;
      info->preview.height = 60;

      return (GP_OK);
}

static int camera_exit (Camera *camera, GPContext *context)
{
      GP_DEBUG ("* camera_exit");

      jamcam_file_count (camera);
      return (GP_OK);
}

#define CHECK_free(result) {        \
      int res;                \
      res = result;                 \
      if (res < 0)  {         \
            free(raw); free(ppm);   \
            return (res);           \
      }                       \
}

static int get_file_func (CameraFilesystem *fs, const char *folder,
                    const char *filename, CameraFileType type,
                    CameraFile *file, void *user_data, GPContext *context)
{
      Camera *camera = user_data;
      char *raw, *ppm;
      char tmp_filename[128];
      unsigned char gtable[256];
      char *ptr;
      int size = 0, n = 0;
      int width, height;
      struct jamcam_file *jc_file;

      GP_DEBUG ("* camera_file_get");
      GP_DEBUG ("*** folder: %s", folder);
      GP_DEBUG ("*** filename: %s",filename);
      GP_DEBUG ("*** type: %d", type);

      CHECK (n = gp_filesystem_number (camera->fs, folder,
                               filename, context));

      if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
            return (GP_ERROR_CANCEL);

      raw = malloc(640*480 * 3);
      ppm = malloc(640*480 * 3 + 200);
      
      switch (type) {
      case GP_FILE_TYPE_PREVIEW:

            CHECK_free (jamcam_request_thumbnail (camera, file, raw, &size, n, context));


            width = 80;
            height = 60;

            sprintf( ppm,
                  "P6\n"
                  "# CREATOR: gphoto2, jamcam library\n"
                  "%d %d\n"
                  "255\n", width, height );

            ptr = ppm + strlen( ppm );

            size = strlen( ppm ) + ( height * width * 3 );

            gp_bayer_decode(raw, width, height, ptr, BAYER_TILE_GBRG );
            gp_gamma_fill_table( gtable, 0.5 );
            gp_gamma_correct_single( gtable, ptr, height * width );

            CHECK_free (gp_file_set_mime_type (file, GP_MIME_PPM));
            CHECK_free (gp_file_set_name (file, filename));
            CHECK_free (gp_file_append (file, ppm, size));
            break;

      case GP_FILE_TYPE_NORMAL:
            CHECK_free (jamcam_request_image (camera, file, raw, &size, n, context));

            jc_file = jamcam_file_info (camera, n);

            sprintf( ppm,
                  "P6\n"
                  "# CREATOR: gphoto2, jamcam library\n"
                  "%d %d\n"
                  "255\n", jc_file->width, jc_file->height );

            ptr = ppm + strlen( ppm );

            size = strlen( ppm ) + ( jc_file->width * jc_file->height * 3 );

            gp_bayer_decode( raw, jc_file->width, jc_file->height, ptr,
                  BAYER_TILE_GBRG );
            gp_gamma_fill_table( gtable, 0.5 );
            gp_gamma_correct_single( gtable, ptr, jc_file->width * jc_file->height );

            CHECK_free (gp_file_set_mime_type (file, GP_MIME_PPM));
            CHECK_free (gp_file_set_name (file, filename));
            CHECK_free (gp_file_append (file, ppm, size));
            break;

      case GP_FILE_TYPE_RAW:
            CHECK_free (jamcam_request_image (camera, file, raw, &size, n, context));
            CHECK_free (gp_file_set_mime_type (file, GP_MIME_RAW));
            strcpy( tmp_filename, filename );
            tmp_filename[strlen(tmp_filename)-3] = 'r';
            tmp_filename[strlen(tmp_filename)-2] = 'a';
            tmp_filename[strlen(tmp_filename)-1] = 'w';
            CHECK_free (gp_file_set_name (file, tmp_filename));
            CHECK_free (gp_file_append (file, raw, size));
            break;
      default:
            free(raw); free(ppm);
            return (GP_ERROR_NOT_SUPPORTED);
      }
      free(raw); free(ppm);
      return (GP_OK);
}

static int camera_summary (Camera *camera, CameraText *summary, GPContext *context)
{
      int count;
      char tmp[1024];

      GP_DEBUG ("* camera_summary");

      /* possibly get # pics, mem free, etc. */
      count = jamcam_file_count (camera);

      sprintf (tmp, _("Frames Taken     : %4d\n"), count);
      strcat (summary->text, tmp );

      return (GP_OK);
}

static int camera_about (Camera *camera, CameraText *about, GPContext *context)
{
      GP_DEBUG ("* camera_about");

      strcpy (about->text,
            _("jamcam library v" JAMCAM_VERSION
            " " JAMCAM_LAST_MOD "\n"
            "Chris Pinkham <cpinkham@infi.net>\n"
            "Support for KBGear JamCam v2.0 & v3.0 digital cameras\n"
            "based on reverse engineering serial protocol.\n"
            "\n"));

      return (GP_OK);
}

static CameraFilesystemFuncs fsfuncs = {
      .file_list_func = file_list_func,
      .get_file_func = get_file_func,
      .get_info_func = get_info_func,
};

int camera_init (Camera *camera, GPContext *context)
{
      int count;
      GPPortSettings settings;

      GP_DEBUG ("* camera_init");
      GP_DEBUG ("   * jamcam library for Gphoto2 by Chris Pinkham <cpinkham@infi.net>");
      GP_DEBUG ("   * jamcam library v%s, %s", JAMCAM_VERSION, JAMCAM_LAST_MOD );

      /* First, set up all the function pointers */
      camera->functions->exit       = camera_exit;
      camera->functions->summary    = camera_summary;
      camera->functions->about      = camera_about;

      CHECK (gp_port_get_settings (camera->port, &settings));
      switch( camera->port->type ) {
      case GP_PORT_SERIAL:
            settings.serial.speed    = 57600;
            settings.serial.bits     = 8;
            settings.serial.parity   = 0;
            settings.serial.stopbits = 1;
            break;
      case GP_PORT_USB:
            /* Use the defaults the core parsed */
            break;
      default:
            fprintf( stderr, "Unknown port type: %d\n", camera->port->type );
            return ( GP_ERROR );
            break;
      }
      CHECK (gp_port_set_settings (camera->port, settings));
      CHECK (gp_port_set_timeout (camera->port, TIMEOUT));

      /* check to see if camera is really there */
      CHECK (jamcam_enq (camera));

      /* get number of images */
      CHECK (count = jamcam_file_count (camera));

      /* Set up the CameraFilesystem */
      return gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
}


Generated by  Doxygen 1.6.0   Back to index