コード例 #1
0
ファイル: pixma_mp750.c プロジェクト: Ichoran/lifespan
static void
mp750_finish_scan (pixma_t * s)
{
  int error;
  mp750_t *mp = (mp750_t *) s->subdriver;

  switch (mp->state)
    {
    case state_transfering:
      drain_bulk_in (s);
      /* fall through */
    case state_scanning:
    case state_warmup:
      error = abort_session (s);
      if (error == PIXMA_ECANCELED)
	read_error_info (s, NULL, 0);
      /* fall through */
    case state_finished:
      if (s->param->source == PIXMA_SOURCE_FLATBED)
	{
	   /*SIM*/ query_status (s);
	  if (abort_session (s) == PIXMA_ECANCELED)
	    {
	      read_error_info (s, NULL, 0);
	      query_status (s);
	    }
	}
      query_status (s);
       /*SIM*/ activate (s, 0);
      if (mp->needs_abort)
	{
	  mp->needs_abort = 0;
	  abort_session (s);
	}
      free (mp->buf);
      mp->buf = mp->rawimg = NULL;
      mp->state = state_idle;
      /* fall through */
    case state_idle:
      break;
    }
}
コード例 #2
0
ファイル: pixma_mp730.c プロジェクト: DspaceSPI/SPIScan
static int
step1 (pixma_t * s)
{
  int error, tmo;

  error = query_status (s);
  if (error < 0)
    return error;
  if ((s->param->source == PIXMA_SOURCE_ADF
       || s->param->source == PIXMA_SOURCE_ADFDUP)
      && !has_paper (s))
    return PIXMA_ENO_PAPER;
  if (has_ccd_sensor (s))
    {
      switch (s->cfg->pid)
        {
          case MF5730_PID:
          case MF5750_PID:
          case MF5770_PID:
          /* MF57x0: Wait 10 sec before starting for 1st page only */
            if (s->param->adf_pageid == 0)
	      {
                tmo = 10;  /* like Windows driver, 10 sec CCD calibration ? */
                while (--tmo >= 0)
                  {
                    error = handle_interrupt (s, 1000);		\
                    if (s->cancel)				\
                      return PIXMA_ECANCELED;			\
                    if (error != PIXMA_ECANCELED && error < 0)	\
                      return error;
                    PDBG (pixma_dbg (2, "CCD Calibration ends in %d sec.\n", tmo));
                  }
              }
            break;

          default:
            break;
        }
        
      activate (s, 0);
      error = calibrate (s);
      
      switch (s->cfg->pid)
        {
          case MF5730_PID:
          case MF5750_PID:
          case MF5770_PID:
          /* MF57x0: calibration returns PIXMA_STATUS_FAILED */
            if (error == PIXMA_ECANCELED)
              error = read_error_info (s, NULL, 0);
            break;

          default:
            break;
        }
    }
  if (error >= 0)
    error = activate (s, 0);
  if (error >= 0)
    error = activate (s, 4);
  return error;
}
コード例 #3
0
ファイル: pixma_mp750.c プロジェクト: Ichoran/lifespan
static int
mp750_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
{
  mp750_t *mp = (mp750_t *) s->subdriver;
  int error;
  uint8_t info;
  unsigned block_size, bytes_received, n;
  int shift[3], base_shift;
  int c;

  c = ((is_ccd_grayscale (s)) ? 3 : s->param->channels) * s->param->depth / 8; /* single-byte or double-byte data */

  if (mp->state == state_warmup)
    {
      int tmo = 60;

      query_status (s);
      check_status (s);
 /*SIM*/ while (!is_calibrated (s) && --tmo >= 0)
        {
          if (s->cancel)
            return PIXMA_ECANCELED;
          if (handle_interrupt (s, 1000) > 0)
            {
              block_size = 0;
              error = request_image_block (s, &block_size, &info);
               /*SIM*/ if (error < 0)
          return error;
            }
        }
      if (tmo < 0)
        {
          PDBG (pixma_dbg (1, "WARNING: Timed out waiting for calibration\n"));
          return PIXMA_ETIMEDOUT;
        }
      pixma_sleep (100000);
      query_status (s);
      if (is_warming_up (s) || !is_calibrated (s))
        {
          PDBG (pixma_dbg (1, "WARNING: Wrong status: wup=%d cal=%d\n",
               is_warming_up (s), is_calibrated (s)));
          return PIXMA_EPROTO;
        }
      block_size = 0;
      request_image_block (s, &block_size, &info);
       /*SIM*/ mp->state = state_scanning;
      mp->last_block = 0;
    }

  /* TODO: Move to other place, values are constant. */
  base_shift = calc_component_shifting (s) * mp->line_size;
  if (s->param->source == PIXMA_SOURCE_ADF)
    {
      shift[0] = 0;
      shift[1] = -base_shift;
      shift[2] = -2 * base_shift;
    }
  else
    {
      shift[0] = -2 * base_shift;
      shift[1] = -base_shift;
      shift[2] = 0;
    }

  do
    {
      if (mp->last_block_size > 0)
        {
          block_size = mp->imgbuf_len - mp->last_block_size;
          memcpy (mp->img, mp->img + mp->last_block_size, block_size);
        }

      do
        {
          if (s->cancel)
            return PIXMA_ECANCELED;
          if (mp->last_block)
            {
              /* end of image */
              info = mp->last_block;
              if (info != 0x38)
                {
                  query_status (s);
                   /*SIM*/ while ((info & 0x28) != 0x28)
                    {
                      pixma_sleep (10000);
                      error = request_image_block2 (s, &info);
                      if (s->cancel)
                        return PIXMA_ECANCELED;	/* FIXME: Is it safe to cancel here? */
                      if (error < 0)
                        return error;
                    }
                }
              mp->needs_abort = (info != 0x38);
              mp->last_block = info;
              mp->state = state_finished;
              return 0;
            }

          check_status (s);
           /*SIM*/ while (handle_interrupt (s, 1) > 0);
           /*SIM*/ block_size = IMAGE_BLOCK_SIZE;
          error = request_image_block (s, &block_size, &info);
          if (error < 0)
            {
              if (error == PIXMA_ECANCELED)
                read_error_info (s, NULL, 0);
              return error;
            }
          mp->last_block = info;
          if ((info & ~0x38) != 0)
            {
              PDBG (pixma_dbg (1, "WARNING: Unknown info byte %x\n", info));
            }
          if (block_size == 0)
            {
              /* no image data at this moment. */
              pixma_sleep (10000);
            }
        }
      while (block_size == 0);

      error = read_image_block (s, mp->rawimg + mp->rawimg_left);
      if (error < 0)
	{
	  mp->state = state_transfering;
	  return error;
	}
      bytes_received = error;
      PASSERT (bytes_received == block_size);

      /* TODO: simplify! */
      mp->rawimg_left += bytes_received;
      n = mp->rawimg_left / 3;
      /* n = number of pixels in the buffer? */

      /* Color to Grayscale converion for CCD sensor */
      if (is_ccd_grayscale (s)) {
	shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size, 
		   mp->imgcol + mp->imgbuf_ofs); 
	/* dst: img, src: imgcol */
	rgb_to_gray (mp->img, mp->imgcol, n, c); /* cropping occurs later? */  
	PDBG (pixma_dbg (4, "*fill_buffer: did grayscale conversion \n"));
      }
      /* Color image processing */
      else {
	shift_rgb (mp->rawimg, n, shift[0], shift[1], shift[2], mp->stripe_shift, mp->line_size, 
		   mp->img + mp->imgbuf_ofs);
	PDBG (pixma_dbg (4, "*fill_buffer: no grayscale conversion---keep color \n")); 
      }

      /* entering remaining unprocessed bytes after last complete pixel into mp->rawimg buffer -- no influence on mp->img */
      n *= 3;
      mp->shifted_bytes += n;
      mp->rawimg_left -= n;	/* rawimg_left = 0, 1 or 2 bytes left in the buffer. */
      mp->last_block_size = n;
      memcpy (mp->rawimg, mp->rawimg + n, mp->rawimg_left);

    }
  while (mp->shifted_bytes <= 0);

  if ((unsigned) mp->shifted_bytes < mp->last_block_size) 
    {
      if (is_ccd_grayscale (s))
	ib->rptr = mp->img + mp->last_block_size/3 - mp->shifted_bytes/3; /* testing---works OK */
      else
	ib->rptr = mp->img + mp->last_block_size - mp->shifted_bytes;
    }
  else
    ib->rptr = mp->img;
  if (is_ccd_grayscale (s))
    ib->rend = mp->img + mp->last_block_size/3; /* testing---works OK */
  else
    ib->rend = mp->img + mp->last_block_size; 
  return ib->rend - ib->rptr;
}
コード例 #4
0
ファイル: pixma_imageclass.c プロジェクト: Ichoran/lifespan
static int
iclass_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
{
  int error, n;
  iclass_t *mf = (iclass_t *) s->subdriver;
  unsigned block_size, lines_size, first_block_size;
  uint8_t info;

/*
 * 1. send a block request cmd (d4 20 00... 04 00 06)
 * 2. examine the response for block size and/or end-of-scan flag
 * 3. read the block one chunk at a time
 * 4. repeat until have enough to process >=1 lines
 */
  do
    {
      do
        {
          if (s->cancel)
            return PIXMA_ECANCELED;
          if (mf->last_block)
            {
              /* end of image */
              mf->state = state_finished;
              return 0;
            }

          first_block_size = 0;
          error = request_image_block (s, 4, &info, &block_size, 
                          mf->blkptr + mf->blk_len, &first_block_size);
          /* add current block to remainder of previous */
          mf->blk_len += first_block_size;
          if (error < 0)
            {
              /* NOTE: seen in traffic logs but don't know the meaning. */
              read_error_info (s, NULL, 0);
              if (error == PIXMA_ECANCELED)
                return error;
            }

          /* info: 0x28 = end; 0x38 = end + ADF empty */
          mf->last_block = info & 0x38;
          if ((info & ~0x38) != 0)
            {
              PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n"));
              PDBG (pixma_hexdump (1, &info, 1));
            }

          if (block_size == 0)
            {
              /* no image data at this moment. */
              /*pixma_sleep(100000); *//* FIXME: too short, too long? */
              handle_interrupt (s, 100);
            }
        }
      while (block_size == 0 && first_block_size == 0);

      error = read_image_block (s, mf->blkptr + mf->blk_len, block_size);
      block_size = error;
      if (error < 0)
        return error;

      /* add current block to remainder of previous */
      mf->blk_len += block_size;
      /* n = number of full lines (rows) we have in the buffer. */
      n = mf->blk_len / s->param->line_size;
      if (n != 0)
        {
          if (s->param->channels != 1 &&
                  s->cfg->pid != MF3010_PID &&
                  s->cfg->pid != MF4410_PID &&
                  s->cfg->pid != MF4770_PID &&
	          s->cfg->pid != MF4550_PID &&
	          s->cfg->pid != MF4600_PID &&
	          s->cfg->pid != MF6500_PID &&
	          s->cfg->pid != MF8030_PID)
            {
              /* color and not MF46xx or MF65xx */
              pack_rgb (mf->blkptr, n, mf->raw_width, mf->lineptr);
            }
          else
            {
              /* grayscale */
              memcpy (mf->lineptr, mf->blkptr, n * s->param->line_size);
            }
          lines_size = n * s->param->line_size;
          /* cull remainder and shift left */
          mf->blk_len -= lines_size;
          memcpy (mf->blkptr, mf->blkptr + lines_size, mf->blk_len);
        }
    }
  while (n == 0);

  /* output full lines, keep partial lines for next block */
  ib->rptr = mf->lineptr;
  ib->rend = mf->lineptr + lines_size;
  return ib->rend - ib->rptr;
}