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

library.c

/* library.c
 *
 * Copyright (C) 2003 Theodore Kilgore <kilgota@auburn.edu>
 *
 * 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 <stdlib.h>
#include <stdio.h>
#include <string.h>

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

#include <gphoto2.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

#include "aox.h"
#include <gphoto2-port.h>

#define GP_MODULE "aox"

struct _CameraPrivateLibrary {
      Model model;
      Info info[2];
};

struct {
      char *name;
      CameraDriverStatus status;
      unsigned short idVendor;
      unsigned short idProduct;
} models[] = {
        {"Concord EyeQMini_1", GP_DRIVER_STATUS_EXPERIMENTAL, 0x03e8, 0x2182},
        {"Concord EyeQMini_2", GP_DRIVER_STATUS_EXPERIMENTAL, 0x03e8, 0x2180},      
      {NULL,0,0}
};

int
camera_id (CameraText *id)
{
      strcpy (id->text, "Aox chipset camera");
      return GP_OK;
}

int
camera_abilities (CameraAbilitiesList *list)
{
      int i;    
      CameraAbilities a;

      for (i = 0; models[i].name; i++) {
            memset (&a, 0, sizeof(a));
                  strcpy (a.model, models[i].name);
                  a.status = models[i].status;
                  a.port   = GP_PORT_USB;
                  a.speed[0] = 0;
                  a.usb_vendor = models[i].idVendor;
                  a.usb_product= models[i].idProduct;
                  if (a.status == GP_DRIVER_STATUS_EXPERIMENTAL)
                  a.operations = GP_OPERATION_NONE;
            else
                  a.operations = GP_OPERATION_CAPTURE_IMAGE;
                  a.folder_operations = GP_FOLDER_OPERATION_NONE;
                  a.file_operations   = GP_FILE_OPERATION_PREVIEW; 
                  gp_abilities_list_append (list, a);
      }
      return GP_OK;
}

static int
camera_summary (Camera *camera, CameraText *summary, GPContext *context)
{

      int num_lo_pics =aox_get_num_lo_pics(camera->pl->info);
      int num_hi_pics =aox_get_num_hi_pics(camera->pl->info);     

      sprintf (summary->text,_("Your USB camera has an Aox chipset.\n" 
                  "Number of lo-res PICs = %i\n"
                  "Number of hi-res PICs = %i\n"      
                  "Number of PICs = %i\n"
                        ), num_lo_pics, num_hi_pics, num_lo_pics+num_hi_pics);  

      return GP_OK;
}


static int
camera_about (Camera *camera, CameraText *about, GPContext *context)
{
      strcpy (about->text, _("Aox generic driver\n"
                      "Theodore Kilgore <kilgota@auburn.edu>\n"));
      return GP_OK;
}

/*************** File and Downloading Functions *******************/

static int
file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
                void *data, GPContext *context)
{
        Camera *camera = data; 
      int num_lo_pics = aox_get_num_lo_pics (camera->pl->info);
      int num_hi_pics = aox_get_num_hi_pics (camera->pl->info);
      int n = num_hi_pics + num_lo_pics;
      char name[n];
      int i;      
      /* Low-resolution pictures are always downloaded first. We do not know 
       * yet how to process them, so they will remain in RAW format. */
      
      for (i=0; i< num_lo_pics; i++){
            sprintf( name, "aox_pic%03i.raw", i+1 );
            gp_list_append(list, name, NULL);   
      }

      for (i = num_lo_pics; i < n; i++){
            sprintf( name, "aox_pic%03i.ppm", i+1 );        
            gp_list_append(list, name, NULL);   
      }
      return GP_OK;
}

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; 

