Ejemplo n.º 1
0
Archivo: _sane.c Proyecto: Bouke/Pillow
static void
SaneDev_dealloc(SaneDevObject *self)
{
  if (self->h) sane_close(self->h);
  self->h=NULL;
  PyObject_DEL(self);
}
Ejemplo n.º 2
0
static void deAlloc (_ScanDevice * self)
{
    if (self->h)
        sane_close (self->h);

    self->h = NULL;
    PyObject_DEL (self);
}
Ejemplo n.º 3
0
Archivo: _sane.c Proyecto: Bouke/Pillow
static PyObject *
SaneDev_close(SaneDevObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ""))
    return NULL;
  if (self->h) sane_close(self->h);
  self->h=NULL;
  Py_INCREF(Py_None);
  return (Py_None);
}
Ejemplo n.º 4
0
static void
sane_idadone(void *data)
{
    struct sane_state *h = data;

    sane_cancel(h->sane);
    sane_close(h->sane);
    sane_exit();
    free(h->buf);
    free(h);
}
Ejemplo n.º 5
0
void
sane_exit (void)
{
  struct device *dev;

  for (dev = devices_head; dev; dev = dev->next)
    if (dev->dn != -1)
      sane_close(dev); /* implies flush */
  
  free_devices ();
}
Ejemplo n.º 6
0
static PyObject *closeScan (_ScanDevice * self, PyObject * args)
{
    if (!PyArg_ParseTuple (args, ""))
        return NULL;

    if (self->h)
        sane_close (self->h);

    self->h = NULL;
    Py_INCREF (Py_None);
    return (Py_None);
}
Ejemplo n.º 7
0
void
sane_exit (void)
{
  DBG (DBG_proc, "sane_exit: enter\n");

  while (first_dev)
    {
      sane_close (first_dev);
    }

  if (devlist)
    {
      free (devlist);
      devlist = NULL;
    }

  DBG (DBG_proc, "sane_exit: exit\n");
}
Ejemplo n.º 8
0
void
sane_exit( void )
{
	ST400_Device *dev;

	DBG(DCODE, "sane_exit()\n");

	while( (dev = st400_devices) != NULL ) {
		st400_devices = dev->next;

		sane_close(dev);
		free((char *)(dev->sane.name));
		free(dev);
	}
	st400_num_devices = 0;
	if( st400_device_array ) {
		DBG(DCODE, "sane_exit: freeing device array\n");
		free(st400_device_array);
		st400_device_array = NULL;
		st400_status.array_valid = 0;
	}
}
Ejemplo n.º 9
0
/** Function Configs_Modify
 *  @brief   oyCMMapi8_s SANE scanner manipulation
 *
 *  @version Oyranos: 0.1.10
 *  @since   2009/01/19 (Oyranos: 0.1.10)
 *  @date    2009/08/21
 *
 *  \todo { Test }
 */
