kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			Update for MP970 (yet for color scan, all resolutions) and bug fix for MP220 at 1200 dpi (reported to work OK)
							rodzic
							
								
									57bfede65b
								
							
						
					
					
						commit
						983e8c0eeb
					
				
							
								
								
									
										13
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										13
									
								
								ChangeLog
								
								
								
								
							|  | @ -1,3 +1,16 @@ | |||
| 2008-04-14  Nicolas Martin <nicols-guest at users.alioth.debian.org> | ||||
| 	* backend/pixma_mp150.c, backend/pixma.h, backend/pixma_mp150.c | ||||
| 	doc/sane-pixma.man, doc/descriptions/pixma.desc: | ||||
| 	With feedback from MP970 owner, updated pixma backend for MP970 | ||||
| 	CCD sensor support (yet in color only), and more generally,  | ||||
| 	support for other CCD sensor PIXMA: MP800, MP810, MP830, MP960, | ||||
| 	but yet untested, which produce shifted color planes  | ||||
| 	scanned images. Current trim based on sample images provided  | ||||
| 	in bug reports and other web pages, but might require some  | ||||
| 	few and simple final tweaks. | ||||
| 	Also fixed a bug for MP220 at 1200 dpi, MP220 is now reported  | ||||
| 	to work fine. | ||||
| 
 | ||||
| 2008-04-13  Julien Blache <jb@jblache.org> | ||||
| 	* frontend/saned.c: fix typo. | ||||
| 	* backend/net.c: plug an information leak in the net backend. When | ||||
|  |  | |||
|  | @ -108,7 +108,7 @@ typedef u_int32_t uint32_t; | |||
| /**@{*/ | ||||
| #define PIXMA_VERSION_MAJOR 0 | ||||
| #define PIXMA_VERSION_MINOR 14 | ||||
| #define PIXMA_VERSION_BUILD 4 | ||||
| #define PIXMA_VERSION_BUILD 5 | ||||
| /**@}*/ | ||||
| 
 | ||||
| /** \name Error codes */ | ||||
|  |  | |||
|  | @ -99,13 +99,13 @@ | |||
| 
 | ||||
| /* Generation 3 */ | ||||
| #define MP210_PID 0x1721 | ||||
| #define MP220_PID 0x1722  /* untested */ | ||||
| #define MP220_PID 0x1722 | ||||
| #define MP470_PID 0x1723 | ||||
| #define MP520_PID 0x1724 | ||||
| #define MP610_PID 0x1725 | ||||
| #define MP970_PID 0x1726  /* untested. Generation 3 ? */ | ||||
| #define MP970_PID 0x1726 | ||||
| #define MX300_PID 0x1727  /* untested */ | ||||
| #define MX310_PID 0x1728  /* untested */ | ||||
| #define MX310_PID 0x1728 | ||||
| #define MX700_PID 0x1729 | ||||
| 
 | ||||
| #define MX850_PID 0x172c  /* untested */ | ||||
|  | @ -131,8 +131,8 @@ enum mp150_cmd_t | |||
|   cmd_read_image = 0xd420, | ||||
|   cmd_error_info = 0xff20, | ||||
| 
 | ||||
