Пример #1
0
void
tcp_dev_close (struct device *dev)
{
    if (!dev)	return;

    DBG (3, "%s: closing dev %p\n", __FUNCTION__, (void *)dev);

    /* finish all operations */
    if (dev->scanning) {
	dev->cancel = 1;
	/* flush READ_IMAGE data */
	if (dev->reading)	sane_read(dev, NULL, 1, NULL);
    /* send cancel if not sent before */
	if (dev->state != SANE_STATUS_CANCELLED)
	    ret_cancel(dev, 0);
    }

    sanei_tcp_close(dev->dn);
    dev->dn = -1;
}
Пример #2
0
/* 1: image is acquired, 0: error or non_blocking mode */
static int dev_acquire(struct device *dev)
{
  if (!dev_cmd_wait(dev, CMD_READ))
    return dev->state;

  dev->state = SANE_STATUS_GOOD;
  dev->vertical = dev->res[0x08] << 8 | dev->res[0x09];
  dev->horizontal = dev->res[0x0a] << 8 | dev->res[0x0b];
  dev->blocklen = dev->res[4] << 24 |
    dev->res[5] << 16 |
    dev->res[6] << 8 |
    dev->res[7];
  dev->final_block = (dev->res[3] == MSG_END_BLOCK)? 1 : 0;

  dev->pixels_per_line = dev->horizontal;
  dev->bytes_per_line = dev->horizontal;

  if (dev->composition == MODE_RGB24)
    dev->bytes_per_line *= 3;
  else if (dev->composition == MODE_LINEART ||
	   dev->composition == MODE_HALFTONE)
    dev->pixels_per_line *= 8;

  DBG (4, "acquiring, size per band v: %d, h: %d, %sblock: %d, slack: %d\n",
       dev->vertical, dev->horizontal, dev->final_block? "last " : "",
       dev->blocklen, dev->blocklen - (dev->vertical * dev->bytes_per_line));

  if (dev->bytes_per_line > DATASIZE) {
    DBG (1, "%s: unsupported line size: %d bytes > %d\n",
	 __FUNCTION__, dev->bytes_per_line, DATASIZE);
    return ret_cancel(dev, SANE_STATUS_NO_MEM);
  }

  dev->reading = 0; /* need to issue READ_IMAGE */

  dev->dataindex = 0;
  dev->datalen = 0;
  dev->dataoff = 0;

  return 1;
}
Пример #3
0
static int cancelled(struct device *dev)
{
  if (dev->cancel)
    return ret_cancel(dev, 1);
  return 0;
}
Пример #4
0
SANE_Status
sane_start (SANE_Handle h)
{
  struct device *dev = h;

  DBG (3, "%s: %p\n", __FUNCTION__, h);

  dev->cancel = 0;
  dev->scanning = 0;
  dev->total_img_size = 0;
  dev->total_out_size = 0;
  dev->total_data_size = 0;
  dev->blocks = 0;

  if (!dev->reserved) {
    if (!dev_cmd_wait(dev, CMD_RESERVE_UNIT))
      return dev->state;
    dev->reserved++;
  }

  if (!dev_set_window(dev) ||
      (dev->state && dev->state != SANE_STATUS_DEVICE_BUSY))
    return dev_stop(dev);

  if (!dev_cmd_wait(dev, CMD_OBJECT_POSITION))
    return dev_stop(dev);

  if (!dev_cmd(dev, CMD_READ) ||
      (dev->state && dev->state != SANE_STATUS_DEVICE_BUSY))
    return dev_stop(dev);

  dev->scanning = 1;
  dev->final_block = 0;
  dev->blocklen = 0;
  dev->pixels_per_line = 0;
  dev->bytes_per_line = 0;
  dev->ulines = 0;

  set_parameters(dev);

  if (!dev->data && !(dev->data = malloc(DATASIZE)))
    return ret_cancel(dev, SANE_STATUS_NO_MEM);

  if (!dev_acquire(dev))
    return dev->state;

  /* make sure to have dev->para <= of real size */
  if (dev->para.pixels_per_line > dev->pixels_per_line) {
    dev->para.pixels_per_line = dev->pixels_per_line;
    dev->para.bytes_per_line = dev->pixels_per_line;
  }

  if (dev->composition == MODE_RGB24)
    dev->para.bytes_per_line = dev->para.pixels_per_line * 3;
  else if (dev->composition == MODE_LINEART ||
	   dev->composition == MODE_HALFTONE) {
    dev->para.bytes_per_line = (dev->para.pixels_per_line + 7) / 8;
    dev->para.pixels_per_line = dev->para.bytes_per_line * 8;
  } else {
    dev->para.bytes_per_line = dev->para.pixels_per_line;
  }

  dev->total_img_size = dev->para.bytes_per_line * dev->para.lines;

  return SANE_STATUS_GOOD;
}
Пример #5
0
SANE_Status
sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * lenp)
{
  SANE_Status status;
  struct device *dev = h;

  DBG (3, "%s: %p, %p, %d, %p\n", __FUNCTION__, h, buf, maxlen, (void *)lenp);

  if (lenp)
    *lenp = 0;
  if (!dev)
    return SANE_STATUS_INVAL;

  if (!dev->scanning)
    return SANE_STATUS_EOF;

  /* if there is no data to read or output from buffer */
  if (!dev->blocklen && dev->datalen <= PADDING_SIZE) {

    /* and we don't need to acquire next block */
    if (dev->final_block) {
      int slack = dev->total_img_size - dev->total_out_size;

      /* but we may need to fill slack */
      if (buf && lenp && slack > 0) {
	*lenp = fill_slack(dev, buf, maxlen);
	dev->total_out_size += *lenp;
	DBG (9, "<> slack: %d, filled: %d, maxlen %d\n",
	     slack, *lenp, maxlen);
	return SANE_STATUS_GOOD;
      } else if (slack < 0) {
	/* this will never happen */
	DBG(1, "image overflow %d bytes\n", dev->total_img_size - dev->total_out_size);
      }

      /* that's all */
      dev_stop(dev);
      return SANE_STATUS_EOF;
    }

    /* queue next image block */
    if (!dev_acquire(dev))
      return dev->state;
  }

  if (!dev->reading) {
    if (cancelled(dev))
      return dev->state;
    DBG (5, "READ_IMAGE\n");
    if (!dev_cmd(dev, CMD_READ_IMAGE))
      return SANE_STATUS_IO_ERROR;
    dev->reading++;
    dev->ulines += dev->vertical;
    dev->y_off = dev->ulines - dev->vertical;
    dev->total_data_size += dev->blocklen;
    dev->blocks++;
  }

  do {
    size_t datalen;
    int clrlen; /* cleared lines len */
    int olen; /* output len */

    /* read as much data into the buffer */
    datalen = DATAROOM(dev) & USB_BLOCK_MASK;
    while (datalen && dev->blocklen) {
      SANE_Byte *rbuf = dev->data + DATATAIL(dev);

      DBG (9, "<> request len: %lu, [%d, %d; %d]\n",
	   (u_long)datalen, dev->dataoff, DATATAIL(dev), dev->datalen);
      if ((status = dev->io->dev_request(dev, NULL, 0, rbuf, &datalen)) !=
	  SANE_STATUS_GOOD)
	return status;
      dev->datalen += datalen;
      dev->blocklen -= datalen;
      DBG (9, "<> got %lu, [%d, %d; %d]\n",
	   (u_long)datalen, dev->dataoff, DATATAIL(dev), dev->datalen);
      if (dev->blocklen < 0)
	return ret_cancel(dev, SANE_STATUS_IO_ERROR);

      datalen = DATAROOM(dev) & USB_BLOCK_MASK;
    }

    if (buf && lenp) { /* read mode */
      /* copy will do minimal of valid data */
      if (dev->para.format == SANE_FRAME_RGB && dev->line_order)
	clrlen = copy_mix_bands_trim(dev, buf, maxlen, &olen);
      else
	clrlen = copy_plain_trim(dev, buf, maxlen, &olen);

      dev->datalen -= clrlen;
      dev->dataoff = (dev->dataoff + clrlen) & DATAMASK;
      buf += olen;
      maxlen -= olen;
      *lenp += olen;
      dev->total_out_size += olen;

      DBG (9, "<> olen: %d, clrlen: %d, blocklen: %d/%d, maxlen %d (%d %d %d)\n",
	   olen, clrlen, dev->blocklen, dev->datalen, maxlen,
	   dev->dataindex / dev->bytes_per_line + dev->y_off,
	   dev->y_off, dev->para.lines);

      /* slack beyond last line */
      if (dev->dataindex / dev->bytes_per_line + dev->y_off >= dev->para.lines) {
	dev->datalen = 0;
	dev->dataoff = 0;
      }

      if (!clrlen || maxlen <= 0)
	break;
    } else { /* flush mode */
      dev->datalen = 0;
      dev->dataoff = 0;
    }

  } while (dev->blocklen);

  if (lenp)
    DBG (9, " ==> %d\n", *lenp);

  return SANE_STATUS_GOOD;
}