Example #1
0
static SANE_Status
attach_one_device (SANE_String_Const devname)
{
  Mustek_Usb_Device *dev;
  SANE_Status status;

  RIE (attach (devname, &dev, SANE_FALSE));

  if (dev)
    {
      /* Keep track of newly attached devices so we can set options as
         necessary.  */
      if (new_dev_len >= new_dev_alloced)
	{
	  new_dev_alloced += 4;
	  if (new_dev)
	    new_dev =
	      realloc (new_dev, new_dev_alloced * sizeof (new_dev[0]));
	  else
	    new_dev = malloc (new_dev_alloced * sizeof (new_dev[0]));
	  if (!new_dev)
	    {
	      DBG (1, "attach_one_device: out of memory\n");
	      return SANE_STATUS_NO_MEM;
	    }
	}
      new_dev[new_dev_len++] = dev;
    }
  return SANE_STATUS_GOOD;
}
Example #2
0
enum vmmerr
cpu_emul_realmode_int (u8 num)
{
	u16 seg, off;
	ulong rflags, rip;
	u16 cs;
	ulong idtr_base, idtr_limit;
	struct cpu_stack st;

	/* FIXME: IDTR LIMIT CHECK */
	/* FIXME: stack limit check */
	current->vmctl.read_idtr (&idtr_base, &idtr_limit);
	RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 0, &off));
	RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 2, &seg));
	current->vmctl.read_flags (&rflags);
	current->vmctl.read_sreg_sel (SREG_CS, &cs);
	current->vmctl.read_ip (&rip);
	RIE (cpu_stack_get (&st));
	RIE (cpu_stack_push (&st, &rflags, OPTYPE_16BIT));
	RIE (cpu_stack_push (&st, &cs, OPTYPE_16BIT));
	RIE (cpu_stack_push (&st, &rip, OPTYPE_16BIT));
	current->vmctl.write_realmode_seg (SREG_CS, seg);
	current->vmctl.write_ip (off);
	rflags &= ~(RFLAGS_TF_BIT | RFLAGS_AC_BIT);
	current->vmctl.write_flags (rflags);
	RIE (cpu_stack_set (&st));
	cpu_emul_cli ();
	return VMMERR_SUCCESS;
}
Example #3
0
SANE_Status
sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
{
  Mustek_Usb_Scanner *s = handle;
  SANE_Status status;

  DBG (5, "sane_get_parameters: start\n");

  RIE (calc_parameters (s));
  if (params)
    *params = s->params;

  DBG (5, "sane_get_parameters: exit\n");

  return SANE_STATUS_GOOD;
}
Example #4
0
enum vmmerr
cpu_emul_realmode_int (u8 num)
{
	u16 seg, off;
	ulong rflags, rip;
	u16 cs;
	ulong idtr_base, idtr_limit;
	struct cpu_stack st;

	/* FIXME: IDTR LIMIT CHECK */
	/* FIXME: stack limit check */
	current->vmctl.read_idtr (&idtr_base, &idtr_limit);
	RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 0, &off));
	RIE (read_linearaddr_w (idtr_base + ((u32)num << 2) + 2, &seg));
	current->vmctl.read_flags (&rflags);
	current->vmctl.read_sreg_sel (SREG_CS, &cs);
	current->vmctl.read_ip (&rip);
#ifdef DISABLE_TCG_BIOS
	if (num == 0x1A) {
		ulong rax;

		current->vmctl.read_general_reg (GENERAL_REG_RAX, &rax);
		rax &= 0xFFFF;
		if (rax == 0xBB00) {	/* TCG_StatusCheck function */
			current->vmctl.write_flags (rflags | RFLAGS_CF_BIT);
			return VMMERR_SUCCESS;
		}
	}
#endif /* DISABLE_TCG_BIOS */
	RIE (cpu_stack_get (&st));
	RIE (cpu_stack_push (&st, &rflags, OPTYPE_16BIT));
	RIE (cpu_stack_push (&st, &cs, OPTYPE_16BIT));
	RIE (cpu_stack_push (&st, &rip, OPTYPE_16BIT));
	current->vmctl.write_realmode_seg (SREG_CS, seg);
	current->vmctl.write_ip (off);
	rflags &= ~(RFLAGS_TF_BIT | RFLAGS_AC_BIT);
	current->vmctl.write_flags (rflags);
	RIE (cpu_stack_set (&st));
	cpu_emul_cli ();
	return VMMERR_SUCCESS;
}
Example #5
0
SANE_Status
sane_open (SANE_String_Const devicename, SANE_Handle * handle)
{
  Mustek_Usb_Device *dev;
  SANE_Status status;
  Mustek_Usb_Scanner *s;
  SANE_Int value;

  DBG (5, "sane_open: start (devicename = `%s')\n", devicename);

  if (devicename[0])
    {
      for (dev = first_dev; dev; dev = dev->next)
	if (strcmp (dev->sane.name, devicename) == 0)
	  break;

      if (!dev)
	{
	  DBG (5,
	       "sane_open: couldn't find `%s' in devlist, trying attach)\n",
	       devicename);
	  RIE (attach (devicename, &dev, SANE_TRUE));
	}
      else
	DBG (5, "sane_open: found `%s' in devlist\n", dev->name);
    }
  else
    {
      /* empty devicname -> use first device */
      dev = first_dev;
      if (dev)
	DBG (5, "sane_open: empty devicename, trying `%s'\n", dev->name);
    }

  if (!dev)
    return SANE_STATUS_INVAL;

  if (dev->chip->scanner_type == MT_UNKNOWN)
    {
      DBG (0, "sane_open: the type of your scanner is unknown, edit "
	   "mustek_usb.conf before using the scanner\n");
      return SANE_STATUS_INVAL;
    }
  s = malloc (sizeof (*s));
  if (!s)
    return SANE_STATUS_NO_MEM;
  memset (s, 0, sizeof (*s));
  s->hw = dev;

  RIE (init_options (s));

  /* insert newly opened handle into list of open handles: */
  s->next = first_handle;
  first_handle = s;

  *handle = s;
  strcpy (s->hw->device_name, dev->name);

  RIE (usb_high_scan_turn_power (s->hw, SANE_TRUE));
  RIE (usb_high_scan_back_home (s->hw));

  s->hw->scan_buffer = (SANE_Byte *) malloc (SCAN_BUFFER_SIZE * 2);
  if (!s->hw->scan_buffer)
    {
      DBG (5, "sane_open: couldn't malloc s->hw->scan_buffer (%d bytes)\n",
	   SCAN_BUFFER_SIZE * 2);
      return SANE_STATUS_NO_MEM;
    }
  s->hw->scan_buffer_len = 0;
  s->hw->scan_buffer_start = s->hw->scan_buffer;

  s->hw->temp_buffer = (SANE_Byte *) malloc (SCAN_BUFFER_SIZE);
  if (!s->hw->temp_buffer)
    {
      DBG (5, "sane_open: couldn't malloc s->hw->temp_buffer (%d bytes)\n",
	   SCAN_BUFFER_SIZE);
      return SANE_STATUS_NO_MEM;
    }
  s->hw->temp_buffer_len = 0;
  s->hw->temp_buffer_start = s->hw->temp_buffer;

  for (value = 0; value < 256; value++)
    {
      s->linear_gamma_table[value] = value;
      s->red_gamma_table[value] = value;
      s->green_gamma_table[value] = value;
      s->blue_gamma_table[value] = value;
      s->gray_gamma_table[value] = value;
    }

  s->red_table = s->linear_gamma_table;
  s->green_table = s->linear_gamma_table;
  s->blue_table = s->linear_gamma_table;
  s->gray_table = s->linear_gamma_table;

  DBG (5, "sane_open: exit\n");

  return SANE_STATUS_GOOD;
}
Example #6
0
static SANE_Status
init_options (Mustek_Usb_Scanner * s)
{
  SANE_Int option;
  SANE_Status status;

  DBG (5, "init_options: start\n");

  memset (s->opt, 0, sizeof (s->opt));
  memset (s->val, 0, sizeof (s->val));

  for (option = 0; option < NUM_OPTIONS; ++option)
    {
      s->opt[option].size = sizeof (SANE_Word);
      s->opt[option].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
    }
  s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
  s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
  s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
  s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;

  /* "Mode" group: */
  s->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan Mode");
  s->opt[OPT_MODE_GROUP].desc = "";
  s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_MODE_GROUP].size = 0;
  s->opt[OPT_MODE_GROUP].cap = 0;
  s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* scan mode */
  mode_list[0] = SANE_VALUE_SCAN_MODE_COLOR;
  mode_list[1] = SANE_VALUE_SCAN_MODE_GRAY;
  mode_list[2] = SANE_VALUE_SCAN_MODE_LINEART;
  mode_list[3] = NULL;

  s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
  s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
  s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
  s->opt[OPT_MODE].type = SANE_TYPE_STRING;
  s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
  s->opt[OPT_MODE].size = max_string_size (mode_list);
  s->opt[OPT_MODE].constraint.string_list = mode_list;
  s->val[OPT_MODE].s = strdup (mode_list[1]);

  /* resolution */
  s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
  s->opt[OPT_RESOLUTION].type = SANE_TYPE_FIXED;
  s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI;
  s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_RESOLUTION].constraint.range = &s->hw->dpi_range;
  s->val[OPT_RESOLUTION].w = s->hw->dpi_range.min;
  if (s->hw->chip->scanner_type == MT_600CU)
    s->hw->dpi_range.max = SANE_FIX (600);
  else
    s->hw->dpi_range.max = SANE_FIX (1200);

  /* preview */
  s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
  s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
  s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
  s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
  s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
  s->val[OPT_PREVIEW].w = SANE_FALSE;

  /* "Geometry" group: */
  s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry");
  s->opt[OPT_GEOMETRY_GROUP].desc = "";
  s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
  s->opt[OPT_GEOMETRY_GROUP].size = 0;
  s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* top-left x */
  s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
  s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
  s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
  s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
  s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
  s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_TL_X].constraint.range = &s->hw->x_range;
  s->val[OPT_TL_X].w = 0;

  /* top-left y */
  s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
  s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
  s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
  s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
  s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
  s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_TL_Y].constraint.range = &s->hw->y_range;
  s->val[OPT_TL_Y].w = 0;

  /* bottom-right x */
  s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
  s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
  s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
  s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
  s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
  s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_BR_X].constraint.range = &s->hw->x_range;
  s->val[OPT_BR_X].w = s->hw->x_range.max;

  /* bottom-right y */
  s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
  s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
  s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
  s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
  s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
  s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_BR_Y].constraint.range = &s->hw->y_range;
  s->val[OPT_BR_Y].w = s->hw->y_range.max;

  /* "Enhancement" group: */
  s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement");
  s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
  s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
  s->opt[OPT_ENHANCEMENT_GROUP].size = 0;
  s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
  s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;

  /* threshold */
  s->opt[OPT_THRESHOLD].name = SANE_NAME_THRESHOLD;
  s->opt[OPT_THRESHOLD].title = SANE_TITLE_THRESHOLD;
  s->opt[OPT_THRESHOLD].desc = SANE_DESC_THRESHOLD;
  s->opt[OPT_THRESHOLD].type = SANE_TYPE_INT;
  s->opt[OPT_THRESHOLD].unit = SANE_UNIT_NONE;
  s->opt[OPT_THRESHOLD].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_THRESHOLD].constraint.range = &u8_range;
  s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
  s->val[OPT_THRESHOLD].w = 128;

  /* custom-gamma table */
  s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
  s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
  s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;

  /* gray gamma vector */
  s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
  s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR].wa = &s->gray_gamma_table[0];

  /* red gamma vector */
  s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
  s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_R].wa = &s->red_gamma_table[0];

  /* green gamma vector */
  s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
  s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_G].wa = &s->green_gamma_table[0];

  /* blue gamma vector */
  s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
  s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
  s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
  s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
  s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
  s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
  s->val[OPT_GAMMA_VECTOR_B].wa = &s->blue_gamma_table[0];

  RIE (calc_parameters (s));

  DBG (5, "init_options: exit\n");
  return SANE_STATUS_GOOD;
}
Example #7
0
SANE_Status
sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
	   SANE_Int * len)
{
  Mustek_Usb_Scanner *s = handle;
  SANE_Word lines_to_read, lines_read;
  SANE_Status status;

  DBG (5, "sane_read: start\n");

  if (!s)
    {
      DBG (1, "sane_read: handle is null!\n");
      return SANE_STATUS_INVAL;
    }

  if (!buf)
    {
      DBG (1, "sane_read: buf is null!\n");
      return SANE_STATUS_INVAL;
    }

  if (!len)
    {
      DBG (1, "sane_read: len is null!\n");
      return SANE_STATUS_INVAL;
    }

  *len = 0;

  if (!s->scanning)
    {
      DBG (3, "sane_read: scan was cancelled, is over or has not been "
	   "initiated yet\n");
      return SANE_STATUS_CANCELLED;
    }

  if (s->hw->scan_buffer_len == 0)
    {
      if (s->read_rows > 0)
	{
	  lines_to_read = SCAN_BUFFER_SIZE / (s->hw->width * s->hw->bpp / 8);
	  if (lines_to_read > s->read_rows)
	    lines_to_read = s->read_rows;
	  s->hw->temp_buffer_start = s->hw->temp_buffer;
	  s->hw->temp_buffer_len = (s->hw->width * s->hw->bpp / 8)
	    * lines_to_read;
	  DBG (4, "sane_read: reading %d source lines\n", lines_to_read);
	  RIE (usb_high_scan_get_rows (s->hw, s->hw->temp_buffer,
				       lines_to_read, SANE_FALSE));
	  RIE (fit_lines (s, s->hw->temp_buffer, s->hw->scan_buffer,
			  lines_to_read, &lines_read));
	  s->read_rows -= lines_to_read;
	  if ((s->total_lines + lines_read) > s->height_dots)
	    lines_read = s->height_dots - s->total_lines;
	  s->total_lines += lines_read;
	  DBG (4, "sane_read: %d destination lines, %d total\n",
	       lines_read, s->total_lines);
	  s->hw->scan_buffer_start = s->hw->scan_buffer;
	  s->hw->scan_buffer_len = (s->width_dots * s->bpp / 8) * lines_read;
	}
      else
	{
	  DBG (4, "sane_read: scan finished -- exit\n");
	  return SANE_STATUS_EOF;
	}
    }
  if (s->hw->scan_buffer_len == 0)
    {
      DBG (4, "sane_read: scan finished -- exit\n");
      return SANE_STATUS_EOF;
    }

  *len = MIN (max_len, (SANE_Int) s->hw->scan_buffer_len);
  memcpy (buf, s->hw->scan_buffer_start, *len);
  DBG (4, "sane_read: exit, read %d bytes from scan_buffer; "
       "%ld bytes remaining\n", *len,
       (long int) (s->hw->scan_buffer_len - *len));
  s->hw->scan_buffer_len -= (*len);
  s->hw->scan_buffer_start += (*len);
  s->total_bytes += (*len);
  return SANE_STATUS_GOOD;
}
Example #8
0
SANE_Status
sane_start (SANE_Handle handle)
{
  Mustek_Usb_Scanner *s = handle;
  SANE_Status status;
  SANE_String val;
  Colormode color_mode;
  SANE_Word dpi, x, y, width, height;

  DBG (5, "sane_start: start\n");

  /* First make sure we have a current parameter set.  Some of the
     parameters will be overwritten below, but that's OK.  */

  s->total_bytes = 0;
  s->total_lines = 0;
  RIE (calc_parameters (s));

  if (s->width_dots <= 0)
    {
      DBG (0, "sane_start: top left x > bottom right x --- exiting\n");
      return SANE_STATUS_INVAL;
    }
  if (s->height_dots <= 0)
    {
      DBG (0, "sane_start: top left y > bottom right y --- exiting\n");
      return SANE_STATUS_INVAL;
    }


  val = s->val[OPT_MODE].s;
  if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART))
    color_mode = GRAY8;
  else if (!strcmp (val, SANE_VALUE_SCAN_MODE_GRAY))
    color_mode = GRAY8;
  else				/* Color */
    color_mode = RGB24;

  dpi = SANE_UNFIX (s->val[OPT_RESOLUTION].w);
  x = s->tl_x_dots;
  y = s->tl_y_dots;
  width = s->width_dots;
  height = s->height_dots;

  if (!s->hw->is_prepared)
    {
      RIE (usb_high_scan_prepare (s->hw));
      RIE (usb_high_scan_reset (s->hw));
    }
  RIE (usb_high_scan_set_threshold (s->hw, 128));
  RIE (usb_high_scan_embed_gamma (s->hw, NULL));
  RIE (usb_high_scan_suggest_parameters (s->hw, dpi, x, y, width, height,
					 color_mode));
  RIE (usb_high_scan_setup_scan (s->hw, s->hw->scan_mode, s->hw->x_dpi,
				 s->hw->y_dpi, 0, s->hw->x, s->hw->y,
				 s->hw->width));

  DBG (3, "sane_start: wanted: dpi=%d, x=%d, y=%d, width=%d, height=%d, "
       "scan_mode=%d\n", dpi, x, y, width, height, color_mode);
  DBG (3, "sane_start: got: x_dpi=%d, y_dpi=%d, x=%d, y=%d, width=%d, "
       "height=%d, scan_mode=%d\n", s->hw->x_dpi, s->hw->y_dpi, s->hw->x,
       s->hw->y, s->hw->width, s->hw->height, s->hw->scan_mode);

  s->scanning = SANE_TRUE;
  s->read_rows = s->hw->height;
  s->hw->line_switch = s->hw->height;
  s->hw->line_offset = 0;
  s->hw->scan_buffer_len = 0;

  DBG (5, "sane_start: exit\n");
  return SANE_STATUS_GOOD;
}
Example #9
0
SANE_Status
sane_control_option (SANE_Handle handle, SANE_Int option,
		     SANE_Action action, void *val, SANE_Int * info)
{
  Mustek_Usb_Scanner *s = handle;
  SANE_Status status;
  SANE_Word cap;
  SANE_Int myinfo = 0;

  DBG (5, "sane_control_option: start: action = %s, option = %s (%d)\n",
       (action == SANE_ACTION_GET_VALUE) ? "get" :
       (action == SANE_ACTION_SET_VALUE) ? "set" :
       (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown",
       s->opt[option].name, option);

  if (info)
    *info = 0;

  if (s->scanning)
    {
      DBG (1, "sane_control_option: don't call this function while "
	   "scanning\n");
      return SANE_STATUS_DEVICE_BUSY;
    }

  if (option >= NUM_OPTIONS || option < 0)
    {
      DBG (1, "sane_control_option: option %d >= NUM_OPTIONS || option < 0\n",
	   option);
      return SANE_STATUS_INVAL;
    }

  cap = s->opt[option].cap;

  if (!SANE_OPTION_IS_ACTIVE (cap))
    {
      DBG (2, "sane_control_option: option %d is inactive\n", option);
      return SANE_STATUS_INVAL;
    }

  if (action == SANE_ACTION_GET_VALUE)
    {
      switch (option)
	{
	  /* word options: */
	case OPT_NUM_OPTS:
	case OPT_RESOLUTION:
	case OPT_PREVIEW:
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_X:
	case OPT_BR_Y:
	case OPT_THRESHOLD:
	case OPT_CUSTOM_GAMMA:
	  *(SANE_Word *) val = s->val[option].w;
	  break;
	  /* word-array options: */
	case OPT_GAMMA_VECTOR:
	case OPT_GAMMA_VECTOR_R:
	case OPT_GAMMA_VECTOR_G:
	case OPT_GAMMA_VECTOR_B:
	  memcpy (val, s->val[option].wa, s->opt[option].size);
	  break;
	  /* string options: */
	case OPT_MODE:
	  strcpy (val, s->val[option].s);
	  break;
	default:
	  DBG (2, "sane_control_option: can't get unknown option %d\n",
	       option);
	}
    }
  else if (action == SANE_ACTION_SET_VALUE)
    {
      if (!SANE_OPTION_IS_SETTABLE (cap))
	{
	  DBG (2, "sane_control_option: option %d is not settable\n", option);
	  return SANE_STATUS_INVAL;
	}

      status = sanei_constrain_value (s->opt + option, val, &myinfo);

      if (status != SANE_STATUS_GOOD)
	{
	  DBG (2, "sane_control_option: sanei_constrain_value returned %s\n",
	       sane_strstatus (status));
	  return status;
	}

      switch (option)
	{
	  /* (mostly) side-effect-free word options: */
	case OPT_RESOLUTION:
	case OPT_TL_X:
	case OPT_TL_Y:
	case OPT_BR_X:
	case OPT_BR_Y:
	  s->val[option].w = *(SANE_Word *) val;
	  RIE (calc_parameters (s));
	  myinfo |= SANE_INFO_RELOAD_PARAMS;
	  break;
	case OPT_THRESHOLD:
	  s->val[option].w = *(SANE_Word *) val;
	  break;
	  /* Boolean */
	case OPT_PREVIEW:
	  s->val[option].w = *(SANE_Bool *) val;
	  break;
	  /* side-effect-free word-array options: */
	case OPT_GAMMA_VECTOR:
	case OPT_GAMMA_VECTOR_R:
	case OPT_GAMMA_VECTOR_G:
	case OPT_GAMMA_VECTOR_B:
	  memcpy (s->val[option].wa, val, s->opt[option].size);
	  check_gamma_table (s->val[option].wa);
	  break;
	case OPT_CUSTOM_GAMMA:
	  s->val[OPT_CUSTOM_GAMMA].w = *(SANE_Word *) val;
	  myinfo |= SANE_INFO_RELOAD_OPTIONS;
	  if (s->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
	    {
	      s->red_table = s->red_gamma_table;
	      s->green_table = s->green_gamma_table;
	      s->blue_table = s->blue_gamma_table;
	      s->gray_table = s->gray_gamma_table;
	      if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
		s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
	      else if (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
		{
		  s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
		}
	    }
	  else
	    {
	      s->red_table = s->linear_gamma_table;
	      s->green_table = s->linear_gamma_table;
	      s->blue_table = s->linear_gamma_table;
	      s->gray_table = s->linear_gamma_table;
	      s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	      s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
	    }
	  break;
	case OPT_MODE:
	  if (s->val[option].s)
	    free (s->val[option].s);
	  s->val[option].s = strdup (val);

	  RIE (calc_parameters (s));

	  s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
	  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;

	  if (strcmp (val, SANE_VALUE_SCAN_MODE_LINEART) == 0)
	    {
	      s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
	    }
	  else
	    {
	      s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
	      if (s->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
		{
		  s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
		  s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
		}
	    }
	  myinfo |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
	  break;
	default:
	  DBG (2, "sane_control_option: can't set unknown option %d\n",
	       option);
	}
    }
  else
    {
      DBG (2, "sane_control_option: unknown action %d for option %d\n",
	   action, option);
      return SANE_STATUS_INVAL;
    }
  if (info)
    *info = myinfo;

  DBG (5, "sane_control_option: exit\n");
  return SANE_STATUS_GOOD;
}