int Configs_Modify(oyConfigs_s * devices, oyOptions_s * options)
{
   oyOption_s *version_opt = NULL;
   oyOption_s *version_opt_dev = NULL;
   oyConfig_s *device = NULL;
   int num_devices, g_error = 0;
   int call_sane_exit = 0;
   const char *command_list = NULL,
              *command_properties = NULL;

   oyAlloc_f allocateFunc = malloc;

   printf(PRFX "Entering %s(). Options:\n%s", __func__, oyOptions_GetText(options, oyNAME_NICK));

   /* "error handling" section */
   if (!devices || !oyConfigs_Count(devices)) {
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "No devices given! Options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK) );
      return 1;
   }

   /* "help" call section */
   if (oyOptions_FindString(options, "command", "help") || !options || !oyOptions_Count(options)) {
    /** oyMSG_WARN should make shure our message is visible. */
      ConfigsFromPatternUsage((oyStruct_s *) options);
      return 0;
   }

   num_devices = oyConfigs_Count(devices);
   command_list = oyOptions_FindString(options, "command", "list");
   command_properties = oyOptions_FindString(options, "command", "properties");

   /* Now we get some options [IN], and we already have some devices with
    * possibly already assigned options. Those provided through the input
    * oyOptions_s should take presedence over ::data & ::backend_core ones.
    * OTOH, all device_* options have a 1-1 relationship meaning if
    * one changes, probably all other should. So the simplest [naive] approach
    * would be to ignore all device_* options [IN] that are already in device.
    * Except from driver_version which has a special meaning.
    */

   /* Handle "driver_version" option [IN] */
   /* Check the first device to see if a positive driver_version is provided. */
   /* If not, consult the input options */
   device = oyConfigs_Get(devices, 0);
   version_opt_dev = oyConfig_Find(device, "driver_version");
   if (version_opt_dev && oyOption_GetValueInt(version_opt_dev, 0) > 0)
      call_sane_exit = 0;
   else
      check_driver_version(options, &version_opt, &call_sane_exit);
   oyConfig_Release(&device);
   oyOption_Release(&version_opt_dev);

   if (command_list) {
      /* "list" call section */
      int i;

      for (i = 0; i < num_devices; ++i) {
         const SANE_Device *device_context = NULL;
         SANE_Status status = SANE_STATUS_INVAL;
         oyOption_s *name_opt_dev = NULL,
                    *handle_opt_dev = NULL,
                    *context_opt_dev = NULL;
         const char *sane_name = NULL,
                    *sane_model = NULL;
         int error = 0;

         device = oyConfigs_Get(devices, i);

         if(oyOptions_Count(*oyConfig_GetOptions(device,"backend_core")))
           printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK));
         if(oyOptions_Count(*oyConfig_GetOptions(device,"data")))
           printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK));

         /*Ignore device without a device_name*/
         if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_name\" is missing from config object!");
            oyConfig_Release(&device);
            g_error++;
            continue;
         }

         /*Handle "driver_version" option [OUT] */
         version_opt_dev = oyConfig_Find(device, "driver_version");
         if (!version_opt_dev && version_opt)
            oyOptions_MoveIn(*oyConfig_GetOptions(device,"backend_core"), &version_opt, -1);
         oyOption_Release(&version_opt_dev);

         /*Handle "device_context" option */
         /*This is always provided by Configs_FromPattern()
          * [or should be alternatively by the user].
          * Configs_Modify() will not scan for SANE devices
          * because it takes too long*/
         context_opt_dev = oyConfig_Find(device, "device_context");
         if (!context_opt_dev) {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_context\" option is missing!");
            error = g_error = 1;
         }
         if (!error) {
            device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc);
            sane_name  = device_context->name;
            sane_model = device_context->model;
         }

         /*Handle "oyNAME_NAME" option */
         name_opt_dev = oyConfig_Find(device, "oyNAME_NAME");
         if (!error && !name_opt_dev && oyOptions_Find(options, "oyNAME_NAME", oyNAME_PATTERN))
            oyOptions_SetFromString(oyConfig_GetOptions(device,"backend_core"),
                                  CMM_BASE_REG OY_SLASH "oyNAME_NAME",
                                  sane_model,
                                  OY_CREATE_NEW);

         /*Handle "device_handle" option */
         handle_opt_dev = oyConfig_Find(device, "device_handle");
         if (!error && !handle_opt_dev) {
            oyPointer_s *handle_ptr = NULL;
            SANE_Handle h;
            status = sane_open(sane_name, &h);
            if (status == SANE_STATUS_GOOD) {
               handle_ptr = oyPointer_New(0);
               oyPointer_Set(handle_ptr,
                            "SANE",
                            "handle",
                            (oyPointer)h,
                            "sane_release_handle",
                            sane_release_handle);
               oyOptions_MoveInStruct(oyConfig_GetOptions(device,"data"),
                                      CMM_BASE_REG OY_SLASH "device_handle",
                                      (oyStruct_s **) &handle_ptr, OY_CREATE_NEW);
            } else
               printf(PRFX "Unable to open sane device \"%s\": %s\n", sane_name, sane_strstatus(status));
         }

         /*Create static rank_map, if not already there*/
         if (!oyConfig_GetRankMap( device))
           oyConfig_SetRankMap( device, _api8.rank_map );

         /*Cleanup*/
         oyConfig_Release(&device);
         oyOption_Release(&context_opt_dev);
         oyOption_Release(&name_opt_dev);
         oyOption_Release(&handle_opt_dev);
      }
   } else if (command_properties) {
      /* "properties" call section */
      int i;

      /*Return a full list of scanner H/W &
       * SANE driver S/W color options
       * with the according rank map */

      for (i = 0; i < num_devices; ++i) {
         SANE_Device *device_context = NULL;
         SANE_Status status = SANE_STATUS_INVAL;
         SANE_Handle device_handle;
         oyOption_s *name_opt_dev = NULL,
                    *handle_opt_dev = NULL,
                    *context_opt_dev = NULL;
         oyConfig_s *device_new = NULL;
         char *device_name = NULL;

         /* All previous device properties are considered obsolete
          * and a new device is created. Basic options are moved from
          * the old to new device */
         device = oyConfigs_Get(devices, i);
         device_new = oyConfig_FromRegistration(CMM_BASE_REG, 0);

         printf(PRFX "Backend core:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"backend_core"), oyNAME_NICK));
         printf(PRFX "Data:\n%s", oyOptions_GetText(*oyConfig_GetOptions(device,"data"), oyNAME_NICK));

         /*Ignore device without a device_name*/
         if (!oyOptions_FindString(*oyConfig_GetOptions(device,"backend_core"), "device_name", NULL)) {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_name\" is NULL, or missing from config object!");
            oyConfig_Release(&device);
            oyConfig_Release(&device_new);
            g_error++;
            continue;
         }

         /*Handle "driver_version" option [OUT] */
         if (version_opt) {
            oyOption_s *tmp = oyOption_Copy(version_opt, 0);
            oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &tmp, -1);
         }

         /* 1. Get the "device_name" from old device */
         name_opt_dev = oyConfig_Find(device, "device_name");
         device_name = oyOption_GetValueText(name_opt_dev, allocateFunc);
         oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"backend_core"), &name_opt_dev, -1);

         /* 2. Get the "device_context" from old device */
         /* It should be there, see "list" call above */
         context_opt_dev = oyConfig_Find(device, "device_context");
         if (context_opt_dev) {
            device_context = (SANE_Device*)oyOption_GetData(context_opt_dev, NULL, allocateFunc);
            if (device_context) {
               oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &context_opt_dev, -1);
            } else {
               SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                       _DBG_ARGS_, "The \"device_context\" is NULL!");
               oyOption_Release(&context_opt_dev);
               g_error++;
            }
         } else {
            SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ ": %s\n",
                    _DBG_ARGS_, "The \"device_context\" option is missing!");
            g_error++;
         }

         /* 3. Get the scanner H/W properties from old device */
         /* FIXME: we only recompute them, just in case they are not in old device */
         if (device_context) {
            DeviceInfoFromContext_(device_context, oyConfig_GetOptions(device_new,"backend_core"));
         }

         /* 4. Get the "device_handle" from old device */
         /* If not there, get one from SANE */
         handle_opt_dev = oyConfig_Find(device, "device_handle");
         if (handle_opt_dev) {
           oyPointer_s * oy_struct = (oyPointer_s*)oyOption_GetStruct(
                                           handle_opt_dev, oyOBJECT_POINTER_S );
           device_handle = (SANE_Handle)oyPointer_GetPointer(oy_struct);
           oyPointer_Release( &oy_struct );
            oyOptions_MoveIn(*oyConfig_GetOptions(device_new,"data"), &handle_opt_dev, -1);
         } else {
            printf(PRFX "Opening sane device \"%s\"..", device_name); fflush(NULL);
            status = sane_open( device_name, &device_handle );
            if (status != SANE_STATUS_GOOD)
               printf("[FAIL: %s]\n", sane_strstatus(status));
            else
               printf("[OK]\n");
         }

         if (handle_opt_dev || status == SANE_STATUS_GOOD) {
            /* Use the device_handle to get the device color options */
            ColorInfoFromHandle(device_handle, oyConfig_GetOptions(device_new,"backend_core"));

            /*5. Set the rank map*/
            oyConfig_SetRankMap( device_new, _api8.rank_map );
         }

         /*Cleanup*/
         /* Remove old, add new device */
         oyConfig_Release(&device);
         oyConfigs_ReleaseAt(devices, i);
         oyConfigs_MoveIn(devices, &device_new, -1);

         /*If we had to open a SANE device, we'll have to close it*/
         if (status == SANE_STATUS_GOOD) {
            printf(PRFX "sane_close(%s)\n", device_name);
            sane_close(device_handle);
         }

         free(device_context);
         free(device_name);
      }
   } else {
      /*unsupported, wrong or no command */
      SANE_msg(oyMSG_WARN, (oyStruct_s *) options, _DBG_FORMAT_ "\n "
              "No supported commands in options:\n%s", _DBG_ARGS_,
              oyOptions_GetText(options, oyNAME_NICK) );
      ConfigsFromPatternUsage((oyStruct_s *) options);
      g_error = 1;
   }

   /*Cleanup*/
   if (call_sane_exit) {
      printf(PRFX "sane_exit()\n");
      sane_exit();
   }

   oyOption_Release(&version_opt);

   printf(PRFX "Leaving %s\n", __func__);
   return g_error;
}
Ejemplo n.º 10
0
// --------------------------------------------------------------
void ControlsWindow::MessageReceived
	(
	BMessage *	msg
	)
{
	switch (msg->what)
		{
		case SET_DEVICE_MSG:
			{
			ssize_t 			data_size;
			SANE_Status			status;
			const SANE_Device *	device_info;
			
			if ( msg->FindData("device", B_RAW_TYPE, (const void **) &device_info, &data_size) != B_OK )
				break;
					
			m_device_info = device_info;
					
			if ( m_device )
				sane_close(m_device);
			m_device 		= NULL;
			
			ScannerOptionView * option;
			BView *	child;

			child = m_panel->ChildAt(0);
			while ( child )
				{
				option = dynamic_cast<ScannerOptionView *>(child);
				if ( option )
					option->RemoveSelf();
			
				child = child->NextSibling();
				};
				
			status = sane_open(m_device_info->name, &m_device);
			if ( status != SANE_STATUS_GOOD )
				{
			 	fprintf (stderr, "sane_open: %s\n", sane_strstatus (status));

				BAlert * alert = new BAlert("sane_open", sane_strstatus(status), "Argh");
				alert->Go();
				break;
				};


			const SANE_Option_Descriptor *	desc;
			
			// m_options_lv->MakeEmpty();
			printf("Options for device %s:\n", m_device_info->name);
			int opt = 1;	// skip first option (option 0 = number of options)
			BRect r = m_panel->Bounds();
			r.top = 80;
			r.InsetBy(8, 8);

			while ( (desc = sane_get_option_descriptor(m_device, opt)) != NULL )
				{
				if (desc->type != SANE_TYPE_GROUP)
					{
					ScannerOptionView * ov = new ScannerOptionView(r, desc->name, B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT, 0,
																m_device, opt);
					if ( ov->Build() == B_OK )
						{
						m_panel->AddChild(ov);
						r.top += ov->Bounds().Height();
						m_tooltip->SetText(ov, desc->desc);
						}
					else
						delete ov;
					};

				BString label;
				if (desc->type == SANE_TYPE_GROUP)
					label << "-- ";
				label << desc->title;
				if (desc->type == SANE_TYPE_GROUP)
					label << " --";

				printf("  %d: name = %s\n"
				       "      title = %s\n"
				       "      desc = %s\n"
				       "      type = %d\n"
				       "      unit = %s\n"
					   "      size = %d\n"
				       "      cap  = 0x%0x\n", opt, desc->name, desc->title, desc->desc,
						desc->type, get_unit2(desc->unit), desc->size, desc->cap);


				// m_options_lv->AddItem(new BStringItem(label.String()));

				opt++;
				};

			BMessage * msg;
		
			msg = new BMessage(MainWindow::DEVICE_CHANGED_MSG);
			msg->AddString("device_name", m_device_info->name);
			
			m_parent_window->PostMessage(msg);
			delete msg;
			break;
			};
			
		case SCAN_MSG:
			{
			SANE_Handle		device;
			
			device = Device();
						
			if ( ! device )
				break;
				
			if ( m_scan_thread_id != -1 )
				{
				// already launched...
				m_cancel_scan = true;
				break;
				};
			
			m_cancel_scan = false;

			m_scan_thread_id = spawn_thread(_ScanThread, "scan", B_NORMAL_PRIORITY, this);
			resume_thread(m_scan_thread_id);
			break;
			};	
		
		default:	
			inherited::MessageReceived(msg);
	}
}
Ejemplo n.º 11
0
// --------------------------------------------------------------
ControlsWindow::~ControlsWindow()
{
	if ( m_device )
		sane_close(m_device);
}
Ejemplo n.º 12
0
/* Open device, return the device handle */
SANE_Status
sane_open (SANE_String_Const devname, SANE_Handle * handle)
{
  unsigned i, j, id = 0;
  struct scanner *s;
  SANE_Int h, bus;
  SANE_Status st = SANE_STATUS_GOOD;
  if (!devlist)
    {
      st = sane_get_devices (NULL, 0);
      if (st)
	return st;
    }
  for (i = 0; devlist[i]; i++)
    {
      if (!strcmp (devlist[i]->name, devname))
	break;
    }
  if (!devlist[i])
    return SANE_STATUS_INVAL;
  for (j = 0; j < sizeof (known_devices) / sizeof (known_devices[0]); j++)
    {
      if (!strcmp (devlist[i]->model, known_devices[j].scanner.model))
	{
	  id = known_devices[j].id;
	  break;
	}
    }

  st = sanei_usb_open (devname, &h);

  if (st == SANE_STATUS_ACCESS_DENIED)
    return st;
  if (st)
    {
      st = sanei_scsi_open (devname, &h, kvs40xx_sense_handler, NULL);
      if (st)
	{
	  return st;
	}
      bus = SCSI;
    }
  else
    {
      bus = USB;
      st = sanei_usb_claim_interface (h, 0);
      if (st)
	{
	  sanei_usb_close (h);
	  return st;
	}
    }

  s = malloc (sizeof (struct scanner));
  if (!s)
    return SANE_STATUS_NO_MEM;
  memset (s, 0, sizeof (struct scanner));
  s->buffer = malloc (MAX_READ_DATA_SIZE + BULK_HEADER_SIZE);
  if (!s->buffer)
    return SANE_STATUS_NO_MEM;

  s->file = h;
  s->bus = bus;
  s->id = id;
  strcpy (s->name, devname);
  *handle = s;
  for (i = 0; i < 3; i++)
    {
      st = kvs40xx_test_unit_ready (s);
      if (st)
	{
	  if (s->bus == SCSI)
	    {
	      sanei_scsi_close (s->file);
	      st = sanei_scsi_open (devname, &h, kvs40xx_sense_handler, NULL);
	      if (st)
		return st;
	    }
	  else
	    {
	      sanei_usb_release_interface (s->file, 0);
	      sanei_usb_close (s->file);
	      st = sanei_usb_open (devname, &h);
	      if (st)
		return st;
	      st = sanei_usb_claim_interface (h, 0);
	      if (st)
		{
		  sanei_usb_close (h);
		  return st;
		}
	    }
	  s->file = h;
	}
      else
	break;
    }
  if (i == 3)
    return SANE_STATUS_DEVICE_BUSY;

  if (id == KV_S4085C || id == KV_S4065C)
    {
      char str[16];
      st = inquiry (s, str);
      if (st)
	goto err;
      if (id == KV_S4085C)
	s->id = !strcmp (str, "KV-S4085CL") ? KV_S4085CL : KV_S4085CW;
      else
	s->id = !strcmp (str, "KV-S4065CL") ? KV_S4065CL : KV_S4065CW;
    }
  kvs40xx_init_options (s);
  st = kvs40xx_set_timeout (s, s->val[FEED_TIMEOUT].w);
  if (st)
    goto err;

  return SANE_STATUS_GOOD;
err:
  sane_close (s);
  return st;
}
Ejemplo n.º 13
0
static void*
sane_idainit(FILE *fp, char *filename, unsigned int page, struct ida_image_info *info,
             int thumbnail)
{
    const SANE_Option_Descriptor *opt;
    SANE_Int flags, count;
    struct sane_state *h;
    int rc,i,value,dpi = 0;

    h = malloc(sizeof(*h));
    memset(h,0,sizeof(*h));

    if (SANE_STATUS_GOOD != (rc = sane_init(NULL,NULL))) {
        fprintf(stderr,"sane_init: %s\n",sane_strstatus(rc));
        goto oops;
    }
    if (SANE_STATUS_GOOD != (rc = sane_open(filename,&h->sane))) {
        fprintf(stderr,"sane_open: %s\n",sane_strstatus(rc));
        goto oops;
    }

    /* set options */
    opt = sane_get_option_descriptor(h->sane,0);
    rc = sane_control_option(h->sane, 0, SANE_ACTION_GET_VALUE,
                             &count, &flags);
    for (i = 1; i < count; i++) {
        opt = sane_get_option_descriptor(h->sane,i);
        if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_TL_X)) {
            value = opt->constraint.range->min;
            sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE,
                                &value, &flags);
        } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_TL_Y)) {
            value = opt->constraint.range->min;
            sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE,
                                &value, &flags);
        } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_BR_X)) {
            value = opt->constraint.range->max;
            sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE,
                                &value, &flags);
        } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_BR_Y)) {
            value = opt->constraint.range->max;
            sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE,
                                &value, &flags);
        } else if (opt->name && 0 == strcmp(opt->name,SANE_NAME_PREVIEW)) {
            value = SANE_FALSE;
            sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE,
                                &value, &flags);
        } else if (opt->cap & SANE_CAP_AUTOMATIC)
            sane_control_option(h->sane, i, SANE_ACTION_SET_AUTO,
                                NULL, &flags);
        if (opt->name && 0 == strcmp(opt->name,SANE_NAME_SCAN_RESOLUTION)) {
            if (sane_res) {
                dpi = sane_res;
                sane_control_option(h->sane, i, SANE_ACTION_SET_VALUE,
                                    &dpi, &flags);
            }
            sane_control_option(h->sane, i, SANE_ACTION_GET_VALUE,
                                &dpi, &flags);
        }
        if (debug)
            dump_desc(h->sane,i,opt);
    }

    if (SANE_STATUS_GOOD != (rc = sane_start(h->sane))) {
        fprintf(stderr,"sane_start: %s\n",sane_strstatus(rc));
        goto oops;
    }
    h->started = 1;

    if (SANE_STATUS_GOOD != (rc = sane_get_parameters(h->sane,&h->parm))) {
        fprintf(stderr,"sane_get_parameters: %s\n",sane_strstatus(rc));
        goto oops;
    }

    if (h->parm.format != SANE_FRAME_GRAY &&
            h->parm.format != SANE_FRAME_RGB) {
        fprintf(stderr,"sane: unsupported frame format (%d)\n",h->parm.format);
        goto oops;
    }
    if (h->parm.depth != 8) {
        fprintf(stderr,"sane: unsupported color depth (%d)\n",h->parm.depth);
        goto oops;
    }
    if (-1 == h->parm.lines) {
        fprintf(stderr,"sane: can't handle unknown image size\n");
        goto oops;
    }

    info->width  = h->parm.pixels_per_line;
    info->height = h->parm.lines;
    if (dpi)
        info->dpi  = dpi;
    h->buf = malloc(h->parm.bytes_per_line * BUF_LINES);
    if (debug)
        fprintf(stderr,"sane: scanning %dx%d %s\n",info->width,info->height,
                (h->parm.format == SANE_FRAME_GRAY) ? "gray" : "color");

    return h;

