kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			canon_dr v29: improved calibration, cancelling and error handling
- split coarse and fine cal to run independently - add side option - reset scan params to user request if calibration fails - better handling of sane_cancel - better handling of errors during sane_start and sane_readmerge-requests/1/head
							rodzic
							
								
									3f1c514ac4
								
							
						
					
					
						commit
						abe0dbacd6
					
				| 
						 | 
				
			
			@ -1,3 +1,11 @@
 | 
			
		|||
2009-06-08 m. allan noah <kitno455 at gmail dot com>
 | 
			
		||||
	* backend/canon_dr.c: backend v29
 | 
			
		||||
	- split coarse and fine cal to run independently
 | 
			
		||||
	- add side option
 | 
			
		||||
	- reset scan params to user request if calibration fails
 | 
			
		||||
	- better handling of sane_cancel
 | 
			
		||||
	- better handling of errors during sane_start and sane_read
 | 
			
		||||
 | 
			
		||||
2009-06-08  Nicolas Martin <nicols-guest at users.alioth.debian.org>
 | 
			
		||||
	* backend/pixma_mp730.c, backend/pixma_imageclass.c:
 | 
			
		||||
	Modifications to support Canon ImageClass MF5770
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -213,6 +213,12 @@
 | 
			
		|||
         - don't eject paper during init
 | 
			
		||||
         - add DR-2010 quirks
 | 
			
		||||
         - switch counter to HARD_SELECT, not SOFT
 | 
			
		||||
      v29 2009-06-01, MAN
 | 
			
		||||
         - split coarse and fine cal to run independently
 | 
			
		||||
         - add side option
 | 
			
		||||
         - reset scan params to user request if calibration fails
 | 
			
		||||
         - better handling of sane_cancel
 | 
			
		||||
         - better handling of errors during sane_start and sane_read
 | 
			
		||||
 | 
			
		||||
   SANE FLOW DIAGRAM
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -273,7 +279,7 @@
 | 
			
		|||
#include "canon_dr.h"
 | 
			
		||||
 | 
			
		||||
#define DEBUG 1
 | 
			
		||||
#define BUILD 28
 | 
			
		||||
#define BUILD 29
 | 
			
		||||
 | 
			
		||||
/* values for SANE_DEBUG_CANON_DR env var:
 | 
			
		||||
 - errors           5
 | 
			
		||||
| 
						 | 
				
			
			@ -1124,7 +1130,8 @@ init_model (struct scanner *s)
 | 
			
		|||
    s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_rRgGbB;
 | 
			
		||||
    s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG;
 | 
			
		||||
    s->duplex_interlace = DUPLEX_INTERLACE_FBFB;
 | 
			
		||||
    s->need_cal = 1;
 | 
			
		||||
    s->need_ccal = 1;
 | 
			
		||||
    s->need_fcal = 1;
 | 
			
		||||
 | 
			
		||||
    /*lies*/
 | 
			
		||||
    s->can_halftone=0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1144,7 +1151,8 @@ init_model (struct scanner *s)
 | 
			
		|||
    s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510;
 | 
			
		||||
    s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510;
 | 
			
		||||
    s->duplex_interlace = DUPLEX_INTERLACE_2510;
 | 
			
		||||
    s->need_cal = 1;
 | 
			
		||||
    s->need_ccal = 1;
 | 
			
		||||
    s->need_fcal = 1;
 | 
			
		||||
    /*s->invert_tly = 1;*/
 | 
			
		||||
 | 
			
		||||
    /*only in Y direction, so we trash them in X*/
 | 
			
		||||
