예제 #1
0
/* 
 * Wait until the scanner is ready.
 */
static SANE_Status
leo_wait_scanner (Leo_Scanner * dev)
{
  SANE_Status status;
  int timeout;
  CDB cdb;

  DBG (DBG_proc, "leo_wait_scanner: enter\n");

  MKSCSI_TEST_UNIT_READY (cdb);

  /* Set the timeout to 60 seconds. */
  timeout = 60;

  while (timeout > 0)
    {

      /* test unit ready */
      status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
				NULL, 0, NULL, NULL);

      if (status == SANE_STATUS_GOOD)
	{
	  return SANE_STATUS_GOOD;
	}

      sleep (1);
    };

  DBG (DBG_proc, "leo_wait_scanner: scanner not ready\n");
  return (SANE_STATUS_IO_ERROR);
}
예제 #2
0
/* Return the number of byte that can be read. */
static SANE_Status
get_filled_data_length (Leo_Scanner * dev, size_t * to_read)
{
  size_t size;
  CDB cdb;
  SANE_Status status;

  DBG (DBG_proc, "get_filled_data_length: enter\n");

  *to_read = 0;

  size = 0x10;
  MKSCSI_GET_DATA_BUFFER_STATUS (cdb, 1, size);
  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
			    NULL, 0, dev->buffer, &size);

  if (size != 0x10)
    {
      DBG (DBG_error,
	   "get_filled_data_length: GET DATA BUFFER STATUS returned an invalid size (%ld)\n",
	   (long) size);
      return SANE_STATUS_IO_ERROR;
    }

  hexdump (DBG_info2, "get_filled_data_length return", dev->buffer, size);

  *to_read = B24TOI (&dev->buffer[9]);

  DBG (DBG_info, "get_filled_data_length: to read = %ld\n", (long) *to_read);

  DBG (DBG_proc, "get_filled_data_length: exit, status=%d\n", status);

  return (status);
}
예제 #3
0
/* Read the size of the scan. */
static SANE_Status
leo_get_scan_size (Leo_Scanner * dev)
{
  size_t size;
  CDB cdb;
  SANE_Status status;

  DBG (DBG_proc, "leo_get_scan_size: enter\n");

  size = 0x10;
  MKSCSI_GET_DATA_BUFFER_STATUS (cdb, 1, size);
  hexdump (DBG_info2, "CDB:", cdb.data, cdb.len);
  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
			    NULL, 0, dev->buffer, &size);

  if (size != 0x10)
    {
      DBG (DBG_error,
	   "leo_get_scan_size: GET DATA BUFFER STATUS returned an invalid size (%ld)\n",
	   (long) size);
      return SANE_STATUS_IO_ERROR;
    }

  hexdump (DBG_info2, "leo_get_scan_size return", dev->buffer, size);


  dev->params.pixels_per_line = B16TOI (&dev->buffer[14]);

  /* The number of lines if the number of lines left plus the number
   * of lines already waiting in the buffer. */
  dev->params.lines = B16TOI (&dev->buffer[12]) +
    (B24TOI (&dev->buffer[9]) / dev->params.bytes_per_line);

  switch (dev->scan_mode)
    {
    case LEO_BW:
    case LEO_HALFTONE:
      dev->params.pixels_per_line &= ~0x7;
      dev->params.bytes_per_line = dev->params.pixels_per_line / 8;
      break;
    case LEO_GRAYSCALE:
      dev->params.bytes_per_line = dev->params.pixels_per_line;
      break;
    case LEO_COLOR:
      dev->params.bytes_per_line = dev->params.pixels_per_line * 3;
      break;
    }

  DBG (DBG_proc, "leo_get_scan_size: exit, status=%d\n", status);

  DBG (DBG_proc, "lines=%d, bpl=%d\n", dev->params.lines,
       dev->params.bytes_per_line);

  return (status);
}
예제 #4
0
/* Start a scan. */
static SANE_Status
leo_scan (Leo_Scanner * dev)
{
  CDB cdb;
  SANE_Status status;

  DBG (DBG_proc, "leo_scan: enter\n");

  MKSCSI_SCAN (cdb);

  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len, NULL, 0, NULL, NULL);

  DBG (DBG_proc, "leo_scan: exit, status=%d\n", status);

  return status;
}
예제 #5
0
파일: epkowa_scsi.c 프로젝트: hean01/iscan
int
sanei_epson_scsi_write (int fd, const void *buf, size_t buf_size,
			SANE_Status * status)
{
  u_char *cmd;

  cmd = t_alloca (8 + buf_size, u_char);
  memset (cmd, 0, 8);
  cmd[0] = WRITE_6_COMMAND;
  cmd[2] = buf_size >> 16;
  cmd[3] = buf_size >> 8;
  cmd[4] = buf_size;
  memcpy (cmd + 8, buf, buf_size);

  if (SANE_STATUS_GOOD ==
      (*status = sanei_scsi_cmd2 (fd, cmd, 6, cmd + 8, buf_size, NULL, NULL)))
    return buf_size;

  return 0;
}
예제 #6
0
/* Send the halftone pattern */
static SANE_Status
leo_send_halftone_pattern (Leo_Scanner * dev)
{
  int i;
  const halftone_pattern_t *pattern;
  SANE_Status status;
  size_t size;
  CDB cdb;

  DBG (DBG_proc, "leo_send_halftone_pattern: enter\n");

  if (dev->scan_mode == LEO_HALFTONE)
    {

      i = get_string_list_index (halftone_pattern_list,
				 dev->val[OPT_HALFTONE_PATTERN].s);
      pattern = halftone_pattern_val[i];

      assert (pattern != NULL);

      size = sizeof (halftone_pattern_t);
      assert (size == 256);
      MKSCSI_SEND_10 (cdb, 0x02, 0x0F, size);

      hexdump (DBG_info2, "leo_send_gamma:", cdb.data, cdb.len);

      status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
				pattern, size, NULL, NULL);
    }
  else
    {
      status = SANE_STATUS_GOOD;
    }

  DBG (DBG_proc, "leo_send_halftone_pattern: exit, status=%d\n", status);

  return status;
}
예제 #7
0
/* Read the image from the scanner and fill the temporary buffer with it. */
static SANE_Status
leo_fill_image (Leo_Scanner * dev)
{
  SANE_Status status;
  size_t size;
  CDB cdb;
  unsigned char *image;

  DBG (DBG_proc, "leo_fill_image: enter\n");

  assert (dev->image_begin == dev->image_end);
  assert (dev->real_bytes_left > 0);

  dev->image_begin = 0;
  dev->image_end = 0;

  while (dev->real_bytes_left)
    {
      /* 
       * Try to read the maximum number of bytes.
       */
      size = 0;
      while (size == 0)
	{
	  status = get_filled_data_length (dev, &size);
	  if (status)
	    return (status);
	  if (size == 0)
	    usleep (100000);	/* sleep 1/10th of second */
	}

      if (size > dev->real_bytes_left)
	size = dev->real_bytes_left;
      if (size > dev->image_size - dev->image_end)
	size = dev->image_size - dev->image_end;

      /* The scanner seems to hang if more than 32KB are read. */
      if (size > 0x7fff)
	size = 0x7fff;

      /* Always read a multiple of a line. */
      size = size - (size % dev->params.bytes_per_line);

      if (size == 0)
	{
	  /* Probably reached the end of the buffer. 
	   * Check, just in case. */
	  assert (dev->image_end != 0);
	  return (SANE_STATUS_GOOD);
	}

      DBG (DBG_info, "leo_fill_image: to read   = %ld bytes (bpl=%d)\n",
	   (long) size, dev->params.bytes_per_line);

      MKSCSI_READ_10 (cdb, 0, 0, size);

      hexdump (DBG_info2, "leo_fill_image: READ_10 CDB", cdb.data, 10);

      image = dev->image + dev->image_end;

      status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
				NULL, 0, image, &size);

      if (status != SANE_STATUS_GOOD)
	{
	  DBG (DBG_error, "leo_fill_image: cannot read from the scanner\n");
	  return status;
	}

      /* Some format conversion. */
      if (dev->scan_mode == LEO_COLOR)
	{

	  /* Reorder the lines. The scanner gives color by color for
	   * each line. */
	  unsigned char *src = image;
	  int nb_lines = size / dev->params.bytes_per_line;
	  int i, j;

	  for (i = 0; i < nb_lines; i++)
	    {

	      unsigned char *dest = dev->buffer;

	      for (j = 0; j < dev->params.pixels_per_line; j++)
		{
		  *dest = src[j + 0 * dev->params.pixels_per_line];
		  dest++;
		  *dest = src[j + 1 * dev->params.pixels_per_line];
		  dest++;
		  *dest = src[j + 2 * dev->params.pixels_per_line];
		  dest++;
		}

	      /* Copy the line back. */
	      memcpy (src, dev->buffer, dev->params.bytes_per_line);

	      src += dev->params.bytes_per_line;
	    }
	}

      dev->image_end += size;
      dev->real_bytes_left -= size;

      DBG (DBG_info, "leo_fill_image: real bytes left = %ld\n",
	   (long) dev->real_bytes_left);
    }

  return (SANE_STATUS_GOOD);	/* unreachable */
}
예제 #8
0
/* Set a window. */
static SANE_Status
leo_set_window (Leo_Scanner * dev)
{
  size_t size;
  CDB cdb;
  unsigned char window[48];
  SANE_Status status;

  DBG (DBG_proc, "leo_set_window: enter\n");

  size = sizeof (window);
  MKSCSI_SET_WINDOW (cdb, size);

  memset (window, 0, size);

  /* size of the windows descriptor block */
  window[7] = sizeof (window) - 8;
  window[1] = sizeof (window) - 2;

  /* X and Y resolution */
  Ito16 (dev->x_resolution, &window[10]);
  Ito16 (dev->y_resolution, &window[12]);

  /* Upper Left (X,Y) */
  Ito32 (dev->x_tl, &window[14]);
  Ito32 (dev->y_tl, &window[18]);

  /* Width and length */
  Ito32 (dev->width, &window[22]);
  Ito32 (dev->length, &window[26]);


  /* Image Composition */
  switch (dev->scan_mode)
    {
    case LEO_BW:
      window[33] = 0x00;
      break;
    case LEO_HALFTONE:
      window[33] = 0x01;
      break;
    case LEO_GRAYSCALE:
      window[33] = 0x02;
      break;
    case LEO_COLOR:
      window[33] = 0x05;
      break;
    }

  /* Depth */
  window[34] = dev->depth;

  /* Unknown - invariants */
  window[31] = 0x80;
  window[43] = 0x01;

  hexdump (DBG_info2, "windows", window, sizeof (window));

  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
			    window, sizeof (window), NULL, NULL);

  DBG (DBG_proc, "leo_set_window: exit, status=%d\n", status);

  return status;
}
예제 #9
0
/* Inquiry a device and returns TRUE if is supported. */
static int
leo_identify_scanner (Leo_Scanner * dev)
{
  CDB cdb;
  SANE_Status status;
  size_t size;
  int i;

  DBG (DBG_proc, "leo_identify_scanner: enter\n");

  size = 5;
  MKSCSI_INQUIRY (cdb, size);
  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
			    NULL, 0, dev->buffer, &size);

  if (status)
    {
      DBG (DBG_error,
	   "leo_identify_scanner: inquiry failed with status %s\n",
	   sane_strstatus (status));
      return (SANE_FALSE);
    }

  size = dev->buffer[4] + 5;	/* total length of the inquiry data */

  if (size < 36)
    {
      DBG (DBG_error,
	   "leo_identify_scanner: not enough data to identify device\n");
      return (SANE_FALSE);
    }

  MKSCSI_INQUIRY (cdb, size);
  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
			    NULL, 0, dev->buffer, &size);

  if (status)
    {
      DBG (DBG_error,
	   "leo_identify_scanner: inquiry failed with status %s\n",
	   sane_strstatus (status));
      return (SANE_FALSE);
    }

  dev->scsi_type = dev->buffer[0] & 0x1f;
  memcpy (dev->scsi_vendor, dev->buffer + 0x08, 0x08);
  dev->scsi_vendor[0x08] = 0;
  memcpy (dev->scsi_product, dev->buffer + 0x10, 0x010);
  dev->scsi_product[0x10] = 0;
  memcpy (dev->scsi_version, dev->buffer + 0x20, 0x04);
  dev->scsi_version[0x04] = 0;

  DBG (DBG_info, "device is \"%s\" \"%s\" \"%s\"\n",
       dev->scsi_vendor, dev->scsi_product, dev->scsi_version);

  /* Lookup through the supported scanners table to find if this
   * backend supports that one. */
  for (i = 0; i < NELEMS (scanners); i++)
    {
      if (dev->scsi_type == scanners[i].scsi_type &&
	  strcmp (dev->scsi_vendor, scanners[i].scsi_vendor) == 0 &&
	  strcmp (dev->scsi_product, scanners[i].scsi_product) == 0)
	{

	  DBG (DBG_error, "leo_identify_scanner: scanner supported\n");

	  /* Get the full inquiry, since that scanner does not fill
	     the length correctly. */
	  size = 0x30;
	  MKSCSI_INQUIRY (cdb, size);
	  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
				    NULL, 0, dev->buffer, &size);
	  if (status != SANE_STATUS_GOOD)
	    {
	      return (SANE_FALSE);
	    }

	  hexdump (DBG_info2, "inquiry", dev->buffer, size);

	  dev->def = &(scanners[i]);
	  dev->res_range.min = 1;
	  dev->res_range.max = B16TOI (&dev->buffer[42]);

	  dev->x_resolution_max = B16TOI (&dev->buffer[40]);
	  dev->y_resolution_max = B16TOI (&dev->buffer[42]);


	  return (SANE_TRUE);
	}
    }

  DBG (DBG_proc, "leo_identify_scanner: exit, device not supported\n");

  return (SANE_FALSE);
}
예제 #10
0
/* Send the gamma */
static SANE_Status
leo_send_gamma (Leo_Scanner * dev)
{
  CDB cdb;
  SANE_Status status;
  struct
  {
    unsigned char gamma_R[GAMMA_LENGTH];
    unsigned char gamma_G[GAMMA_LENGTH];	/* also gray */
    unsigned char gamma_B[GAMMA_LENGTH];
  }
  param;
  size_t i;
  size_t size;

  DBG (DBG_proc, "leo_send_gamma: enter\n");

  size = sizeof (param);
  assert (size == 3 * GAMMA_LENGTH);
  MKSCSI_SEND_10 (cdb, 0x03, 0x01, size);

  if (dev->val[OPT_CUSTOM_GAMMA].w)
    {
      /* Use the custom gamma. */
      if (dev->scan_mode == LEO_GRAYSCALE)
	{
	  /* Gray */
	  for (i = 0; i < GAMMA_LENGTH; i++)
	    {
	      param.gamma_R[i] = dev->gamma_GRAY[i];
	      param.gamma_G[i] = 0;
	      param.gamma_B[i] = 0;
	    }
	}
      else
	{
	  /* Color */
	  for (i = 0; i < GAMMA_LENGTH; i++)
	    {
	      param.gamma_R[i] = dev->gamma_R[i];
	      param.gamma_G[i] = dev->gamma_G[i];
	      param.gamma_B[i] = dev->gamma_B[i];
	    }
	}
    }
  else
    {
      for (i = 0; i < GAMMA_LENGTH; i++)
	{
	  param.gamma_R[i] = gamma_init[i];
	  param.gamma_G[i] = gamma_init[i];
	  param.gamma_B[i] = gamma_init[i];
	}
    }

  hexdump (DBG_info2, "leo_send_gamma:", cdb.data, cdb.len);

  status = sanei_scsi_cmd2 (dev->sfd, cdb.data, cdb.len,
			    &param, size, NULL, NULL);

  DBG (DBG_proc, "leo_send_gamma: exit, status=%d\n", status);

  return (status);
}