oops:
    if (h->buf)
        free(h->buf);
    if (h->started)
        sane_cancel(h->sane);
    if (h->sane)
        sane_close(h->sane);
    sane_exit();
    free(h);
    return NULL;
}
Ejemplo n.º 14
0
extern char *internalGetScannerDetails(char *device, char *lang) {

  char *answer = NULL;
  SANE_Status status;
  char *deviceList = o_strdup("");; 
  int hlp = 0, resolution = 300, minRes=50, maxRes=50, phashAvailable=0;
  char *resolution_s, *maxRes_s, *minRes_s;
  SANE_Handle *openDeviceHandle;

  o_log(DEBUGM, "sane_open of \"%s\"", device);
  status = sane_open (device, (SANE_Handle)&openDeviceHandle);
  if(status != SANE_STATUS_GOOD) {
    o_log(ERROR, "Could not open: '%s' with error: %s", device, sane_strstatus(status));
    free(deviceList);
    return NULL;
  }


  //
  // Find resolution ranges
  //
  for (hlp = 0; hlp < 9999; hlp++) {

    const SANE_Option_Descriptor *sod;

    sod = sane_get_option_descriptor (openDeviceHandle, hlp);
    if (sod == NULL)
      break;

    // Just a placeholder
    if (sod->type == SANE_TYPE_GROUP
    || sod->name == NULL
    || hlp == 0)
      continue;

    if ( 0 == strcmp(sod->name, SANE_NAME_SCAN_RESOLUTION) ) {

      // Some kind of sliding range
      if (sod->constraint_type == SANE_CONSTRAINT_RANGE) {
        o_log(DEBUGM, "Resolution setting detected as 'range'");

        // Fixed resolution
        if (sod->type == SANE_TYPE_FIXED)
          maxRes = (int)SANE_UNFIX (sod->constraint.range->max);
        else
          maxRes = sod->constraint.range->max;
      }

      // A fixed list of options
      else if (sod->constraint_type == SANE_CONSTRAINT_WORD_LIST) {
        int lastIndex = sod->constraint.word_list[0];
        o_log(DEBUGM, "Resolution setting detected as 'word list': lastIndex = %d",lastIndex);

        // maxRes = sod->constraint.word_list[lastIndex];
        // resolution list cannot be treated as low to high ordered list 
        // remark: impl capability to select scan resolution in webInterface
        int n=0;
        maxRes = 0;
        for (n=1; n<=lastIndex; n++ ) {
          o_log(DEBUGM, "index results %d --> %d", n ,(int)sod->constraint.word_list[n]);
          if ( maxRes < sod->constraint.word_list[n] ) {
            maxRes=sod->constraint.word_list[n];
          }
        }

      }

      break; // we've found our resolution - no need to search more
    }
  }
  o_log(DEBUGM, "Determined max resultion to be %d", maxRes);


  // Define a default
  if(resolution >= maxRes)
    resolution = maxRes;
  if(resolution <= minRes)
    resolution = minRes;

  o_log(DEBUGM, "sane_cancel");
  sane_cancel(openDeviceHandle);

  o_log(DEBUGM, "sane_close");
  sane_close(openDeviceHandle);



  //
  // What languages can we OCR for?
  //
  char *availableLangs = o_strdup("");
#ifdef CAN_OCR
  struct simpleLinkedList *languages = getOCRAvailableLanguages();
  while (languages != NULL ) {
    if ( checkOCRLanguage( languages->data ) == 0 ) {
      o_concatf(&availableLangs, "<lang>%s</lang>", languages->data);
    }
    languages = sll_getNext(languages);
  }
  sll_destroy( languages );
#endif /* CAN_OCR */


  //
  // Can we give the option of doing 'find simmilar'?
  //
#ifdef CAN_PHASH
  phashAvailable = 1;
#endif /* CAN_PHASH */

  // Build Reply
  //
  resolution_s = itoa(resolution,10);
  maxRes_s = itoa(maxRes,10);
  minRes_s = itoa(minRes,10);

  o_concatf(&deviceList, "<Resolution><max>%s</max><min>%s</min><default>%s</default></Resolution><OCRLanguages>%s</OCRLanguages><phash>%d</phash>", maxRes_s, minRes_s, resolution_s, availableLangs, phashAvailable);

  free(maxRes_s);
  free(minRes_s);
  free(resolution_s);
  free(availableLangs);

  // The escaped string placeholder will be interprited in the sane dispatcher client
  answer = o_printf("<?xml version='1.0' encoding='utf-8'?>\n<Response><ScannerDetails>%s</ScannerDetails></Response>", deviceList);
  free(deviceList);

  return answer;

}
Ejemplo n.º 15
0
char *internalDoScanningOperation(char *uuid, char *lang) {

  int request_resolution = 0;
  int docid;
  int current_page = 0;
  int total_requested_pages;
  double totbytes = 0;
  SANE_Status status;
  SANE_Handle *openDeviceHandle;
  SANE_Byte *raw_image;
  SANE_Parameters pars;
  char *docid_s;
  char *total_requested_pages_s;
  char *devName;
  char *outFilename;
  char *raw_image_format;
  char *header;

  o_log(DEBUGM, "doScanningOperation: sane initialized uuid(%s)",(char *)uuid);
  updateScanProgress(uuid, SCAN_WAITING_ON_SCANNER, 0);

  // Open the device
  devName = getScanParam(uuid, SCAN_PARAM_DEVNAME);
  o_log(DEBUGM, "sane_open of \"%s\"",devName);
  status = sane_open ((SANE_String_Const) devName, (SANE_Handle)&openDeviceHandle);
  if(status != SANE_STATUS_GOOD) {
    handleSaneErrors("Cannot open device ", devName, status, 0);
    updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status);
    free(devName);
    return 0;
  }
  free(devName);

  /* ========================================================== */
  if ( ! setOptions( (char *)uuid, openDeviceHandle, &request_resolution ) )
    return 0;
  o_log(DEBUGM, "sane_start: setOptions returned request_resolution %d\n",request_resolution);

  int timeout = 5;
  while( 0 < timeout ) {
    status = sane_start (openDeviceHandle);
    if(status == SANE_STATUS_GOOD) {  
      break;
    }
    else {
      if(status == SANE_STATUS_DEVICE_BUSY ) {  
        // BUSY signal could be the scanner just having a 
        // bit of lag - specially network connected devices
        timeout--;
        if ( timeout == 0 ) {
          handleSaneErrors("Cannot start scanning", "even after trying several time", status, 0);
          updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status);
          return 0;
        }
        else {
          o_log(WARNING, "Device reports not ready to 'start', waiting 500ms. Will try another %d times", timeout);
          usleep(500 * 1000); // 500ms or 0.5sec
        }
      }
      else {
        handleSaneErrors("Cannot start scanning", "", status, 0);
        updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status);
        return 0;
      }
    }
  }

  // Get scanning params (from the scanner)
  if( request_resolution == 0 ) {
    o_log(DEBUGM, "Resolution did not get set in scanner setup.");
    updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10004);
    return 0;
  }

  o_log(DEBUGM, "Get scanning params");
  status = sane_get_parameters (openDeviceHandle, &pars);
  o_log(INFORMATION, "Scanner Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d",
    sane_strstatus (status),
    pars.format, pars.last_frame,
    pars.bytes_per_line, pars.pixels_per_line,
    pars.lines, pars.depth);

  switch (pars.format) {
    case SANE_FRAME_GRAY:
      o_log(DEBUGM, "Expecting Gray data (1 channel only).");
      raw_image_format = o_strdup( "P5" );
      break;
    case SANE_FRAME_RGB:
      o_log(DEBUGM, "Expecting RGB data (3 channels).");
      raw_image_format = o_strdup( "P6" );
      break;
    default:
      o_log(DEBUGM, "backend returns three frames speratly. We do not currently support this.");
      updateScanProgress(uuid, SCAN_INTERNAL_ERROR, 10003);
      return 0;
      break;
  }
  
  header = o_printf ("%s\n# SANE data follows\n%d %d\n%d\n", 
    raw_image_format, pars.pixels_per_line, pars.lines,
    (pars.depth <= 8) ? 255 : 65535);
  free( raw_image_format );


  // Save Record
  //
  docid_s = getScanParam(uuid, SCAN_PARAM_DOCID);
  total_requested_pages_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_PAGES);
  total_requested_pages = atoi(total_requested_pages_s);
  free(total_requested_pages_s);
  if( docid_s == NULL ) {
    o_log(DEBUGM, "Saving record");
    updateScanProgress(uuid, SCAN_DB_WORKING, 0);

    docid_s = addNewScannedDoc(pars.lines, pars.pixels_per_line, request_resolution, total_requested_pages); 
    setScanParam(uuid, SCAN_PARAM_DOCID, docid_s);
    setScanParam(uuid, SCAN_PARAM_ON_PAGE, "1");
    current_page = 1;
  }
  else {
    char *current_page_s = getScanParam(uuid, SCAN_PARAM_ON_PAGE);
    current_page = atoi(current_page_s);
    free(current_page_s);

    current_page++;

    current_page_s = itoa(current_page, 10);
    setScanParam(uuid, SCAN_PARAM_ON_PAGE, current_page_s);
    free(current_page_s);
  }
  docid = atoi(docid_s);
  free(docid_s);

  totbytes = (double)((pars.bytes_per_line * pars.lines));

  /* ========================================================== */
  raw_image = collectData( (char *)uuid, openDeviceHandle, totbytes, pars.bytes_per_line, header );
  o_log(INFORMATION, "Scanning done.");

  o_log(DEBUGM, "sane_cancel");
  sane_cancel(openDeviceHandle);

  o_log(DEBUGM, "sane_close");
  sane_close(openDeviceHandle);


  // Convert Raw into JPEG
  //
  updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 0);
  PIX *pix;
  if ( ( pix = pixReadMem( raw_image, (pars.bytes_per_line*pars.lines)+strlen(header) ) ) == NULL) {
    o_log(ERROR, "Could not load the image data into a PIX");
  }
  updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 55);
  o_log(INFORMATION, "Convertion process: Loaded (depth: %d)", pixGetDepth(pix));
  free(raw_image);
  free(header);

  outFilename = o_printf("%s/scans/%d_%d.jpg", BASE_DIR, docid, current_page);
  pixWrite(outFilename, pix, IFF_JFIF_JPEG);
  free(outFilename);
  updateScanProgress(uuid, SCAN_CONVERTING_FORMAT, 100);
  o_log(INFORMATION, "Conversion process: Complete");




  // Do OCR - on this page
  // - OCR libs just wants the raw data and not the image header
  ocrImage( uuid, docid, current_page, request_resolution, pix, lang );