|   cmd1_ccd_3 = 0xd520, | ||||
|   cmd2_ccd_3 = 0xd720, | ||||
|   cmd_start_calibrate_ccd_3 = 0xd520, | ||||
|   cmd_end_calibrate_ccd_3 = 0xd720, | ||||
|   cmd_scan_param_3 = 0xd820, | ||||
|   cmd_scan_start_3 = 0xd920, | ||||
|   cmd_status_3 = 0xda20, | ||||
|  | @ -147,10 +147,13 @@ typedef struct mp150_t | |||
|   uint8_t *imgbuf; | ||||
|   uint8_t current_status[16]; | ||||
|   unsigned last_block; | ||||
|   int generation; | ||||
|   /* for Generation 3 */ | ||||
|   uint8_t generation; | ||||
|   /* for Generation 3 and CCD shift */ | ||||
|   uint8_t *linebuf; | ||||
|   unsigned linelag; | ||||
|   uint8_t *data_left_ofs; | ||||
|   unsigned data_left_len; | ||||
|   int shift[3]; | ||||
|   unsigned lines_shift; | ||||
| } mp150_t; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -234,31 +237,6 @@ is_calibrated (pixma_t * s) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| /* For processing Generation 3 high dpi images.
 | ||||
|  * Each complete line in mp->imgbuf is reordered for 1200,2400 and 4800 dpi Generation 3 format. */ | ||||
| static int | ||||
| process_high_dpi_3 (pixma_t * s, pixma_imagebuf_t * ib) | ||||
| { | ||||
|   mp150_t *mp = (mp150_t *) s->subdriver; | ||||
|   uint8_t *rptr = mp->imgbuf; | ||||
|   unsigned i; | ||||
|   const unsigned n = s->param->xdpi / 600; | ||||
|   const unsigned m = s->param->w / n; | ||||
|   const unsigned c = s->param->channels; | ||||
| 
 | ||||
|   while (rptr + s->param->line_size <= ib->rend) | ||||
|     { | ||||
|       for (i = 0; i < s->param->w; i++) | ||||
| 	{ | ||||
| 	  memcpy (mp->linebuf + (c * (n * (i % m) + i / m)), rptr + (c * i), | ||||
| 		  c); | ||||
| 	} | ||||
|       memcpy (rptr, mp->linebuf, s->param->line_size); | ||||
|       rptr += s->param->line_size; | ||||
|     } | ||||
|   return ib->rend - rptr; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| has_paper (pixma_t * s) | ||||
| { | ||||
|  | @ -288,10 +266,10 @@ send_cmd_e920 (pixma_t * s) | |||
| } | ||||
| 
 | ||||
| static int | ||||
| send_cmd_ccd1 (pixma_t * s) | ||||
| send_cmd_start_calibrate_ccd_3 (pixma_t * s) | ||||
| { | ||||
|   mp150_t *mp = (mp150_t *) s->subdriver; | ||||
|   return pixma_exec_short_cmd (s, &mp->cb, cmd1_ccd_3); | ||||
|   return pixma_exec_short_cmd (s, &mp->cb, cmd_start_calibrate_ccd_3); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
|  | @ -490,10 +468,10 @@ init_ccd_3 (pixma_t * s) | |||
|   int error, status_len; | ||||
| 
 | ||||
|   status_len = 8; | ||||
|   error = send_cmd_ccd1 (s); | ||||
|   error = send_cmd_start_calibrate_ccd_3 (s); | ||||
|   if (error >= 0)  | ||||
|     { | ||||
|       data = pixma_newcmd (&mp->cb, cmd2_ccd_3, 0, status_len); | ||||
|       data = pixma_newcmd (&mp->cb, cmd_end_calibrate_ccd_3, 0, status_len); | ||||
|       error = pixma_exec (s, &mp->cb); | ||||
|       if (error >= 0) | ||||
|         { | ||||
|  | @ -734,6 +712,7 @@ mp150_open (pixma_t * s) | |||
|   mp->generation = (s->cfg->pid >= MP160_PID) ? 2 : 1; | ||||
|   if (s->cfg->pid >= MP210_PID) | ||||
|     mp->generation = 3; | ||||
| 
 | ||||
|   /* And exceptions to be added here */ | ||||
|   if (s->cfg->pid == MP140_PID) | ||||
|     mp->generation = 2; | ||||
|  | @ -806,25 +785,35 @@ mp150_scan (pixma_t * s) | |||
| 
 | ||||
|   if (has_ccd_sensor (s)) | ||||
|     { | ||||
|       /* FIXME: What does this command do? */ | ||||
|       error = (mp->generation <= 2) ? send_cmd_e920 (s) : send_cmd_ccd1 (s); | ||||
|       if (error == 0) | ||||
| 	{ | ||||
| 	  query_status (s); | ||||
| 	} | ||||
|       else if (error == PIXMA_ECANCELED || error == PIXMA_EBUSY) | ||||
| 	{ | ||||
| 	  PDBG (pixma_dbg | ||||
| 		(2, "cmd e920 or d520 returned %s\n", pixma_strerror (error))); | ||||
| 	  query_status (s); | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  PDBG (pixma_dbg | ||||
| 		(1, "WARNING:cmd e920 or d520 failed %s\n", pixma_strerror (error))); | ||||
| 	  return error; | ||||
| 	} | ||||
|       pixma_sleep(2000000); /* like Windows driver, CCD warmup ? */ | ||||
|       error = (mp->generation <= 2) ? send_cmd_e920 (s)  | ||||
|                                     : send_cmd_start_calibrate_ccd_3 (s); | ||||
|       switch (error) | ||||
|         { | ||||
|           case PIXMA_ECANCELED: | ||||
|           case PIXMA_EBUSY: | ||||
|             PDBG (pixma_dbg | ||||
|               (2, "cmd e920 or d520 returned %s\n", pixma_strerror (error))); | ||||
|           /* fall through */ | ||||
|           case 0: | ||||
| 	    query_status (s); | ||||
|             break; | ||||
|           default: | ||||
| 	    PDBG (pixma_dbg | ||||
| 	      (1, "WARNING:cmd e920 or d520 failed %s\n", pixma_strerror (error))); | ||||
|             return error; | ||||
|         } | ||||
|       tmo = 3;  /* like Windows driver, 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)); | ||||
|         } | ||||
|       /* pixma_sleep(2000000); */ | ||||
|     } | ||||
| 
 | ||||
|   tmo = 10; | ||||
|  | @ -859,6 +848,10 @@ mp150_scan (pixma_t * s) | |||
|     error = init_ccd_3 (s); | ||||
|   if (error >= 0) | ||||
|     error = send_gamma_table (s); | ||||
|   if ((error >= 0) && (mp->generation == 3))  | ||||
|     error = send_gamma_table (s); | ||||
|   if ((error >= 0) && (mp->generation == 3))  | ||||
|     error = send_gamma_table (s); | ||||
|   if (error >= 0) | ||||
|     error = send_scan_param (s); | ||||
|   if ((error >= 0) && (mp->generation == 3)) | ||||
|  | @ -871,12 +864,105 @@ mp150_scan (pixma_t * s) | |||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| /* This post process function deals both with CCD sensors PIXMAs
 | ||||
|  * producing shifted color planes images, and Generation 3 high dpi images. | ||||
|  * Each complete line in mp->imgbuf is processed for shifting CCD sensor  | ||||
|  * color planes, and reordering pixels for above 600 dpi Generation 3 format. */ | ||||
| static unsigned | ||||
| post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib) | ||||
| { | ||||
|   mp150_t *mp = (mp150_t *) s->subdriver; | ||||
|   const unsigned n = s->param->xdpi / 600; | ||||
|   const unsigned c = s->param->channels; | ||||
|   const unsigned m = (n > 0) ? s->param->w / n : 1; | ||||
|   unsigned lines, i, j; | ||||
|   uint8_t *sptr = mp->imgbuf; | ||||
|   uint8_t *dptr = mp->imgbuf; | ||||
|   const int sr = mp->shift[0]; | ||||
|   const int sg = mp->shift[1]; | ||||
|   const int sb = mp->shift[2]; | ||||
| 
 | ||||
|   lines = (ib->rend - ib->rptr) / s->param->line_size; | ||||
|   if (lines > 2 * mp->lines_shift) | ||||
|     { | ||||
|       for (j = 0; j < lines - 2 * mp->lines_shift; j++) | ||||
|         { | ||||
|           if (has_ccd_sensor (s) && (c == 3)) | ||||
|             {   | ||||
|               for (i = 0; i < s->param->w; i++) | ||||
|                 { | ||||
|                   *sptr++ = *(dptr++ + sr); | ||||
|                   *sptr++ = *(dptr++ + sg); | ||||
|                   *sptr++ = *(dptr++ + sb); | ||||
|                 } | ||||
|               sptr -= s->param->line_size; | ||||
|             }  | ||||
|           if ((mp->generation == 3) && (s->cfg->pid != MP220_PID)) | ||||
|             { | ||||
|               for (i = 0; i < s->param->w; i++) | ||||
| 	        { | ||||
| 	          memcpy (mp->linebuf + (c * (n * (i % m) + i / m)),  | ||||
|                       sptr + (c * i), c); | ||||
| 	        } | ||||
|               memcpy (sptr, mp->linebuf, s->param->line_size); | ||||
|             } | ||||
|           sptr += s->param->line_size; | ||||
|         } | ||||
|     } | ||||
|   return ib->rend - sptr; | ||||
| } | ||||
| 
 | ||||
| static unsigned | ||||
| calc_shifting (pixma_t * s) | ||||
| { | ||||
|   mp150_t *mp = (mp150_t *) s->subdriver; | ||||
|   unsigned base_shift; | ||||
| 
 | ||||
|   mp->lines_shift = 0; | ||||
|   if (has_ccd_sensor (s)) | ||||
|     { | ||||
|       switch (s->cfg->pid) | ||||
|         { | ||||
|           case MP970_PID: | ||||
|             if  (s->param->ydpi > 75) | ||||
|               mp->lines_shift = s->param->ydpi / 50; | ||||
|             break; | ||||
| 
 | ||||
|           case MP800_PID: | ||||
|           case MP810_PID: | ||||
|           case MP830_PID: | ||||
|           case MP960_PID: | ||||
|           default:  | ||||
|             mp->lines_shift =  s->param->ydpi / 100; | ||||
|         } | ||||
|       base_shift = mp->lines_shift * s->param->line_size; | ||||
|       switch (s->cfg->pid) | ||||
|         { | ||||
|           case MP970_PID: | ||||
|             mp->shift[0] = 0; | ||||
|             mp->shift[1] = base_shift; | ||||
|             mp->shift[2] = 2 * base_shift; | ||||
|             break; | ||||
| 
 | ||||
|           case MP800_PID: | ||||
|           case MP810_PID: | ||||
|           case MP830_PID: | ||||
|           case MP960_PID: | ||||
|           default: | ||||
|             mp->shift[0] = 2 * base_shift; | ||||
|             mp->shift[1] = base_shift; | ||||
|             mp->shift[2] = 0; | ||||
|         } | ||||
|     } | ||||
|   return mp->lines_shift; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| mp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) | ||||
| { | ||||
|   int error; | ||||
|   mp150_t *mp = (mp150_t *) s->subdriver; | ||||
|   unsigned block_size, bytes_received; | ||||
|   unsigned block_size, bytes_received, proc_buf_size; | ||||
|   uint8_t header[16]; | ||||
| 
 | ||||
|   if (mp->state == state_warmup) | ||||
|  | @ -889,14 +975,14 @@ mp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) | |||
|       mp->state = state_scanning; | ||||
|       mp->last_block = 0; | ||||
| 
 | ||||
|       mp->cb.buf = | ||||
| 	realloc (mp->cb.buf, | ||||
| 		 CMDBUF_SIZE + IMAGE_BLOCK_SIZE + 2 * s->param->line_size); | ||||
|       proc_buf_size = (2 * calc_shifting (s) + 2) * s->param->line_size; | ||||
|       mp->cb.buf = realloc (mp->cb.buf, | ||||
|              CMDBUF_SIZE + IMAGE_BLOCK_SIZE + proc_buf_size); | ||||
|       if (!mp->cb.buf) | ||||
| 	return PIXMA_ENOMEM; | ||||
|       mp->linebuf = mp->cb.buf + CMDBUF_SIZE; | ||||
|       mp->imgbuf = mp->linebuf + s->param->line_size; | ||||
|       mp->linelag = 0; | ||||
|       mp->imgbuf = mp->data_left_ofs = mp->linebuf + s->param->line_size; | ||||
|       mp->data_left_len = 0; | ||||
|     } | ||||
| 
 | ||||
|   do | ||||
|  | @ -911,9 +997,8 @@ mp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) | |||
| 	  mp->state = state_finished; | ||||
| 	  return 0; | ||||
| 	} | ||||
| 
 | ||||