/* The camera will always download the low-resolution pictures first, if any.
 * As those are JPEG compressed, they are not of fixed size. Unfortunately, 
 * their JPEG format seems to be not quite standard. 
 * For a high-resolution picture, the size is always the same. 
 * Every picture file has a header, which is of length 0x98. The high-
 * resolution pictures are just Bayer data; their headers will be discarded.  
 */

        int i, j, k, n, num_lo_pics, num_hi_pics, w = 0, h = 0;   
      unsigned char temp;
      unsigned char *data;
      unsigned char *p_data = NULL;
      unsigned char *output = NULL;     
      int len;
      int header_len;
      char header[128]; 
      unsigned char gtable[256];

      k = gp_filesystem_number(camera->fs, "/", filename, context);
      num_lo_pics = aox_get_num_lo_pics(camera->pl->info);
      num_hi_pics = aox_get_num_hi_pics(camera->pl->info);

      if ( (k < num_lo_pics) ) { 
            n = k; 
            w = 320;
            h = 240;
      } else {
            n = k - num_lo_pics;
            w = 640;    
            h = 480;
      }

      len = aox_get_picture_size (camera->port, num_lo_pics, 
                                    num_hi_pics, n, k);
      GP_DEBUG("len = %i\n", len);
      data = malloc(len);
      if (!data) {
            printf("Malloc failed\n"); return 0;}
      aox_read_picture_data (camera->port, data, len, n);

      switch (type) {
      case GP_FILE_TYPE_PREVIEW:
      case GP_FILE_TYPE_NORMAL:
            if ((w == 320)) {
                  gp_file_detect_mime_type (file); /* Detected as "raw"*/
                  gp_file_set_data_and_size (file, data, len);
                  gp_file_adjust_name_for_mime_type (file);
            }
            if ((w == 640)){
                  /* Stripping useless header */
                  p_data = data + 0x98;
                  /* Picture is mirror-imaged.*/
                  for (i = 0; i < h; ++i) {
                        for (j = 0 ; j < w/2; j++) { 
                              temp = p_data[w*i +j];
                              p_data[w*i +j] = p_data[w*i+ w -1 -j];
                              p_data[w*i + w  - 1 - j] = temp;
                        }
                  }     
                  /* Not only this, but some columns are 
                   * interchanged, too. */
                  for (i = 0; i < w*h/4; i++) {
                        temp = p_data[4*i +1];
                        p_data[4*i + 1] = p_data[4*i+2];
                        p_data[4*i+2] = temp;
                  }
                  GP_DEBUG("size of data = %i\n", sizeof(data));
                  GP_DEBUG("size of p_data = %i\n", sizeof(p_data));
                  /* And now create a ppm file, with our own header */
                  header_len = snprintf(header, 127, 
                        "P6\n" 
                        "# CREATOR: gphoto2, aox library\n" 
                        "%d %d\n" 
                        "255\n", w, h);

                  output = malloc(3*w*h);
                  if (output) {
                        gp_bayer_decode (p_data, w, h, 
                              output, BAYER_TILE_GRBG);
                        /* gamma correction of .65 may not be optimal. */
                        gp_gamma_fill_table (gtable, .65);
                        gp_gamma_correct_single (gtable, output, w * h);
                        gp_file_set_mime_type (file, GP_MIME_PPM);
                        gp_file_append (file, header, header_len);
                        gp_file_append (file, output, 3*w*h);
                  }
            }
            free (data);
            free (output);
            break;
      case GP_FILE_TYPE_RAW:
            gp_file_set_data_and_size (file, data, len);
            gp_file_set_mime_type (file, GP_MIME_RAW);
            gp_file_adjust_name_for_mime_type(file);
            free(data);
            break;
      default:
            return (GP_ERROR_NOT_SUPPORTED);    

      }

      return GP_OK;
}

/*************** Exit and Initialization Functions ******************/

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

      if (camera->pl) {
            free (camera->pl);
            camera->pl = NULL;
      }

      return GP_OK;
}

int
camera_init(Camera *camera, GPContext *context)
{
      GPPortSettings settings;
      int ret = 0;

      /* First, set up all the function pointers */
      camera->functions->summary      = camera_summary;
      camera->functions->about        = camera_about;
      camera->functions->exit     = camera_exit;
   
      GP_DEBUG ("Initializing the camera\n");
      ret = gp_port_get_settings(camera->port,&settings);
      if (ret < 0) return ret; 

      switch (camera->port->type) {
            case GP_PORT_SERIAL:
                  return ( GP_ERROR );
            case GP_PORT_USB:
                  settings.usb.config = 1;
                  settings.usb.altsetting = 0;
                  settings.usb.interface = 1;
                  settings.usb.inep = 0x84;
                  settings.usb.outep =0x05;
                  break;
            default:
                  return ( GP_ERROR );
      }

      ret = gp_port_set_settings(camera->port,settings);
      if (ret < 0) return ret; 

      GP_DEBUG("interface = %i\n", settings.usb.interface);
      GP_DEBUG("inep = %x\n", settings.usb.inep);     
      GP_DEBUG("outep = %x\n", settings.usb.outep);

        /* Tell the CameraFilesystem where to get lists from */
      gp_filesystem_set_list_funcs (camera->fs, file_list_func, NULL, camera);
      gp_filesystem_set_file_funcs (camera->fs, get_file_func, NULL, camera);

      camera->pl = malloc (sizeof (CameraPrivateLibrary));
      if (!camera->pl) return GP_ERROR_NO_MEMORY;
      memset (camera->pl, 0, sizeof (CameraPrivateLibrary));

      /* Connect to the camera */
      aox_init (camera->port, &camera->pl->model, camera->pl->info);

      return GP_OK;
}

Generated by  Doxygen 1.6.0   Back to index