/* Start scanning */ SANE_Status sane_start (SANE_Handle handle) { struct scanner *s = (struct scanner *) handle; SANE_Status st = SANE_STATUS_GOOD; int duplex = s->val[DUPLEX].w, i; unsigned data_avalible; int start = 0; if (s->thread) { pthread_join (s->thread, NULL); s->thread = 0; } if (!s->scanning) { st = kvs40xx_test_unit_ready (s); if (st) return st; st = wait_document (s); if (st) return st; st = kvs40xx_reset_window (s); if (st) return st; st = kvs40xx_set_window (s, SIDE_FRONT); if (st) return st; if (duplex) { st = kvs40xx_set_window (s, SIDE_BACK); if (st) return st; } st = scan (s); if (st) return st; if (s->val[CROP].b || s->val[LENGTHCTL].b || s->val[LONG_PAPER].b) { unsigned w, h, res = s->val[RESOLUTION].w; SANE_Parameters *p = &s->params; w = 297; /*A3 */ h = 420; p->pixels_per_line = w * res / 25.4 + .5; p->lines = h * res / 25.4 + .5; } else { st = kvs40xx_read_picture_element (s, SIDE_FRONT, &s->params); if (st) return st; } start = 1; s->scanning = 1; s->page = 0; s->read = 0; s->side = SIDE_FRONT; sane_get_parameters (s, NULL); } if (duplex && s->side == SIDE_FRONT && !start) { s->side = SIDE_BACK; s->read = 0; return SANE_STATUS_GOOD; } do { st = get_buffer_status(s, &data_avalible); if (st) goto err; } while (!data_avalible); for (i = 0; i < (duplex ? 2 : 1); i++) { st = buf_init (&s->buf[i], s->side_size); if (st) goto err; } if (pthread_create (&s->thread, NULL, (void *(*)(void *)) read_data, s)) { st = SANE_STATUS_IO_ERROR; goto err; } if (s->val[CROP].b || s->val[LENGTHCTL].b || s->val[LONG_PAPER].b) { pthread_join (s->thread, NULL); s->thread = 0; } return SANE_STATUS_GOOD; err: s->scanning = 0; return st; }
/* Start scanning */ SANE_Status sane_start (SANE_Handle handle) { struct scanner *s = (struct scanner *) handle; SANE_Status st; int duplex = s->val[DUPLEX].w; if (!s->scanning) { unsigned dummy_length; st = kvs20xx_test_unit_ready (s); if (st) return st; st = wait_document (s); if (st) return st; st = kvs20xx_reset_window (s); if (st) return st; st = kvs20xx_set_window (s, SIDE_FRONT); if (st) return st; if (duplex) { st = kvs20xx_set_window (s, SIDE_BACK); if (st) return st; } st = kvs20xx_scan (s); if (st) return st; st = kvs20xx_read_picture_element (s, SIDE_FRONT, &s->params); if (st) return st; if (duplex) { st = get_adjust_data (s, &dummy_length); if (st) return st; } else { dummy_length = 0; } s->scanning = 1; s->page = 0; s->read = 0; s->side = SIDE_FRONT; sane_get_parameters (s, NULL); s->saved_dummy_size = s->dummy_size = dummy_length ? (dummy_length * s->val[RESOLUTION].w / 1200 - 1) * s->params.bytes_per_line : 0; s->side_size = s->params.lines * s->params.bytes_per_line; s->data = realloc (s->data, duplex ? s->side_size * 2 : s->side_size); if (!s->data) { s->scanning = 0; return SANE_STATUS_NO_MEM; } } if (duplex) { unsigned side = SIDE_FRONT; unsigned read, mx; if (s->side == SIDE_FRONT && s->read == s->side_size - s->dummy_size) { s->side = SIDE_BACK; s->read = s->dummy_size; s->dummy_size = 0; return SANE_STATUS_GOOD; } s->read = 0; s->dummy_size = s->saved_dummy_size; s->side = SIDE_FRONT; st = kvs20xx_document_exist (s); if (st) return st; for (mx = s->side_size * 2; !st; mx -= read, side ^= SIDE_BACK) st = kvs20xx_read_image_data (s, s->page, side, &s->data[s->side_size * 2 - mx], mx, &read); } else { unsigned read, mx; s->read = 0; st = kvs20xx_document_exist (s); if (st) return st; DBG (DBG_INFO, "start: %d\n", s->page); for (mx = s->side_size; !st; mx -= read) st = kvs20xx_read_image_data (s, s->page, SIDE_FRONT, &s->data[s->side_size - mx], mx, &read); } if (st && st != SANE_STATUS_EOF) { s->scanning = 0; return st; } s->page++; return SANE_STATUS_GOOD; }