|       memcpy (mp->imgbuf, mp->linebuf, mp->linelag); | ||||
|       error = read_image_block (s, header, mp->imgbuf + mp->linelag); | ||||
|       memmove (mp->imgbuf, mp->data_left_ofs, mp->data_left_len); | ||||
|       error = read_image_block (s, header, mp->imgbuf + mp->data_left_len); | ||||
|       if (error < 0) | ||||
| 	{ | ||||
| 	  if (error == PIXMA_ECANCELED) | ||||
|  | @ -939,19 +1024,16 @@ mp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) | |||
| 	  /* no image data at this moment. */ | ||||
| 	  pixma_sleep (10000); | ||||
| 	} | ||||
|     } | ||||
|   while (block_size == 0); | ||||
| 
 | ||||
|   ib->rptr = mp->imgbuf; | ||||
|   ib->rend = mp->imgbuf + bytes_received; | ||||
|       ib->rptr = mp->imgbuf; | ||||
|       ib->rend = mp->data_left_ofs = mp->imgbuf + mp->data_left_len + bytes_received; | ||||
| 
 | ||||
|   if ((s->param->xdpi > 600) && (mp->generation == 3)) | ||||
|     { | ||||
|       ib->rend += mp->linelag; | ||||
|       mp->linelag = process_high_dpi_3 (s, ib); | ||||
|       ib->rend -= mp->linelag; | ||||
|       memcpy (mp->linebuf, ib->rend, mp->linelag); | ||||
|       mp->data_left_len = post_process_image_data (s, ib); | ||||
|       mp->data_left_ofs -= mp->data_left_len; | ||||
|       ib->rend -= mp->data_left_len; | ||||
|     } | ||||
|   while (ib->rend == ib->rptr); | ||||
| 
 | ||||