| 
						 | 
				
			
			@ -1935,6 +1943,17 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
 | 
			
		|||
     opt->cap = SANE_CAP_INACTIVE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(option==OPT_SIDE){
 | 
			
		||||
    opt->name = "side";
 | 
			
		||||
    opt->title = "Duplex side";
 | 
			
		||||
    opt->desc = "Tells which side (0=front, 1=back) of a duplex scan the next call to sane_read will return.";
 | 
			
		||||
    opt->type = SANE_TYPE_BOOL;
 | 
			
		||||
    opt->unit = SANE_UNIT_NONE;
 | 
			
		||||
    opt->size = sizeof(SANE_Word);
 | 
			
		||||
    opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
 | 
			
		||||
    opt->constraint_type = SANE_CONSTRAINT_NONE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* "Sensor" group ------------------------------------------------------ */
 | 
			
		||||
  if(option==OPT_SENSOR_GROUP){
 | 
			
		||||
    opt->name = SANE_NAME_SENSORS;
 | 
			
		||||
| 
						 | 
				
			
			@ -2239,6 +2258,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
 | 
			
		|||
          *val_p = s->buffermode;
 | 
			
		||||
          return SANE_STATUS_GOOD;
 | 
			
		||||
 | 
			
		||||
        case OPT_SIDE:
 | 
			
		||||
          *val_p = s->side;
 | 
			
		||||
          return SANE_STATUS_GOOD;
 | 
			
		||||
 | 
			
		||||
        /* Sensor Group */
 | 
			
		||||
        case OPT_START:
 | 
			
		||||
          ret = read_panel(s,OPT_START);
 | 
			
		||||
| 
						 | 
				
			
			@ -3024,6 +3047,9 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
  /* undo any prior sane_cancel calls */
 | 
			
		||||
  s->cancelled=0;
 | 
			
		||||
 | 
			
		||||
  /* protect this block from sane_cancel */
 | 
			
		||||
  s->reading=1;
 | 
			
		||||
 | 
			
		||||
  /* not finished with current side, error */
 | 
			
		||||
  if (s->started && s->u.bytes_sent[s->side] != s->u.bytes_tot[s->side]) {
 | 
			
		||||
    DBG(5,"sane_start: previous transfer not finished?");
 | 
			
		||||
| 
						 | 
				
			
			@ -3033,6 +3059,14 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
  /* batch start? inititalize struct and scanner */
 | 
			
		||||
  if(!s->started){
 | 
			
		||||
 | 
			
		||||
    /* load side marker */
 | 
			
		||||
    if(s->u.source == SOURCE_ADF_BACK){
 | 
			
		||||
      s->side = SIDE_BACK;
 | 
			
		||||
    }
 | 
			
		||||
    else{
 | 
			
		||||
      s->side = SIDE_FRONT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* eject paper leftover*/
 | 
			
		||||
    if(object_position (s, SANE_FALSE)){
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot eject page\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -3042,21 +3076,7 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
    ret = wait_scanner (s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot wait scanner\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* grab next page */
 | 
			
		||||
    ret = object_position (s, SANE_TRUE);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot load page\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* wait for scanner to finish load */
 | 
			
		||||
    ret = wait_scanner (s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot wait scanner\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* AFE cal */
 | 
			
		||||
| 
						 | 
				
			
			@ -3080,70 +3100,76 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
    ret = update_params(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot update_params\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* buffer/duplex/ald command */
 | 
			
		||||
    ret = ssm_buffer(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot ssm buffer\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* dropout color command */
 | 
			
		||||
    ret = ssm_do(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot ssm do\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* double feed detection command */
 | 
			
		||||
    ret = ssm_df(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot ssm df\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* set window command */
 | 
			
		||||
    ret = set_window(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot set window\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* load side marker */
 | 
			
		||||
    if(s->u.source == SOURCE_ADF_BACK){
 | 
			
		||||
      s->side = SIDE_BACK;
 | 
			
		||||
    /* buffer/duplex/ald command */
 | 
			
		||||
    ret = ssm_buffer(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot ssm buffer\n");
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
    else{
 | 
			
		||||
      s->side = SIDE_FRONT;
 | 
			
		||||
 | 
			
		||||
    /* dropout color command */
 | 
			
		||||
    ret = ssm_do(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot ssm do\n");
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* double feed detection command */
 | 
			
		||||
    ret = ssm_df(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot ssm df\n");
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* clean scan params for new scan */
 | 
			
		||||
    ret = clean_params(s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot clean_params\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* make large buffers to hold the images */
 | 
			
		||||
    ret = image_buffers(s,1);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot load buffers\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* grab next page */
 | 
			
		||||
    ret = object_position (s, SANE_TRUE);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot load page\n");
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* wait for scanner to finish load */
 | 
			
		||||
    ret = wait_scanner (s);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot wait scanner\n");
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* start scanning */
 | 
			
		||||
    ret = start_scan (s,0);
 | 
			
		||||
    if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
      DBG (5, "sane_start: ERROR: cannot start_scan\n");
 | 
			
		||||
      return ret;
 | 
			
		||||
      goto errors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->started = 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* stuff done between subsequent pages */
 | 
			
		||||
  /* stuff done for subsequent images */
 | 
			
		||||
  else{
 | 
			
		||||
 | 
			
		||||
    /* duplex needs to switch sides */
 | 
			
		||||
| 
						 | 
				
			
			@ -3162,7 +3188,7 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
      ret = clean_params(s);
 | 
			
		||||
      if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
        DBG (5, "sane_start: ERROR: cannot clean_params\n");
 | 
			
		||||
        return ret;
 | 
			
		||||
        goto errors;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /* big scanners and small ones in non-buff mode: OP to detect paper */
 | 
			
		||||
| 
						 | 
				
			
			@ -3170,7 +3196,7 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
        ret = object_position (s, SANE_TRUE);
 | 
			
		||||
        if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
          DBG (5, "sane_start: ERROR: cannot load page\n");
 | 
			
		||||
          return ret;
 | 
			
		||||
          goto errors;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* user wants unbuffered scans */
 | 
			
		||||
| 
						 | 
				
			
			@ -3179,7 +3205,7 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
          ret = start_scan (s,0);
 | 
			
		||||
          if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
            DBG (5, "sane_start: ERROR: cannot start_scan\n");
 | 
			
		||||
            return ret;
 | 
			
		||||
            goto errors;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -3189,11 +3215,12 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
        ret = read_panel (s, OPT_COUNTER);
 | 
			
		||||
        if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
          DBG (5, "sane_start: ERROR: cannot load page\n");
 | 
			
		||||
          return ret;
 | 
			
		||||
          goto errors;
 | 
			
		||||
        }
 | 
			
		||||
        if(s->prev_page == s->panel_counter){
 | 
			
		||||
          DBG (5, "sane_start: same counter (%d) no paper?\n",s->prev_page);
 | 
			
		||||
          return SANE_STATUS_NO_DOCS;
 | 
			
		||||
          ret = SANE_STATUS_NO_DOCS;
 | 
			
		||||
          goto errors;
 | 
			
		||||
        }
 | 
			
		||||
        DBG (5, "sane_start: diff counter (%d/%d)\n",
 | 
			
		||||
          s->prev_page,s->panel_counter);
 | 
			
		||||
| 
						 | 
				
			
			@ -3201,23 +3228,6 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  /* put cal buffers in the image */
 | 
			
		||||
  memcpy(
 | 
			
		||||
    s->buffers[s->side],
 | 
			
		||||
    s->f_offset[s->side],
 | 
			
		||||
    s->s.Bpl
 | 
			
		||||
  );
 | 
			
		||||
  s->s.bytes_sent[s->side] += s->s.Bpl;
 | 
			
		||||
 | 
			
		||||
  memcpy(
 | 
			
		||||
    s->buffers[s->side]+s->s.bytes_sent[s->side],
 | 
			
		||||
    s->f_gain[s->side],
 | 
			
		||||
    s->s.Bpl
 | 
			
		||||
  );
 | 
			
		||||
  s->s.bytes_sent[s->side] += s->s.Bpl;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* reset jpeg params on each page */
 | 
			
		||||
  s->jpeg_stage=JPEG_STAGE_NONE;
 | 
			
		||||
  s->jpeg_ff_offset=0;
 | 
			
		||||
| 
						 | 
				
			
			@ -3225,9 +3235,18 @@ sane_start (SANE_Handle handle)
 | 
			
		|||
  DBG (15, "started=%d, side=%d, source=%d\n",
 | 
			
		||||
    s->started, s->side, s->u.source);
 | 
			
		||||
 | 
			
		||||
  DBG (10, "sane_start: finish %d\n", ret);
 | 
			
		||||
  ret = check_for_cancel(s);
 | 
			
		||||
  s->reading = 0;
 | 
			
		||||
 | 
			
		||||
  DBG (10, "sane_start: finish %d\n", ret);
 | 
			
		||||
  return ret;
 | 
			
		||||
 | 
			
		||||
  errors:
 | 
			
		||||
    DBG (10, "sane_start: error %d\n", ret);
 | 
			
		||||
    s->started = 0;
 | 
			
		||||
    s->cancelled = 0;
 | 
			
		||||
    s->reading = 0;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -3521,39 +3540,6 @@ start_scan (struct scanner *s, int type)
 | 
			
		|||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* sends cancel command to scanner, clears s->started. don't call
 | 
			
		||||
 * this function asyncronously, wait for scan to complete */
 | 
			
		||||
static SANE_Status
 | 
			
		||||
cancel(struct scanner *s)
 | 
			
		||||
{
 | 
			
		||||
  SANE_Status ret = SANE_STATUS_GOOD;
 | 
			
		||||
 | 
			
		||||
  unsigned char cmd[CANCEL_len];
 | 
			
		||||
  size_t cmdLen = CANCEL_len;
 | 
			
		||||
 | 
			
		||||
  DBG (10, "cancel: start\n");
 | 
			
		||||
 | 
			
		||||
  memset(cmd,0,cmdLen);
 | 
			
		||||
  set_SCSI_opcode(cmd, CANCEL_code);
 | 
			
		||||
 | 
			
		||||
  ret = do_cmd (
 | 
			
		||||
      s, 1, 0,
 | 
			
		||||
      cmd, cmdLen,
 | 
			
		||||
      NULL, 0,
 | 
			
		||||
      NULL, NULL
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  if(!object_position(s,SANE_FALSE)){
 | 
			
		||||
    DBG (5, "cancel: ignoring bad eject\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  s->started = 0;
 | 
			
		||||
 | 
			
		||||
  DBG (10, "cancel: finish\n");
 | 
			
		||||
 | 
			
		||||
  return SANE_STATUS_CANCELLED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called by SANE to read data.
 | 
			
		||||
 * 
 | 
			
		||||
| 
						 | 
				
			
			@ -3590,6 +3576,8 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
 | 
			
		|||
    return SANE_STATUS_EOF;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  s->reading = 1;
 | 
			
		||||
 | 
			
		||||
  /* double width pnm interlacing */
 | 
			
		||||
  if(s->s.source == SOURCE_ADF_DUPLEX
 | 
			
		||||
    && s->s.format <= SANE_FRAME_RGB
 | 
			
		||||
| 
						 | 
				
			
			@ -3601,7 +3589,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
 | 
			
		|||
      ret = read_from_scanner_duplex(s, 0);
 | 
			
		||||
      if(ret){
 | 
			
		||||
        DBG(5,"sane_read: front returning %d\n",ret);
 | 
			
		||||
        return ret;
 | 
			
		||||
        goto errors;
 | 
			
		||||
      }
 | 
			
		||||
      /*read last block, update counter*/
 | 
			
		||||
      if(s->s.eof[SIDE_FRONT] && s->s.eof[SIDE_BACK]){
 | 
			
		||||
| 
						 | 
				
			
			@ -3617,7 +3605,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
 | 
			
		|||
      ret = read_from_scanner(s, s->side, 0);
 | 
			
		||||
      if(ret){
 | 
			
		||||
        DBG(5,"sane_read: side %d returning %d\n",s->side,ret);
 | 
			
		||||
        return ret;
 | 
			
		||||
        goto errors;
 | 
			
		||||
      }
 | 
			
		||||
      /*read last block, update counter*/
 | 
			
		||||
      if(s->s.eof[s->side]){
 | 
			
		||||
| 
						 | 
				
			
			@ -3629,18 +3617,21 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
 | 
			
		|||
 | 
			
		||||
  /* copy a block from buffer to frontend */
 | 
			
		||||
  ret = read_from_buffer(s,buf,max_len,len,s->side);
 | 
			
		||||
 | 
			
		||||
  /* we've read everything, and user cancelled */
 | 
			
		||||
  /* tell scanner to stop */
 | 
			
		||||
  if(s->s.eof[s->side] && 
 | 
			
		||||
    (s->cancelled /*|| (!read_panel(s,OPT_STOP) && s->panel_stop)*/)
 | 
			
		||||
  ){
 | 
			
		||||
    DBG(5,"sane_read: user cancelled\n");
 | 
			
		||||
    return cancel(s);
 | 
			
		||||
  }
 | 
			
		||||
  if(ret)
 | 
			
		||||
    goto errors;
 | 
			
		||||
  
 | 
			
		||||
  ret = check_for_cancel(s);
 | 
			
		||||
  s->reading = 0;
 | 
			
		||||
 | 
			
		||||
  DBG (10, "sane_read: finish %d\n", ret);
 | 
			
		||||
  return ret;
 | 
			
		||||
 | 
			
		||||
  errors:
 | 
			
		||||
    DBG (10, "sane_read: error %d\n", ret);
 | 
			
		||||
    s->reading = 0;
 | 
			
		||||
    s->cancelled = 0;
 | 
			
		||||
    s->started = 0;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static SANE_Status
 | 
			
		||||
| 
						 | 
				
			
			@ -4436,7 +4427,7 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
 | 
			
		||||
  DBG (10, "calibrate_AFE: start\n");
 | 
			
		||||
 | 
			
		||||
  if(!s->need_cal){
 | 
			
		||||
  if(!s->need_ccal){
 | 
			
		||||
    DBG (10, "calibrate_AFE: not required\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -4456,6 +4447,11 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
 | 
			
		||||
  if(s->c_res == s->s.dpi_x && s->c_mode == s->s.mode){
 | 
			
		||||
    DBG (10, "calibrate_AFE: already done\n");
 | 
			
		||||
    /* recover user settings */
 | 
			
		||||
    s->u.tl_y = old_tl_y;
 | 
			
		||||
    s->u.br_y = old_br_y;
 | 
			
		||||
    s->u.mode = old_mode;
 | 
			
		||||
    s->u.source = old_source;
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4493,6 +4489,8 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
  
 | 
			
		||||
  /* first pass (black offset), lamp off, no offset/gain/exposure */
 | 
			
		||||
  DBG (15, "calibrate_AFE: offset\n");
 | 
			
		||||
 | 
			
		||||
  /* blast all the existing coarse cal data */
 | 
			
		||||
  for(i=0;i<2;i++){
 | 
			
		||||
    s->c_gain[i]   = 1;
 | 
			
		||||
    s->c_offset[i] = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -4501,6 +4499,12 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = write_AFE(s);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = calibration_scan(s,0xff);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot make offset cal scan\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -4525,6 +4529,12 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = write_AFE(s);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = calibration_scan(s,0xfe);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot make exposure cal scan\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -4552,6 +4562,13 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
 | 
			
		||||
  /*handle third pass (gain), lamp on with current offset/exposure */
 | 
			
		||||
  DBG (15, "calibrate_AFE: gain\n");
 | 
			
		||||
 | 
			
		||||
  ret = write_AFE(s);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = calibration_scan(s,0xfe);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot make gain cal scan\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -4579,6 +4596,13 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
  /*handle fourth pass (offset again), lamp off*/
 | 
			
		||||
#if 0
 | 
			
		||||
  DBG (15, "calibrate_AFE: offset2\n");
 | 
			
		||||
 | 
			
		||||
  ret = write_AFE(s);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = calibration_scan(s,0xff);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot make offset2 cal scan\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -4596,6 +4620,13 @@ calibrate_AFE (struct scanner *s)
 | 
			
		|||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /*send final afe params to scanner*/
 | 
			
		||||
  ret = write_AFE(s);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibrate_AFE: ERROR: cannot write afe\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* recover user settings */
 | 
			
		||||
  s->u.tl_y = old_tl_y;
 | 
			
		||||
  s->u.br_y = old_br_y;
 | 
			
		||||
| 
						 | 
				
			
			@ -4629,7 +4660,7 @@ calibrate_fine (struct scanner *s)
 | 
			
		|||
 | 
			
		||||
  DBG (10, "calibrate_fine: start\n");
 | 
			
		||||
 | 
			
		||||
  if(!s->need_cal){
 | 
			
		||||
  if(!s->need_fcal){
 | 
			
		||||
    DBG (10, "calibrate_fine: not required\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -4648,6 +4679,10 @@ calibrate_fine (struct scanner *s)
 | 
			
		|||
 | 
			
		||||
  if(s->f_res == s->s.dpi_x && s->f_mode == s->s.mode){
 | 
			
		||||
    DBG (10, "calibrate_fine: already done\n");
 | 
			
		||||
    /* recover user settings */
 | 
			
		||||
    s->u.tl_y = old_tl_y;
 | 
			
		||||
    s->u.br_y = old_br_y;
 | 
			
		||||
    s->u.source = old_source;
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4708,7 +4743,7 @@ calibrate_fine (struct scanner *s)
 | 
			
		|||
    hexdump(15, "off:", s->f_offset[i], s->s.valid_Bpl);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*handle sixth pass (fine gain), lamp off*/
 | 
			
		||||
  /*handle sixth pass (fine gain), lamp on*/
 | 
			
		||||
  DBG (15, "calibrate_fine: gain\n");
 | 
			
		||||
  ret = calibration_scan(s,0xfe);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
| 
						 | 
				
			
			@ -4766,13 +4801,6 @@ calibration_scan (struct scanner *s, int scan)
 | 
			
		|||
    DBG (5, "calibration_scan: ERROR: cannot clean_params\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* send calibration */
 | 
			
		||||
  ret = write_AFE(s);
 | 
			
		||||
  if (ret != SANE_STATUS_GOOD) {
 | 
			
		||||
    DBG (5, "calibration_scan: ERROR: cannot cal afe\n");
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /* start scanning */
 | 
			
		||||
  ret = start_scan (s,scan);
 | 
			
		||||
| 
						 | 
				
			
			@ -4940,7 +4968,7 @@ gain_buffers (struct scanner *s, int setup)
 | 
			
		|||
 * cancel the currently pending operation of the device represented by
 | 
			
		||||
 * handle h.  This function can be called at any time (as long as
 | 
			
		||||
 * handle h is a valid handle) but usually affects long-running
 | 
			
		||||
 * operations only (such as image is acquisition). It is safe to call
 | 
			
		||||
 * operations only (such as image acquisition). It is safe to call
 | 
			
		||||
 * this function asynchronously (e.g., from within a signal handler).
 | 
			
		||||
 * It is important to note that completion of this operaton does not
 | 
			
		||||
 * imply that the currently pending operation has been cancelled. It
 | 
			
		||||
| 
						 | 
				
			
			@ -4958,9 +4986,63 @@ sane_cancel (SANE_Handle handle)
 | 
			
		|||
 | 
			
		||||
  DBG (10, "sane_cancel: start\n");
 | 
			
		||||
  s->cancelled = 1;
 | 
			
		||||
 | 
			
		||||
  /* if there is no other running function to check, we do it */
 | 
			
		||||
  if(!s->reading)
 | 
			
		||||
    check_for_cancel(s);
 | 
			
		||||
 | 
			
		||||
  DBG (10, "sane_cancel: finish\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* checks started and cancelled flags in scanner struct,
 | 
			
		||||
 * sends cancel command to scanner if required. don't call
 | 
			
		||||
 * this function asyncronously, wait for pending operation */
 | 
			
		||||
static SANE_Status
 | 
			
		||||
check_for_cancel(struct scanner *s)
 | 
			
		||||
{
 | 
			
		||||
  SANE_Status ret=SANE_STATUS_GOOD;
 | 
			
		||||
 | 
			
		||||
  DBG (10, "check_for_cancel: start\n");
 | 
			
		||||
 | 
			
		||||
  if(s->started && s->cancelled){
 | 
			
		||||
    unsigned char cmd[CANCEL_len];
 | 
			
		||||
    size_t cmdLen = CANCEL_len;
 | 
			
		||||
  
 | 
			
		||||
    DBG (15, "check_for_cancel: cancelling\n");
 | 
			
		||||
  
 | 
			
		||||
    /* cancel scan */
 | 
			
		||||
    memset(cmd,0,cmdLen);
 | 
			
		||||
    set_SCSI_opcode(cmd, CANCEL_code);
 | 
			
		||||
  
 | 
			
		||||
    ret = do_cmd (
 | 
			
		||||
        s, 1, 0,
 | 
			
		||||
        cmd, cmdLen,
 | 
			
		||||
        NULL, 0,
 | 
			
		||||
        NULL, NULL
 | 
			
		||||
    );
 | 
			
		||||
    if(!ret){
 | 
			
		||||
      DBG (5, "check_for_cancel: ignoring bad cancel: %d\n",ret);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    ret = object_position(s,SANE_FALSE);
 | 
			
		||||
    if(!ret){
 | 
			
		||||
      DBG (5, "check_for_cancel: ignoring bad eject\n",ret);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->started = 0;
 | 
			
		||||
    s->cancelled = 0;
 | 
			
		||||
    ret = SANE_STATUS_CANCELLED;
 | 
			
		||||
  }
 | 
			
		||||
  else if(s->cancelled){
 | 
			
		||||
    DBG (15, "check_for_cancel: already cancelled\n");
 | 
			
		||||
    s->cancelled = 0;
 | 
			
		||||
    ret = SANE_STATUS_CANCELLED;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DBG (10, "check_for_cancel: finish %d\n",ret);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Ends use of the scanner.
 | 
			
		||||
 * 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,7 @@ enum scanner_Option
 | 
			
		|||
  OPT_DROPOUT_COLOR_F,
 | 
			
		||||
  OPT_DROPOUT_COLOR_B,
 | 
			
		||||
  OPT_BUFFERMODE,
 | 
			
		||||
  OPT_SIDE,
 | 
			
		||||
 | 
			
		||||
  /*sensor group*/
 | 
			
		||||
  OPT_SENSOR_GROUP,
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +156,8 @@ struct scanner
 | 
			
		|||
  int max_y_fb;
 | 
			
		||||
 | 
			
		||||
  int can_color;     /* actually might be in vpd, but which bit? */
 | 
			
		||||
  int need_cal;      /* scanner needs software to help with calibration */
 | 
			
		||||
  int need_ccal;     /* scanner needs software to help with afe calibration */
 | 
			
		||||
  int need_fcal;     /* scanner needs software to help with fine calibration */
 | 
			
		||||
 | 
			
		||||
  int has_counter;
 | 
			
		||||
  int has_rif;
 | 
			
		||||
| 
						 | 
				
			
			@ -509,6 +511,7 @@ static SANE_Status send_panel(struct scanner *s);
 | 
			
		|||
 | 
			
		||||
static SANE_Status start_scan (struct scanner *s, int type);
 | 
			
		||||
 | 
			
		||||
static SANE_Status check_for_cancel(struct scanner *s);
 | 
			
		||||
static SANE_Status cancel(struct scanner *s);
 | 
			
		||||
 | 
			
		||||
static SANE_Status read_from_scanner(struct scanner *s, int side, int exact);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue