1/* sane - Scanner Access Now Easy. 2 3 Copyright (C) 2007-2008 Philippe Rétornaz 4 5 This file is part of the SANE package. 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the 10 License, or (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. 19 20 As a special exception, the authors of SANE give permission for 21 additional uses of the libraries contained in this release of SANE. 22 23 The exception is that, if you link a SANE library with other files 24 to produce an executable, this does not by itself cause the 25 resulting executable to be covered by the GNU General Public 26 License. Your use of that executable is in no way restricted on 27 account of linking the SANE library code into it. 28 29 This exception does not, however, invalidate any other reasons why 30 the executable file might be covered by the GNU General Public 31 License. 32 33 If you submit changes to SANE to the maintainers to be included in 34 a subsequent release, you agree by submitting the changes that 35 those changes may be distributed with this exception intact. 36 37 If you write modifications of your own for SANE, it is your choice 38 whether to permit this exception to apply to your modifications. 39 If you do not wish that, delete this exception notice. 40 41 This backend is for HP LaserJet M1005 MFP 42 43 Highly inspired from the epson backend 44*/ 45 46#define BUILD 1 47 48#include "../include/sane/config.h" 49#include <math.h> 50 51#include <limits.h> 52#include <stdio.h> 53#include <string.h> 54#include <stdlib.h> 55#include <ctype.h> 56#include <fcntl.h> 57#include <unistd.h> 58#include <errno.h> 59#include <stdint.h> 60#include <netinet/in.h> 61#define BACKEND_NAME hpljm1005 62#include "../include/sane/sanei_backend.h" 63#include "../include/sane/sanei_usb.h" 64#include "../include/sane/saneopts.h" 65 66#define MAGIC_NUMBER 0x41535001 67#define PKT_READ_STATUS 0x0 68#define PKT_UNKNOW_1 0x1 69#define PKT_START_SCAN 0x2 70#define PKT_GO_IDLE 0x3 71#define PKT_DATA 0x5 72#define PKT_READCONF 0x6 73#define PKT_SETCONF 0x7 74#define PKT_END_DATA 0xe 75#define PKT_RESET 0x15 76 77#define RED_LAYER 0x3 78#define GREEN_LAYER 0x4 79#define BLUE_LAYER 0x5 80#define GRAY_LAYER 0x6 81 82#define MIN_SCAN_ZONE 101 83 84struct usbdev_s 85{ 86 SANE_Int vendor_id; 87 SANE_Int product_id; 88 SANE_String_Const vendor_s; 89 SANE_String_Const model_s; 90 SANE_String_Const type_s; 91}; 92 93/* Zero-terminated USB VID/PID array */ 94static struct usbdev_s usbid[] = { 95 {0x03f0, 0x3b17, "Hewlett-Packard", "LaserJet M1005", 96 "multi-function peripheral"}, 97 {0x03f0, 0x5617, "Hewlett-Packard", "LaserJet M1120", 98 "multi-function peripheral"}, 99 {0x03f0, 0x5717, "Hewlett-Packard", "LaserJet M1120n", 100 "multi-function peripheral"}, 101 {0, 0, NULL, NULL, NULL}, 102 {0, 0, NULL, NULL, NULL} 103}; 104 105static int cur_idx; 106 107#define BR_CONT_MIN 0x1 108#define BR_CONT_MAX 0xb 109 110#define RGB 1 111#define GRAY 0 112 113#define MAX_X_H 0x350 114#define MAX_Y_H 0x490 115#define MAX_X_S 220 116#define MAX_Y_S 330 117 118#define OPTION_MAX 9 119 120static SANE_Word resolution_list[] = { 121 7, 75, 100, 150, 200, 300, 600, 1200 122}; 123static SANE_Range range_x = { 0, MAX_X_S, 0 }; 124static SANE_Range range_y = { 0, MAX_Y_S, 0 }; 125 126static SANE_Range range_br_cont = { BR_CONT_MIN, BR_CONT_MAX, 0 }; 127 128static const SANE_String_Const mode_list[] = { 129 SANE_VALUE_SCAN_MODE_GRAY, 130 SANE_VALUE_SCAN_MODE_COLOR, 131 NULL 132}; 133 134#define X1_OFFSET 2 135#define X2_OFFSET 4 136#define Y1_OFFSET 3 137#define Y2_OFFSET 5 138#define RES_OFFSET 1 139#define COLOR_OFFSET 8 140#define BRIGH_OFFSET 6 141#define CONTR_OFFSET 7 142 143#define STATUS_IDLE 0 144#define STATUS_SCANNING 1 145#define STATUS_CANCELING 2 146 147struct device_s 148{ 149 struct device_s *next; 150 SANE_String_Const devname; 151 int idx; /* Index in the usbid array */ 152 int dn; /* Usb "Handle" */ 153 SANE_Option_Descriptor optiond[OPTION_MAX]; 154 char *buffer; 155 int bufs; 156 int read_offset; 157 int write_offset_r; 158 int write_offset_g; 159 int write_offset_b; 160 int status; 161 int width; 162 int height; 163 SANE_Word optionw[OPTION_MAX]; 164 uint32_t conf_data[512]; 165 uint32_t packet_data[512]; 166}; 167 168 169static void 170do_cancel(struct device_s *dev); 171 172 173static struct device_s *devlist_head; 174static int devlist_count; /* Number of element in the list */ 175 176/* 177 * List of pointers to devices - will be dynamically allocated depending 178 * on the number of devices found. 179 */ 180static SANE_Device **devlist = NULL; 181 182/* round() is c99, so we provide our own, though this version won't return -0 */ 183static double 184round2(double x) 185{ 186 return (double)(x >= 0.0) ? (int)(x+0.5) : (int)(x-0.5); 187} 188 189static void 190update_img_size (struct device_s *dev) 191{ 192 int dx, dy; 193 194 /* Only update the width when not scanning, 195 * otherwise the scanner give us the correct width */ 196 if (dev->status == STATUS_SCANNING) 197 { 198 dev->height = -1; 199 return; 200 } 201 202 dx = dev->optionw[X2_OFFSET] - dev->optionw[X1_OFFSET]; 203 dy = dev->optionw[Y2_OFFSET] - dev->optionw[Y1_OFFSET]; 204 205 switch (dev->optionw[RES_OFFSET]) 206 { 207 case 75: 208 dev->width = round2 ((dx / ((double) MAX_X_S)) * 640); 209 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 880); 210 break; 211 case 100: 212 dev->width = round2 ((dx / ((double) MAX_X_S)) * 848); 213 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 1180); 214 break; 215 case 150: 216 dev->width = round2 ((dx / ((double) MAX_X_S)) * 1264); 217 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 1775); 218 break; 219 case 200: 220 dev->width = round2 ((dx / ((double) MAX_X_S)) * 1696); 221 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 2351); 222 break; 223 case 300: 224 dev->width = round2 ((dx / ((double) MAX_X_S)) * 2528); 225 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 3510); 226 break; 227 case 600: 228 dev->width = round2 ((dx / ((double) MAX_X_S)) * 5088); 229 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 7020); 230 break; 231 case 1200: 232 dev->width = round2 ((dx / ((double) MAX_X_S)) * 10208); 233 dev->height = round2 ((dy / ((double) MAX_Y_S)) * 14025); 234 break; 235 } 236 237 DBG(2,"New image size: %dx%d\n",dev->width, dev->height); 238 239} 240 241/* This function is copy/pasted from the Epson backend */ 242static size_t 243max_string_size (const SANE_String_Const strings[]) 244{ 245 size_t size, max_size = 0; 246 int i; 247 248 for (i = 0; strings[i]; i++) 249 { 250 size = strlen (strings[i]) + 1; 251 if (size > max_size) 252 max_size = size; 253 } 254 return max_size; 255} 256 257 258static SANE_Status 259attach (SANE_String_Const devname) 260{ 261 struct device_s *dev; 262 263 dev = malloc (sizeof (struct device_s)); 264 if (!dev) 265 return SANE_STATUS_NO_MEM; 266 memset (dev, 0, sizeof (struct device_s)); 267 268 dev->devname = devname; 269 DBG(1,"New device found: %s\n",dev->devname); 270 271/* Init the whole structure with default values */ 272 /* Number of options */ 273 dev->optiond[0].name = ""; 274 dev->optiond[0].title = NULL; 275 dev->optiond[0].desc = NULL; 276 dev->optiond[0].type = SANE_TYPE_INT; 277 dev->optiond[0].unit = SANE_UNIT_NONE; 278 dev->optiond[0].size = sizeof (SANE_Word); 279 dev->optionw[0] = OPTION_MAX; 280 281 /* resolution */ 282 dev->optiond[RES_OFFSET].name = "resolution"; 283 dev->optiond[RES_OFFSET].title = "resolution"; 284 dev->optiond[RES_OFFSET].desc = "resolution"; 285 dev->optiond[RES_OFFSET].type = SANE_TYPE_INT; 286 dev->optiond[RES_OFFSET].unit = SANE_UNIT_DPI; 287 dev->optiond[RES_OFFSET].type = SANE_TYPE_INT; 288 dev->optiond[RES_OFFSET].size = sizeof (SANE_Word); 289 dev->optiond[RES_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 290 dev->optiond[RES_OFFSET].constraint_type = SANE_CONSTRAINT_WORD_LIST; 291 dev->optiond[RES_OFFSET].constraint.word_list = resolution_list; 292 dev->optionw[RES_OFFSET] = 75; 293 294 /* scan area */ 295 dev->optiond[X1_OFFSET].name = "tl-x"; 296 dev->optiond[X1_OFFSET].title = "tl-x"; 297 dev->optiond[X1_OFFSET].desc = "tl-x"; 298 dev->optiond[X1_OFFSET].type = SANE_TYPE_INT; 299 dev->optiond[X1_OFFSET].unit = SANE_UNIT_MM; 300 dev->optiond[X1_OFFSET].size = sizeof (SANE_Word); 301 dev->optiond[X1_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 302 dev->optiond[X1_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE; 303 dev->optiond[X1_OFFSET].constraint.range = &range_x; 304 dev->optionw[X1_OFFSET] = 0; 305 306 dev->optiond[Y1_OFFSET].name = "tl-y"; 307 dev->optiond[Y1_OFFSET].title = "tl-y"; 308 dev->optiond[Y1_OFFSET].desc = "tl-y"; 309 dev->optiond[Y1_OFFSET].type = SANE_TYPE_INT; 310 dev->optiond[Y1_OFFSET].unit = SANE_UNIT_MM; 311 dev->optiond[Y1_OFFSET].size = sizeof (SANE_Word); 312 dev->optiond[Y1_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 313 dev->optiond[Y1_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE; 314 dev->optiond[Y1_OFFSET].constraint.range = &range_y; 315 dev->optionw[Y1_OFFSET] = 0; 316 317 dev->optiond[X2_OFFSET].name = "br-x"; 318 dev->optiond[X2_OFFSET].title = "br-x"; 319 dev->optiond[X2_OFFSET].desc = "br-x"; 320 dev->optiond[X2_OFFSET].type = SANE_TYPE_INT; 321 dev->optiond[X2_OFFSET].unit = SANE_UNIT_MM; 322 dev->optiond[X2_OFFSET].size = sizeof (SANE_Word); 323 dev->optiond[X2_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 324 dev->optiond[X2_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE; 325 dev->optiond[X2_OFFSET].constraint.range = &range_x; 326 dev->optionw[X2_OFFSET] = MAX_X_S; 327 328 dev->optiond[Y2_OFFSET].name = "br-y"; 329 dev->optiond[Y2_OFFSET].title = "br-y"; 330 dev->optiond[Y2_OFFSET].desc = "br-y"; 331 dev->optiond[Y2_OFFSET].type = SANE_TYPE_INT; 332 dev->optiond[Y2_OFFSET].unit = SANE_UNIT_MM; 333 dev->optiond[Y2_OFFSET].size = sizeof (SANE_Word); 334 dev->optiond[Y2_OFFSET].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 335 dev->optiond[Y2_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE; 336 dev->optiond[Y2_OFFSET].constraint.range = &range_y; 337 dev->optionw[Y2_OFFSET] = MAX_Y_S; 338 339 /* brightness */ 340 dev->optiond[BRIGH_OFFSET].name = "brightness"; 341 dev->optiond[BRIGH_OFFSET].title = "Brightness"; 342 dev->optiond[BRIGH_OFFSET].desc = "Set the brightness"; 343 dev->optiond[BRIGH_OFFSET].type = SANE_TYPE_INT; 344 dev->optiond[BRIGH_OFFSET].unit = SANE_UNIT_NONE; 345 dev->optiond[BRIGH_OFFSET].size = sizeof (SANE_Word); 346 dev->optiond[BRIGH_OFFSET].cap = 347 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 348 dev->optiond[BRIGH_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE; 349 dev->optiond[BRIGH_OFFSET].constraint.range = &range_br_cont; 350 dev->optionw[BRIGH_OFFSET] = 0x6; 351 352 /* contrast */ 353 dev->optiond[CONTR_OFFSET].name = "contrast"; 354 dev->optiond[CONTR_OFFSET].title = "Contrast"; 355 dev->optiond[CONTR_OFFSET].desc = "Set the contrast"; 356 dev->optiond[CONTR_OFFSET].type = SANE_TYPE_INT; 357 dev->optiond[CONTR_OFFSET].unit = SANE_UNIT_NONE; 358 dev->optiond[CONTR_OFFSET].size = sizeof (SANE_Word); 359 dev->optiond[CONTR_OFFSET].cap = 360 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 361 dev->optiond[CONTR_OFFSET].constraint_type = SANE_CONSTRAINT_RANGE; 362 dev->optiond[CONTR_OFFSET].constraint.range = &range_br_cont; 363 dev->optionw[CONTR_OFFSET] = 0x6; 364 365 /* Color */ 366 dev->optiond[COLOR_OFFSET].name = SANE_NAME_SCAN_MODE; 367 dev->optiond[COLOR_OFFSET].title = SANE_TITLE_SCAN_MODE; 368 dev->optiond[COLOR_OFFSET].desc = SANE_DESC_SCAN_MODE; 369 dev->optiond[COLOR_OFFSET].type = SANE_TYPE_STRING; 370 dev->optiond[COLOR_OFFSET].size = max_string_size (mode_list); 371 dev->optiond[COLOR_OFFSET].cap = 372 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; 373 dev->optiond[COLOR_OFFSET].constraint_type = SANE_CONSTRAINT_STRING_LIST; 374 dev->optiond[COLOR_OFFSET].constraint.string_list = mode_list; 375 dev->optionw[COLOR_OFFSET] = RGB; 376 dev->dn = 0; 377 dev->idx = cur_idx; 378 dev->status = STATUS_IDLE; 379 380 dev->next = devlist_head; 381 devlist_head = dev; 382 devlist_count++; 383 384 385 386 return SANE_STATUS_GOOD; 387} 388 389SANE_Status 390sane_init (SANE_Int * version_code, 391 SANE_Auth_Callback __sane_unused__ authorize) 392{ 393 394 if (version_code != NULL) 395 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD); 396 397 DBG_INIT(); 398 399 sanei_usb_init (); 400 401 return SANE_STATUS_GOOD; 402} 403 404void 405sane_exit (void) 406{ 407 /* free everything */ 408 struct device_s *iter; 409 410 if (devlist) 411 { 412 int i; 413 for (i = 0; devlist[i]; i++) 414 free (devlist[i]); 415 free (devlist); 416 devlist = NULL; 417 } 418 if (devlist_head) 419 { 420 iter = devlist_head->next; 421 free (devlist_head); 422 devlist_head = NULL; 423 while (iter) 424 { 425 struct device_s *tmp = iter; 426 iter = iter->next; 427 free (tmp); 428 } 429 } 430 devlist_count = 0; 431} 432 433SANE_Status 434sane_get_devices (const SANE_Device * **device_list, 435 SANE_Bool __sane_unused__ local_only) 436{ 437 struct device_s *iter; 438 int i; 439 440 devlist_count = 0; 441 442 if (devlist_head) 443 { 444 iter = devlist_head->next; 445 free (devlist_head); 446 devlist_head = NULL; 447 while (iter) 448 { 449 struct device_s *tmp = iter; 450 iter = iter->next; 451 free (tmp); 452 } 453 } 454 455 /* Rebuild our internal scanner list */ 456 for (cur_idx = 0; usbid[cur_idx].vendor_id; cur_idx++) 457 sanei_usb_find_devices (usbid[cur_idx].vendor_id, 458 usbid[cur_idx].product_id, attach); 459 460 if (devlist) 461 { 462 for (i = 0; devlist[i]; i++) 463 free (devlist[i]); 464 free (devlist); 465 } 466 467 /* rebuild the sane-API scanner list array */ 468 devlist = malloc (sizeof (devlist[0]) * (devlist_count + 1)); 469 if (!devlist) 470 return SANE_STATUS_NO_MEM; 471 472 memset (devlist, 0, sizeof (devlist[0]) * (devlist_count + 1)); 473 474 for (i = 0, iter = devlist_head; i < devlist_count; i++, iter = iter->next) 475 { 476 devlist[i] = malloc (sizeof (SANE_Device)); 477 if (!devlist[i]) 478 { 479 int j; 480 for (j = 0; j < i; j++) 481 free (devlist[j]); 482 free (devlist); 483 devlist = NULL; 484 return SANE_STATUS_NO_MEM; 485 } 486 devlist[i]->name = iter->devname; 487 devlist[i]->vendor = usbid[iter->idx].vendor_s; 488 devlist[i]->model = usbid[iter->idx].model_s; 489 devlist[i]->type = usbid[iter->idx].type_s; 490 } 491 if (device_list) 492 *device_list = (const SANE_Device **) devlist; 493 return SANE_STATUS_GOOD; 494} 495 496SANE_Status 497sane_open (SANE_String_Const name, SANE_Handle * h) 498{ 499 struct device_s *dev; 500 int ret; 501 502 if(!devlist_head) 503 sane_get_devices(NULL,(SANE_Bool)0); 504 505 dev = devlist_head; 506 507 if (strlen (name)) 508 for (; dev; dev = dev->next) 509 if (!strcmp (name, dev->devname)) 510 break; 511 512 if (!dev) { 513 DBG(1,"Unable to find device %s\n",name); 514 return SANE_STATUS_INVAL; 515 } 516 517 DBG(1,"Found device %s\n",name); 518 519 /* Now open the usb device */ 520 ret = sanei_usb_open (name, &(dev->dn)); 521 if (ret != SANE_STATUS_GOOD) { 522 DBG(1,"Unable to open device %s\n",name); 523 return ret; 524 } 525 526 /* Claim the first interface */ 527 ret = sanei_usb_claim_interface (dev->dn, 0); 528 if (ret != SANE_STATUS_GOOD) 529 { 530 sanei_usb_close (dev->dn); 531 /* if we cannot claim the interface, this is because 532 someone else is using it */ 533 DBG(1,"Unable to claim scanner interface on device %s\n",name); 534 return SANE_STATUS_DEVICE_BUSY; 535 } 536#ifdef HAVE_SANEI_USB_SET_TIMEOUT 537 sanei_usb_set_timeout (30000); /* 30s timeout */ 538#endif 539 540 *h = dev; 541 542 return SANE_STATUS_GOOD; 543} 544 545void 546sane_close (SANE_Handle h) 547{ 548 struct device_s *dev = (struct device_s *) h; 549 550 /* Just in case if sane_cancel() is called 551 * after starting a scan but not while a sane_read 552 */ 553 if (dev->status == STATUS_CANCELING) 554 { 555 do_cancel(dev); 556 } 557 558 sanei_usb_release_interface (dev->dn, 0); 559 sanei_usb_close (dev->dn); 560 561} 562 563const SANE_Option_Descriptor * 564sane_get_option_descriptor (SANE_Handle h, SANE_Int option) 565{ 566 struct device_s *dev = (struct device_s *) h; 567 568 if (option >= OPTION_MAX || option < 0) 569 return NULL; 570 return &(dev->optiond[option]); 571} 572 573static SANE_Status 574getvalue (SANE_Handle h, SANE_Int option, void *v) 575{ 576 struct device_s *dev = (struct device_s *) h; 577 578 if (option != COLOR_OFFSET) 579 *((SANE_Word *) v) = dev->optionw[option]; 580 else 581 { 582 strcpy ((char *) v, 583 dev->optiond[option].constraint.string_list[dev-> 584 optionw[option]]); 585 } 586 return SANE_STATUS_GOOD; 587} 588 589static SANE_Status 590setvalue (SANE_Handle h, SANE_Int option, void *value, SANE_Int * info) 591{ 592 struct device_s *dev = (struct device_s *) h; 593 SANE_Status status = SANE_STATUS_GOOD; 594 int s_unit; 595 int s_unit_2; 596 597 if (option == 0) 598 return SANE_STATUS_UNSUPPORTED; 599 600 601 status = sanei_constrain_value (&(dev->optiond[option]), value, info); 602 603 if (status != SANE_STATUS_GOOD) 604 return status; 605 606 607 608 if (info) 609 *info |= SANE_INFO_RELOAD_PARAMS; 610 switch (option) 611 { 612 case X1_OFFSET: 613 dev->optionw[option] = *((SANE_Word *) value); 614 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_X_S)) 615 * MAX_X_H); 616 s_unit_2 = (int) round2 ((dev->optionw[X2_OFFSET] / ((double) MAX_X_S)) 617 * MAX_X_H); 618 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE) 619 s_unit = s_unit_2 - MIN_SCAN_ZONE; 620 dev->optionw[option] = round2 ((s_unit / ((double) MAX_X_H)) * MAX_X_S); 621 if (info) 622 *info |= SANE_INFO_INEXACT; 623 break; 624 625 case X2_OFFSET: 626 /* X units */ 627 /* convert into "scanner" unit, then back into mm */ 628 dev->optionw[option] = *((SANE_Word *) value); 629 630 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_X_S)) 631 * MAX_X_H); 632 s_unit_2 = (int) round2 ((dev->optionw[X1_OFFSET] / ((double) MAX_X_S)) 633 * MAX_X_H); 634 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE) 635 s_unit = s_unit_2 + MIN_SCAN_ZONE; 636 dev->optionw[option] = round2 ((s_unit / ((double) MAX_X_H)) * MAX_X_S); 637 if (info) 638 *info |= SANE_INFO_INEXACT; 639 break; 640 case Y1_OFFSET: 641 /* Y units */ 642 dev->optionw[option] = *((SANE_Word *) value); 643 644 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_Y_S)) 645 * MAX_Y_H); 646 647 s_unit_2 = (int) round2 ((dev->optionw[Y2_OFFSET] / ((double) MAX_Y_S)) 648 * MAX_Y_H); 649 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE) 650 s_unit = s_unit_2 - MIN_SCAN_ZONE; 651 652 dev->optionw[option] = round2 ((s_unit / ((double) MAX_Y_H)) * MAX_Y_S); 653 if (info) 654 *info |= SANE_INFO_INEXACT; 655 break; 656 case Y2_OFFSET: 657 /* Y units */ 658 dev->optionw[option] = *((SANE_Word *) value); 659 660 s_unit = (int) round2 ((dev->optionw[option] / ((double) MAX_Y_S)) 661 * MAX_Y_H); 662 663 s_unit_2 = (int) round2 ((dev->optionw[Y1_OFFSET] / ((double) MAX_Y_S)) 664 * MAX_Y_H); 665 if (abs (s_unit_2 - s_unit) < MIN_SCAN_ZONE) 666 s_unit = s_unit_2 + MIN_SCAN_ZONE; 667 668 dev->optionw[option] = round2 ((s_unit / ((double) MAX_Y_H)) * MAX_Y_S); 669 if (info) 670 *info |= SANE_INFO_INEXACT; 671 break; 672 case COLOR_OFFSET: 673 if (!strcmp ((char *) value, mode_list[0])) 674 dev->optionw[option] = GRAY; /* Gray */ 675 else if (!strcmp ((char *) value, mode_list[1])) 676 dev->optionw[option] = RGB; /* RGB */ 677 else 678 return SANE_STATUS_INVAL; 679 break; 680 default: 681 dev->optionw[option] = *((SANE_Word *) value); 682 } 683 return SANE_STATUS_GOOD; 684} 685 686SANE_Status 687sane_control_option (SANE_Handle h, SANE_Int option, 688 SANE_Action a, void *v, SANE_Int * i) 689{ 690 691 if (option < 0 || option >= OPTION_MAX) 692 return SANE_STATUS_INVAL; 693 694 if (i) 695 *i = 0; 696 697 698 switch (a) 699 { 700 case SANE_ACTION_GET_VALUE: 701 return getvalue (h, option, v); 702 703 case SANE_ACTION_SET_VALUE: 704 return setvalue (h, option, v, i); 705 706 default: 707 return SANE_STATUS_INVAL; 708 } 709} 710 711SANE_Status 712sane_get_parameters (SANE_Handle h, SANE_Parameters * p) 713{ 714 struct device_s *dev = (struct device_s *) h; 715 716 if (!p) 717 return SANE_STATUS_INVAL; 718 719 p->format = 720 dev->optionw[COLOR_OFFSET] == RGB ? SANE_FRAME_RGB : SANE_FRAME_GRAY; 721 p->last_frame = SANE_TRUE; 722 p->depth = 8; 723 724 update_img_size (dev); 725 p->pixels_per_line = dev->width; 726 p->lines = dev->height; 727 p->bytes_per_line = p->pixels_per_line; 728 if (p->format == SANE_FRAME_RGB) 729 p->bytes_per_line *= 3; 730 731 return SANE_STATUS_GOOD; 732} 733 734static void 735send_pkt (int command, int data_size, struct device_s *dev) 736{ 737 size_t size = 32; 738 739 DBG(100,"Sending packet %d, next data size %d, device %s\n", command, data_size, dev->devname); 740 741 memset (dev->packet_data, 0, size); 742 dev->packet_data[0] = htonl (MAGIC_NUMBER); 743 dev->packet_data[1] = htonl (command); 744 dev->packet_data[5] = htonl (data_size); 745 sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->packet_data, &size); 746} 747 748 749/* s: printer status */ 750/* Return the next packet size */ 751static int 752wait_ack (struct device_s *dev, int *s) 753{ 754 SANE_Status ret; 755 size_t size; 756 DBG(100, "Waiting scanner answer on device %s\n",dev->devname); 757 do 758 { 759 size = 32; 760 ret = 761 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->packet_data, 762 &size); 763 } 764 while (SANE_STATUS_EOF == ret || size == 0); 765 if (s) 766 *s = ntohl (dev->packet_data[4]); 767 return ntohl (dev->packet_data[5]); 768} 769 770static void 771send_conf (struct device_s *dev) 772{ 773 int y1, y2, x1, x2; 774 size_t size = 100; 775 DBG(100,"Sending configuration packet on device %s\n",dev->devname); 776 y1 = (int) round2 ((dev->optionw[Y1_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H); 777 y2 = (int) round2 ((dev->optionw[Y2_OFFSET] / ((double) MAX_Y_S)) * MAX_Y_H); 778 x1 = (int) round2 ((dev->optionw[X1_OFFSET] / ((double) MAX_X_S)) * MAX_X_H); 779 x2 = (int) round2 ((dev->optionw[X2_OFFSET] / ((double) MAX_X_S)) * MAX_X_H); 780 781 DBG(100,"\t x1: %d, x2: %d, y1: %d, y2: %d\n",x1, x2, y1, y2); 782 DBG(100,"\t brightness: %d, contrast: %d\n", dev->optionw[BRIGH_OFFSET], dev->optionw[CONTR_OFFSET]); 783 DBG(100,"\t resolution: %d\n",dev->optionw[RES_OFFSET]); 784 785 dev->conf_data[0] = htonl (0x15); 786 dev->conf_data[1] = htonl (dev->optionw[BRIGH_OFFSET]); 787 dev->conf_data[2] = htonl (dev->optionw[CONTR_OFFSET]); 788 dev->conf_data[3] = htonl (dev->optionw[RES_OFFSET]); 789 dev->conf_data[4] = htonl (0x1); 790 dev->conf_data[5] = htonl (0x1); 791 dev->conf_data[6] = htonl (0x1); 792 dev->conf_data[7] = htonl (0x1); 793 dev->conf_data[8] = 0; 794 dev->conf_data[9] = 0; 795 dev->conf_data[10] = htonl (0x8); 796 dev->conf_data[11] = 0; 797 dev->conf_data[12] = 0; 798 dev->conf_data[13] = 0; 799 dev->conf_data[14] = 0; 800 dev->conf_data[16] = htonl (y1); 801 dev->conf_data[17] = htonl (x1); 802 dev->conf_data[18] = htonl (y2); 803 dev->conf_data[19] = htonl (x2); 804 dev->conf_data[20] = 0; 805 dev->conf_data[21] = 0; 806 dev->conf_data[22] = htonl (0x491); 807 dev->conf_data[23] = htonl (0x352); 808 809 if (dev->optionw[COLOR_OFFSET] == RGB) 810 { 811 dev->conf_data[15] = htonl (0x2); 812 dev->conf_data[24] = htonl (0x1); 813 DBG(100,"\t Scanning in RGB format\n"); 814 } 815 else 816 { 817 dev->conf_data[15] = htonl (0x6); 818 dev->conf_data[24] = htonl (0x0); 819 DBG(100,"\t Scanning in Grayscale format\n"); 820 } 821 sanei_usb_write_bulk (dev->dn, (unsigned char *) dev->conf_data, &size); 822} 823 824static SANE_Status 825get_data (struct device_s *dev) 826{ 827 int color; 828 size_t size; 829 int packet_size; 830 unsigned char *buffer = (unsigned char *) dev->packet_data; 831 if (dev->status == STATUS_IDLE) 832 return SANE_STATUS_IO_ERROR; 833 /* first wait a standard data pkt */ 834 do 835 { 836 size = 32; 837 sanei_usb_read_bulk (dev->dn, buffer, &size); 838 if (size) 839 { 840 if (ntohl (dev->packet_data[0]) == MAGIC_NUMBER) 841 { 842 if (ntohl (dev->packet_data[1]) == PKT_DATA) 843 break; 844 if (ntohl (dev->packet_data[1]) == PKT_END_DATA) 845 { 846 dev->status = STATUS_IDLE; 847 DBG(100,"End of scan encountered on device %s\n",dev->devname); 848 send_pkt (PKT_GO_IDLE, 0, dev); 849 wait_ack (dev, NULL); 850 wait_ack (dev, NULL); 851 send_pkt (PKT_UNKNOW_1, 0, dev); 852 wait_ack (dev, NULL); 853 send_pkt (PKT_RESET, 0, dev); 854 sleep (2); /* Time for the scanning head to go back home */ 855 return SANE_STATUS_EOF; 856 } 857 } 858 } 859 } 860 while (1); 861 packet_size = ntohl (dev->packet_data[5]); 862 if (!dev->buffer) 863 { 864 dev->bufs = packet_size - 24 /* size of header */ ; 865 if (dev->optionw[COLOR_OFFSET] == RGB) 866 dev->bufs *= 3; 867 dev->buffer = malloc (dev->bufs); 868 if (!dev->buffer) 869 return SANE_STATUS_NO_MEM; 870 dev->write_offset_r = 0; 871 dev->write_offset_g = 1; 872 dev->write_offset_b = 2; 873 874 } 875 /* Get the "data header" */ 876 do 877 { 878 size = 24; 879 sanei_usb_read_bulk (dev->dn, buffer, &size); 880 } 881 while (!size); 882 color = ntohl (dev->packet_data[0]); 883 packet_size -= size; 884 dev->width = ntohl (dev->packet_data[5]); 885 DBG(100,"Got data size %d on device %s. Scan width: %d\n",packet_size, dev->devname, dev->width); 886 /* Now, read the data */ 887 do 888 { 889 int j; 890 int i; 891 int ret; 892 do 893 { 894 size = packet_size > 512 ? 512 : packet_size; 895 ret = sanei_usb_read_bulk (dev->dn, buffer, &size); 896 } 897 while (!size || ret != SANE_STATUS_GOOD); 898 packet_size -= size; 899 switch (color) 900 { 901 case RED_LAYER: 902 DBG(101,"Got red layer data on device %s\n",dev->devname); 903 i = dev->write_offset_r + 3 * size; 904 if (i > dev->bufs) 905 i = dev->bufs; 906 for (j = 0; dev->write_offset_r < i; dev->write_offset_r += 3) 907 dev->buffer[dev->write_offset_r] = buffer[j++]; 908 break; 909 case GREEN_LAYER: 910 DBG(101,"Got green layer data on device %s\n",dev->devname); 911 i = dev->write_offset_g + 3 * size; 912 if (i > dev->bufs) 913 i = dev->bufs; 914 for (j = 0; dev->write_offset_g < i; dev->write_offset_g += 3) 915 dev->buffer[dev->write_offset_g] = buffer[j++]; 916 break; 917 case BLUE_LAYER: 918 DBG(101,"Got blue layer data on device %s\n",dev->devname); 919 i = dev->write_offset_b + 3 * size; 920 if (i > dev->bufs) 921 i = dev->bufs; 922 for (j = 0; dev->write_offset_b < i; dev->write_offset_b += 3) 923 dev->buffer[dev->write_offset_b] = buffer[j++]; 924 break; 925 case GRAY_LAYER: 926 DBG(101,"Got gray layer data on device %s\n",dev->devname); 927 if (dev->write_offset_r + (int)size >= dev->bufs) 928 size = dev->bufs - dev->write_offset_r; 929 memcpy (dev->buffer + dev->write_offset_r, buffer, size); 930 dev->write_offset_r += size; 931 break; 932 } 933 } 934 while (packet_size > 0); 935 return SANE_STATUS_GOOD; 936} 937 938SANE_Status 939sane_start (SANE_Handle h) 940{ 941 struct device_s *dev = (struct device_s *) h; 942 int status; 943 size_t size; 944 945 dev->read_offset = 0; 946 dev->write_offset_r = 0; 947 dev->write_offset_g = 1; 948 dev->write_offset_b = 2; 949 950 free (dev->buffer); 951 dev->buffer = NULL; 952 953 954 send_pkt (PKT_RESET, 0, dev); 955 send_pkt (PKT_READ_STATUS, 0, dev); 956 wait_ack (dev, &status); 957 if (status) 958 return SANE_STATUS_IO_ERROR; 959 960 send_pkt (PKT_READCONF, 0, dev); 961 962 if ((size = wait_ack (dev, NULL))) 963 { 964 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size); 965 } 966 send_pkt (PKT_SETCONF, 100, dev); 967 send_conf (dev); 968 wait_ack (dev, NULL); 969 970 send_pkt (PKT_START_SCAN, 0, dev); 971 wait_ack (dev, NULL); 972 if ((size = wait_ack (dev, NULL))) 973 { 974 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size); 975 } 976 if ((size = wait_ack (dev, NULL))) 977 { 978 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size); 979 } 980 if ((size = wait_ack (dev, NULL))) 981 { 982 sanei_usb_read_bulk (dev->dn, (unsigned char *) dev->conf_data, &size); 983 } 984 985 dev->status = STATUS_SCANNING; 986 /* Get the first data */ 987 return get_data (dev); 988} 989 990 991static void 992do_cancel(struct device_s *dev) 993{ 994 while (get_data (dev) == SANE_STATUS_GOOD); 995 free (dev->buffer); 996 dev->buffer = NULL; 997} 998 999static int 1000min3 (int r, int g, int b) 1001{ 1002 /* Optimize me ! */ 1003 g--; 1004 b -= 2; 1005 if (r < g && r < b) 1006 return r; 1007 if (b < r && b < g) 1008 return b; 1009 return g; 1010} 1011 1012SANE_Status 1013sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len) 1014{ 1015 struct device_s *dev = (struct device_s *) h; 1016 int available; 1017 int ret; 1018 *len = 0; 1019 if (dev->status == STATUS_IDLE) 1020 return SANE_STATUS_IO_ERROR; 1021 if (dev->optionw[COLOR_OFFSET] == RGB) 1022 { 1023 while (min3 (dev->write_offset_r, dev->write_offset_g, 1024 dev->write_offset_b) <= dev->read_offset) 1025 { 1026 ret = get_data (dev); 1027 if (ret != SANE_STATUS_GOOD) 1028 { 1029 if (min3 (dev->write_offset_r, 1030 dev->write_offset_g, 1031 dev->write_offset_b) <= dev->read_offset) 1032 return ret; 1033 } 1034 } 1035 available = min3 (dev->write_offset_r, dev->write_offset_g, 1036 dev->write_offset_b); 1037 } 1038 else 1039 { 1040 while (dev->write_offset_r <= dev->read_offset) 1041 { 1042 ret = get_data (dev); 1043 if (ret != SANE_STATUS_GOOD) 1044 if (dev->write_offset_r <= dev->read_offset) 1045 return ret; 1046 } 1047 available = dev->write_offset_r; 1048 } 1049 *len = available - dev->read_offset; 1050 if (*len > maxlen) 1051 *len = maxlen; 1052 memcpy (buf, dev->buffer + dev->read_offset, *len); 1053 dev->read_offset += *len; 1054 if (dev->read_offset == dev->bufs) 1055 { 1056 free (dev->buffer); 1057 dev->buffer = NULL; 1058 dev->read_offset = 0; 1059 dev->write_offset_r = 0; 1060 dev->write_offset_g = 1; 1061 dev->write_offset_b = 2; 1062 } 1063 1064 /* Special case where sane_cancel is called while scanning */ 1065 if (dev->status == STATUS_CANCELING) 1066 { 1067 do_cancel(dev); 1068 return SANE_STATUS_CANCELLED; 1069 } 1070 return SANE_STATUS_GOOD; 1071} 1072 1073void 1074sane_cancel (SANE_Handle h) 1075{ 1076 struct device_s *dev = (struct device_s *) h; 1077 1078 1079 if (dev->status == STATUS_SCANNING) 1080 { 1081 dev->status = STATUS_CANCELING; 1082 return; 1083 } 1084 1085 free (dev->buffer); 1086 dev->buffer = NULL; 1087} 1088 1089SANE_Status 1090sane_set_io_mode (SANE_Handle __sane_unused__ handle, 1091 SANE_Bool __sane_unused__ non_blocking) 1092{ 1093 return SANE_STATUS_UNSUPPORTED; 1094} 1095 1096SANE_Status 1097sane_get_select_fd (SANE_Handle __sane_unused__ handle, 1098 SANE_Int __sane_unused__ * fd) 1099{ 1100 return SANE_STATUS_UNSUPPORTED; 1101} 1102