|   return ib->rend - ib->rptr; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,8 +59,8 @@ | |||
| :model "PIXMA MP220" | ||||
| :interface "USB" | ||||
| :usbid "0x04a9" "0x1722" | ||||
| :status :untested | ||||
| :comment "Testers needed! Likely to use generation 3 protocol like MP210." | ||||
| :status :good | ||||
| :comment "All resolutions supported (up to 1200DPI)" | ||||
| 
 | ||||
| :model "PIXMA MP450" | ||||
| :interface "USB" | ||||
|  | @ -168,8 +168,8 @@ | |||
| :model "PIXMA MP970" | ||||
| :interface "USB" | ||||
| :usbid "0x04a9" "0x1726" | ||||
| :status :untested | ||||
| :comment "Not working yet, need a USB snoop." | ||||
| :status :good | ||||
| :comment "All resolutions supported (up to 4800DPI)" | ||||
| 
 | ||||
| :model "SmartBase MP360" | ||||
| :interface "USB" | ||||
|  | @ -217,13 +217,13 @@ | |||
| :interface "USB" | ||||
| :usbid "0x04a9" "0x1727" | ||||
| :status :untested | ||||
| :comment "Probably uses the same protocol as MX700 ?" | ||||
| :comment "Probably uses the same protocol as MX310 and MX700 ?" | ||||
| 
 | ||||