#ifdef CAN_PHASH
  // Calulate the pHash, so we can compare images later
  if( current_page == 1 ) {
    updateScanProgress(uuid, SCAN_CALULATING_PHASH, 0);
    unsigned long long hash = getImagePhash_px( pix );
    savePhash( docid, hash );
  }
#endif /* CAN_PHASH */
  pixDestroy( &pix );


  // cleaup && What should we do next
  //
  o_log(DEBUGM, "mostly done.");
  if(current_page >= total_requested_pages)
    updateScanProgress(uuid, SCAN_FINISHED, docid);
  else
    updateScanProgress(uuid, SCAN_WAITING_ON_NEW_PAGE, ++current_page);

  o_log(DEBUGM, "Page scan done.");

  return o_strdup("OK"); 
}
Ejemplo n.º 16
0
void
testsane (const char *dev_name)
{
  int hlp, x;
  SANE_Status bla;
  SANE_Int blubb;
  SANE_Handle hand;
  SANE_Parameters pars;
  const SANE_Option_Descriptor *sod;
  const SANE_Device **device_list;
  char buffer[2048];

  bla = sane_init (&blubb, auth_callback);
  fprintf (stderr, "Init : stat=%d ver=%x\nPress Enter to continue...",
	   bla, blubb);
  getchar ();
  if (bla != SANE_STATUS_GOOD)
    return;

  bla = sane_get_devices (&device_list, SANE_FALSE);
  fprintf (stderr, "GetDev : stat=%s\n", sane_strstatus (bla));
  if (bla != SANE_STATUS_GOOD)
    return;

  bla = sane_open (dev_name, &hand);
  fprintf (stderr, "Open : stat=%s hand=%p\n", sane_strstatus (bla), hand);
  if (bla != SANE_STATUS_GOOD)
    return;

  bla = sane_set_io_mode (hand, 0);
  fprintf (stderr, "SetIoMode : stat=%s\n", sane_strstatus (bla));

  for (hlp = 0; hlp < 9999; hlp++)
    {
      sod = sane_get_option_descriptor (hand, hlp);
      if (sod == NULL)
	break;
      fprintf (stderr, "Gopt(%d) : stat=%p\n", hlp, sod);
      fprintf (stderr, "name : %s\n", sod->name);
      fprintf (stderr, "title: %s\n", sod->title);
      fprintf (stderr, "desc : %s\n", sod->desc);

      fprintf (stderr, "type : %d\n", sod->type);
      fprintf (stderr, "unit : %d\n", sod->unit);
      fprintf (stderr, "size : %d\n", sod->size);
      fprintf (stderr, "cap  : %d\n", sod->cap);
      fprintf (stderr, "ctyp : %d\n", sod->constraint_type);
      switch (sod->constraint_type)
	{
	case SANE_CONSTRAINT_NONE:
	  break;
	case SANE_CONSTRAINT_STRING_LIST:
	  fprintf (stderr, "stringlist:\n");
	  break;
	case SANE_CONSTRAINT_WORD_LIST:
	  fprintf (stderr, "wordlist (%d) : ", sod->constraint.word_list[0]);
	  for (x = 1; x <= sod->constraint.word_list[0]; x++)
	    fprintf (stderr, " %d ", sod->constraint.word_list[x]);
	  fprintf (stderr, "\n");
	  break;
	case SANE_CONSTRAINT_RANGE:
	  fprintf (stderr, "range: %d-%d %d \n", sod->constraint.range->min,
		   sod->constraint.range->max, sod->constraint.range->quant);
	  break;
	}
    }

  bla = sane_get_parameters (hand, &pars);
  fprintf (stderr,
	   "Parm : stat=%s form=%d,lf=%d,bpl=%d,pixpl=%d,lin=%d,dep=%d\n",
	   sane_strstatus (bla),
	   pars.format, pars.last_frame,
	   pars.bytes_per_line, pars.pixels_per_line,
	   pars.lines, pars.depth);
  if (bla != SANE_STATUS_GOOD)
    return;

  bla = sane_start (hand);
  fprintf (stderr, "Start : stat=%s\n", sane_strstatus (bla));
  if (bla != SANE_STATUS_GOOD)
    return;

  do
    {
      bla = sane_read (hand, buffer, sizeof (buffer), &blubb);
      /*printf("Read : stat=%s len=%d\n",sane_strstatus (bla),blubb); */
      if (bla != SANE_STATUS_GOOD)
	{
	  if (bla == SANE_STATUS_EOF)
	    break;
	  return;
	}
      fwrite (buffer, 1, blubb, stdout);
    }
  while (1);

  sane_cancel (hand);
  fprintf (stderr, "Cancel.\n");

  sane_close (hand);
  fprintf (stderr, "Close\n");

  for (hlp = 0; hlp < 20; hlp++)
    fprintf (stderr, "STRS %d=%s\n", hlp, sane_strstatus (hlp));

  fprintf (stderr, "Exit.\n");
}