| :model "PIXMA MX310" | ||||
| :interface "USB" | ||||
| :usbid "0x04a9" "0x1728" | ||||
| :status :untested | ||||
| :comment "Probably uses the same protocol as MX700 ?" | ||||
| :status :good | ||||
| :comment "Flatbed and ADF scan. All resolutions supported (up to 1200DPI)" | ||||
| 
 | ||||
| :model "PIXMA MX700" | ||||
| :interface "USB" | ||||
|  | @ -235,4 +235,4 @@ | |||
| :interface "USB" | ||||
| :usbid "0x04a9" "0x172c" | ||||
| :status :untested | ||||
| :comment "Does it use Generation 3 protocol ? TBD." | ||||
| :comment "Does it use Generation 3 protocol ?" | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| .TH "sane-pixma" "5" "16 March 2008" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" | ||||
| .TH "sane-pixma" "5" "13 April 2008" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" | ||||
| .IX sane-pixma | ||||
| .SH NAME | ||||
| sane-pixma \- SANE backend for Canon PIXMA MP series | ||||
|  | @ -10,13 +10,15 @@ access to Canon PIXMA multi-function devices (All-in-one printers). | |||
| Currently, the following models work with this backend: | ||||
| .PP | ||||
| .RS | ||||
| PIXMA MP140, MP150, MP160, MP170, MP180, MP210, MP450, MP460, MP470 | ||||
| PIXMA MP140, MP150, MP160, MP170, MP180, MP210, MP220 | ||||
| .br | ||||
| PIXMA MP500, MP510, MP520, MP530, MP600, MP600R, MP610, MP710 | ||||
| PIXMA MP450, MP460, MP470, MP500, MP510, MP520, MP530 | ||||
| .br | ||||
| PIXMA MP800, MP800R, MP810, MP830, MP960  | ||||
| PIXMA MP600, MP600R, MP610, MP710 | ||||
| .br | ||||
| PIXMA MX700  | ||||
| PIXMA MP800, MP800R, MP810, MP830, MP960, MP970  | ||||
| .br | ||||
| PIXMA MX310, MX700 | ||||
| .br | ||||
| MultiPASS MP700, PIXMA MP750 (no grayscale) | ||||
| .RE | ||||
|  | @ -36,7 +38,7 @@ in the backend so that they get recognized and activated. | |||
| Feedback in the Sane-dev mailing list welcome. | ||||
| .PP | ||||
| .RS | ||||
| PIXMA MP220, MP740, MX300, MX310 | ||||
| PIXMA MP740, MX300 | ||||
| .RE | ||||
| .PP | ||||
| The following models may use partly the same Pixma protocol as MPs listed | ||||
|  | @ -45,7 +47,7 @@ experimental. Snoop logs are required to further investigate, please contact | |||
| the Sane-dev mailing list. | ||||
| .PP | ||||
| .RS | ||||
| PIXMA MX850, MP970 | ||||
| PIXMA MX850 | ||||
| .RE | ||||
| .PP | ||||
| .\".PP | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Nicolas Martin
						Nicolas Martin