diff options
296 files changed, 77856 insertions, 61504 deletions
diff --git a/.editorconfig b/.editorconfig index 0faa31d..107f9ec 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,3 +12,7 @@ root = true ; look no further charset = utf-8 insert_final_newline = true trim_trailing_whitespace = true + +[backend/escl/*] +indent_size = 4 +indent_style = space diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f35992f..5c8758e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,22 +6,25 @@ variables: REGISTRY_HUB: "registry.gitlab.com/sane-project/ci-envs" CONFIGURE_MINI: "--enable-silent-rules" - CONFIGURE_FULL: "--with-usb --enable-avahi --enable-pnm-backend" + CONFIGURE_FULL: "--with-usb --enable-avahi --enable-pnm-backend --with-libcurl" stages: - - prepare + - tarball - compile - - archive + - snapshot - release -prepare: - image: $REGISTRY_HUB:debian-stretch-mini - stage: prepare +# This job creates the source tarball that is the *sole* input to our +# compile stage. The job is meant to be run on the stable release of +# Debian GNU/Linux. + +make-dist: + image: $REGISTRY_HUB:debian-buster-mini + stage: tarball script: - git ls-files | xargs ./tools/style-check.sh - ./autogen.sh - ./tools/create-changelog.sh - - ./tools/update-upstreams.sh - ./configure - make dist artifacts: @@ -38,15 +41,26 @@ prepare: - ./configure $CONFIGURE_OPTS - make -j2 -k $MAKE_FLAGS -compile:debian-9-mini: - image: $REGISTRY_HUB:debian-stretch-mini +debian-9-full: + image: $REGISTRY_HUB:debian-stretch-full + variables: + CONFIGURE_OPTS: "$CONFIGURE_MINI $CONFIGURE_FULL" + MAKE_FLAGS: "CFLAGS=-Werror CXXFLAGS=-Werror" + <<: *compile_definition + +debian-10-mini: + image: $REGISTRY_HUB:debian-buster-mini variables: CONFIGURE_OPTS: "$CONFIGURE_MINI" MAKE_FLAGS: "CFLAGS=-Werror" <<: *compile_definition -compile:debian-9-full: - image: $REGISTRY_HUB:debian-stretch-full +# In addition to the regular compile check, the full Debian stable +# environment is used to keep some of the HTML documentation that's +# available from our website up-to-date. + +debian-10-full: + image: $REGISTRY_HUB:debian-buster-full variables: CONFIGURE_OPTS: "$CONFIGURE_MINI $CONFIGURE_FULL" MAKE_FLAGS: "CFLAGS=-Werror CXXFLAGS=-Werror" @@ -62,43 +76,34 @@ compile:debian-9-full: - doc/sanei-html expire_in: 1 day -compile:debian-10-mini: - image: $REGISTRY_HUB:debian-buster-mini - variables: - CONFIGURE_OPTS: "$CONFIGURE_MINI" - #MAKE_FLAGS: "CFLAGS=-Werror" - <<: *compile_definition - -compile:debian-10-full: - image: $REGISTRY_HUB:debian-buster-full - variables: - CONFIGURE_OPTS: "$CONFIGURE_MINI $CONFIGURE_FULL" - #MAKE_FLAGS: "CFLAGS=-Werror" - <<: *compile_definition - -compile:fedora-29-clang: - image: $REGISTRY_HUB:fedora-29-clang +fedora-31-clang: + image: $REGISTRY_HUB:fedora-31-clang variables: CONFIGURE_OPTS: "$CONFIGURE_MINI $CONFIGURE_FULL" <<: *compile_definition -compile:fedora-30-clang: - image: $REGISTRY_HUB:fedora-30-clang +alpine-3.11-musl: + image: $REGISTRY_HUB:alpine-3.11-musl variables: CONFIGURE_OPTS: "$CONFIGURE_MINI $CONFIGURE_FULL" <<: *compile_definition -compile:alpine-3.10-musl: - image: $REGISTRY_HUB:alpine-3.10-musl - variables: - CONFIGURE_OPTS: "$CONFIGURE_MINI $CONFIGURE_FULL" - <<: *compile_definition +# This snapshot stage job makes sure that the source tarball has all +# it needs to rebuild itself, install everything built and cleans up +# without leaving any droppings behind when uninstalling. The build +# result will be available as a snapshot for a limited time period. +# People that prefer a source tarball to work with should use this +# snapshot. +# Some HTML documentation derived from this project's source is also +# uploaded for use by our website so it uses the latest information. +# It gets these artifacts from the full compile job on Debian stable, +# hence the dependency. -archive: - image: $REGISTRY_HUB:debian-stretch-full - stage: archive +make-distcheck: + image: $REGISTRY_HUB:debian-buster-full + stage: snapshot dependencies: - - compile:debian-9-full + - debian-10-full script: - tar xzf sane-backends-*.tar.gz --strip-components=1 - rm sane-backends-*.tar.gz @@ -109,8 +114,13 @@ archive: - sane-backends-*.tar.gz - lists - doc/sanei-html + expire_in: 90 days + +# For release tags only, this manual job handles putting all of the +# releasables on the Project Releases page. See the script for more +# details. -release: +upload: image: alpine stage: release before_script: @@ -32,6 +32,7 @@ Backends: epson: Karl Heinz Kremer epson2: Alessandro Zummo epsonds: Alessandro Zummo + escl: Touboul Nathane, Thierry HUCHARD (*) fujitsu: Randolph Bentson, Frederik Ramm, Oliver Schirrmeister, m. allan noah (*) genesys: Henning Geinitz, Gerhard Jaeger (*), Stéphane Voltz, @@ -248,9 +249,11 @@ Sergey Vlasov <vsu@altlinux.ru> Simon Krix <kinsei@users.sourceforge.net> Simon Munton <simon@munton.demon.co.uk> Stéphane Voltz <stef.dev@free.fr> +Thierry HUCHARD <thierry@ordissimo.com> Thomas Soumarmon <soumarmt@nerim.net> Tom Martone <tom@martoneconsulting.com> Tom Wang <tom.wang@mustek.com.tw> +Touboul Nathane <nathane.touboul@gmail.com> Tristan Tarrant <ttarrant@etnoteam.it> Troy Rollo <sane@troy.rollo.name> Ullrich Sigwanz <usigwanz@freesurf.ch> diff --git a/ChangeLogs/ChangeLog-1.0.11 b/ChangeLogs/ChangeLog-1.0.11 new file mode 100644 index 0000000..2591ba8 --- /dev/null +++ b/ChangeLogs/ChangeLog-1.0.11 @@ -0,0 +1,10 @@ +****** Release of sane-backends 1.0.12. End of code freeze ****** + +2003-02-09 Henning Meier-Geinitz <henning@meier-geinitz.de> + + * frontend/saned.c sanei/sanei_codec_bin.c sanei/sanei_wire.c: Check + the IP address of the remote host before any communication occurs. + Check for a errors before trsuting values that came from remote. + Make sure that strings are 0-terminated. + +Older entries can be found in ChangeLog-1.0.10. diff --git a/ChangeLogs/ChangeLog-1.0.12 b/ChangeLogs/ChangeLog-1.0.12 index f0eb34a..1b106f1 100644 --- a/ChangeLogs/ChangeLog-1.0.12 +++ b/ChangeLogs/ChangeLog-1.0.12 @@ -957,4 +957,4 @@ * configure configure.in: Warnings enabled again. Used extra version -cvs. -Older entries can be found in ChangeLog-1.0.10. +Older entries can be found in ChangeLog-1.0.11. diff --git a/ChangeLogs/ChangeLog-1.0.28 b/ChangeLogs/ChangeLog-1.0.28 new file mode 100644 index 0000000..0a161f1 --- /dev/null +++ b/ChangeLogs/ChangeLog-1.0.28 @@ -0,0 +1,4695 @@ +commit 5aa523289f82d1c7f01dde601356214920646542 (HEAD, tag: 1.0.28, origin/master) +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-31 20:39:43 +0900 + + NEWS: Document changes for upcoming release + +commit 7799a072b4ee31f7848bac7b52b916dd8d627817 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-30 22:40:11 +0900 + + CI: Add a scripted release process + +commit a8d4d4b7786e0cca227ab716f9d865bc9c288b25 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-07-29 22:34:13 +0200 + + pixma: Canon PIXMA TS8200 Series is working + + https://alioth-lists.debian.net/pipermail/sane-devel/2019-July/036877.html + +commit 9dce0eaf74facef88fae83ba4d7f9fe886307d4c +Merge: 05bdcbd8 a4e122ad +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-07-29 17:27:07 +0200 + + Merge branch 'update_de_translation' + +commit a4e122add55e4b315d96183ced77acc76ab74737 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-07-28 23:04:23 +0200 + + update German translation + +commit ef11a785404c9f9bb663b2cc3d14d956c7fec4d8 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-07-27 13:11:28 +0200 + + 1st bunch of updated German translation + +commit 05bdcbd81a5a92da12e1d4e1559d3f7faf7782ac +Merge: 8eb5850f d4164a73 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-27 06:49:23 +0000 + + Merge branch 'en_GB_translation' into 'master' + + Updated en_GB translations + + See merge request sane-project/backends!89 + +commit d4164a7320e3b73547ae624817e974e1fb2086e3 +Author: Ralph Little <littlesincanada@yahoo.co.uk> +Date: 2019-07-26 23:20:29 -0700 + + Fix trailing whitespace and update translator + +commit 78359453e1c21af2055559be99040d979aececdb +Author: Ralph Little <littlesincanada@yahoo.co.uk> +Date: 2019-07-26 10:05:41 -0700 + + Updated en_GB translations + +commit 8eb5850f2749ba8b8c7e1d8e4d7aed18d3adf67a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-26 13:55:23 +0900 + + po/nl.po: Update Dutch translations + + [skip ci] + +commit 3a0f0df8fb0bf63c2980b80950b4314b93830ba7 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-23 21:15:24 +0900 + + po/*.po: Sync with latest source + +commit 97f04e16e462f61cb87a0acc19868c3357c259eb +Merge: 8ae2569a a8a5f58f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-22 23:13:51 +0000 + + Merge branch 'genesys-fix-calibration' into 'master' + + genesys: Fix crash when deserializing calibration files + + Closes #97 + + See merge request sane-project/backends!88 + +commit a8a5f58f21554af7c4c945fa07ed33fa03fc0421 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-23 02:00:44 +0300 + + genesys: Add tests for serialization of calibration data + +commit 25ed10029cea095e5e757f12b5dccf46eb4ca973 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-23 02:00:43 +0300 + + genesys: Make set_calibration_value() more robust + +commit b9fb97e0f77efba9059834096845a1d1a49d20e6 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-23 02:00:42 +0300 + + genesys: Make serialization of calibration data less error prone + +commit 8ae2569a879c39f520120f33bda94991b1dd10ab +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-17 18:26:59 +0900 + + INSTALL.linux: Document need to run autogen.sh for clean checkouts + + Fixes #102. + +commit cb8171734110fd3f42a24b57be735163f903076b +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-14 17:09:33 +0900 + + .gitignore: more build artifacts + +commit dc328a8d5fdf3daf4aa7deaecb46bd69797a99c6 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-14 17:08:08 +0900 + + ChangeLog: Fix awkward grammar + +commit c52eef6e215cb9f3bfab19a64dbcd96d39aaca25 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-14 14:03:56 +0900 + + CI: Drop Debian 8, add Debian 10 + + This uses the updated Debian images which now use codenames instead + of version numbers. + + Note that `CFLAGS=-Werror` has been disabled until such time as all + new warnings have been addressed. + +commit 3fb0f020154eecb95a81e0ab32a441709ead361f +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-10 22:58:40 +0900 + + utsushi.desc: Sync with upstream + +commit 7b2d2cd0b3b6a2052635a35bdf4d0eeab10a3b5d +Merge: 6f6a4928 4742f213 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-07 02:16:49 +0000 + + Merge branch 'fix-warnings-memset-size' into 'master' + + Fix invocations of memset with incorrect size + + See merge request sane-project/backends!87 + +commit 4742f213185c9c18f5a194a133adc2752b97660d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-06 22:14:11 +0300 + + Fix invocations of memset with incorrect size + +commit 6f6a4928741ce99dd6c4d5fe4eed5357d11e9964 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-07-03 22:19:52 +0900 + + Raise the bar for archiving of source tarballs + + They now have to pass a `make distcheck`. The compile stage takes + care of compiler errors/warnings. We are interested in all checks + passing and the source archive being self-consistent. + +commit 14e00fa360839fbb0222c742e8f5f31c530998a4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-30 21:58:57 +0900 + + Drop Linux Software Map file; it has outlived its purpose + + Source and binary packages are readily available from most major Linux + distributions. + +commit 02b0a7e4b6a1ba02b566d96f5aa477e32a8efdb0 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-30 17:48:34 +0900 + + m4: Move byteorder.m4 back to m4/ directory + + There is little value in putting this in its own directory just + because it is a non-generated file. + +commit 2f14ac2fcc6124c7170fdc2bbb868813c5bdfeb7 +Merge: 72d68c73 640fa9db +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-05 23:39:04 +0000 + + Merge branch 'genesys-error-handling' into 'master' + + genesys: Improve error handling + + See merge request sane-project/backends!86 + +commit 640fa9dbbaaab7f03b7aff0e9d6abcc17ce4689e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-06 02:10:08 +0300 + + genesys: Always initialize status variable + +commit 0454f42c36422c1d7b3c3595be0a10bc13da4be1 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-06 02:10:07 +0300 + + genesys: Report USB errors via exceptions to reduce code duplication + +commit b9cd547aea749ee1064fec6a8a3bafba88761efa +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-06 02:10:06 +0300 + + genesys: Support printf-like messages in debug helper + +commit 22b7fb5105e8e32936e540c8f4276d167ee9508d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-06 02:10:05 +0300 + + genesys: Move more error functionality to genesys_error.{h,cc} + +commit 942f3fbbf7083d77f5af96455f523c577148f4d7 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-06 02:10:04 +0300 + + genesys: Move error-related functions to separate header + +commit 9d07e2108a5fdc45136cb73be7617ba80d448431 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-07-06 02:10:03 +0300 + + genesys: Support message argument to exceptions + +commit 72d68c7367e4713a340ea1ab109360ce9788266d +Merge: ec8017a8 14bbe802 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 23:16:47 +0000 + + Merge branch 'genesys-canoscan-8600f' into 'master' + + genesys: Preparation for infrared channel support on 8600F (part 2) + + See merge request sane-project/backends!84 + +commit ec8017a8c0238ba319b87d94fa7214cd2cb92c86 +Author: Alex Belkin <abc@telekom.ru> +Date: 2019-06-30 18:54:46 +0300 + + xerox_mfp: Mark SCX-4x16 as unsupported + + As reported by Andrew Sotnikov in issue #95 Samsung SCX-4216F is not + really supported. Change SCX-4x16 status from untested to unsupported. + Closes #95. + +commit 14bbe802dbdd748d439bb54c62800ad73141880f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:29 +0300 + + genesys: Move move_to_ta() calls out of *_init_regs_for_*() + +commit a92187edadb28c071c092ce17ffdd13759723d91 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:28 +0300 + + genesys: Move moving to home out of *_init_regs_for_scan() + +commit 442ffd048663994bb4b7a1a884e6abd49f65709e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:27 +0300 + + genesys: Move waiting for motor stop out of *_init_regs_for_scan() + +commit bba75702b6d8b136562bc6d13c466d5d8232716a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:26 +0300 + + genesys: Add utility to print debug messages upon function exit + +commit 397994b215605814713f008a474f8ff12607bd07 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:25 +0300 + + genesys: Make exposure configuration more consistent + +commit 1e7da8638e34168ad2ba656e7be51ac7c088c50c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:24 +0300 + + genesys: Use a more descriptive filename for coarse gain debug images + +commit 6d11f6df25a5fc764781c097a592366d33c01d9c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:23 +0300 + + genesys: Fix support for large exposures on GL843 + +commit f41440ef9fd7ffc377939725e9454ef931860909 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:22 +0300 + + genesys: Extract debug_dump for Genesys_Current_Setup + +commit fe8383543dbf3d8abb3addbdc3d144213954390a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:21 +0300 + + genesys: Remove code for G4050 CCD that's unused and likely incorrect + +commit 7bd68b5225f4feeccd61c54a11441087846dc82f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:20 +0300 + + genesys: Fix crash in sane_open_impl due to uninitialized variable + +commit 616c86de2fa70d852ebed3659b3c224127fdbf93 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:19 +0300 + + genesys: Fix incorrect use of TGTIME for pixel coordinates + +commit 89d06c9a3aa3f6013ee9fc94e2d30e61a2484d6c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:18 +0300 + + genesys: Fix error handling in the presence of exceptions + +commit 3050f50b256dd7f902fd02549959a168772113c5 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:17 +0300 + + genesys: Add a macro to convert status return to exception + +commit 1685e6e8636dbfe77e01f865c0ab50e8ccc51feb +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:16 +0300 + + genesys: Return bool out of *_is_compatible_calibration() + +commit eaa4cb77664122251a9085a7fd974c323359c641 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-30 14:05:15 +0300 + + genesys: Return void out of *_calculate_current_setup() + +commit 7a07f47b4796f4d4c4f853b8bf76edd5c424f291 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-30 14:53:00 +0900 + + Include po/README in the source tarball + + Makefile.in.in ignores EXTRA_DIST. + +commit 2ea6e8eaaa214da7a551070763ef8e4f370018db +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-30 11:52:33 +0900 + + po: Fix inconsistent word wrapping when using custom width + + This fixes test failures run during a `make distcheck` for generated + message catalogs for LINGUAS such as `en@boldquot` and `en@quot`. + +commit f29e1c88def371a227d0dbd9de7dcb64eae863d5 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-30 11:51:55 +0900 + + Make potential issues stick out when running `make distcheck` + +commit 9b109a7bd70892f69228d916fc19c2bbd3594f61 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-30 11:17:59 +0900 + + Fix typo + +commit 7af0d47e2957c7c53884904656ef8b9f39b75b53 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-30 11:15:20 +0900 + + Keep warning out of redirected image data. Fixes testsuite + +commit adc64520eedbdea6946c6a7b05ba2d9da15917a3 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-29 17:31:25 +0900 + + Fix test suite, following bf00b9f49c1ed91e898e5c6f4bc93f7c483c651e + +commit 02d33a0e6d8712c5e1fa18ec5c549cde8bcd3792 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-29 17:08:52 +0900 + + Take "advantage" of CI environment changes + + The mini variant now has everything needed to roll a source tarball. + It also has git installed so we don't need a convoluted find for our + style check anymore. + +commit 1017d790b61fce2944ea57f2fe4a1a767c09b505 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-29 17:29:15 +0900 + + Always use the latest upstream config.{guess,sub} in source tarballs + + This was one of the release tasks but we may as well find out as soon + as possible whether these break anything ;-) + +commit b596f9887998fc2f2e30ce904bb42e37e428ddfd +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-29 15:57:04 +0900 + + Include an up-to-date ChangeLog with every build + +commit 8b2fa76497f195208623298d129a2c3fd7917c1b +Merge: bf00b9f4 0dd1feec +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-27 20:00:38 +0900 + + Merge branch 'yurchor:uk_update' + +commit 0dd1feec2d62caddbe7e9702a213cf87c3e5b027 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-27 20:00:05 +0900 + + po/uk.po: Remove trailing blank line + +commit d976a5124fdc300bebf67ff09b93a5cea64c2027 +Author: Yuri Chornoivan <yurchor@ukr.net> +Date: 2019-06-26 18:18:47 +0300 + + Update Ukrainian translation + +commit bf00b9f49c1ed91e898e5c6f4bc93f7c483c651e +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-25 21:54:37 +0900 + + Use git to put a version in configure + + CI has been using this for a long time. Now that generated files are + no longer in the repository, new clones require autotools already and + adding a git requirement doesn't seem like a big burden. + +commit 2ab39228b9120b0aba4e71269edf8fdbc5a45def +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-25 21:52:48 +0900 + + Ignore generated English message catalogs w/ quotation marks + +commit 9bbb2b37a189bc275bc11a655e832bb781b7d998 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-20 20:02:15 +0900 + + Bump Alpine build from 3.9 to 3.10 + +commit f3577168d2bb8ed9fd7bdf53997ad511ac800870 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-20 19:47:32 +0900 + + autogen.sh: Fix out-of-tree invocation + + The check for unsubstituted macros on configure would silently pass + if configure was not created in the current working directory. + +commit ec1a614d6b73214a3510e9654c0f33d4a876bc3e +Merge: f901462f 9173e5db +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-20 08:58:33 +0000 + + Merge branch 'genesys-canoscan-8600f' into 'master' + + genesys: Preparation for infrared channel support on 8600F + + See merge request sane-project/backends!82 + +commit f901462f9937e884c4da7bfe9e96f6d12dfdccf1 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-19 21:12:51 +0900 + + Fix AS_CASE clause matching + + See https://alioth-lists.debian.net/pipermail/sane-devel/2019-June/036809.html + +commit 46e98476acc831c43cc60fb82756aad19b214e5d +Merge: 6d95bc19 8aa5318f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-16 15:40:29 +0000 + + Merge branch 'genesys-canoscan-8600f' into 'master' + + genesys: Add initial support for 2400 and 4800 dpi transparency scanning on CanoScan 8600F + + See merge request sane-project/backends!81 + +commit 6d95bc191f796eef07da3f5334d840e8b31bf4cf +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-16 21:40:39 +0900 + + Drop unneeded C++ compiler flag additions to AM_CXXFLAGS. Re #92 + + The AX_CXX_COMPILE_STDCXX_11 macro takes care of doing so if needed + already. + +commit a4862d8526ca238fb667658a4bcd83de27915cb8 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-16 21:39:45 +0900 + + Predicate genesys compilation on documented variable. Re #92 + +commit 424bb7d923965327a28e303d1c424d5fc00e977c +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-06-16 13:13:48 +0200 + + INSTALL.linux: add missing development environment packages + +commit 4c05fb474282c64c8e700ab9852b465eda32617e +Merge: cadf5a9b f111032e +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-15 06:50:27 +0000 + + Merge branch 'backend/as6e' into 'master' + + as6e: Avoid out of bound access + + See merge request sane-project/backends!31 + +commit cadf5a9b1a9e62829fe630b474d91c5a94c4e68a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-15 14:45:36 +0900 + + Prevent segfault in case strndup cannot allocate memory + + This complements 18f9e5598c224e90554d333b7f9f05ba8fa14ad0 + +commit f9eb32317abf2f109fe21478358e637750df7f32 +Merge: d22516c7 0b5ab0b5 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-15 05:43:06 +0000 + + Merge branch 'sanei-usb-testing-mode-prep' into 'master' + + sanei: Preparation to support capture and replay of USB data for testing + + See merge request sane-project/backends!74 + +commit d22516c76ac52c3b5208b62fc82312b223efc7ad +Merge: 767cbfaa 9c42d6ac +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-12 10:48:14 +0000 + + Merge branch 'remove-autoconf-generated-files' into 'master' + + Remove autoconf generated files + + See merge request sane-project/backends!72 + +commit 9173e5dbddf5f616ae2343222315310edfad2ccf +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:30 +0300 + + genesys: Merge XPA lamp setup to a single function + +commit 4adb96b7afa8935c663279c5b5caccb60a7241b8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:29 +0300 + + genesys: Merge XPA motor setup to a single function + +commit 4d4b3be12d566ed3eb3bc81b9f8db915d81ed5e8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:28 +0300 + + genesys: Cache logical lamp and XPA state in register set + +commit d11971b220c8c780b043ed08c58d2cb8b527c5f4 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:27 +0300 + + genesys: Only ever use sanei_genesys_set_lamp_power() to turn on lamp + +commit 6d9e783a517f2481ff0a661ebc2c7f8b8918daf1 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:26 +0300 + + genesys: Only ever use sanei_genesys_set_motor_power() to turn on motor + +commit 5b788022dc37d5dd259e784dcc23b6354d3e6991 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:25 +0300 + + genesys: Extract sanei_genesys_set_motor_power() + +commit 57480021dd6853267e4af266afc9d55dac04f3e7 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:24 +0300 + + genesys: Extract sanei_genesys_set_lamp_power() + +commit 8d5ff56ee97969671ca3ea9e7e6cb20508b9c2df +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:23 +0300 + + genesys: Use scan method out of setup params for cache comparison + +commit bf0ed8ed09f4aa710dfb6c5e543928a89a42c184 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:22 +0300 + + genesys: Store scan method within params struct + +commit be19edfd7241d00f2fc8990f50dbbb9c8a1c6fe3 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:21 +0300 + + genesys: Store setup params to current setup struct + +commit 9f3c86cd57a61cc841bec66849ffe255c2b96fec +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:20 +0300 + + genesys: Wrap data into SetupParams in *_calculate_current_setup() + +commit 6796315cc10f41033d4666942e2600abb1406624 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:19 +0300 + + genesys: Remove useless condition in lineart setup check + + The flag in the remaining condition can only be set if the second + condition is true. + +commit 65bb8724c67619c57ed25fcbf98c21d3f0b37eb9 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:18 +0300 + + genesys: Use scan params to compute scan geometry, not settings + +commit 2a8f642787b8ebd33c82727a5e2f518f1f80760a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:17 +0300 + + genesys: Fix sign comparison warnings + +commit bf395270e807e50a89bf98bcdf14bde1e9e58f1c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:16 +0300 + + genesys: Refactor color filter into an enum + +commit 0ffbd6c0238aee9f6eed676c94478bb9938da375 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:15 +0300 + + genesys: Specify underlying types of enums + +commit cd7186965b3418a4c4c21d1f0b6d49f07137a0b2 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:14 +0300 + + genesys: Don't use floating point numbers in SetupParams unnecessarily + +commit ca070fb5697124f0a92432fcb7c87b73048098fe +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:13 +0300 + + genesys: Extract function to dump SetupParams to debug + +commit a8b61d0501fffa2eff1fcdd841c7c4fd11dba048 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:12 +0300 + + genesys: Update gl646_setup_registers() doc + +commit e47a6dfb56468d19bb1482258d9947aee3039458 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:11 +0300 + + genesys: Represent color as channels on GL646 + +commit 6ae640cac17c504c060676e099851e9514a9a896 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:10 +0300 + + genesys: Simplify channel setup in gl646_setup_registers() + +commit a843704cc198fcbc10d1eeb0ba537b68cf4438c4 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:09 +0300 + + genesys: Move color filter setup to gl646_setup_registers() + +commit 8184699bbfac3a6ded6f4dfb26a6adc6534a5c77 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:08 +0300 + + genesys: Allocate GL646 slope tables on stack + +commit e129bdd1e16de8556ec458dbf50a3f76a6f20481 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:07 +0300 + + genesys: Move low-level computations to gl646_setup_registers() + +commit fb8014d77e3de4fe0188d9ef0e554d7df1ae1838 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:06 +0300 + + genesys: Store scan setup data in SetupParams struct + +commit 42ae7ea2d8fef1141f7f110051ee2f94d13c555c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:05 +0300 + + genesys: Reuse SetupParams on GL847 code + +commit 1841e5b276c21578b2296f382861a08bf5ffb31a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:04 +0300 + + genesys: Reuse SetupParams on GL846 code + +commit 6719f885da49dc616a80e8bd317e6ad08bc11cfd +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:03 +0300 + + genesys: Reuse SetupParams on GL841 code + +commit 50f5007b3d0d1f0d4713d767590c6a54e2f582b6 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:02 +0300 + + genesys: Reuse SetupParams on GL124 code + +commit 319a5082ac3cda6c70bca9c568fd7f24ed9fab90 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:01 +0300 + + genesys: Remove unused command set API + +commit d92bfd1e9e831e3044f24e7d430d03a9273ffe39 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:04:00 +0300 + + genesys: Remove unused fields out of Genesys_Settings struct + +commit efd7723a4f16c20b31fc874a1792bf3dd52cc920 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:59 +0300 + + genesys: Deduplicate dumping of Genesys_Current_Setup to logs + +commit 7020001ba77cec3a2d4368ba4bbd1da7bc7c9bca +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:58 +0300 + + genesys: Remove unused ScanColorMode::COLOR_MULTI_PASS + +commit 6e657e3eac1f878d881d058ca272646afcb4542d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:57 +0300 + + genesys: Refactor scan color mode into an enum + +commit 723426d78bd90802199301ef7d75febb8766cc74 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:56 +0300 + + genesys: Don't use dev->calib_reg directly when possible + +commit c09370eab49b1c1522964d418c6e1344adc07ede +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:55 +0300 + + genesys: Add support for selecting infrared channel + +commit a63c8a5f8c8422cd51aea00efc30fd11c68fb780 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:54 +0300 + + genesys: Support more than two scan methods + +commit f1e583aea8f5e6a4ef1e74071ef1f41390c447ad +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:53 +0300 + + genesys: Refactor scan method into an enum + +commit 374a3043fafcae61a64f601a3329afc04f748060 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:52 +0300 + + genesys: Use STR_ prefix to macros yielding to strings + +commit 06157f753cf9a5c1114d63604b2710131cb58a6a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:51 +0300 + + genesys: Extract remaining options out of option list + +commit 38ccdc67881de4c5e0e7fc19467229ea8ab56bf8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:50 +0300 + + genesys: Extract resolution and bit_depth options out of option list + +commit a7a2e0abd6c9d58dc9782add70384fe707b48da4 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:49 +0300 + + genesys: Extract string options out of options list + +commit 3301e0fbea7bb731f70d3420fdcb088400700c45 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:48 +0300 + + genesys: Extract position options out of option list + +commit 3f184b795f302aa63c331982113b0f0427a8928d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-08 14:03:47 +0300 + + genesys: Simplify sensor handling + +commit 9c42d6ac11fc0ef71d4712607381d19636829d9c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-08 13:00:25 +0900 + + Check AX_CXX_COMPILE_STDCXX macro expansion in configure + + If not expanded, the user is informed how to deal with this. + +commit c0b07792d948e46ef9cde8910a5b78f5f9e958fc +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-08 12:37:49 +0900 + + Ignore harmless patch backups + + When patching `ltmain.sh` the `patch` utility creates this file if the + patch did not apply cleanly, e.g. when it applied with an offset. Any + hunks that *failed* to apply end up in `ltmain.sh.rej`. This file you + probably want to see in `git status` so it is not ignored. + It should not be committed, of course. + +commit 8b51e449f67aa220b515364bceae960e8b1090e8 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-08 12:36:06 +0900 + + Add ignore patterns + + These files were removed in 1c143f630e3c8ef4b649a369260eebebf10c869c. + +commit b35e0184027c36e51fd73e1f52f8705f525cc4d8 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-08 12:34:58 +0900 + + Remove files provided/created by Gettext. Re !72 + +commit ee604e33653537db8825e76bcc8560dd8cb53910 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-07 20:48:40 +0900 + + Update autotools related information. Re !72 + +commit 165aad31bcc115013658683a53195279122c0800 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-06 20:50:29 +0900 + + Make tar invocation work with Busybox tar version + +commit 03591a4c4a1014cac0cd39aff3daf8dde927563a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-06 20:37:08 +0900 + + Fix current working directory assumptions + +commit 103be60e24a07e14b3c8bd98e53472f3822d8a16 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-05 23:44:43 +0900 + + Really make it a no-op script. Re !72 + +commit a367df0994ec7fb1e43a0e6e191096bca71d143a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-05 23:39:44 +0900 + + Add no-op script to satisfy GitLab CI requirements. Re !72 + +commit 4ddd89dc16700cbe968c7627870be583bf6264d5 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-05 23:34:56 +0900 + + Move source tarball creation to prepare stage. Re !72 + + The build jobs use this tarball to exercise the build and only if all + builds pass will it be "archived". + +commit b6f8053af8f2c2ef301c23fbf9e24fe75b4463d7 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-04 18:18:59 +0900 + + Carry forward configure.ac tweak only. Re !72 + +commit 767cbfaa7f8d190648345a97637d76120f3aa1c9 +Merge: 1f847e41 1f383b37 +Author: Ilia Sotnikov <hostcc@gmail.com> +Date: 2019-06-03 06:10:26 +0000 + + Merge branch 'hp5590-devel' into 'master' + + HP5590: Add options for reading out user settings from scanner panel. + + See merge request sane-project/backends!66 + +commit 1f383b379540bc8a4b2300b066fe9ed6cfc7f550 +Author: Bernard B Badeer <bb3138@live.de> +Date: 2019-06-03 06:10:26 +0000 + + Add options for reading LCD counter and LED indicator. + + * Add command line parameters for readling LCD counter and LED indicator. + * Code refactoring: Use static parameter strings instead of dynamically + allocated string in order to avoid memory leak. + +commit 1c143f630e3c8ef4b649a369260eebebf10c869c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-02 21:33:22 +0900 + + Remove more generated files. Re !72 + +commit 93be23ccf5b0a29024d619f6cc13191c9088b32b +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-06-02 21:21:42 +0900 + + Fix libtool requirement for autogen.sh. Re !72 + +commit 8aa5318f90a084ae7fb0c27258a456723540f552 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:48:04 +0300 + + genesys: Make frontend register list generic + +commit 24853e657a3a57d18d8c10005074159ed7882547 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:48:03 +0300 + + genesys: Refactor frontend table to initialize data explicitly + +commit 63054332102eb4c4f1b8b56d442c436aa8a3f82a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:48:02 +0300 + + genesys: Cache the initial frontend values in the device + +commit ba778a7d84e555c58843d1664db65f683c1f5d4c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:48:01 +0300 + + genesys: Add a way to set custom FE registers depending on scan mode + +commit c05b0c15983b223dc43957f569def6609f7ee165 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:48:00 +0300 + + genesys: Add initial support for 8600F 4800dpi transparency scanning + +commit 91a37b65588a23eef009283d307b0650c91be34d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:59 +0300 + + genesys: Add a way to calibrate partial width of the scanner + +commit a2f451526c5d0b05a60f5407923e79061b5788fe +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:58 +0300 + + genesys: Extract GenesysRegisterSettingSet::{fread,fwrite}() + +commit ac624433bbacdcf3c1cfe5cbcfd16803baae2097 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:57 +0300 + + sanei: Print the number of read bytes on bulk USB read error + +commit a9689de4784deb240073a964c85fbee14ea125b0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:56 +0300 + + genesys: Don't hardcode ccd size divisor for start position + +commit 3a8f1ddf6c8d3f8bdf7ddeee4af5d3734cf6b390 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:55 +0300 + + genesys: Support 2400dpi transparency scans on 8600F + +commit 8520b810fdc7901db6e5fa5fbf773723ba077f22 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:54 +0300 + + genesys: Add support for mixed half/quarter-ccd mode on the same scanner + +commit 36872e57518f22da7e8588b697b3ac24ea56597d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:53 +0300 + + genesys: Add support for half-ccd and quarter-ccd modes on the same chip + + Previously we hardcoded half-ccd mode to be actually quarter-ccd mode on + GL843. + +commit 8a9a4e3f719d2d7fdf3c41b1431dd9dd29d5d54f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:52 +0300 + + genesys: Move GL843 sensor profiles to global sensor database + + Note that gl843_setup_sensor() did not write certain registers and they + weren't written to the scanner anywhere else, thus they have been + excluded from the new definitions. + +commit 723aa2b73cf213b58310e74d4baca78ff03e4a61 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:51 +0300 + + genesys: Don't store current sensor in device as it depends on the scan + +commit f8e8243b78fa3a13d366bbdacdc2b13158a66c36 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:50 +0300 + + genesys: Don't modify sensor with gamma data + +commit dafd2a150b908b37065c5d5817e36c044ae6c675 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:49 +0300 + + genesys: Extract gamma creation into a single function + +commit ea74f8e6ef3fe496a75d3f7fc7165c4dd3b4adca +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:48 +0300 + + genesys: Pass gamma tables as vectors + +commit dd2884ede7dbe619bd1b845708d4e74440289a73 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:47 +0300 + + genesys: Don't read registers to get data available from model flags + +commit 5adaea3e2f22c53108f062d3763ba4f34e4ec72b +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:46 +0300 + + genesys: Pass sensor to genesys_coarse_calibration() as param + +commit 60289d58e20ded371dee4f82eae786ac4afb53c5 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:45 +0300 + + genesys: Pass sensor to genesys_average_white() as param + +commit 35e45196b950227057b9858d1e62614fcb6fc696 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:44 +0300 + + genesys: Pass sensor to sanei_genesys_search_reference_point() as param + +commit 43c86ecd819307b076aecba880d6bf55012b98bf +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:43 +0300 + + genesys: Only ever name Genesys_Sensor as "sensor" to reduce confusion + +commit 773841251710c8933aecab8e9ff7002ffe888245 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:42 +0300 + + genesys: Remove vim indent settings + +commit 6fdabd817477b5d69733d18e9244fc05a7af2f8a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:41 +0300 + + genesys: Remove unused sensor config + +commit d3f13839af4a985308c1cdf67d2307966ca01e1c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:40 +0300 + + genesys: Remove no longer needed explicit initialization and copying + +commit 4269f67c4a04862627795ec17559fb8d75c00aaf +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:39 +0300 + + genesys: Always initialize Genesys_Frontend + +commit 68df437faf1d025f6a3e16a47816ed261707f172 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:38 +0300 + + genesys: Always initialize Genesys_Motor + +commit 52f73ffd8d673641176379aa75879b2a7154f294 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:37 +0300 + + genesys: Always initialize Genesys_Gpo + +commit d39189e424dcda05c295a60e01ffff25a97f374e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:36 +0300 + + genesys: Always initialize Genesys_Settings + +commit 03ecbf1bb0af74f857172a2792ebfc55d40c76f8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:35 +0300 + + genesys: Always initialize Genesys_Current_Setup + +commit a287f4945cb63e425b37aa9b6d0682de8570a8d8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:34 +0300 + + genesys: Extract computation of session setup to callers + +commit d688429ccd3558fb6eb5948efce9e812d7a23776 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:33 +0300 + + genesys: Fix use of wrong dpi when computing output pixel count + +commit 1a9e05b2918b831c4e3afa5d05ee32c61793ddc6 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:32 +0300 + + genesys: Extract params to gl843_init_scan_regs to a struct + +commit 836a78bef5713d6e7ade520e23c4959ef3a31386 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:31 +0300 + + genesys: Extract exposure to separate variable in sensor definition + +commit e9419d5e33c0bda22e7f358e9d1ef6a33127a699 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:30 +0300 + + genesys: Make per-sensor register override list generic + +commit 7f22e35e2c6ec20a552e588decc000996385a3df +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:29 +0300 + + genesys: Use internal sleep wrapper for remaining sleep calls + +commit 90814ac7d3c30bdc1a4c4b19d8822e908aedefdc +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:28 +0300 + + genesys: Move half CCD property to sensor definition + +commit 7359412548cfc662b913a79ee014aa8e30fb19c1 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:27 +0300 + + genesys: Remove dead code + +commit 04c5b4afde1a88454df1682e00dcb8a1b360eb49 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-02 11:47:26 +0300 + + genesys: Improve type safety of Genesys_Register_Set + +commit 1f847e4128a3f1f2d425b5ebb5509f64f2d32f2b +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-06-01 18:23:41 +0200 + + INSTALL.linux: add missing development package + +commit 3b2ecec808b54543ec341a8028055b36d650e17e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-01 14:41:32 +0300 + + style-check: Ignore patch files + +commit 61bff8b60153f0189a9bcc5cb70d4a2b042b3f13 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 09:12:18 +0300 + + autotools: Restore patch to libtool to change libsane soname + +commit 72320897d8f1b5b8bfc296791d114de01b4b4bd1 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 09:12:17 +0300 + + autotools: Move byteorder.m4 to prevent mixing with generated files + +commit 9e6a83860b2f8644a739ba837f6434d3815105a6 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 09:12:16 +0300 + + autotools: Add autogen.sh to run autotools in appropriate way + +commit 1c3e1aa1846ec04bf8a48bd918a2ad62ac77dd2e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 09:12:15 +0300 + + autotools: Remove files generated by autotools from version control + +commit 6b4759252043534f74caa18918ce6f2d91b52651 +Merge: 26b3d8aa 916d4e0d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-01 02:40:24 +0000 + + Merge branch 'genesys-fix-read-set-reg-from-set' into 'master' + + genesys: Fix sanei_genesys_{read,set}_reg_from_set() + + See merge request sane-project/backends!80 + +commit 916d4e0db9e62a444cdcbef6c6512b7ecf6dd238 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-06-01 05:24:58 +0300 + + genesys: Fix sanei_genesys_{read,set}_reg_from_set() + + There can be registers in the register set with zero address. In + particular, the 0x0b register's address is set to zero on most + sub-backends to prevent writes to it. This leads to the functions in + question not do anything in most scenarios. + +commit 26b3d8aaa0854f87dd39dce1dbe5af3ae1adbfcc +Merge: ceec219c 1df69527 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-30 21:17:10 +0000 + + Merge branch 'genesys-canoscan-8600f' into 'master' + + genesys: Add basic support for CanoScan 8600F + + See merge request sane-project/backends!79 + +commit 1df6952788f1724fe63bb17c588e56d98d0ce23f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-31 00:07:44 +0300 + + doc: Update description for CanoScan 8600F + +commit ceec219cecb467e9d2cd082f88096f0a1686200b +Merge: dc42318d aeefb370 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-30 20:51:27 +0000 + + Merge branch 'genesys-fix-gl843-calib-pixel-count' into 'master' + + genesys: Fix read pixel count calculation during calibration on GL843 + + See merge request sane-project/backends!78 + +commit aeefb370724cd0bfa085f728d3bf7132a9134863 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-30 23:33:13 +0300 + + genesys: Fix read pixel count calc during calibration on GL843 + +commit dc42318d905e35f09a5e5d0a9560d296eb43cf06 +Merge: 9f461060 50b27fe8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-29 21:28:43 +0000 + + Merge branch 'genesys-use-containers' into 'master' + + genesys: Use C++ containers to remove chances of memory leaks + + See merge request sane-project/backends!76 + +commit 9f461060aac2c6517e471699a7efa7e254b8048d +Merge: 5d7fc4e0 896385a0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-28 01:21:44 +0000 + + Merge branch 'genesys-catch-exceptions' into 'master' + + genesys: Catch C++ exceptions when returning to C code + + See merge request sane-project/backends!75 + +commit 0b5ab0b5e47f74ddf7e6a609bf91c3f4b36c0369 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-27 12:16:10 +0300 + + sanei_usb: Fall through to the end of sanei_usb_get_descriptor() + +commit 422e0831757681e1ff3cd6d6c93b80c38a8d1e67 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-27 12:16:09 +0300 + + sanei_usb: Fall through the end in sanei_usb_control_msg() + +commit d865705ef13a5d9f261abf1ed39b02319d414004 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-27 12:16:08 +0300 + + sanei_usb: Don't change input size variable in USBCALLS bulk code paths + +commit 18f9e5598c224e90554d333b7f9f05ba8fa14ad0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-27 12:16:07 +0300 + + dll: Don't unnecessarily use alloca + +commit 50b27fe8367cbe5f1e426d709be00aae478c6b15 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:42 +0300 + + genesys: Use std::string for Genesys_Device::calib_file + +commit 38986c2c6f39da0f326c922b3607b78c1591b5e9 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:41 +0300 + + genesys: Use std::vector for Genesys_Device::img_buffer + +commit eb93267fa9af5632d1cff5cf221b3ea2916c69d0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:40 +0300 + + genesys: Use std::vector instead of custom vector implementation + +commit 69485e9f11963cee51ff10fd63d069bd2fea06a8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:39 +0300 + + genesys: Remove unused new device list + +commit 3096dcee0ee25ea93123801e56a1d75cd153aca1 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:38 +0300 + + genesys: Use s_devices.size() for num_devices + +commit 9c2fdeeb3d91d581d55fa8972b583e7d7cb8b765 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:37 +0300 + + genesys: Use proper containers for device lists + +commit 5a90b7bb8fb72ba9fed235d2ff974c8e26dfba30 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:36 +0300 + + genesys: Convert Genesys_Buffer to C++ class + +commit 247658f23ed81be58a5bfea6f62f9d229b163ff4 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:35 +0300 + + genesys: Return std::vector from GL646 simple_scan() + +commit e48b6c4e2dc7065ead61015673fed89d16f1c81a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:34 +0300 + + genesys: Store global Genesys_Scanner instances in std::list + +commit 15b373a5cc388aed628d5514e00f979cf8df6222 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:33 +0300 + + genesys: Use std::vector for calibration cache average data + +commit 64ca298d02d03dbd2818d8c887f7c94c350ac42e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:32 +0300 + + genesys: Store calibration class using std::list + +commit 52b1989edaa99dea1d1ab6bbcc9486d64ae28360 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:31 +0300 + + genesys: Remove no longer used RIEF and RIEF2 macros + +commit 3d44c89f1e7a3ef548275730127d956c415773ba +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:30 +0300 + + genesys: Use std::vector for Genesys_Device::{dark,white}_average_data + +commit 2dc4e5d1fc3c48cf1cd7ae1010dd5cc3328754dc +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:29 +0300 + + genesys: Use std::vector for Genesys_Sensor::gamma_table + +commit 555be1c3eb5e3becac770170687713d73756511b +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:28 +0300 + + genesys: Use Genesys_Device as C++ class + +commit cb189cfe2d9ec1004e83c285612f6ee386f44100 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:27 +0300 + + genesys: Rewrite sensor table to use std::vector + +commit e5eff5d76f98170d6b583aa19e9c6ebd58407eb4 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:26 +0300 + + genesys: Add facility for auto releasing static data on backend exit + +commit 9cea33b53c4fb351e8983c0a1f6e2694220f8127 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 11:15:25 +0300 + + genesys: Use std::vector instead of malloc for local allocations + +commit 896385a082f0d44a4fa4abb21c4c5fd110d51d8e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 10:03:15 +0300 + + genesys: Ensure that functions passed to C API don't throw + +commit 23f3ebf612456f3328c925764abfcaaa31c80e39 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-25 10:03:14 +0300 + + genesys: Wrap exported functions to always catch exceptions + +commit 5d7fc4e0ed3489982082be3c1845fa3f2eba42d9 +Merge: 216e8b28 58ee13d0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-24 18:25:58 +0000 + + Merge branch 'genesys-fix-warning' into 'master' + + genesys: Fix warning + + See merge request sane-project/backends!71 + +commit 58ee13d057f0db1c07edb6627aaf973e6a3d6566 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-24 21:13:37 +0300 + + genesys: Fix warning + +commit 216e8b28a0b792276ede8a46618a713ad5ef4b9d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-22 21:48:32 +0900 + + Turn C++ compiler warning into error on the right job. Re #85 + + Fixes 8d67531c70e8cc346d8705477ac9c53d0a4571d8 where the flags were + set for a job that runs in an environment *without* a C++ compiler. + +commit 199a685d0b174ce618d23decd0565b591be67b91 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-22 21:35:08 +0900 + + Restore availability of config.status for archive stage. Re #85 + +commit 8d67531c70e8cc346d8705477ac9c53d0a4571d8 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-22 21:31:13 +0900 + + Turn C++ compiler warnings into errors. See #85 + +commit 57ee89a6760621d92fa8564bdc066c36c17618d7 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-22 21:19:54 +0900 + + Drop caching of untracked files. Re #85 + +commit be9736020f48119a1060088d95ec1ac8eef8ac07 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-21 22:11:50 +0900 + + autofoo: Sync generated files + + The AX_CXX_COMPILE_STDCXX* macros that were embedded in aclocal.m4 + have been replaced with the versions found in the autoconf-archive + package from Debian 9. + +commit e2d89c1ab3b06cb81634a869ed94620d91af6d68 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-21 22:10:12 +0900 + + Expand AM_CXXFLAGS in our Makefiles. Fixes #84 + +commit 16a3945ce6b585c97a90461419b573a2d389d58f +Merge: f498e5fa 0a66ed1d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-20 09:47:38 +0000 + + Merge branch 'genesys-sleep' into 'master' + + genesys: Add wrapper for sleep that can be turned off when testing + + See merge request sane-project/backends!70 + +commit f498e5fa66718a76adbcd60be8228a50cc903ab1 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-20 18:32:48 +0900 + + genesys: Add missing pointer cast on malloc call + + Fixes build on Fedora 29 and 30. + +commit 2bb5ed655ade84281435d80cf133403f8e11bb29 +Merge: 2a116229 185303a1 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-20 09:10:53 +0000 + + Merge branch 'genesys-enable-cxx' into 'master' + + Use C++ for the genesys backend + + See merge request sane-project/backends!61 + +commit 2a11622967ff2f5f09d4b47ffc3e1817645f814a +Merge: 75855385 7a8ae928 +Author: Stanislav Yuzvinsky <yu-stas@yandex.ru> +Date: 2019-05-19 18:18:57 +0000 + + Merge branch 'teardown' into 'master' + + ricoh2: Rearrange init/deinit code of ricoh2 to correctly support "code flow" + + See merge request sane-project/backends!65 + +commit 758553859589a1c5ec0a7ff688fe4621e81b62db +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-19 21:41:16 +0900 + + epson2: Add XP-255 as supported. Fixes #81 + +commit 71bf2daec6584db1228975c88cb737375244e57e +Merge: 8cdd5ae2 a4ab6937 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 12:02:50 +0000 + + Merge branch 'genesys-remove-static' into 'master' + + genesys: Remove uses of GENESYS_STATIC + + See merge request sane-project/backends!68 + +commit 8cdd5ae22e3ac4c3b059edba56e174eafcfc404d +Merge: e13b80fa 4c2c4eb6 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 11:56:38 +0000 + + Merge branch 'genesys-debug-cleanup' into 'master' + + genesys: Use the same debug identifier for the whole backend + + See merge request sane-project/backends!67 + +commit a4ab69376c3f05a37d51953776a938731c277683 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 14:49:44 +0300 + + genesys: Remove uses of GENESYS_STATIC + +commit 4c2c4eb6397b974c90a20c1f4f355730b700be27 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 14:46:46 +0300 + + genesys: Remove duplicate definition of DBGSTART and DBGCOMPLETED + +commit 6f617e9889be1c35f5960b2a00dcc702aa3787f2 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 14:46:45 +0300 + + genesys: Don't define different backend names in source files + +commit 873e82c0a06a6a240cdb8e0178f4bc6f5d87c1c2 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 14:46:44 +0300 + + genesys: Remove logging of the build number + + A git commit would be much more useful in log messages + +commit 185303a18d18e855df38b85a0647d595a1c0462f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 13:50:11 +0300 + + Enable warnings in C++ source + +commit 42fb5a3e038d1344534e5ff1b175dc4c7125ff0d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-19 13:39:42 +0300 + + Don't compile genesys backend when C++11 is not available + +commit c536f3cf7094a597fe389cfdb1acf2c7753522f2 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:12 +0300 + + genesys: Fix calibration size calculation for 8600F + + The current approach of marking the scanner as + GENESYS_FLAG_FULL_HWDPI_MODE is counter-productive, because only the + register value is always full DPI, the actual resolution is different. + For now, let's just work around this by having a special case for the + scanner. + +commit 0a0a14042338ca26c77910ed08e1248578e16d30 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:11 +0300 + + genesys: Correctly adjust pixels per line during calibration + +commit 190361b724b0bea6ec253b9296e02e17b8767387 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:10 +0300 + + genesys: Work around first line having artifacts during calibration + +commit 3a4f67feefe8c262a6da95b9c64057ff1548e089 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:09 +0300 + + genesys: Fix lockups on GL843 during calibration + +commit ed582c585841279827cd0a3117dfdb3fc1848e44 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:08 +0300 + + genesys: Fix gain calibration on GL843 + +commit b2205121721306db13b75fa9400c93f92b20a27a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:07 +0300 + + genesys: Add a separate shading line count param for TA mode + + q + +commit b7ef75d63f8acc8fb71d8fa74429dcc52eddb012 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:06 +0300 + + genesys: Implement transparency support for 8600F + +commit 126e98524a3543f83e79dd1a15e3cd6674dc6324 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:05 +0300 + + genesys: Remove special ADF handling for G4050 + +commit 091fdbe6d66315430cf227b5e92d30639d214f01 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:04 +0300 + + genesys: Use correct offsets for transparency scan + +commit d0c4f87ac793a7dafcf35796edfee9f23878fdde +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:03 +0300 + + genesys: Don't set exposure to zero on 8600F + +commit 33a60dcc7bae671f63bbacc684c996167c5307df +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:02 +0300 + + genesys: Implement support for 8600F + +commit 41e2029e4bcb25371cc0b89170dfab8e47a40b96 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:01 +0300 + + genesys: Initialize 0x7e register on GL843 + +commit 966ef337100c4143408a68a609bef8054442b65c +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:56:00 +0300 + + genesys: Fix pixel calculation during calibration on gl843 + +commit df889c96f5d979369ba702a87ae0cafcda9aba9a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:55:59 +0300 + + genesys: Deduplicate pixel count computation during calibration + +commit 695addaafd0d7de46309384587d4d864261083cb +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:55:58 +0300 + + genesys: Fix pixel count when scanning in half-ccd mode on GL843 + +commit d2b4a1b838eb5df1a27f5a0fde8e2297fd17b1e9 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:55:57 +0300 + + genesys: Extract gl843_compute_physical_params() + +commit 76bf1ad072bc5b50743273060f3c4b3cd67e0950 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-18 14:55:56 +0300 + + genesys: Improve documentations for registers in various places + +commit 7a8ae928626a2ccecc5dd40dd4564c47d8dcb9a4 +Author: Stanislav Yuzvinsky <yu-stas@yandex.ru> +Date: 2019-05-08 11:03:15 +0300 + + ricoh2: Rearrange init/deinit code of ricoh2 to correctly support "code flow" + + The backend worked incorrectly when scanning process was interrupted before the + current page was scanned completely. For example, scanimage tool could not scan + the next page if the previous one was interrupted. Now this issue is fixed. + + See also "4.4. Code Flow" in SANE API specification v.1.06. + + Also debug levels was changed to have better control over what should be + logged. + +commit e13b80fa6ff333cede132dc29377eec9b6c02f48 +Merge: ae871333 0273c05c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-12 03:11:00 +0000 + + Merge branch 'add_sg3100' into 'master' + + Add support for Aficio SG3100SNw + + See merge request sane-project/backends!57 + +commit ae871333ef09d867c6d95edd6c3adf3bd05c2fea +Merge: 4df63ef5 ee6d6da3 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-12 02:36:36 +0000 + + Merge branch 'scanimage-output-path' into 'master' + + scanimage: Allow specification of the output path via option + + See merge request sane-project/backends!46 + +commit 0273c05c95040b0cd3141117d67bbd08e4a03e5b +Author: Stanislav Yuzvinsky <yu-stas@yandex.ru> +Date: 2019-05-11 16:17:40 +0300 + + Fix review comments; add the backend to dll.conf + +commit 4df63ef5480103edf5c2a92a1641afdc0eddca04 +Merge: 3c8b9b91 988a91ae +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 09:20:45 +0000 + + Merge branch 'genesys-debug-improvements' into 'master' + + genesys: Miscellaneous debug improvements + + See merge request sane-project/backends!64 + +commit 3c8b9b9167947def05544160153d8f3bc5312548 +Merge: 74fffa64 8de5a1fd +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 09:14:06 +0000 + + Merge branch 'genesys-reduce-duplication' into 'master' + + genesys: Reduce duplication in low level functions + + See merge request sane-project/backends!63 + +commit 988a91aec47697f1ec37ecc492819223df40b18f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:12:29 +0300 + + genesys: Write all offset calibration debug to a single file on gl843 + +commit 36bc194405ed82e56ec12b68b5cc9491ed3ef199 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:12:28 +0300 + + genesys: Add a small C array implementation + +commit 5321427e55b67a1d7274f3b0851e89dced66e1a0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:12:27 +0300 + + genesys: Don't write identical debug pnm files + +commit 882741d78ae5ebffbd128104d850eec95a9e5a50 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:12:26 +0300 + + genesys: Prepend file identifier to debug image filenames + +commit d3b25a59664a2779481329d4c5627f9018af3f83 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:12:25 +0300 + + genesys: Don't write identical debug pnm files + +commit 74fffa64791f6e670942604eac27bc330afc339b +Merge: 15fd9bc9 88775919 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 09:08:11 +0000 + + Merge branch 'genesys-force-calibration' into 'master' + + genesys: Add option to force calibration ignoring caches + + See merge request sane-project/backends!62 + +commit 8de5a1fdb10498c85a998ad8eeb4e6b228019fb2 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:26 +0300 + + genesys: Remove unused code + +commit da81a523fa231858a18232186c878730c849aa6f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:25 +0300 + + genesys: Reuse sanei_genesys_bulk_write_register() on GL841 + +commit 2b1f13fddb9fdfe16523c855242a768f39a64f57 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:24 +0300 + + genesys: Reuse sanei_genesys_bulk_write_register() on GL646 + +commit b683a40fdda7eae26ca80995935d473a272521e6 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:23 +0300 + + genesys: Reuse common genesys register functions on GL646 + +commit 58e1eb8ac4692423ce4795a815d0d7c2ef2b25cf +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:22 +0300 + + genesys: Reuse sanei_genesys_bulk_write_data() on GL646 + +commit 80efacab1022351597dac95f6183204fb3f3e800 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:21 +0300 + + genesys: Reuse sanei_genesys_bulk_write_data() on GL841 + +commit d62d4f0d164b1ee3a5a3debebd307b6484fa5a8f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:20 +0300 + + genesys: Use sanei_genesys_get_bulk_max_size() for max bulk out size + +commit 7ee139bd4bc0dbc6740df0d9fbe0bc89794c18da +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:19 +0300 + + genesys: Pass device to sanei_genesys_write_ahb() as ptr not number + +commit d7bff42cba003c99197ce7bb2384d08383dd4ef9 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:18 +0300 + + genesys: Add generic sanei_genesys_bulk_write_data() out of GL843 impl + +commit 98258549cb48955aadba7fb6e2ed266aeec3eb68 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:17 +0300 + + genesys: Extract sanei_genesys_get_bulk_max_size() + +commit 5b9d0145927b0974cb49d4f042e7d2927abdd97d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:16 +0300 + + genesys: Remove commented out code for buffer size alignment + +commit 9dc8bbfac95c2106aabe2833dbd7ccf191aee62a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:15 +0300 + + genesys: Reuse sanei_genesys_bulk_read_data() on GL847 + +commit 4af3557bbf622b4937278273daef782baaf42157 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:14 +0300 + + genesys: Reuse sanei_genesys_bulk_read_data() on GL846 + +commit 216c18f9ff02b2984c55b65b4050caef70956a7b +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:13 +0300 + + genesys: Reuse sanei_genesys_bulk_read_data() on GL843 + +commit 55e5c7b7ac745ada19dc95dd59929a6a03313431 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:12 +0300 + + genesys: Reuse sanei_genesys_bulk_read_data() on GL841 + +commit 8e8511a49e8bfb4aae993a64bc8845f82e26d513 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:11 +0300 + + genesys: Reuse sanei_genesys_bulk_read_data() on GL646 + +commit 69435b3bb2a35ba11ac1a1e79ee91bd4a5c2f9a5 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:10 +0300 + + genesys: Revert 512-byte bulk transfer alignment workaround + + It should be handled by libusb. + +commit 4a899d26f33e337b56e0d5c8ad834bee7cfb132d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:05:09 +0300 + + genesys: Create generic sanei_genesys_bulk_read_data out of gl124 impl + +commit 887759192bbf2f8265f5897ba43acdcf5a10cbe5 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 12:00:25 +0300 + + genesys: Add option to force calibration ignoring caches + +commit ee6d6da339459bc8393547005e087e97d3d4987b +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 23:28:21 +0300 + + scanimage: Update manual page + +commit 728de89d7166708331907726571c7027b4921d82 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 23:28:20 +0300 + + scanimage: Guess --format from --output-file if possible + +commit 86e917b04b9bd1fbeb53d58323b118f30c8efc15 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 23:28:19 +0300 + + scanimage: Prevent --output-file and --batch to be used together + +commit 7f4944f0a7d1c7ce90d5f4f79078112bc5d52dff +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 23:28:18 +0300 + + scanimage: Warn when output format is not set + +commit 877cc29d88529f9af8e898a52b4be99863a20eea +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 23:28:17 +0300 + + scanimage: Raise an error if --format option is an unknown format + +commit 15fd9bc9ce70953d70fd3fa2f48bf725cb27a37d +Merge: 85639110 16a8d554 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-11 08:13:18 +0000 + + Merge branch 'log-messages-no-git-conflict-markers' into 'master' + + Don't use strings that are similar to conflict markers in debug msgs + + See merge request sane-project/backends!60 + +commit ca051cc22736909c7eaddbb1ba549eb718ea36f8 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-10 21:16:11 +0300 + + genesys: Compile library as C++ code + +commit 72121bc7d88bbd6577cd3ea88b301d91ac35d675 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-10 21:16:10 +0300 + + sanei: Use C linkage for internal functions in C++ mode + +commit 9e3b5d6381b5c8d49b71753e7b28b65f45feebee +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-10 21:16:09 +0300 + + Update generated files + +commit b93340b8623de865c73b7e12a5b448732f9a5f68 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-11 00:02:47 +0300 + + Enable C++ in autoconf + +commit 856391100f00b49bdf245930cd68c52f3116b6f7 +Merge: 56c01c00 47e7f087 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-10 18:23:32 +0000 + + Merge branch 'genesys-explicit-casts' into 'master' + + genesys: Perform type casts explicitly + + See merge request sane-project/backends!59 + +commit 47e7f087c62234c540cac2cdcf86d4334a4026ea +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-10 21:04:15 +0300 + + genesys: Perform type casts explicitly + +commit 16a8d554809171156ed2727c6e1f4e2fdff5b5e3 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-05-10 21:05:51 +0300 + + Don't use strings that are similar to conflict markers in debug msgs + +commit 56c01c005a8ddda04d24e81a337e724f673faece +Merge: f6038a70 29654290 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-05 09:27:29 +0000 + + Merge branch '24-hp-scanjet-8250-duplex-broken-avision-backend' into 'master' + + avision: Fix threaded ADF flipping duplex handling + + Closes #24 + + See merge request sane-project/backends!58 + +commit 296542905e84c5607e3dc5da5766fd574015f66d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-04 23:39:33 +0900 + + avision: Fix threaded ADF flipping duplex handling. Re #24 + +commit f6038a70ec2c4492d7488e81021fed04891f5d06 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-04 09:19:26 +0900 + + Add a Fedora 30 build, drop the Fedora 28 one + +commit 1b8f7926fe18b2d5c646480a4fa691f1984114a3 +Merge: fa940e86 25feb1be +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-05-02 06:16:55 +0000 + + Merge branch 'debian-bts-869673-genesys-usb-mode-initialization' into 'master' + + genesys: Fix use of uninitialized variable + + See merge request sane-project/backends!56 + +commit 25feb1be0c89f14d4cbca09e5e44b50ac1ebb8ed +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-08-03 18:50:05 +0900 + + genesys: Fix use of uninitialized variable + + See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=869673 + +commit 3514d06156424373b832f2e46a7d7e3311f6d15b +Author: Stanislav Yuzvinsky <yu-stas@yandex.ru> +Date: 2019-05-01 01:14:45 +0300 + + Add support for Aficio SG3100SNw + +commit fa940e86bbac2ac21c969b80722d8cf341eac389 +Merge: 916ce82f 0921d366 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 21:02:16 +0000 + + Merge branch 'sanei-endpoint-refactor' into 'master' + + sanei_usb: Deduplicate endpoint setup code + + See merge request sane-project/backends!48 + +commit 5dbd51d1ec36ba4389a7ec18ff041fd04ee3c5da +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-20 23:09:03 +0200 + + scanimage: Allow specification of the output path via option + +commit 0a66ed1dbcb3f85bedab81581cb84320a8c3c2c1 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 17:47:45 +0300 + + genesys: Use a function to sleep ms to reduce chance of errors + +commit d9f65eefc0fca4a45fb3ac1b944d55fb33fd319a +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 17:47:44 +0300 + + genesys: Fix a bug in sleep duration calculation + +commit baaa934dce8db53bd1c4f0e0308f7dac1000201f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-28 17:47:43 +0300 + + genesys: Use a wrapper of usleep() + +commit 916ce82f007e0eb297dadda9a0577482f0fb2dc0 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-04-25 21:31:27 +0200 + + pixma: backend version 0.23.0 + +commit 28d87cb6e5400df519c703bc4769808a37b6f990 +Merge: 392beeec 9fe7d990 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-04-25 21:27:53 +0200 + + Merge remote-tracking branch 'origin/master' + +commit 9fe7d990891cd53ec6295610507be0238ad868c6 +Merge: d50f3330 a3c64bc0 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-04-25 19:26:50 +0000 + + Merge branch 'master' into 'master' + + Added Imageclass MF634Cdw + + See merge request sane-project/backends!49 + +commit 392beeec74b97cd712469953962c2b3a6bf2b31f +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-04-25 21:24:40 +0200 + + pixma: new scanners Canon i-SENSYS MF110, MF260, MF420, MF510, MF520, MF640 and MF740 Series + +commit d50f33306f9c9ae0d976dce247c316c071ae3715 +Merge: a569bfbf a814df33 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-22 22:07:19 +0000 + + Merge branch 'genesys-numeric-model-ids' into 'master' + + genesys: Add numeric model IDs and prefer them to string comparisons + + See merge request sane-project/backends!54 + +commit a814df3343110b0329dfaab83d4e4e31e1ad27e5 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:55:46 +0300 + + genesys: Prefer numeric model IDs instead of string comparisons + +commit ad164ce9c6a7b924ec88d6496fa89f7093272581 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:55:45 +0300 + + genesys: Fix a typo in LiDE 120 gpio setup + +commit f240a77e92d0557996ed37b650ddfaf3ae64342e +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:55:44 +0300 + + genesys: Add numeric model IDs to model tables + +commit a569bfbf02c1d85b440db0b00f5e3a6564991564 +Merge: 595e1fc7 3cd8a4cd +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-22 21:38:29 +0000 + + Merge branch 'genesys-misc' into 'master' + + genesys: Miscellaneous changes/improvements + + See merge request sane-project/backends!53 + +commit 3cd8a4cd015769d275816252b256cc0e97b9a847 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:14:49 +0300 + + genesys: Use hex to print USB vendor and product IDs to debug log + +commit 595e1fc754cfa463f771f25daff5c7bea79715d8 +Merge: c9ebf2b5 23416187 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-22 21:15:44 +0000 + + Merge branch 'genesys-bugs' into 'master' + + Several genesys bugfixes + + See merge request sane-project/backends!52 + +commit d7c17f75403aa5619c711b7d19e81932fa9a47b1 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:14:48 +0300 + + genesys: Limit maximum bulk transfer size to allow data capture + +commit f04119b12626d0bb7c71e46a8a82837501da7ee9 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:14:47 +0300 + + genesys: Remove support for fake USB mode + + WIP implement support for 8600F + +commit 902610132b04d1adc279f11cc2cb7541a28b0ba7 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:14:46 +0300 + + genesys: Include genesys_low.h + +commit 23416187205c4d7ef4ec9c1a4b1eaa3f0e03a4c4 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:05:35 +0300 + + genesys: Work around reads from non-initialized memory in gamma setup + +commit 88c22e38beef49e2722656f47f39e33b329bd967 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:05:34 +0300 + + genesys: Fix double free in sanei_genesys_send_gamma_table() + +commit 621c9799fe535d296218f80701a9ea06e538974d +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-23 00:05:33 +0300 + + genesys: Fix use of uninitialized memory + +commit c9ebf2b5605e263d8d93f1132cb4df73ebee4516 +Merge: 4f5eb745 2fd3b562 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-22 20:56:38 +0000 + + Merge branch 'genesys-remove-unneeded-function-names-in-dbg-args' into 'master' + + genesys: Remove unneeded function name in DBG macro args + + See merge request sane-project/backends!51 + +commit 2fd3b5622b395bc60beb903b5e5539d23ca9b6eb +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-04-22 23:48:23 +0300 + + genesys: Remove unneeded function name in DBG macro args + +commit 4f5eb745ac680479ed23eff0741911903090d21c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-04-17 21:00:47 +0900 + + epson2_usb.c: Sync USB product IDs with epson2.desc content + +commit ddbcb2b28588068f845d6ef3feaa32c60f6e57d3 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-04-17 21:00:10 +0900 + + epson2.desc: Add the EPSON L380 as supported. Re #23 + +commit 3f6f9f829eca56791cd3f28e755eaaef5761357a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-04-06 17:11:47 +0900 + + utsushi.desc: Sync with upstream + +commit a3c64bc0cad104d09ba14f833828ae963dbc72f9 +Author: MackPi <mack@prototypeiteration.com> +Date: 2019-04-03 16:37:03 -0700 + + Added Imageclass MF634Cdw + + Added MF634Cdw using MF733Cdw as reference + +commit 155248dde28b2a9ec4114d59dc294b69b3260142 +Author: Louis Lagendijk <louis.lagendijk@gmail.com> +Date: 2019-03-27 19:09:43 +0100 + + pixma_bjnp: change default timeout from 1 to 10 seconds (10000) + +commit d15aa248c78c6f296fe1dbef189f54052c80386b +Author: Louis Lagendijk <louis.lagendijk@gmail.com> +Date: 2019-03-27 18:46:17 +0100 + + pixma_bjnp.c: corrected url-rewrite as it set bjnp:// unconditionally rather than honor the received method + function renamed to add_default_timeout() to clarify its purpose + +commit 4ac6550e7ca64a4f6c7ece2156c3d43033600b52 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-03-23 14:09:24 +0900 + + utsushi.desc: Sync with upstream + +commit 0921d3661812615b4cb12d16d0754af49445bd05 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-22 15:56:57 +0200 + + sanei_usb: Deduplicate endpoint setup code + +commit 276670f3c249e4a59267bc5c45e170c8e7be7286 +Merge: e92a3d6e 2653cbae +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-22 14:27:53 +0000 + + Merge branch 'rerun-autoreconf' into 'master' + + Rerun autoreconf and automake + + See merge request sane-project/backends!44 + +commit e92a3d6ebaca4fcedb262e7861155b9fd49e5bf0 +Merge: de5c63ee d866998f +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-22 14:25:39 +0000 + + Merge branch 'remove-unused-unit-testing' into 'master' + + Remove uses of unused UNIT_TESTING ifdef + + See merge request sane-project/backends!45 + +commit de5c63ee7cff16115fa04ed998c988fb79087bda +Merge: 13350ba4 265f4a96 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-22 14:24:48 +0000 + + Merge branch 'genesys-enums' into 'master' + + genesys: Prefer enums to #defines + + See merge request sane-project/backends!47 + +commit 265f4a96ea0d3ba898b65adb56f7c7b83ae18b30 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-22 14:50:03 +0200 + + genesys: Prefer enums to #defines + +commit 2653cbaec799fbfd365362c45e61796ce90b6466 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-20 23:09:07 +0200 + + Run autoreconf and automake + +commit d866998f102f242ed421ff4b4480aa2a4073c166 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-20 23:09:05 +0200 + + genesys: Remove uses of unused UNIT_TESTING ifdef + +commit b7b5ca79c8f7a92d488d96d0b1d0963d01d86423 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2019-03-20 23:09:04 +0200 + + rts8891: Remove uses of unused UNIT_TESTING ifdef + +commit 13350ba4ba0a40e0fae4567bb23566575a0317e2 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:46:18 +0100 + + pixma: backend version 0.22.0 + +commit dfc5f5ed760b7922c98280e03099aed5bcc719ad +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:45:27 +0100 + + pixma: new scanners Canon PIXUS XK50, XK70, XK80 Series + +commit 6f4440152f58507f5a4d4f915f41a5de7c0a5e2e +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:44:19 +0100 + + pixma: new scanners PIXMA TS6130, TS6180, TS6230, TS6280, TS8100, + TS8130, TS8180, TS8200, TS8230, TS8280, + TS9180, TS9580 Series + +commit adef5537994948794ca6db3369b71269ffaa1d45 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:26:29 +0100 + + pixma: new scanners Canon PIXMA TR4500, TR7350, TR8530, TR8580, TR9530 Series + +commit 83ddbd0fc4ae64c694bf8f9ba5f695aa5f7d3bd8 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:23:20 +0100 + + pixma: new scanners Canon PIXMA G3010, G4010 Series + +commit 96e6eff1ae18d9d34d24a5e9ae4684da80c70165 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:21:36 +0100 + + pixma: fix some descriptions names + +commit 953562ae8e6e1c215e1b3818911edc35c6e8aec7 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:17:45 +0100 + + pixma: new scanner Canon PIXMA E4200 Series + +commit 0678ce8e3bd8f73efc3189df225b25d6de368679 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-11 17:15:54 +0100 + + pixma: fix some interface descriptions + +commit 960a6d5d697bac72dd5d068eefe12741a5d68de5 +Merge: 9d69d94f 2915756a +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-08 20:56:26 +0000 + + Merge branch 'master' into 'master' + + Add Driver Canon Pixma TS 6200 Serie. + + See merge request sane-project/backends!43 + +commit 9d69d94f0219fa71b8e16968f08293f902d0016f +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-03-08 17:28:36 +0100 + + add missing development packages to INSTALL.linux + +commit 2915756ae4262b6a87490b5d96959f58c498307b +Author: Thierry <thierry@substantiel.fr> +Date: 2019-03-05 08:43:31 +0100 + + Add Driver Canon Pixma TS 6200 Serie. + +commit 9e4344b33a2d83aa7663b65d6d8a49c7306d72c7 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-27 19:37:58 +0100 + + remove canon_mfp from doc/sane-mfgs-external.html + + all listed scanners are supported by the pixma backend + +commit 9c4ac1f07f67b9f07f53a380897b3af11601a240 +Author: m. allan noah <kitno455@gmail.com> +Date: 2019-02-24 20:37:55 -0500 + + canon_dr backend v57 + + - complete support for X-10, including hardware cropping (by manuarg) + - minor comments and move a bit of code for consistency + +commit 81faeb46f28c4b6c251123aabac118ff0262d9e7 +Merge: 2d0912af 60dffda6 +Author: m. allan noah <kitno455@gmail.com> +Date: 2019-02-25 01:37:03 +0000 + + Merge branch 'canon_drx10c' into 'master' + + Add support for Canon DR-X10C scanner + + See merge request sane-project/backends!12 + +commit 2d0912afdcdb174721dbad0cb2e200880e5ddb15 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-24 12:40:16 +0100 + + pixma: backend version 0.21.1 + +commit 0c00dac37adbf61db5f64a5bcb67be039a19bd58 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-24 12:39:54 +0100 + + pixma: update doc files for MF731/733 + +commit d0e4f0fa5268294993ec640a18bcd8893a4d1e51 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-24 12:38:37 +0100 + + pixma: add comment for MF733C + +commit 73645abba08a0df68c43f798dee9cf28451b785d +Merge: 5ae6f698 b327c3d7 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-24 11:22:07 +0000 + + Merge branch 'mikef-MF733C' into 'master' + + Mikef mf733 c + + See merge request sane-project/backends!42 + +commit 5ae6f698aedd58ad83802b0ecfe87d171f30ee72 +Author: m. allan noah <kitno455@gmail.com> +Date: 2019-02-23 15:46:59 -0500 + + remove trailing whitespace + +commit 156f7c9bd442105038adeb9962a60fb1b56b6349 +Author: m. allan noah <kitno455@gmail.com> +Date: 2019-02-23 15:16:32 -0500 + + fujitsu backend v134 + + rewrite init_vpd for scanners which fail to report overscan correctly + update description and man page to match + rebuild po files with updated line numbers + +commit 057a10e9842997aeb7166fcd7a255390d047d3d9 +Author: m. allan noah <kitno455@gmail.com> +Date: 2019-02-23 15:14:34 -0500 + + move three scanners to unsupported.desc + + These three machines are unsupportable by fujitsu backend. Remove + them from fujitsu backend files. + +commit 941f6bb3808fd45760ab0cf0fa0cf53a6f197986 +Author: m. allan noah <kitno455@gmail.com> +Date: 2019-02-23 14:54:48 -0500 + + remove nonexistant scanners + + the fi-6125 and 6135 were never released, though they showed in + some old versions of the windows driver. here, we remove them. + +commit b608751b82cad09a82d816dcb2210c5352996bcd +Author: m. allan noah <kitno455@gmail.com> +Date: 2019-02-23 14:50:49 -0500 + + Fix a few typos + +commit b327c3d780a486b3069f2f17c589fcc083289788 +Author: Mike Ferrara <mikef@mrf.sonoma.ca.us> +Date: 2019-02-22 11:01:51 -0800 + + Typo. fixed. + +commit eadd663676c17a30ba27854e82ad8dfebefb4aa6 +Merge: 7277cec0 ff04ede4 +Author: Mike Ferrara <mikef@mrf.sonoma.ca.us> +Date: 2019-02-22 10:40:29 -0800 + + Merge branch 'master' into mikef-MF733C + +commit 7277cec027c80386f90193b330aacf1b555d0c96 +Author: Mike Ferrara <mikef@mrf.sonoma.ca.us> +Date: 2019-02-22 10:30:18 -0800 + + Mods to support imageCLASS MF733Cdw USA color laser MFP + +commit ff04ede4adb4f0267351150122fa63fea354f0bb +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-20 19:51:57 +0100 + + pixma: Canon PIXMA G2000 is working + + reported by William Bombardelli da Silva + +commit 7521ff5b339c1513560014f1885742f57cfa5b36 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-20 19:25:46 +0100 + + pixma: Canon imageRUNNER 1133 is working + + See issue sane-project/website#15 + +commit c9c0d956c60a9e7d36bdfbdcdfdf1340499d2edd +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-20 19:14:19 +0100 + + pixma: backend version 0.21.0 + +commit 7bbc9bf1c76c9ce1a36d3c771e38d8585c724d86 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-20 19:12:55 +0100 + + pixma: new scanner CanoScan LIDE 300 + + See issue sane-project/website#18 + +commit 0d193b838b49335c848ad2b6e0d5edee95796837 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-20 19:00:32 +0100 + + pixma: fix manpage section + +commit ab1b746c69e2490102fd2cec36f7489b797b4bd4 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-20 18:47:24 +0100 + + pixma: add button support for CanoScan LiDE400 + +commit c784e82d65689fd1e315bb814e381959a56d2b98 +Merge: 2b0c7a31 d9784940 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-02-20 17:44:44 +0000 + + Merge branch 'master' into 'master' + + pixma: Added Canon LiDE 400 + + See merge request sane-project/backends!36 + +commit d9784940968d4dec9ffc4b1810b01729bb9270a2 +Author: pekhterev <pekhterev.e@gmail.com> +Date: 2019-02-20 17:44:44 +0000 + + pixma: new scanner CanoScan LiDE 400 + + See merge request sane-project/backends!36 + +commit 60dffda6036ae15d89b2a94af269d32dcb300786 +Author: Manuel Argüelles <manuel.arguelles@smartmatic.com> +Date: 2019-02-08 22:40:15 -0500 + + Add mention of company contributing to canon_dr.c + +commit 2b0c7a3170a6ef0ab74bbf652069aa06a069e8c6 +Author: Alex Belkin <abc@telekom.ru> +Date: 2019-02-05 15:19:27 +0300 + + xerox_mfp: Add Samsung C480W usb id + + Reported in #54 by Lambrigts walter. + +commit 78ffe3235db28a1048561d32267dc69fdc3b79d1 +Merge: 66fed7c4 fd18d197 +Author: Alex Belkin <abc@telekom.ru> +Date: 2019-02-05 15:08:17 +0300 + + Merge branch 'Piraty/backends-samsung-m2070' + +commit fd18d197f8346ebee2841fc0ddbd5bbca6e8649e +Author: Piraty <piraty1@inbox.ru> +Date: 2019-02-03 15:06:59 +0100 + + xerox_mfp: Add Samsung Xpress M2070 + + Device is tested with latest sane (1.0.27) on several Linux + distributions (Void Linux + Ubuntu), using the proposed addition. + + Frontends used to test are: simple-scan and xsane + +commit 66fed7c4bfb28fb0a97abb470751636ada871c82 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-02-02 10:38:35 +0900 + + Bump Alpine build from 3.8 to 3.9 + +commit 4354fc7f6da2ee65cbe940a715f11abecdad3f49 +Merge: 93340afd 00d31e14 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2019-01-21 11:51:48 +0000 + + Merge branch '7-discolored-bar-on-scan-canolide-200-from-1-0-25-onwards' into 'master' + + Restore slow_back_home use, disable rewind for gl847 + + Closes #7 + + See merge request sane-project/backends!34 + +commit 93340afddfbc4085a5297fe635b65dd7f7f3ef05 +Author: Bernhard Ãœbelacker <bernhardu@mailbox.org> +Date: 2018-12-17 00:05:43 +0100 + + mustek_usb2: Avoid stack smashing. Fixes #35 + + Use a properly sized variable in call to sanei_usb_{read,write}_bulk. + + Debian-Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=886777 + Debian-Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=907972 + +commit a8fb090f560aa8f15df137c4162090524fd31323 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-01-03 12:12:28 +0100 + + add missing development package to INSTALL.linux + +commit 99abf804109b330a77a4bf7c74e37df965698138 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-01-01 14:25:23 +0100 + + pixma: backend version 0.20.0 + +commit 8fdc6f79eaa050d60257f9f541382ffa1ebe0aa4 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-01-01 14:24:41 +0100 + + Revert "pixma: backend version 0.19.0" + + This reverts commit dd6e2632418d46baaed6d6f5aec1d4c8fc625d9f. + +commit 46ef5ffa4198847e306aae8047fe04bf53ab5aa7 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-01-01 14:24:27 +0100 + + pixma: update copyright + +commit 107f334d7f0693756dfc148e05265e78da75816a +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-01-01 14:20:46 +0100 + + pixma: update copyright + +commit dd6e2632418d46baaed6d6f5aec1d4c8fc625d9f +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-01-01 14:14:19 +0100 + + pixma: backend version 0.19.0 + +commit ff021ddcf919039a95d75f1fb87c05332264274e +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2019-01-01 14:13:58 +0100 + + pixma: new scanner Canon imageCLASS D550 + +commit ac83c8110c47659993266dae3de6aafb29308716 +Merge: 36648cba d71f5e4b +Author: Gerhard Jäger <gerhard@gjaeger.de> +Date: 2018-12-31 14:13:26 +0000 + + Merge branch 'plustek-fix-color-banding-64bit' into 'master' + + backend/plustek: fix "color-banding" on 64bit + + Closes #42 + + See merge request sane-project/backends!33 + +commit 36648cba52c90df11ee5a6c3d3a4a7506b0cc7cd +Merge: 2d14283d 47f9b1ee +Author: Gerhard Jäger <gerhard@gjaeger.de> +Date: 2018-12-31 14:09:56 +0000 + + Merge branch 'lide700' into 'master' + + Fix a bug with Canon LiDE 700 where bright areas overflow + + See merge request sane-project/backends!32 + +commit 2d14283d0c443cfd505088f2503b6e59d47b192d +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-12-20 12:57:14 +0100 + + pixma: backend version 0.19.0 + +commit 2f3cdcb58089ca62e36151d687bf29839882f748 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-12-20 12:56:47 +0100 + + pixma: new scanner Canon PIXMA TS9500 Series + +commit 08a638dc319a9f10810f2653002c7f348dd492d6 +Author: Nico R <nico@n1c0.de> +Date: 2018-10-06 17:50:47 +0200 + + xerox_mfp: Add Samsung Xpress C1860FW + + Device status is “untestedâ€, because it was not really tested _in depth_. + Basic scanning of a number of pages using the automated feeder worked. + + See https://alioth-lists.debian.net/pipermail/sane-devel/2018-October/036411.html + +commit 00d31e14f8a5339a2756af29697ec3c2ff6e7d4d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-12-16 22:25:12 +0900 + + genesys: fix [-Wunused-function] compiler warning + +commit d609de285b710ca0a9c76c653abee4b8f4315f57 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-12-16 21:56:52 +0900 + + Restore slow_back_home use, disable rewind for gl847 + + See #7. + +commit d71f5e4bc87500c2de8e4297e140bab09e3f6272 +Author: MichaÅ‚ Wróbel <mvv@google.com> +Date: 2018-12-09 22:21:18 +0100 + + backend/plustek: fix "color-banding" on 64bit + + Fixes https://gitlab.com/sane-project/backends/issues/42 + +commit dc3e6e6e41f4698c0676bb8d0119777ed91d287a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-12-08 20:33:20 +0900 + + .gitignore: `make check` artifacts + +commit 866c451edb420855c6d9dff6b7a6c21a0a2d96ce +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-12-08 20:29:22 +0900 + + Add a Fedora 29 build, drop the Fedora 27 one + +commit b72e2bc758a9d6a93b25083f8f4ac73dadff1e86 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-12-08 20:24:00 +0900 + + utsushi.desc: Sync with upstream + +commit 47f9b1eeed2deb1f0d0f63c25f83dab5aeea0c8d +Author: Mark Hills <mark@xwax.org> +Date: 2018-12-01 21:01:57 +0000 + + Fix a bug with Canon LiDE 700 where bright areas overflow + + On this scanner, white areas are easily seen to become yellow, implying + some kind of integer overflow in the blue channel first, followed by + others. + + I can't be 100% sure this is the correct fix without knowing more about + the design or having a data sheet; this "target_code" was established + experimentally. + + This is a fix to issue #43. + +commit 4423421806d727885918b81f94fde1d21409059e +Author: Mark Hills <mark@xwax.org> +Date: 2018-12-01 21:00:47 +0000 + + A switch statement prepares us for additional entries + + Avoid the negative 'if' case which is harder to reason about. Preparing + for new entries to be added here. + +commit 1bc6ade107d294d93ad4c50727bd9fd77caf63ec +Author: Manuel Argüelles <manuel.arguelles@smartmatic.com> +Date: 2018-11-30 10:50:13 -0500 + + Fix image displacement for lineart/halftone during hardware crop + + Increases the width of the image if the reported size is less than the byte + boundary. + +commit ecac81eee2f79fc3f089f3a3d3509a2860e3f4c0 +Author: Manuel Argüelles <manuel.arguelles@smartmatic.com> +Date: 2018-11-12 14:01:24 -0500 + + Set scan area to maximum when hardware crop is enable + +commit dc8b27c1eff4617596f7b9304ef743d415791c26 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-11-12 21:14:18 +0900 + + Add new maintainer to genesys backend + +commit 5c048d58df598c31e6918ad19179fa7131f56b43 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-11-09 20:31:29 +0900 + + Mention commit access for ricoh2 backend maintainer. + + [skip ci] + +commit 0af6149aa8799f0d0b08570af34a99c3de63eaba +Merge: 6f797d94 9cf0de75 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-11-04 11:33:33 +0000 + + Merge branch 'master' into 'master' + + Add new backend ricoh2 + + See merge request sane-project/backends!20 + +commit 9cf0de7559fe68a40db8e9f7421696e6d8c90c03 +Author: Stanislav Yuzvinsky <yu-stas@yandex.ru> +Date: 2018-11-02 23:12:44 +0300 + + Address review comments + +commit 6f797d94e572e333341d11a32aa37a6b36018584 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-28 12:29:36 +0100 + + pixma: backend version 0.18.2 + +commit 1675697366e0d69edf1e413265c6fc15e6f3ab97 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-28 12:28:11 +0100 + + pixma: MP490 Series doesn't need special image formatting @ high dpi + +commit 5fee88415b175054f38a9a31967c007c8b36d20f +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-28 12:11:49 +0100 + + pixma: Canon imageCLASS MF8030 is working + +commit f111032e7f05e735422d02a88b1d04cb7b5da1c2 +Author: Martin Güthle <mguethle@xunit.de> +Date: 2018-10-25 08:53:58 +0200 + + as6e: Avoid out of bound access + + This fixes a crash due to a stack corruption. + To reproduce the bug, set a path within the PATH variable, to something, + which exceeds 128 chars. Maybe more chars are needed, to reach the stack + corruption. + +commit 54aa154d918245d5090fc342d4d1b00cf12a2477 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-24 20:25:40 +0200 + + pixma: backend version 0.18.1 + +commit 8818879297155abb8f91b242b98b62a4d0024331 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-24 20:24:00 +0200 + + pixma: Canon PIXMA E510 is working + +commit e41090725370cf0abaf15cd9c34ad7e711fece3f +Merge: ef85977e 1846b038 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-24 20:05:00 +0200 + + Merge branch 'kapcake/backends-patch-1' + +commit 1846b0381e06359033f122986f3296afa3445677 +Author: Laurent Kap <me@kapcake.net> +Date: 2018-10-17 21:30:17 +0000 + + Adds button support for Pixma MG5350 + +commit ef85977ec4ba55254dba31752c84b4e160b63923 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-12 12:33:46 +0200 + + pixma: Canon PIXMA TS3100 Series is working + +commit 54c42b04a8ccfce2c140782007a11d2b3a1627fe +Merge: f633bad6 05400ad6 +Author: Gerhard Jäger <gerhard@gjaeger.de> +Date: 2018-10-11 07:36:54 +0000 + + Merge branch 'lide80-increase-bright-point' into 'master' + + backend/genesys: Increase excessively low bright point on Lide 80 calib + + See merge request sane-project/backends!10 + +commit f633bad6ec1dd4b306ea245dc10a602020df7bba +Merge: 030153b3 92c40c44 +Author: Gerhard Jäger <gerhard@gjaeger.de> +Date: 2018-10-11 07:34:14 +0000 + + Merge branch 'lide80-reduce-dark-area-offset' into 'master' + + backend/genesys_gl841: Reduce extra dark area offset for Lide 80 + + See merge request sane-project/backends!9 + +commit 030153b39b82aca45b724b940aa107fdfe0c4b37 +Merge: 6abb072d 065855e1 +Author: Gerhard Jäger <gerhard@gjaeger.de> +Date: 2018-10-11 07:33:24 +0000 + + Merge branch 'lide80-disable-ledadd' into 'master' + + backend/genesys_gl841: Disable LEDADD on Lide 80 since it's broken there (fixes issue #12) + + Closes #12 + + See merge request sane-project/backends!7 + +commit 6abb072ded1daea860c64375b140287fb180bfbd +Merge: c980c732 a64f2096 +Author: Gerhard Jäger <gerhard@gjaeger.de> +Date: 2018-10-11 07:29:59 +0000 + + Merge branch 'master' into 'master' + + genesys: Add buttons to LiDE 60 + + See merge request sane-project/backends!6 + +commit c980c73259de59b5af1785068b21c5417173e47e +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-10-11 00:46:55 +0900 + + Remove cached lists of supported devices + + Caching was introduced in e7d9779dfc3748f8f205585fa09ebc7181874642. + + Fixes sane-project/website#7. + +commit e2bfb2e00ad5f87d4f905218daa7d066f908c28b +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-10-11 00:30:20 +0900 + + Bump Alpine build from 3.7 to 3.8 + +commit b31ef5e4aafdc02eb019039a7a5f1b4e80e874ef +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-08 21:25:47 +0200 + + pixma: backend version 0.18.0 + +commit e8bdbe1f50fd44a87f6f95c40577ac1ea462b01f +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-08 21:24:51 +0200 + + pixma: new scanners Canon MAXIFY MB5100, MB5400 Series + +commit b5e92b8b8de83985f25484adcdeb5b2a4ecd0df9 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-10-08 21:24:04 +0200 + + pixma: new scanners Canon PIXMA TR7500, TR8500, TS3100, TS5100, TS9100 Series + +commit 8ba4c51bae5df65b67b692da9ade5e7808cee9eb +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-10-02 22:09:18 +0900 + + utsushi.desc: SYnc with upstream + +commit 30579b0f54dc079549bdf8190e59477814852799 +Merge: 428dc565 de8ab756 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-10-02 11:27:47 +0000 + + Merge branch 'for-upstream/backend_avision_gitignore' into 'master' + + add .po~ to gitignore + + See merge request sane-project/backends!24 + +commit 428dc5657d4e02d8eefabd0231e8117e73c17ccd +Merge: 6bdb2486 37bbbed3 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-10-01 21:17:45 +0000 + + Merge branch 'check-po.awk-typos2' into 'master' + + check-po.awk: Fix minor typos + + See merge request sane-project/backends!27 + +commit 37bbbed3cbe8ae80035f356d41e144c2e4255b3a +Author: Simon J Mudd <sjmudd@pobox.com> +Date: 2018-09-30 20:29:16 +0200 + + check-po.awk: Fix minor typos + +commit de8ab7560898550cbb6e3dcac655b46c52adaeaf +Author: Michael Niewoehner <foss@mniewoehner.de> +Date: 2018-09-20 19:26:43 +0200 + + add .po~ to gitignore + +commit 6bdb2486aeba08a4d75964b325da5a75b14c68bf +Merge: 04fc0ca8 cfbc7448 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-29 20:39:05 +0200 + + Merge remote-tracking branch 'origin/master' + +commit 04fc0ca8bd7bd64a1d4fbee6790d4353a79275a4 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-29 20:37:59 +0200 + + pixma: TS6100 Series is working + +commit d62ba623b2118ca009a8491e40daedbbd643f267 +Author: Stanislav Yuzvinsky <yu-stas@yandex.ru> +Date: 2018-09-22 01:00:06 +0300 + + Add new backend ricoh2 + +commit 3437b6e48ed235d5fcec6a4625eddf6bb52b77df +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-22 12:54:05 +0200 + + pixma: i-SENSYS MF730 Series is working + +commit cfbc744826f5ca29936fd00ae05b385819ce9988 +Author: Alex Belkin <abc@telekom.ru> +Date: 2018-09-21 21:35:03 +0300 + + xerox_mfp: Change support status of SCX-4623FW after user feedback + + Also fix spelling of previous commit. + +commit 22af4c8e251e34d28c13db79da8b5743e330a030 +Author: Alex Belkin <abc@telekom.ru> +Date: 2018-09-20 15:11:16 +0300 + + xerox_mfp: Update xerox_mfp.desc with useful comments + +commit 9ee0d41f4a0529fc2dd17b976337f6902053acff +Merge: 8bc33176 46e59346 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-09-17 00:36:35 +0000 + + Merge branch 'master' into 'master' + + Add Hebrew translation by Elishai Shkury + + See merge request sane-project/backends!17 + +commit 46e59346ea4f24210f50d82052e83486287004b0 +Author: Yuri Chornoivan <yurchor@ukr.net> +Date: 2018-09-16 22:57:27 +0300 + + Add Hebrew translation by Elishai Shkury + +commit 8bc331761a88491c80524cd7d4b1ae64c1fccc92 +Merge: 0b811391 eceeaa80 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-09-16 13:07:31 +0900 + + Merge branch 'master' of https://gitlab.com/bellaperez/backends + +commit eceeaa80afcfacb541f653380d4fbadba6c94e9c +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-15 22:28:48 +0200 + + Add a new transtalion for Valencian Language + +commit 0b811391a9b3bacfe17f8760da16b96663ba647e +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-13 19:07:42 +0200 + + pixma: new scanner i-SENSYS MF410 Series + +commit e8b11ec2eb948d5b13bc05287ddd58aad24bc413 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-13 18:43:55 +0200 + + pixma: backend version 0.17.51 + +commit 3b5223b16b043bba1c74a70df87047c889c7bc88 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-13 18:43:31 +0200 + + pixma: new scanner imageCLASS D570 + +commit 01533e2e3e99e72ec29272a039ef6997360e99e6 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-12 22:09:06 +0200 + + pixma: backend version 0.17.50 + +commit dbecf846d5c040eb0688eba2af21a168dbe29114 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-09-12 22:08:41 +0200 + + pixma: new scanner TS6100 Series + +commit 92dc8789be48297c4dca68b1150dfb0c83603c90 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-10 23:30:40 +0200 + + Sync source code + +commit 4bea45b632e68d7b6aa2972523d664fe42140a08 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-10 00:43:34 +0200 + + Fixes from Softcatalà .org mailing list + +commit 4c562f8142b0b67e8646975f07a3d0ebb588703f +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-09-09 09:54:38 +0900 + + Document that Ethernet works for the Canon MB5300 Series + + See https://alioth-lists.debian.net/pipermail/sane-devel/2018-September/036346.html + +commit fd8aedea4c475f1c8c51c3efe28bc81495ece61c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-09-08 20:15:15 +0900 + + List Canon MB5300 Series as supported + + See https://alioth-lists.debian.net/pipermail/sane-devel/2018-September/036340.html + +commit f0f349b0ce2088dac9c8762959f9bf2f93313e9b +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-07 15:22:17 +0200 + + Last fixes reported + +commit 36d1618b76d692e58523e02e869d8eab0834c413 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-07 14:52:27 +0200 + + 100% translated, whaiting mailing list fixes... ;-) + +commit 3ee997194a7026085b3c390289bfec89fb81e40c +Merge: 2f944738 1484b475 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-09-06 12:30:34 +0000 + + Add support for Plustek OpticSlim 500+ + + See merge request sane-project/backends!4 + +commit 1484b47582d20eab6a78a1f0461f5e90ceb7faa8 +Author: Mikhail Strizhov <mishastrij@mail.ru> +Date: 2018-09-06 12:36:26 +0300 + + add support of Plustek OpticSlim 500+ + +commit 210ea90b107337a79e4505c372124db4a6ad41b8 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-04 23:26:43 +0200 + + More updates + +commit 2f944738803fbaf90a37e3960b06f565274c1174 +Merge: 1d58e23c 32d05417 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-09-04 12:24:52 +0000 + + Merge branch 'master' into 'master' + + Update Ukrainian translation + + See merge request sane-project/backends!14 + +commit 7f551a79e33df168b5faaa73ea0bcb7d5b8f7269 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-03 01:23:23 +0200 + + Updates and fixes for initial translation + +commit 617037837aff3952dae719265250f4a1e3d657d6 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-02 21:33:36 +0200 + + Fixes from SoftCatalà .org + +commit ceb6b2787e5f904c6a652988ef8f77f44ef4d826 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-02 21:06:41 +0200 + + Last fixes for initial translation + +commit 32d05417c898fad4985f3cb87b465826ec99fd60 +Author: Yuri Chornoivan <yurchor@ukr.net> +Date: 2018-09-02 20:23:47 +0300 + + Update Ukrainian translation + +commit 1d58e23c91bce08693ae75ae18d66c938927b6b7 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-09-02 20:52:51 +0900 + + utsushi.desc: Sync with upstream + +commit 4a73b1cb0c0184cb7340fb398d39c63f649341cb +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-01 23:26:55 +0200 + + KDE fixes (pology) for initial translation + +commit 7459debf0ed2de477111f2246f15c24758e6b19e +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-09-01 20:52:05 +0200 + + Update initial translation + +commit a1f3fbcef869e865aef7a6817a12aba3f8cda58e +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-08-28 19:55:01 +0200 + + Sync all languages (test Catalan translations) + +commit 2143773b063e58754c9fe56a6cc5c9cfbf676964 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-08-28 19:31:57 +0200 + + Update initial translation + +commit 158898f2a4e26467f84ff15d01e0da8eeec38c7f +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-08-28 00:52:26 +0200 + + More updates for initial translation + +commit 5230430a572c078605cf9cd3894de2ebb80b1956 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-08-27 21:57:24 +0200 + + pixma: backend version 0.17.49 + +commit eb11c2fc94ccc7ae0e002a6a488546dd31f17171 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-08-27 21:56:48 +0200 + + pixma: new scanner i-SENSYS MF731/733 + +commit c187b6c36334789f9d71f1e74f89615725a9f068 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-08-27 02:05:11 +0200 + + Updates for initial translation + +commit d61a59ca01b638474b6a847bf26e6dfb9420e064 +Author: Manuel Argüelles <manuel.arguelles@smartmatic.com> +Date: 2018-07-30 17:26:13 -0500 + + Add support for Canon DR-X10C scanner + + Added initial support for DR-X10C SSM2 scanner with dropout color, hardware + deskew and hardware crop. + +commit a76b0b21543f38996fb6a516f7d8e25cb80d08c7 +Author: Antoni Bella Pérez <antonibella5@yahoo.com> +Date: 2018-08-21 14:10:54 +0200 + + Add an initial translation + +commit 082cf4cdf3cad1f97f4d1a5c0ffb1ad2c69ab9df +Merge: 1a2a8ee7 d6aace7d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-07-22 13:01:55 +0000 + + Merge branch 'hp5590-fix-compile-error' into 'master' + + hp5590: Fix sanei_net.h include path. + + See merge request sane-project/backends!8 + +commit 05400ad69b8047f0a2320a120519941fa99faf36 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2018-07-21 03:37:45 +0300 + + backend/genesys: Increase excessively low bright point on Lide 80 calib + +commit 92c40c44b9a6c7ce7a5cc865db1f4b61fb1bd3c0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2018-07-21 03:37:44 +0300 + + backend/genesys_gl841: Reduce extra dark area offset for LIDE 80 + +commit 065855e1da5c088e561580c26d96ad2b051685c4 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2018-07-21 03:37:46 +0300 + + backend/genesys_gl841: Disable LEDADD on Lide 80 since it's broken there + +commit d6aace7d5167b39d474f57c5671f0a400cad0bc0 +Author: Povilas Kanapickas <povilas@radix.lt> +Date: 2018-07-21 03:37:43 +0300 + + hp5590: Fix compile error + +commit 1a2a8ee744ceacdb2a46906e626327c5d9496af6 +Author: Ilia Sotnikov <hostcc@gmail.com> +Date: 2018-07-15 14:09:49 +0300 + + backend/hp5590.c, backend/hp5590_cmds.c: + + Files header have been expanded to mention of scanbd integration by + Damiano Scaramuzza and Bernard Badr + +commit bfc63709a796704005642edfacf0b4bb92732597 +Merge: fc88e525 1649d5bf +Author: Ilia Sotnikov <hostcc@gmail.com> +Date: 2018-07-15 11:00:18 +0000 + + Merge branch 'master' into 'master' + + HP5590: scanbd integration is ready. + + See merge request sane-project/backends!5 + +commit 1649d5bfea36bc2209a7c673df333ac6c71ac376 +Author: Bernard B Badr <bb3138@live.de> +Date: 2018-07-15 11:00:18 +0000 + + HP5590: scanbd integration is ready. + +commit a64f2096438970ca0c1b9a86f363a0f3ce8476ef +Author: iosabi <iosabi@yahoo.com> +Date: 2018-07-02 22:48:02 +0200 + + genesys: Add buttons to LiDE 60 + + Canon LiDE 60 has four buttons. These are already supported in the + GL841, we just needed to add them to the config. Tested it with scanbd. + +commit fc88e5251130ef39a7e56930c3323aa1d8d7762d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-06-13 21:23:43 +0900 + + utsushi.desc: Sync with upstream + +commit a80f3b575ea7f2ef90efb1368949a7d0cf451366 +Author: Ilia Sotnikov <hostcc@gmail.com> +Date: 2018-06-11 11:11:53 +0300 + + backend/hp5590.c, backend/hp5590_cmds.c: + + Files header have been expanded to mention of ADF page detection and + high DPI fixes by Bernard Badr + * Use C-style comments instead of C++ ones + +commit 8c912284299d37dd32ea8e3216d16cada180928e +Merge: 85efea28 b1da51f7 +Author: Ilia Sotnikov <hostcc@gmail.com> +Date: 2018-06-11 07:56:28 +0000 + + Merge branch 'master' into 'master' + + HP5590: Fixed ADF handling, fixed 48bit color mode, fixed 2400 dpi color layer shift. + + See merge request sane-project/backends!3 + +commit b1da51f7fe04f6186dc0f1826bd7c0e67f1e41f8 +Author: Bernard Badr <bb3138@live.de> +Date: 2018-06-11 07:56:28 +0000 + + HP5590: Fixed ADF handling, fixed 48bit color mode, fixed 2400 dpi color layer shift. + +commit 85efea28aeb14c0f769a25d527055636aa9ec915 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-05-31 22:15:04 +0900 + + Add a Fedora 28 build, drop the Fedora 26 one + +commit ad20558bb23195f3a5c7cbcc9cb81af3e05dcd19 +Author: Alex Belkin <abc@telekom.ru> +Date: 2018-05-18 01:51:01 +0300 + + xerox_mfp: Blacklist Samsung M288x Series from jpeg mode + + Fix issue #315839 reported by Jan Christoph Ebersach + https://alioth.debian.org/tracker/?func=detail&group_id=30186&aid=315839&atid=410366 + +commit 54a55700f66eaeef827de3ab2dbf802dd32ea697 +Author: Alex Belkin <abc@telekom.ru> +Date: 2018-05-18 01:31:46 +0300 + + xerox_mfp: blacklist SCX-4500W from jpeg mode + + Fix issue #315876 reported by Bernard Cafarelli + https://alioth.debian.org/tracker/?func=detail&atid=410366&aid=315876&group_id=30186 + +commit 4accdae4edbaf4ab88dcf458282c82189f8e39a3 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-05-16 21:29:50 +0200 + + pixma: backend version 0.17.48 + +commit 15aebab5149a767e02e25b47abb7145f7fa6f668 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-05-16 21:29:14 +0200 + + pixma: Canon MAXIFY MB2100 and MB2700 Series support 1200 dpi + +commit 6a7e4141eb53876511829b5bb87aae311d828402 +Merge: 9d315bc2 5e5183c8 +Author: Rolf Bensch <rolf@bensch-online.de> +Date: 2018-05-16 18:08:42 +0000 + + Merge branch 'mb2100_adf_oop' into 'master' + + Return NO_DOCS after last ADF page, not IO_ERROR + + See merge request sane-project/backends!2 + +commit 5e5183c84efe4d71675a3d4cc968a4eb09511a7d +Author: Earle F. Philhower, III <earlephilhower@yahoo.com> +Date: 2018-05-15 20:16:44 -0700 + + Return NO_DOCS after last ADF page, not IO_ERROR + + When scanning from ADF in MP150 based scanners, after the last page is + scanned the XML session-close was sent. However, when using the ADF, if + the frontend called sane_start/sane_read(), it would try and send an + XML command that was not valid after the session abort. This would give + an IO error up through the stack. + + Now, check if ADF scanning is happening and on reads after the last page + return SANE_STATUS_NO_DOCS on read. and abort. + + Finally, minor fix of max DPI for Pixma MAXIFY MB21xx/27xx to 1200 DPI. + +commit 9d315bc2f71c48622511c49fdeeb756b71a69e38 +Author: Robert A. Schmied <uwppp@flash.net> +Date: 2018-05-14 21:28:40 +0900 + + Fix typo in debugging statement + +commit a1c42247ab36682d9664affb1dab5933dbd3fd20 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-05-12 20:54:38 +0200 + + pixma: backend version 0.17.47 + +commit 72f9411257345c941459703f3e08f79d8ea8f46e +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-05-12 20:55:16 +0200 + + pixma: new scanners Canon Maxify MB2100 and MB2700 Series + +commit 8c340a34a49312a29f959e22286c3b83be9bf19b +Merge: c6bfe88c d90f9054 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-05-12 20:35:41 +0200 + + Merge branch 'earlephilhower/backends-pixma_jpeg' + + merge request #1 + +commit d90f9054c6fd2f4ecad78142411bef91c449c19f +Author: Earle F. Philhower, III <earlephilhower@yahoo.com> +Date: 2018-05-09 13:40:10 -0700 + + Add JPEG scanning, MB2100/2700 to PIXMA + + The Maxify scanners seem to only be able to return JPEG data for ADF + sources. Attempting to send a gamma LUT will result in an error on + sane_start when trying to use the ADF. Flatbed scanning is unaffected + and runs fine with LUTs like prior models. + + This patch adds support to the PIXMA backend for returned JPEG scans + and keys it off of the new capability, ADF_JPEG. + + Tested on a Maxify MB2120 using the ADF and the flatbed scanner. + + This may also fix other Maxify MB* models where it seems the ADF does + not with with the prior code, but I only have the MB2120 to test. + +commit c6bfe88c31f3f582fdc0bea08199282efceb3914 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-04-18 21:36:00 +0900 + + Update mailing lists addresses to new location + +commit 4ade295ab1c1d3bbd23ae3fe2118424c2bb5c799 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-04-18 21:12:44 +0900 + + Update mail archive links to point to new location + +commit d22f36f8cc759d9ee978a438be08b1bd57bfe170 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-04-10 19:41:24 +0900 + + utsushi.desc: Sync with upstream + +commit f17585e1595e50ee0bbdd36210bc141e1a137f53 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-26 21:31:57 +0900 + + *.desc: Mark backends that have become unmaintained + +commit 872a7521f5e0177cacfd3f800105237fd596fd9e +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-26 21:30:57 +0900 + + AUTHORS: Update git access status following project member changes + +commit 07f1351df510ea9453811b9137e71b8c26b4ac38 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-20 21:48:24 +0900 + + sane-p5.man: Point to new issue tracker location + +commit 2d374b0a690fe4e8116fa2714ef426cc3fd536d1 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-16 21:55:35 +0900 + + ltmain.sh: revert removal of SANE specific tweaks + +commit a78969384b2b7ac233694e7e21add44ad055dbea +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-16 21:54:42 +0900 + + autotools: Sync derived files + + This was done by running + + libtoolize --copy + autoreconf --force --install + + on Debian GNU/Linux 9.3. + +commit c8d8f05256523cb0aafe24309ea2b3c93bea20f2 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-16 20:56:47 +0900 + + Bump autofoo dependencies to match those present in Debian 9 + + This gets rid of the warning that AM_PROG_MKDIR_P is deprecated and + should be replaced with AC_PROG_MKDIR_P warning. + +commit f162fad98c55f792828acc05ff32c3e036490ea7 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-15 09:22:53 +0900 + + Bump the "canonical" build environment to Debian 9 + +commit 5944c15d03b6aadaa8691cd0b7615b551f60d196 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-15 09:41:58 +0900 + + Bump Alpine build from 3.6 to 3.7 + +commit 080702ae7df21e882d2e135fc35a0bbde04aca8b +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-15 09:04:31 +0900 + + Add a Fedora 27 build, drop the Fedora 25 one + +commit a5ae2dad1d4202911be927933b8f8d6a8dde6413 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-03-11 12:08:18 +0100 + + pixma: backend version 0.17.46 + +commit 12dbae0fc5d08c597deb85150521945c5b806488 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-03-11 12:06:51 +0100 + + pixma: MB2300 Series has no duplex document scanner + +commit 4f156894db02d3232a04ab17ca49da84540e7d13 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-03-11 11:13:43 +0100 + + pixma: add button support for MB2300 Series + +commit 393cf040b950b274090372b58693227a4455aa16 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-10 10:14:06 +0900 + + Add doxygen generated sanei HTML documentation to archive + +commit fadb3d809ae850b5f260550d149713dde763945d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-09 22:36:39 +0900 + + Add doxygen generated sanei HTML documentation to artifacts + +commit 82b9d215fc6d943cb9245c8eded11f51f4f1f154 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-09 22:23:12 +0900 + + Update configuration files to match newer doxygen version + + The comments have been dropped to cut down on future diff chatter. + Please refer to the doxygen documentation instead. + +commit 9b0db823ede07e1bb0cb867b64b87d019cff5741 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-07 21:38:56 +0900 + + Make absolute URLs in the sane-desc HTML output site-relative + +commit 8849137abb3f7ac2836609c69ee2c89af7538ee8 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-03-05 20:21:58 +0900 + + Make root-relative hrefs/src properties site-relative + + This allows for hosting content on any level below a domain. + +commit 48f950b95a1a851e8656c0da53ddd553f5f397c9 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-27 21:38:06 +0900 + + utsushi.desc: Sync with upstream + +commit bb56d44eb99cc8fc122728995fc8a2aa68aa83f5 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-25 17:01:10 +0900 + + CI: Actually move the *html files + +commit ef0610ce2e8155b1edfca45dc03e653f80cf66c3 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-21 21:09:59 +0900 + + CI: Generate device support status HTML in after_script + +commit 936a45b4aa3b818c5c963109e06d7cece5c19af1 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-21 20:50:07 +0900 + + Include device support status HTML pages in archive target + + This is meant to make it easier for the website to get the latest + information up. + +commit a84290a8f96f2a93ab4ac4cdc36e7e771d4a3e48 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-20 21:24:56 +0900 + + sane.man: Fix typo in stv680 backend name + +commit f38a1731a643e0c54f27f065ff35a4d66635f68d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-09 18:37:21 +0900 + + Point to new GitLab.com repository location + +commit c32c78fe8e19835cde4bf7b3742d488e3ec9092b +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-08 21:58:45 +0900 + + epson2.desc: Add ET-2650/L495 as supported + + Information courtesy of Ed Hamrick. + +commit 1b2e4b0b3bef6dc07e750bdb9288f593faf146a2 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-08 21:53:02 +0900 + + include/sane/sanei_ir.h: Adjust doc params to match code + +commit 0e7b3b79251274cff6c136cb54785e7ccc047966 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-02-08 21:52:14 +0900 + + utsushi.desc: sync with upstream + +commit 3c6a3d499236e7f8ad9e9f7d43d2b22f26d17480 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-02-04 13:12:34 +0100 + + pixma: Canon MAXIFY MB2300 Series is working + + - reported by Patrick Roncagliolo + +commit b487db3af0251171e43d8a5458f9200954cf79a9 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-01-04 19:52:16 +0100 + + pixma: Canon i-SENSYS MF620 Series is working + + reported by Markus Heiser + +commit 74898c4330cc25521ddbf008aa18db75fc00af1b +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2018-01-03 16:13:16 +0900 + + Fix array indexing + + This fixes a glaring oversight in 39ceeae6. Thanks to James Ring for + reporting this. + +commit b6873cfa5a5e57e1ba60f90b137cfa4400bfb99a +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-01-03 21:01:32 +0100 + + pixma: backend version 0.17.45 + +commit a873a5e444a067c6d2ac7f813b2e97e31e98c582 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-01-03 21:00:51 +0100 + + pixma: new scanner Canon i-SENSYS MF630 Series [#315892] + +commit e6db7a8f14a107bcdc1edbb068cee15a34f2d030 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-01-03 20:52:39 +0100 + + pixma: new scanner Canon i-SENSYS MF630 Series + +commit 463e010f1a83063610b43b7aae6f378b8c532a07 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-01-03 20:07:33 +0100 + + pixma: new scanner Canon i-SENSYS MF620 Series + + many thanks to Markus Heiser + +commit 781c4ad080d1f240e763fc87f193a9349e23a23d +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2018-01-02 14:14:05 +0100 + + pixma: Canon MAXIFY MB2000 Series is working, except ADF (#315538) + +commit e895ee55bec8a3320a0e972b32c05d35b47fe226 +Author: Edward Betts <edward@angle4.com> +Date: 2017-12-01 00:49:00 +0900 + + sane-find-scanner: Recognize --help as a valid option + +commit 214f82e36a3bbcac21053cc282dfe67ecef9a0f9 +Author: Gerhard Jaeger <gerhard@gjaeger.de> +Date: 2017-11-18 15:07:25 +0100 + + [#315864] CanoScan LiDE25 -> CanoScan LiDE 25 + Change LiDE descriptions and split as suggested in the ticket. + While here remove outdated URL. + +commit d6a93b83a7dc3a3871db31ecf11adebe470b52a4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-11-18 17:35:30 +0900 + + epson2: Add Expression 12000XL / DS-G20000 as supported + + Also removed stale comment in epson2.desc. + + See https://lists.alioth.debian.org/pipermail/sane-devel/2017-November/035744.html + +commit 76600e397459e237af2a174664fe7fc1e3b5c110 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-11-18 16:42:39 +0900 + + utsushi.desc: sync with upstream + +commit c51af8fd996f124151f82e13d6a6e94fcd906b94 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-11-14 22:16:40 +0100 + + pixma: fix typos + +commit 77722d754f2eb06d1a26380989dd098fcb8da533 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-10-11 22:09:43 +0900 + + utsushi.desc: sync with upstream + +commit 99a98e448b603fccb438aea94a7c28ea2ca2059a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-09-29 21:49:08 +0900 + + saned: Brush up manual page's OPTIONS section following 5288dd5f + +commit f9a76395da768f2bd4ee803a78ca5e5604df0c8d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-09-29 21:48:14 +0900 + + saned: Fix typo in help message + +commit 5288dd5f61b32da2f4bc18950c247dc3b6e1579d +Author: Luiz Angelo Daros de Luca <luizluca@gmail.com> +Date: 2017-09-18 04:25:37 -0300 + + saned: reorganize flags, remove run_mode SANED_RUN_DEBUG + + Flags like -a, -d and -s have many overlap effects. This patch restricts + the effect of flags to a simple action. + + New -u (user) flag replaces -a optional argument for running saned as a different user. + The code that retrieve the user info and drop privileges migrated to runas_user(). + As a side effect, PID file can be created even if getting user info fails. + + New -l (listen) flag sets run_mode to standalone. + New -D (daemonize) flag daemonizes saned after bind. + New -o (once) make saned exit after the first client disconnects. + Flag -s (syslog) is gone. Previous behavior can be reproduced with '-a -d level -o -f'. + New -e (stderr) flag for redirecting output to stderr, instead of syslog. + + Flag -d (debug) now only sets the debug level and argument is required. Previous behavior + can be reproduced with '-a -d level -o -f -e'. + + The run_mode SANED_RUN_DEBUG and SANED_RUN_ALONE shared most of its code + path. With the new flags dealing with their difference, SANED_RUN_DEBUG is gone. + + Flag '-a' still works as before but it can be replaced by '-l -D -u user'. + + Current uses of -d (debug) or -s (syslog) will break. + + Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> + +commit c9356cb184c0babeb9a8b525728e33d01e2a878c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-09-09 15:37:13 +0900 + + saned: Fix incorrect claim about passing options to inetd etc. + +commit 1f68d8d8c43ff049b0c6921d3823f6c32fdece41 +Author: Farid Benamrouche <fariouche@yahoo.fr> +Date: 2017-07-22 21:34:00 +0900 + + saned: Cancel scan if data connection appears to have gone away + + The data connection timeout default to 4000ms but is configurable + in saned.conf. + + See Alioth 315765 + +commit 0a62202e95983493598d3b94718bb277f5e71b2f +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-09-01 12:15:40 +0200 + + pixma: backend version 0.17.44 + +commit 055c3ffa8643da6dad885bb69b08a7d4f45d1cc0 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-09-01 12:15:10 +0200 + + pixma: new scanners Canon PIXMA E410 Series, E3100 Series, G2000 and G3000 + +commit 61ca162fc069dff85964ad5352b1f2faaca692c5 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-09-01 12:07:57 +0200 + + pixma: fix definitions for PIXMA G4000 + +commit d78013afc6943b6cd86d468b045fe16fe495350d +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-09-01 11:52:39 +0200 + + pixma_mp150: fix comments for generation 5 scanners + +commit fef19d7740fc1dd1c3109efe47040b1eca046fe6 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-08-31 20:34:32 +0200 + + pixma: backend version 0.17.43 + +commit 450e55c2309d372a088ef963082252fd2f27c524 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-08-31 13:27:16 +0200 + + pixma_mp150: send XML end of scan dialog also for generation 5 scanners + +commit 9b95970b917a74d4c973dc536192b7546603c9b7 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-08-20 14:08:33 +0900 + + utsushi.desc: Sync with upstream + +commit 6eb2a0d10a9f5e116b8ef3aff508dfec51ca273a +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-08-18 10:06:17 +0200 + + pixma: fix device interface info for PIXMA MG7100 Series + +commit 5a0e30b5e31586bf3ec5488876a7744341e16331 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-08-17 21:24:14 +0900 + + epson2: Add the Epson XP-243 245 247 Series as supported + + See https://alioth.debian.org/tracker/?func=detail&atid=410366&aid=315818&group_id=30186 + +commit 1e87016dca2593e4d595654435fe0bbaf6311fd3 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-08-12 14:14:05 +0900 + + epson2: Add the Epson XP-427 as supported + + See https://alioth.debian.org/tracker/index.php?func=detail&aid=315805&group_id=30186&atid=410366 + +commit 519ff57bed9391c9c178f660648669f4c77b7d3a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-08-12 15:03:51 +0900 + + install: Make sure configuration files get created before install + +commit f19a41e6f7b693e55fd4e26b988e55e3a30b6eb8 +Author: Luiz Angelo Daros de Luca <luizluca@gmail.com> +Date: 2017-07-22 05:43:17 -0300 + + saned: update man for option -b + +commit fc57a5a6a5b9d1039915145223571a2211ce6173 +Author: Luiz Angelo Daros de Luca <luizluca@gmail.com> +Date: 2017-07-22 05:43:16 -0300 + + saned: fix --debug help message (output is stderr) + + Man page was correct. + + Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com> + +commit f482b498a25326ae380c16f22dfdfc34ec6edfe3 +Author: Jeremy Bicha <jbicha@ubuntu.com> +Date: 2017-07-26 18:32:36 -0400 + + po: Fix Plural-Forms header for es and gl + + Fixes 315801. + +commit f88b5ea2b6bccf7dc356fa2c2944428f0a67d41d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-22 15:31:42 +0900 + + umax_pp: Fix [-Wsign-compare] compiler warnings + +commit 14e701438dd87dc47b500c504702c4b5b98b5c3d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-22 14:19:02 +0900 + + umax_pp: Fix [-Wunused-but-set-variable] compiler warnings + +commit 772f31d4a0624c00b698fc4873feafb5820c2141 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-22 14:02:10 +0900 + + umax_pp: Fix [-Wunused-variable] compiler warnings + + The variable declaration section has been completely rewritten to + follow the #ifdef structure of the function's implementation. + +commit 56398ead607d8bcb9deef7ca3f4d7f78478f1b4c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-22 11:48:14 +0900 + + sane-usb: Document SANE_USB_WORKAROUND variable + + Fixes Alioth#315792. Thanks Zdenek Dohnal + +commit 1f8bfd69a253fa0e3af39e30d1a5ce00891550d2 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-18 21:02:43 +0900 + + dell1600n_net: Fix [-Wincompatible-pointer-types] compiler warnings + + This casts the pointers to the type expected by the functions as per + POSIX stipulations. + + See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/netinet_in.h.html + +commit bdba3cc073055ac852bc93e126ae97f938b2d06f +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-18 20:46:01 +0900 + + tools/umax_pp: Fix [-Wunused-variable] compiler warning + + The file descriptor is only used in code conditionalised on the + HAVE_LINUX_PPDEV_H preprocessor define. + +commit 3258b70de42f0abf891b139b01fc0a731f2974e8 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-16 11:46:27 +0200 + + pixma: fix device status for i-SENSYS MF240 Series + and add comment for image width workaround (see: 611647b) + +commit 8f61317f00529ecb0b1e44a726266e33512759ad +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 22:52:00 +0900 + + autofoo: Sync generated files + +commit f18ab2e2a29058c098d7709cbad6169064b70da2 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 22:48:29 +0900 + + plustek-pp: Replace sys/signal.h include with signal.h + + All other backends already `#include <signal.h>` directly, without any + configure time checking or problems. + + Fixes [-Wcc] compiler warning on Alpine. + +commit 68ec98d7b1ef636f4d230c81c8e1e8de7e62c66d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 22:15:18 +0900 + + hp3500: Fix [-Wunused-function] compiler warning + + The sigtermHandler is only used when _POSIX_SOURCE is defined. + +commit d94c29a726667604f3ba1cf18185a48ad7355966 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 22:06:05 +0900 + + autofoo: Sync generated files + +commit 54627bdeacf5f8bff8d622469f3c02f6f9c8ef79 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 21:58:51 +0900 + + lib/isfdtype.c: Remove badly broken substitute + + The substitute completely ignores the fdtype argument and only works + correctly for S_IFSOCK values. This happened to be the only way the + function was invoked but for safety's sake this has been replaced by + a local implementation that does pretty much the same thing, without + the misleading bit. + + Found courtesy of a [-Wunused-parameter] compiler warning on Alpine. + +commit c754d440eaec35b231537a26ee6c6d230c489733 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 20:27:28 +0900 + + sanei_thread: Fix [-Wunused-function] compiler warning + + The sanei_thread_set_invalid static function is only used by code that + exists if USE_PTHREAD is defined. + +commit f3334500860115aab264de850db1c0cb6411099e +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 17:19:38 +0900 + + CI: Add a Fedora 26 Clang build + +commit 2c1f3d696f1c5ba6f410fca6e103da51c6a814a4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 17:17:21 +0900 + + autofoo: Sync generated files + + This pulls in the changes from 756d286f and e7d9779d. + +commit 756d286f3605143b26471eb7e1e7a45bc7ba356a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 17:13:34 +0900 + + pthread: Disable support if pthread_t is *not* an integer type + + The sanei_thread implementation assumes an integer type in case of + pthread based thread support. As anything else is unlikely to work + correctly, it's safer to just fall back to forked processes. + +commit 73861ea91cd046c1b42b6c1270ff387c34d10fa4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 17:11:06 +0900 + + pixma: Fix [-Wint-conversion] and [-Wpedantic] compiler warnings + + These are also related to the SANE_Pid type issues. + +commit ddd7d821f68ab6f4389563c19d1915097f9c5a19 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 17:07:13 +0900 + + sanei_thread: Fix [-Wformat=] compiler warnings + +commit ad09bbdd1860899f0d8badb359c26be4848b64c9 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 17:06:20 +0900 + + sanei_thread: Fix [-Wint-conversion] compiler warnings + +commit 3caf05c0335858cbf22dedff3fbac47f3b9f7a91 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 17:00:08 +0900 + + hp: Fix [-Wint-conversion] compiler warnings + + Don't do yourself what sanei_thread does for you already ;-) + +commit df1aba21bc318dffc316fc28bd7eee82531a707c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-15 14:47:54 +0900 + + SANE_Pid: Fix [-Wint-conversion] issues + + Not all pthreads implementations use an integer type for pthread_t. + As a matter of fact, POSIX has explicitly withdrawn the requirement + that it must be an arithmatic type. + + The musl C library uses a `struct __pthread *` which triggered the + warnings. As of this change, sanei_thread.h works around this by + providing two new macros to help keep this issue out of sight. All + backends have been changed to use these macros. + +commit 3f8db8e2d0ee2b0282f94ea108db5ac4462334a8 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-12 21:31:31 +0900 + + AWARE: Treat compiler warnings as errors on the debian-9-* builds + +commit 3eb3d6b9bf827be6ee62ab7e155f71ba9b09d633 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-12 21:20:12 +0900 + + plustek-pp: Fix [-Wmisleading-indentation] compiler warnings + +commit 48cb209f2a780fd83a497201e79b9c4147e7b4a9 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-11 14:02:11 +0200 + + pixma: backend version 0.17.42 + +commit 611647b61ca3dbb2dd720f67cd219f68f6dea1d1 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-11 14:00:40 +0200 + + pixma_imageclass.c: restrict image width to 215mm for i-SENSYS MF240 Series + + this scanner produces black stripes in 216mm wide images @ 600dpi + +commit 62fcf80c0b733211a602c9dd2073551dfc36361a +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-10 23:34:01 +0200 + + pixma: PIXMA TS5000 Series (#315764) and TS8000 Series (#315763) are working + +commit 02a4ec11bfae075e0ab8d3d87e37d17c9ef19ff0 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-10 23:07:35 +0200 + + pixma: backend version 0.17.41 + +commit 862f265631386ef8531106d6cd04f6e0c0e9ccec +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-10 23:12:22 +0200 + + pixma: remove unreachable and depreciated websites from man page + +commit 49ae62618cd0b5d0063c884ce8521b165bae7c22 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-10 23:06:29 +0200 + + pixma_mp150.c: new generation 5 for scanners without special image format @ high dpi + +commit 890aa30a7cc7e9ac43d379e38c280679f78ad3d7 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-10 22:01:26 +0200 + + pixma: i-SENSYS MF210 Series is working + +commit fbbb6cabf3f69334837413d6d4e4822efe23f476 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-06-25 10:02:43 +0200 + + pixma: fix capabilities for TS* Series + +commit b5f78dd081c41a91b381943726412e4142bc5338 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-07-10 21:46:57 +0200 + + pixma_imageclass.c: fix image block size calculation for particular scanners + +commit a08f5630d83328a38602b47f74f2728489656377 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-07-08 17:58:49 +0900 + + sanei_scsi: Fix [-Wdeprecated-declarations] compiler warning + + The readdir_r() using loop in sanei_scsi_find_devices() has been + modified to use readdir(). + + With the exception of sane_cancel(), the SANE API is not re-entrant. + The sanei_scsi_find_devices() function is referenced neither directly + nor indirectly from any of the sane_cancel() implementations so there + is no inherent need to use readdir_r(). + +commit 0bf4595273b89b660bf1cef1c2752cdbf164b27d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 19:13:51 +0900 + + plustek: Fix [-Wpedantic] compiler warning + + The warning reads: + + enumerator value for '_PS_INP_MIO6' is not an integer constant + expression + + and that comes about as _PS_INP_MIO6 evaluates to 0x8000000, which + does not fit in the *signed* integer range which has been allotted + to enumeration constants by ISO C99. + + Seeing that the _PS_INP* values appear to be bitflags (despite the + arithmatic additions in backend/plustek-usbdev.c!) it is safer to + use #defines instead of an enum. + +commit a74cb99c1aa3dbddf0bb8250a9b2af72584d9b42 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 18:19:27 +0900 + + u12: Fix [-Wmisleading-indentation] compiler warning + + It appears that what the compiler has to do is what was intended. + Fixing the indentation to make that clearer. + +commit 6ad9e8479d9dc1fbf72ed7ae1d275753288365b9 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 18:07:11 +0900 + + pixma: Fix [-Wmisleading-indentation] compiler warning + + There is no point in falling through the case branch so the break + should be at the same level as the if. + +commit 08e1ba12866eb5592e27f879479a878fa9d21c70 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 18:01:34 +0900 + + pieusb: Fix [-Wmisleading-indentation] compiler warning + + The indentation has been aligned what is used inside the while loop. + The function appears to have been copied from elsewhere and slightly + modified. + + The msg variable is set to NULL inside the if branch for efficiency + only. + +commit 3191056a4c0b4f21b9b31ae0bccc68d40934954d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 17:58:44 +0900 + + microtek2: Fix [-Wmisleading-indentation] compiler warnings + + The case branches have been made to follow other case branches in the + same switch. + +commit e04261673f60dd9797d41528297c95fae8e24ecb +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 17:57:14 +0900 + + magicolor: Fix [-Wmisleading-indentation] compiler warning + + The assumption is that the failure should be returned to the caller. + +commit 0f90a5c2e33e7b893e432d1c096198951829598c +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 17:55:30 +0900 + + hp: Fix [-Wmisleading-indentation] compiler warning + + Indentation based on the style used in the immediate neighbourhood. + The file uses a mix of styles though. + +commit 2ff1d7da59eeca5a83e1f83d32382daf07914d95 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 17:52:08 +0900 + + genesys: Fix [-Wmisleading-indentation] compiler warning + + The fix is based on similar code in backend/genesys_gl846.c and fixes + a potential infinite loop as well. + +commit 5098b9bfbb8707f55930864fbbcaccc8356a1efe +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 17:51:40 +0900 + + genesys: Fix [-Wmisleading-indentation] compiler warnings + +commit a1133aa194fbf407998e62c9d20c0ecc2a90c937 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:28:54 +0900 + + pnm: Fix [-Wshift-negative-value] compiler warning + +commit deb856cb279bd5a31b5e8b72b2a65f6a66a16122 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:09:54 +0900 + + umax: Fix [-Wshift-negative-value] compiler warning + +commit ff535ef1ead749526ff41c56b24bd72ea0b16705 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:09:39 +0900 + + u12: Fix [-Wshift-negative-value] compiler warning + +commit 0c6fc8b1745465c2071f8346406aed8d86c7eef2 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:09:23 +0900 + + snapscan: Fix [-Wshift-negative-value] compiler warning + +commit 582a3b89877c149f5122f414abc6a75127eb553a +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:09:06 +0900 + + s9036: Fix [-Wshift-negative-value] compiler warning + +commit 73e1d3568dabb1ef7e66985c94b716909df34c5d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:08:51 +0900 + + plustek_pp: Fix [-Wshift-negative-value] compiler warning + +commit 1a1c808c15c78ec63ecb66a9f4538ddb6d5a5761 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:08:37 +0900 + + plustek: Fix [-Wshift-negative-value] compiler warning + +commit f8eb12b49d43c69a4ab7259b201158f1f2dba793 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:08:17 +0900 + + mustek: Fix [-Wshift-negative-value] compiler warning + +commit 02ce2b5d46d1aa352d1444ac61c67c865b4ae962 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 12:07:24 +0900 + + agfafocus: Fix [-Wshift-negative-value] compiler warning + +commit 702a8e27b61a4bb5de0da2c4f84326e96b9dde10 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:43:01 +0900 + + p5: Fix [-Wunused-const-variable=] compiler warning + + The u8_range and threshold_percentage_range constants have not been + used for anything ever since the backend's addition. They probable + ended up in the code as a result of copy-and-paste. + +commit aa5468552bbe036aed5d8a4df1b61ff5b42c751b +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:39:50 +0900 + + teco2: Fix [-Wunused-const-variable=] compiler warning + + The default_dpi_color_adjust variable hasn't been used ever since the + backend was added. + +commit a2083538e97b6419e70414ab0c42aa42a78fbce4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:35:06 +0900 + + tamarack: Fix [-Wunused-const-variable=] compiler warning + + The u8_range has been `#if 0`'d to match the gamma options' have been + disabled (since the initial revision). The options refer to u8_range. + +commit 2442ddf6d17b2721192d311cd961f29eaa0b55cd +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:28:10 +0900 + + sp15c: Fix [-Wunused-const-variable=] compiler warning + + The RCSid* variables have never been used for anything by the backend + code. + +commit 86ab41d8f1bd85d75af1e8e2cd1ed387b8ab9fc0 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:19:55 +0900 + + mustek_usb: Fix [-Wunused-const-variable=] compiler warning + + The brightness option that used the char_range variable was renamed to + threshold and changed to use u8_range in c95e4638. + +commit 39849809d126de710318e4c70f93728c3d4ade1f +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:16:55 +0900 + + mustek: Fix [-Wunused-const-variable=] compiler warning + + The const variables' definition has been #ifdef'd to prevent loss of + protocol info. + + Neither scsi_area_and_windows nor scsi_lookup_table appear to have + been used for anything. + +commit 398d5850fa5a1d3ce6a7f5eb13b3cfb7e1c11296 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:08:03 +0900 + + avision: Fix [-Wunused-const-variable=] compiler warning + + The const variable's definition has been #ifdef'd to prevent loss of + protocol info. + +commit 0f70ce9aac2e1d7f198b8d73524657b404a99f2d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 11:05:01 +0900 + + avision: Fix [-Wunused-const-variable=] compiler warning + + The threshold option which used the abs_percentage_range was removed + in e2169ec4. + +commit 2f5c9e14990b90b2716a12fcb449527e0fb1ffb4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 10:57:50 +0900 + + kvs1025: Fix [-Wunused-const-variable=] compiler warning + + The go_paper_max_width value hasn't been used for anything since the + initial revision of the file. + +commit ed0062d474530d0dd95f9152ee7c2bb88abe010d +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 10:50:40 +0900 + + gt68xx: Fix [-Wunused-const-variable=] compiler warning + + The options that used offset_range were removed in a3a8808b. + +commit fa4497047352583cd3113d2962d919589f0044ae +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 10:45:42 +0900 + + epson2: Fix [-Wunused-const-variable=] compiler warning + + The s8_range variable appears to be a left-over from the epson + backend's "fork" and became superfluous after refactoring the + colour correction support in the epson2 backend. + +commit 754a7164f35aa6331f2f5a02076fcb5082b521d8 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 10:38:44 +0900 + + dc25: Fix [-Wunused-const-variable=] compiler warning + + The percentage_range hasn't been used for anything since the initial + revision of the file. + + This also gets rid of a [-Wshift-negative-value] warning as well as a + "initializer element is not a constant expression" pedantic warning. + +commit a52d843da40a945c4e2a55b59e92f362b6d77479 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-26 10:34:14 +0900 + + canon: Fix [-Wunused-const-variable=] compiler warning + + The papersize_list hasn't been used for anything since the initial + revision of the file. + +commit fe3299a9b069865aef81aa50a0bca0b7a114d74f +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-22 20:36:59 +0900 + + Add minimal and full CI compile tests for Debian 9 + +commit e7d9779dfc3748f8f205585fa09ebc7181874642 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-17 12:38:21 +0900 + + CI: Build `git describe` versioned snapshot tarballs + + This: + - modifies `configure.ac` to get a version number courtesy of `git` + when `autoconf` is run + - runs a `make dist` when all compilation targets succeed + - makes the resulting tarball available as a build artifact + - renames the various pipeline stages + +commit a06e9a40751dd3c4c87d35a821f7c9281fa71644 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-12 20:53:53 +0900 + + Script updating of upstream files + +commit baec9c4e264329a13899e28090b59fe7182b80dd +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-07 22:50:56 +0900 + + autofoo: Sync with configure.ac, Makefile.am changes + +commit a2f1cc1c82e1ca4dfb04c386a6d51cfad3934d33 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-07 22:06:05 +0900 + + libsane: Only depend on and link in the kitchen sink if needed + + There is no need to depend on and link in all the various dependencies + for whatever backends *might* be preloaded if none are. Distributions + habitually rip these out, rightfully so, to reduce the list of package + dependencies. This will achieve the same while still doing the "right + thing" for builds that do preload one or more backens. + +commit 2284c6e03438c489bd3f077810e3e24771fed294 +Author: Jerome Duval <jerome.duval@gmail.com> +Date: 2017-06-04 12:22:31 +0200 + + epsonds: add missing includes + + Fixes build failure on Haiku. Alioth Tracker: 315750. + +commit fbe2f6d332702c7878483d24d1daf66fe83633d4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-02 21:08:44 +0900 + + CI: add a "lint" stage before the builds + + This is mostly meant for "cheap" policy checks that do not require the + sources to be compiled. + +commit 828f1a39495198aace07d1991e7a785d3a7ce291 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-06-02 20:52:12 +0900 + + style-check: skip directories, sanitize file names + + When generating lists of files with `find`, directories may get output + if you try to prune paths and it has a habit of prefixing paths with a + leading `./`. + +commit 75e271444ae76b3a6c845943a765a17664987e4e +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-06-01 14:11:48 +0200 + + pixma: backend version 0.17.40 + +commit 80445f9e5775b976dce1f6162974839197b8a10d +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-06-01 14:09:21 +0200 + + pixma_imageclass.c: MF240 Series restricts adf scans to max. 300dpi + +commit c2594e949bc77b2fc23988062af67c2fa9e988d5 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-06-01 14:06:43 +0200 + + Revert "pixma_imageclass.c: MF240 Series supports only 300dpi for adf scans" + + This reverts commit 60e0c31bb7a080385fba0e9acf0afe55f293526a. + + Truly this scanner restricts adf scans to max. 300dpi. + +commit ba8e76d937c520a6841cf838867760f58f7758f9 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-31 21:28:45 +0900 + + .editorconfig: add script to check and fix style issues + + The various checks cover all settings in the `.editorconfig` file. + The `--fix` support, however, does not attempt to correct charset + issues because the encoding cannot be determined automatically. + + Note that image files as well as generated files in the repository + are exempted from all style checks. + +commit 01c5dbc82b78db865cd88c0044d22199babb3e6f +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-30 22:39:30 +0900 + + .editorconfig: Fix sane-desc tool to match cleaned up references + + Changes to the test reference files should not, famous last words ;-), + have any effect on the use of the tool's actual outputs. + + Note that the tests use a "concocted" `testfile.desc` as their input. + +commit fc4b250a090eef934b9c77afedcebaf146f119c0 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-27 15:22:15 +0900 + + .editorconfig: use utf-8 charset throughout + +commit f0f187f995c45226e95dfbeb3231a316f76e11ea +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-27 15:37:14 +0900 + + .editorconfig: trim trailing blank lines + +commit ffa573f65eade56a7c76c91ca4a584692c8bfb97 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-27 13:57:01 +0900 + + .editorconfig: insert a newline at end-of-file + + This keeps `git` from "complaining" about this when doing a diff. It + also keeps your prompt at the left edge when you `cat` a file. + +commit 23891a2646c171f7396bc399d25079f9887c10a0 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-27 14:27:22 +0900 + + .editorconfig: trim trailing whitespace + +commit 45a7aabc80b0bc18e6fec1c3015466e1a2debca4 +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-27 13:52:59 +0900 + + Add .editorconfig to maintain a more consistent coding style + + This does not set anything yet. + + See http://editorconfig.org/ for more information. + +commit 55257bea66c8d0b48cb3e306d5863b190752cfed +Author: Olaf Meeuwissen <paddy-hack@member.fsf.org> +Date: 2017-05-29 21:02:53 +0900 + + Bump Alpine builder to 3.6 + +commit 7893b77d926139452be1162a4bea4dc2b595face +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-05-26 23:37:28 +0200 + + pixma: backend version 0.17.39 + +commit bcf1f4398eb967cc4db313a3b15104fff5587eb3 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-05-26 23:36:52 +0200 + + pixma_imageclass.c: reduce max. scan width to 216mm for particular scanners + +commit 2b0028b4af61761420fbff4459310b799bc13c7b +Merge: 35dc4426 2bba2739 +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-05-23 21:16:52 +0200 + + Merge branch 'pixma/mf240_adf_only_300dpi' + +commit 35dc4426d2dad67167af40e6c136feb229b4f3ac +Author: m. allan noah <kitno455@gmail.com> +Date: 2017-05-22 21:08:33 -0400 + + Open repo for 1.0.28 development + +commit 2bba2739937ba26059701eec1ae5e4372ff9de2a +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-05-19 11:21:59 +0200 + + pixma: backend version 0.17.38 + +commit 60e0c31bb7a080385fba0e9acf0afe55f293526a +Author: Rolf Bensch <roben-guest@alioth.debian.org> +Date: 2017-05-19 11:26:00 +0200 + + pixma_imageclass.c: MF240 Series supports only 300dpi for adf scans diff --git a/INSTALL.linux b/INSTALL.linux index a851852..703b9e3 100644 --- a/INSTALL.linux +++ b/INSTALL.linux @@ -19,8 +19,11 @@ $ make install - optional: git (b) missing development packages - libusb-dev or libusb-devel or libusb-compat-devel + - libusb-1.0.0-dev or similar - libjpeg-dev or libjpeg8-dev or libjpeg-turbo-devel or turbojpeg-devel - libpng-dev or similar + - libcurl4-gnutls-dev or similar + - libxml2-dev or similar 2.2. Get the latest SANE backend from git: You can download "daily git snapshot" from here: diff --git a/Makefile.am b/Makefile.am index 54d0f27..0e4150d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,12 +7,44 @@ SUBDIRS = include lib sanei backend frontend tools doc po testsuite DIST_SUBDIRS = include lib sanei backend frontend tools doc po japi testsuite -dist_doc_DATA = AUTHORS ChangeLog COPYING LICENSE NEWS PROBLEMS PROJECTS \ +dist_doc_DATA = AUTHORS COPYING LICENSE NEWS PROBLEMS PROJECTS \ README README.aix README.beos README.darwin README.djpeg README.freebsd \ README.hp-ux README.linux README.netbsd README.openbsd README.os2 \ README.solaris README.unixware2 README.unixware7 README.windows \ README.zeta +dist_doc_DATA += ChangeLog +changelogsdir = $(docdir)/ChangeLogs +dist_changelogs_DATA = ChangeLogs/ChangeLog-1.0.28 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.27 +## sane-backends-1.0.26 was skipped +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.25 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.24 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.23 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.22 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.21 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.20 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.19 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.18 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.17 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.16 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.15 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.14 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.13 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.12 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.11 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.10 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.9 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.8 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.7 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.6 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.5 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.4 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.3 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.2 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.1 +dist_changelogs_DATA += ChangeLogs/ChangeLog-1.0.0 + EXTRA_DIST = .editorconfig EXTRA_DIST += po/README @@ -1,5 +1,41 @@ <!-- -*- Mode: markdown -*- --> +## New with 1.0.29 (upcoming release) + +### Backends + +- adds an `escl` backend (theoretically supporting *all* AirPrint + devices with a scan unit) +- adds support for 23 new scanner models via existing backends +- significantly changes `genesys` and `pixma` backends +- fixes bugs in `canon_dr`, `fujitsu`, `hp3900`, `mustek_usb2`, + `plustek` and `xerox_mfp` backends +- fixes *all* compiler warnings on Debian 10 (#120) +- fixes portability issues for uClibc-ng and MacOS builds +- adds support to record and replay USB I/O traffic +- adds timestamps to debug logs + +### Frontends + +- fixes a 32-bit arithmetic overflow issue in `scanimage` + +### Documentation + +- updates translations for British English, Catalan, German, + Ukrainian, Valencian +- adds `scangearmp2` external backend descriptions +- updates `hpaio` and `utsushi` external backend descriptions +- adds the `ChangeLogs/` directory to the source tarball (#103) + +### Build + +- additionally requires `libcurl` and `libxml2` to build the `escl` + backend +- requires `libxml2` for USB I/O recording and replay functionality +- re-enables pthread support for backends that use its API directly, + irrespective of the `pthread_t` type (#153) +- moves the `genesys` and `pixma` backends to a directory of their own + ## New with 1.0.28 (released 2019-07-31) ### Backends diff --git a/acinclude.m4 b/acinclude.m4 index 1bc3b74..7c90c64 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -252,21 +252,22 @@ AC_DEFUN([SANE_CHECK_PTHREAD], [Define if pthread_t is integer.]) else # Until the sanei_thread implementation is fixed. - have_pthread=no use_pthread=no fi + if test "$have_pthread" = "yes" ; then + AM_CPPFLAGS="${AM_CPPFLAGS} -D_REENTRANT" + fi + AC_SUBST(PTHREAD_LIBS) + if test $use_pthread = yes ; then AC_DEFINE_UNQUOTED(USE_PTHREAD, "$use_pthread", [Define if pthreads should be used instead of forked processes.]) + SANEI_THREAD_LIBS=$PTHREAD_LIBS else - dnl Reset library in case it was found but we are not going to use it. - PTHREAD_LIBS="" + SANEI_THREAD_LIBS="" fi - if test "$have_pthread" = "yes" ; then - AM_CPPFLAGS="${AM_CPPFLAGS} -D_REENTRANT" - fi - AC_SUBST(PTHREAD_LIBS) + AC_SUBST(SANEI_THREAD_LIBS) AC_MSG_CHECKING([whether to enable pthread support]) AC_MSG_RESULT([$have_pthread]) AC_MSG_CHECKING([whether to use pthread instead of fork]) @@ -611,6 +612,26 @@ for be in ${BACKENDS}; do fi ;; + escl) + if test "x${enable_avahi}" != "xyes"; then + echo "*** $be backend requires AVAHI library - $DISABLE_MSG" + backend_supported="no" + fi + if test "x${with_libcurl}" != "xyes"; then + echo "*** $be backend requires cURL library - $DISABLE_MSG" + backend_supported="no" + fi + if test "x${have_libxml}" != "xyes"; then + echo "*** $be backend requires XML library - $DISABLE_MSG" + backend_supported="no" + fi + # FIXME: Remove when PNG and/or PDF support have been added. + if test "x${sane_cv_use_libjpeg}" != "xyes"; then + echo "*** $be backend currently requires JPEG library - $DISABLE_MSG" + backend_supported="no" + fi + ;; + gphoto2) if test "${HAVE_GPHOTO2}" != "true" \ || test "${sane_cv_use_libjpeg}" != "yes"; then diff --git a/backend/.gitignore b/backend/.gitignore index 6ebfbd5..6276e61 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1,5 +1,6 @@ *-s.c -*-s.cc +*-s.cpp *.conf +.dirstamp dll-preload.c dll-preload.h diff --git a/backend/Makefile.am b/backend/Makefile.am index 44d1e17..1dc1a58 100644 --- a/backend/Makefile.am +++ b/backend/Makefile.am @@ -17,7 +17,12 @@ DIST_LIBS_LDFLAGS = $(AM_LDFLAGS) -rpath '$(libdir)' -version-number $(V_MAJOR): LIBTOOL += --silent FIRMWARE_DIRS = artec_eplus48u gt68xx snapscan epjitsu +# Needed by most backends as they add sane_strstatus.lo to their list +# of libraries to link with via libsane_${BACKEND}_la_LIBADD. Due to +# the implicit dependency, automake does not notice the need to clean +# up the dependency tracking file. EXTRA_DIST = sane_strstatus.c +CLEANFILES = $(DEPDIR)/sane_strstatus.Plo all: becfg @@ -29,7 +34,7 @@ EXTRA_DIST += stubs.c $(AM_V_at)rm -f $@ $(AM_V_at)$(LN_S) $(srcdir)/stubs.c $@ -%-s.cc: $(srcdir)/stubs.c +%-s.cpp: $(srcdir)/stubs.c $(AM_V_at)rm -f $@ $(AM_V_at)$(LN_S) $(srcdir)/stubs.c $@ @@ -63,8 +68,8 @@ BACKEND_CONFS= abaton.conf agfafocus.conf apple.conf artec.conf \ canon_pp.conf cardscan.conf coolscan2.conf coolscan3.conf \ coolscan.conf dc210.conf dc240.conf dc25.conf \ dell1600n_net.conf dmc.conf epjitsu.conf epson2.conf \ - epson.conf epsonds.conf fujitsu.conf genesys.conf gphoto2.conf \ - gt68xx.conf hp3900.conf hp4200.conf hp5400.conf \ + epson.conf epsonds.conf escl.conf fujitsu.conf genesys.conf \ + gphoto2.conf gt68xx.conf hp3900.conf hp4200.conf hp5400.conf \ hp.conf hpsj5s.conf hs2p.conf ibm.conf kodak.conf kodakaio.conf\ kvs1025.conf \ leo.conf lexmark.conf ma1509.conf magicolor.conf \ @@ -133,7 +138,7 @@ uninstall-hook: rmdir $(DESTDIR)$(datadir)/sane/$${dir} ; \ done -CLEANFILES = $(BACKEND_CONFS) $(be_convenience_libs) +CLEANFILES += $(BACKEND_CONFS) $(be_convenience_libs) clean-local: find . -type l -name \*-s.c | xargs rm -f @@ -156,7 +161,7 @@ be_convenience_libs = libabaton.la libagfafocus.la \ libcoolscan2.la libcoolscan3.la libdc25.la \ libdc210.la libdc240.la libdell1600n_net.la \ libdmc.la libdll.la libdll_preload.la libepjitsu.la libepson.la \ - libepson2.la libepsonds.la libfujitsu.la libgenesys.la \ + libepson2.la libepsonds.la libescl.la libfujitsu.la libgenesys.la \ libgphoto2_i.la libgt68xx.la libhp.la \ libhp3500.la libhp3900.la libhp4200.la \ libhp5400.la libhp5590.la libhpljm1005.la \ @@ -189,8 +194,8 @@ be_dlopen_libs = libsane-abaton.la libsane-agfafocus.la \ libsane-coolscan2.la libsane-coolscan3.la libsane-dc25.la \ libsane-dc210.la libsane-dc240.la libsane-dell1600n_net.la \ libsane-dmc.la libsane-epjitsu.la libsane-epson.la \ - libsane-epson2.la libsane-epsonds.la libsane-fujitsu.la libsane-genesys.la \ - libsane-gphoto2.la libsane-gt68xx.la libsane-hp.la \ + libsane-epson2.la libsane-epsonds.la libsane-escl.la libsane-fujitsu.la \ + libsane-genesys.la libsane-gphoto2.la libsane-gt68xx.la libsane-hp.la \ libsane-hp3500.la libsane-hp3900.la libsane-hp4200.la \ libsane-hp5400.la libsane-hp5590.la libsane-hpljm1005.la \ libsane-hpsj5s.la libsane-hs2p.la libsane-ibm.la libsane-kodak.la libsane-kodakaio.la\ @@ -219,7 +224,7 @@ lib_LTLIBRARIES = libsane.la sanelibdir = $(libdir)/sane sanelib_LTLIBRARIES = $(BACKEND_LIBS_ENABLED) libsane-dll.la -COMMON_LIBS = ../lib/liblib.la +COMMON_LIBS = ../lib/liblib.la $(XML_LIBS) # Each backend should define a convenience library that compiles # all related files within backend directory. General guideline @@ -252,7 +257,7 @@ libagfafocus_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=agfafocus nodist_libsane_agfafocus_la_SOURCES = agfafocus-s.c libsane_agfafocus_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=agfafocus libsane_agfafocus_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_agfafocus_la_LIBADD = $(COMMON_LIBS) libagfafocus.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(SCSI_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_agfafocus_la_LIBADD = $(COMMON_LIBS) libagfafocus.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(SCSI_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += agfafocus.conf.in libapple_la_SOURCES = apple.c apple.h @@ -279,7 +284,7 @@ libartec_eplus48u_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=artec_eplus48u nodist_libsane_artec_eplus48u_la_SOURCES = artec_eplus48u-s.c libsane_artec_eplus48u_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=artec_eplus48u libsane_artec_eplus48u_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_artec_eplus48u_la_LIBADD = $(COMMON_LIBS) libartec_eplus48u.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMEG_LIBS) +libsane_artec_eplus48u_la_LIBADD = $(COMMON_LIBS) libartec_eplus48u.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMEG_LIBS) EXTRA_DIST += artec_eplus48u.conf.in libas6e_la_SOURCES = as6e.c as6e.h @@ -296,7 +301,7 @@ libavision_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=avision nodist_libsane_avision_la_SOURCES = avision-s.c libsane_avision_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=avision libsane_avision_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_avision_la_LIBADD = $(COMMON_LIBS) libavision.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_avision_la_LIBADD = $(COMMON_LIBS) libavision.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += avision.conf.in libbh_la_SOURCES = bh.c bh.h @@ -363,7 +368,7 @@ libcoolscan_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=coolscan nodist_libsane_coolscan_la_SOURCES = coolscan-s.c libsane_coolscan_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=coolscan libsane_coolscan_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_coolscan_la_LIBADD = $(COMMON_LIBS) libcoolscan.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_coolscan_la_LIBADD = $(COMMON_LIBS) libcoolscan.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += coolscan.conf.in libcoolscan2_la_SOURCES = coolscan2.c @@ -429,6 +434,21 @@ libsane_dmc_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) libsane_dmc_la_LIBADD = $(COMMON_LIBS) libdmc.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo $(SCSI_LIBS) $(RESMGR_LIBS) EXTRA_DIST += dmc.conf.in +if have_libavahi +if have_libcurl +if have_libxml2 +libescl_la_SOURCES = escl/escl.c escl/escl_capabilities.c escl/escl_devices.c escl/escl.h escl/escl_newjob.c escl/escl_reset.c escl/escl_scan.c escl/escl_status.c escl/escl_jpeg.c escl/escl_png.c escl/escl_tiff.c +libescl_la_CPPFLAGS = $(AM_CPPFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) $(TIFF_CFLAGS) $(XML_CFLAGS) $(libcurl_CFLAGS) $(AVAHI_CFLAGS) -DBACKEND_NAME=escl + +nodist_libsane_escl_la_SOURCES = escl-s.c +libsane_escl_la_CPPFLAGS = $(AM_CPPFLAGS) $(JPEG_CFLAGS) $(PNG_CFLAGS) $(TIFF_CFLAGS) $(XML_CFLAGS) $(libcurl_CFLAGS) $(AVAHI_CFLAGS) -DBACKEND_NAME=escl +libsane_escl_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) +libsane_escl_la_LIBADD = $(COMMON_LIBS) libescl.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo $(JPEG_LIBS) $(PNG_LIBS) $(TIFF_LIBS) $(XML_LIBS) $(libcurl_LIBS) $(AVAHI_LIBS) +endif +endif +endif +EXTRA_DIST += escl.conf.in + libepjitsu_la_SOURCES = epjitsu.c epjitsu.h epjitsu-cmd.h libepjitsu_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=epjitsu @@ -480,22 +500,56 @@ libsane_fujitsu_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) libsane_fujitsu_la_LIBADD = $(COMMON_LIBS) libfujitsu.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_magic.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(RESMGR_LIBS) EXTRA_DIST += fujitsu.conf.in -libgenesys_la_SOURCES = genesys.cc genesys.h genesys_sanei.h genesys_sanei.cc genesys_error.h genesys_error.cc \ - genesys_serialize.h \ - genesys_gl646.cc genesys_gl646.h genesys_gl841.cc genesys_gl841.h \ - genesys_gl843.cc genesys_gl843.h genesys_gl846.cc genesys_gl846.h \ - genesys_gl847.cc genesys_gl847.h genesys_gl124.cc genesys_gl124.h \ - genesys_low.cc genesys_low.h +libgenesys_la_SOURCES = genesys/genesys.cpp genesys/genesys.h \ + genesys/buffer.h genesys/buffer.cpp \ + genesys/calibration.h \ + genesys/command_set.h \ + genesys/conv.h genesys/conv.cpp \ + genesys/device.h genesys/device.cpp \ + genesys/enums.h genesys/enums.cpp \ + genesys/error.h genesys/error.cpp \ + genesys/fwd.h \ + genesys/gl646.cpp genesys/gl646.h genesys/gl646_registers.h \ + genesys/gl124.cpp genesys/gl124.h genesys/gl124_registers.h \ + genesys/gl841.cpp genesys/gl841.h genesys/gl841_registers.h \ + genesys/gl843.cpp genesys/gl843.h genesys/gl843_registers.h \ + genesys/gl846.cpp genesys/gl846.h genesys/gl846_registers.h \ + genesys/gl847.cpp genesys/gl847.h genesys/gl847_registers.h \ + genesys/row_buffer.h \ + genesys/image_buffer.h genesys/image_buffer.cpp \ + genesys/image_pipeline.h genesys/image_pipeline.cpp \ + genesys/image_pixel.h genesys/image_pixel.cpp \ + genesys/image.h genesys/image.cpp \ + genesys/motor.h genesys/motor.cpp \ + genesys/register.h \ + genesys/register_cache.h \ + genesys/scanner_interface.h genesys/scanner_interface.cpp \ + genesys/scanner_interface_usb.h genesys/scanner_interface_usb.cpp \ + genesys/sensor.h genesys/sensor.cpp \ + genesys/settings.h genesys/settings.cpp \ + genesys/serialize.h \ + genesys/static_init.h genesys/static_init.cpp \ + genesys/status.h genesys/status.cpp \ + genesys/tables_frontend.cpp \ + genesys/tables_gpo.cpp \ + genesys/tables_model.cpp \ + genesys/tables_motor.cpp \ + genesys/tables_motor_profile.cpp \ + genesys/tables_sensor.cpp \ + genesys/test_scanner_interface.h genesys/test_scanner_interface.cpp \ + genesys/test_settings.h genesys/test_settings.cpp \ + genesys/test_usb_device.h genesys/test_usb_device.cpp \ + genesys/usb_device.h genesys/usb_device.cpp \ + genesys/low.cpp genesys/low.h \ + genesys/utilities.h libgenesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys -nodist_libsane_genesys_la_SOURCES = genesys-s.cc +nodist_libsane_genesys_la_SOURCES = genesys-s.cpp libsane_genesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys libsane_genesys_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) libsane_genesys_la_LIBADD = $(COMMON_LIBS) libgenesys.la ../sanei/sanei_magic.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo $(MATH_LIB) $(USB_LIBS) $(RESMGR_LIBS) EXTRA_DIST += genesys.conf.in -# TODO: Why are this distributed but not compiled? -EXTRA_DIST += genesys_conv.cc genesys_conv_hlp.cc genesys_devices.cc libgphoto2_i_la_SOURCES = gphoto2.c gphoto2.h libgphoto2_i_la_CPPFLAGS = $(AM_CPPFLAGS) $(GPHOTO2_CPPFLAGS) -DBACKEND_NAME=gphoto2 @@ -523,7 +577,7 @@ libhp_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=hp nodist_libsane_hp_la_SOURCES = hp-s.c libsane_hp_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=hp libsane_hp_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_hp_la_LIBADD = $(COMMON_LIBS) libhp.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_pio.lo ../sanei/sanei_thread.lo $(SCSI_LIBS) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_hp_la_LIBADD = $(COMMON_LIBS) libhp.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_pio.lo ../sanei/sanei_thread.lo $(SCSI_LIBS) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += hp.conf.in # TODO: These should be moved to ../docs/hp; don't belong here. EXTRA_DIST += hp.README hp.TODO @@ -534,7 +588,7 @@ libhp3500_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=hp3500 nodist_libsane_hp3500_la_SOURCES = hp3500-s.c libsane_hp3500_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=hp3500 libsane_hp3500_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_hp3500_la_LIBADD = $(COMMON_LIBS) libhp3500.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_hp3500_la_LIBADD = $(COMMON_LIBS) libhp3500.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) libhp3900_la_SOURCES = hp3900.c libhp3900_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=hp3900 @@ -726,7 +780,7 @@ libmicrotek2_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=microtek2 nodist_libsane_microtek2_la_SOURCES = microtek2-s.c libsane_microtek2_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=microtek2 libsane_microtek2_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_microtek2_la_LIBADD = $(COMMON_LIBS) libmicrotek2.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(SCSI_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_microtek2_la_LIBADD = $(COMMON_LIBS) libmicrotek2.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(SCSI_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += microtek2.conf.in libmustek_la_SOURCES = mustek.c mustek.h @@ -735,7 +789,7 @@ libmustek_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=mustek nodist_libsane_mustek_la_SOURCES = mustek-s.c libsane_mustek_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=mustek libsane_mustek_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_mustek_la_LIBADD = $(COMMON_LIBS) libmustek.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo ../sanei/sanei_ab306.lo ../sanei/sanei_pa4s2.lo $(IEEE1284_LIBS) $(SCSI_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_mustek_la_LIBADD = $(COMMON_LIBS) libmustek.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo ../sanei/sanei_ab306.lo ../sanei/sanei_pa4s2.lo $(IEEE1284_LIBS) $(SCSI_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += mustek.conf.in # TODO: Why are these distributed but not compiled? EXTRA_DIST += mustek_scsi_pp.c mustek_scsi_pp.h @@ -768,7 +822,7 @@ libmustek_usb2_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=mustek_usb2 nodist_libsane_mustek_usb2_la_SOURCES = mustek_usb2-s.c libsane_mustek_usb2_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=mustek_usb2 libsane_mustek_usb2_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_mustek_usb2_la_LIBADD = $(COMMON_LIBS) libmustek_usb2.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(PTHREAD_LIBS) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_mustek_usb2_la_LIBADD = $(COMMON_LIBS) libmustek_usb2.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo $(MATH_LIB) $(PTHREAD_LIBS) $(USB_LIBS) $(RESMGR_LIBS) # TODO: Why are these distributed but not compiled? EXTRA_DIST += mustek_usb2_asic.c mustek_usb2_asic.h mustek_usb2_high.c mustek_usb2_high.h mustek_usb2_reflective.c mustek_usb2_transparent.c @@ -806,7 +860,7 @@ libpie_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=pie nodist_libsane_pie_la_SOURCES = pie-s.c libsane_pie_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=pie libsane_pie_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_pie_la_LIBADD = $(COMMON_LIBS) libpie.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo $(SCSI_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_pie_la_LIBADD = $(COMMON_LIBS) libpie.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo $(SCSI_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += pie.conf.in libpieusb_la_SOURCES = pieusb.h pieusb_buffer.c pieusb_buffer.h pieusb_scancmd.c pieusb_scancmd.h pieusb_specific.c pieusb_specific.h pieusb_usb.c pieusb_usb.h pieusb.c @@ -815,7 +869,7 @@ libpieusb_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=pieusb nodist_libsane_pieusb_la_SOURCES = pieusb-s.c libsane_pieusb_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=pieusb libsane_pieusb_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_pieusb_la_LIBADD = $(COMMON_LIBS) libpieusb.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo ../sanei/sanei_usb.lo ../sanei/sanei_ir.lo ../sanei/sanei_magic.lo $(PTHREAD_LIBS) $(RESMGR_LIBS) $(USB_LIBS) $(MATH_LIB) +libsane_pieusb_la_LIBADD = $(COMMON_LIBS) libpieusb.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_scsi.lo ../sanei/sanei_thread.lo ../sanei/sanei_usb.lo ../sanei/sanei_ir.lo ../sanei/sanei_magic.lo $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) $(USB_LIBS) $(MATH_LIB) EXTRA_DIST += pieusb.conf.in libp5_la_SOURCES = p5.c p5.h p5_device.h @@ -835,16 +889,30 @@ libsane_pint_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=pint libsane_pint_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) libsane_pint_la_LIBADD = $(COMMON_LIBS) libpint.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo -libpixma_la_SOURCES = pixma.c pixma.h pixma_io_sanei.c pixma_io.h pixma_common.c pixma_common.h pixma_mp150.c pixma_mp730.c pixma_mp750.c pixma_mp810.c pixma_imageclass.c pixma_bjnp.c pixma_bjnp.h pixma_bjnp_private.h pixma_rename.h +libpixma_la_SOURCES = pixma/pixma.c \ + pixma/pixma.h \ + pixma/pixma_io_sanei.c \ + pixma/pixma_io.h \ + pixma/pixma_common.c \ + pixma/pixma_common.h \ + pixma/pixma_mp150.c \ + pixma/pixma_mp730.c \ + pixma/pixma_mp750.c \ + pixma/pixma_mp800.c \ + pixma/pixma_imageclass.c \ + pixma/pixma_bjnp.c \ + pixma/pixma_bjnp.h \ + pixma/pixma_bjnp_private.h \ + pixma/pixma_rename.h libpixma_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=pixma nodist_libsane_pixma_la_SOURCES = pixma-s.c libsane_pixma_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=pixma libsane_pixma_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_pixma_la_LIBADD = $(COMMON_LIBS) libpixma.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(SANEI_SANEI_JPEG_LO) $(JPEG_LIBS) $(MATH_LIB) $(SOCKET_LIBS) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_pixma_la_LIBADD = $(COMMON_LIBS) libpixma.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(SANEI_SANEI_JPEG_LO) $(JPEG_LIBS) $(MATH_LIB) $(SOCKET_LIBS) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += pixma.conf.in -# TODO: Why are these distributed but not compiled? -EXTRA_DIST += pixma_sane_options.c pixma_sane_options.h +# included in pixma.c +EXTRA_DIST += pixma/pixma_sane_options.c pixma/pixma_sane_options.h libplustek_la_SOURCES = plustek.c plustek.h libplustek_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=plustek @@ -852,7 +920,7 @@ libplustek_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=plustek nodist_libsane_plustek_la_SOURCES = plustek-s.c libsane_plustek_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=plustek libsane_plustek_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_plustek_la_LIBADD = $(COMMON_LIBS) libplustek.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_lm983x.lo ../sanei/sanei_access.lo $(MATH_LIB) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_plustek_la_LIBADD = $(COMMON_LIBS) libplustek.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_lm983x.lo ../sanei/sanei_access.lo $(MATH_LIB) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += plustek.conf.in EXTRA_DIST += plustek-usb.c plustek-usb.h plustek-usbcal.c plustek-usbcalfile.c plustek-usbdevs.c plustek-usbhw.c plustek-usbimg.c plustek-usbio.c plustek-usbmap.c plustek-usbscan.c plustek-usbshading.c @@ -862,7 +930,7 @@ libplustek_pp_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=plustek_pp nodist_libsane_plustek_pp_la_SOURCES = plustek_pp-s.c libsane_plustek_pp_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=plustek_pp libsane_plustek_pp_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_plustek_pp_la_LIBADD = $(COMMON_LIBS) libplustek_pp.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_pp.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(IEEE1284_LIBS) $(PTHREAD_LIBS) +libsane_plustek_pp_la_LIBADD = $(COMMON_LIBS) libplustek_pp.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_pp.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(IEEE1284_LIBS) $(SANEI_THREAD_LIBS) EXTRA_DIST += plustek_pp.conf.in # TODO: Why are these distributed but not compiled? EXTRA_DIST += plustek-pp_dac.c plustek-pp_dbg.h plustek-pp_detect.c plustek-pp_genericio.c plustek-pp_hwdefs.h plustek-pp_image.c plustek-pp_io.c plustek-pp_map.c plustek-pp_misc.c plustek-pp_models.c plustek-pp_motor.c plustek-pp_p12.c plustek-pp_p12ccd.c plustek-pp_p48xx.c plustek-pp_p9636.c plustek-pp_procfs.c plustek-pp_procs.h plustek-pp_ptdrv.c plustek-pp_scale.c plustek-pp_scan.h plustek-pp_scandata.h plustek-pp_sysdep.h plustek-pp_tpa.c plustek-pp_types.h plustek-pp_wrapper.c @@ -969,7 +1037,7 @@ libsnapscan_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=snapscan nodist_libsane_snapscan_la_SOURCES = snapscan-s.c libsane_snapscan_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=snapscan libsane_snapscan_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_snapscan_la_LIBADD = $(COMMON_LIBS) libsnapscan.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_snapscan_la_LIBADD = $(COMMON_LIBS) libsnapscan.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += snapscan.conf.in # TODO: Why are these distributed but not compiled? EXTRA_DIST += snapscan-data.c snapscan-mutex.c snapscan-options.c snapscan-scsi.c snapscan-sources.c snapscan-sources.h snapscan-usb.c snapscan-usb.h @@ -980,7 +1048,7 @@ libsp15c_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=sp15c nodist_libsane_sp15c_la_SOURCES = sp15c-s.c libsane_sp15c_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=sp15c libsane_sp15c_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_sp15c_la_LIBADD = $(COMMON_LIBS) libsp15c.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(SCSI_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_sp15c_la_LIBADD = $(COMMON_LIBS) libsp15c.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(SCSI_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += sp15c.conf.in libst400_la_SOURCES = st400.c st400.h @@ -1007,7 +1075,7 @@ libtamarack_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=tamarack nodist_libsane_tamarack_la_SOURCES = tamarack-s.c libsane_tamarack_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=tamarack libsane_tamarack_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_tamarack_la_LIBADD = $(COMMON_LIBS) libtamarack.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(SCSI_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_tamarack_la_LIBADD = $(COMMON_LIBS) libtamarack.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo $(SCSI_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += tamarack.conf.in libtest_la_SOURCES = test.c test.h @@ -1016,7 +1084,7 @@ libtest_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=test nodist_libsane_test_la_SOURCES = test-s.c libsane_test_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=test libsane_test_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_test_la_LIBADD = $(COMMON_LIBS) libtest.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_thread.lo $(PTHREAD_LIBS) +libsane_test_la_LIBADD = $(COMMON_LIBS) libtest.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_thread.lo $(SANEI_THREAD_LIBS) EXTRA_DIST += test.conf.in # TODO: Why are these distributed but not compiled? EXTRA_DIST += test-picture.c @@ -1054,7 +1122,7 @@ libu12_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=u12 nodist_libsane_u12_la_SOURCES = u12-s.c libsane_u12_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=u12 libsane_u12_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_u12_la_LIBADD = $(COMMON_LIBS) libu12.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_u12_la_LIBADD = $(COMMON_LIBS) libu12.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo $(MATH_LIB) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += u12.conf.in # TODO: Why are these distributed but not compiled? EXTRA_DIST += u12-ccd.c u12-hw.c u12-hwdef.h u12-if.c u12-image.c u12-io.c u12-map.c u12-motor.c u12-scanner.h u12-shading.c u12-tpa.c @@ -1065,7 +1133,7 @@ libumax_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=umax nodist_libsane_umax_la_SOURCES = umax-s.c libsane_umax_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=umax libsane_umax_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS) -libsane_umax_la_LIBADD = $(COMMON_LIBS) libumax.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo ../sanei/sanei_pv8630.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +libsane_umax_la_LIBADD = $(COMMON_LIBS) libumax.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_thread.lo ../sanei/sanei_scsi.lo ../sanei/sanei_pv8630.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) EXTRA_DIST += umax.conf.in # TODO: Why are these distributed but not compiled? EXTRA_DIST += umax-scanner.c umax-scanner.h umax-scsidef.h umax-uc1200s.c umax-uc1200se.c umax-uc1260.c umax-uc630.c umax-uc840.c umax-ug630.c umax-ug80.c umax-usb.c @@ -1110,8 +1178,10 @@ EXTRA_DIST += xerox_mfp.conf.in libdll_preload_la_SOURCES = dll.c libdll_preload_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=dll -DENABLE_PRELOAD +libdll_preload_la_LIBADD = ../sanei/sanei_usb.lo $(USB_LIBS) $(XML_LIBS) libdll_la_SOURCES = dll.c libdll_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=dll +libdll_la_LIBADD = ../sanei/sanei_usb.lo $(USB_LIBS) $(XML_LIBS) BUILT_SOURCES = dll-preload.h CLEANFILES += dll-preload.h @@ -1142,13 +1212,13 @@ EXTRA_DIST += dll.aliases # what backends are preloaded. It should include what is needed by # those backends that are actually preloaded. if preloadable_backends_enabled -PRELOADABLE_BACKENDS_LIBS = ../sanei/sanei_config2.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_pv8630.lo ../sanei/sanei_pp.lo ../sanei/sanei_thread.lo ../sanei/sanei_lm983x.lo ../sanei/sanei_access.lo ../sanei/sanei_net.lo ../sanei/sanei_wire.lo ../sanei/sanei_codec_bin.lo ../sanei/sanei_pa4s2.lo ../sanei/sanei_ab306.lo ../sanei/sanei_pio.lo ../sanei/sanei_tcp.lo ../sanei/sanei_udp.lo ../sanei/sanei_magic.lo $(LIBV4L_LIBS) $(MATH_LIB) $(IEEE1284_LIBS) $(TIFF_LIBS) $(JPEG_LIBS) $(GPHOTO2_LIBS) $(SOCKET_LIBS) $(USB_LIBS) $(AVAHI_LIBS) $(SCSI_LIBS) $(PTHREAD_LIBS) $(RESMGR_LIBS) +PRELOADABLE_BACKENDS_LIBS = ../sanei/sanei_config2.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_pv8630.lo ../sanei/sanei_pp.lo ../sanei/sanei_thread.lo ../sanei/sanei_lm983x.lo ../sanei/sanei_access.lo ../sanei/sanei_net.lo ../sanei/sanei_wire.lo ../sanei/sanei_codec_bin.lo ../sanei/sanei_pa4s2.lo ../sanei/sanei_ab306.lo ../sanei/sanei_pio.lo ../sanei/sanei_tcp.lo ../sanei/sanei_udp.lo ../sanei/sanei_magic.lo $(LIBV4L_LIBS) $(MATH_LIB) $(IEEE1284_LIBS) $(TIFF_LIBS) $(JPEG_LIBS) $(GPHOTO2_LIBS) $(SOCKET_LIBS) $(USB_LIBS) $(AVAHI_LIBS) $(SCSI_LIBS) $(SANEI_THREAD_LIBS) $(RESMGR_LIBS) $(XML_LIBS) PRELOADABLE_BACKENDS_DEPS = ../sanei/sanei_config2.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_pv8630.lo ../sanei/sanei_pp.lo ../sanei/sanei_thread.lo ../sanei/sanei_lm983x.lo ../sanei/sanei_access.lo ../sanei/sanei_net.lo ../sanei/sanei_wire.lo ../sanei/sanei_codec_bin.lo ../sanei/sanei_pa4s2.lo ../sanei/sanei_ab306.lo ../sanei/sanei_pio.lo ../sanei/sanei_tcp.lo ../sanei/sanei_udp.lo ../sanei/sanei_magic.lo $(SANEI_SANEI_JPEG_LO) endif nodist_libsane_la_SOURCES = dll-s.c libsane_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=dll libsane_la_LDFLAGS = $(DIST_LIBS_LDFLAGS) -libsane_la_LIBADD = $(COMMON_LIBS) $(PRELOADABLE_BACKENDS_ENABLED) libdll_preload.la sane_strstatus.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo $(PRELOADABLE_BACKENDS_LIBS) $(DL_LIBS) +libsane_la_LIBADD = $(COMMON_LIBS) $(PRELOADABLE_BACKENDS_ENABLED) libdll_preload.la sane_strstatus.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo $(PRELOADABLE_BACKENDS_LIBS) $(DL_LIBS) $(XML_LIBS) # WARNING: Automake is getting this wrong so have to do it ourselves. libsane_la_DEPENDENCIES = $(COMMON_LIBS) $(PRELOADABLE_BACKENDS_ENABLED) libdll_preload.la sane_strstatus.lo ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo $(PRELOADABLE_BACKENDS_DEPS) diff --git a/backend/agfafocus.c b/backend/agfafocus.c index 0b59d2d..8177f38 100644 --- a/backend/agfafocus.c +++ b/backend/agfafocus.c @@ -1485,6 +1485,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, case OPT_BR_Y: if (info) *info |= SANE_INFO_RELOAD_PARAMS; + // fall through case OPT_SHARPEN: case OPT_EXPOSURE: case OPT_ATTENUATION_RED: diff --git a/backend/apple.c b/backend/apple.c index 167f6ea..980edb4 100644 --- a/backend/apple.c +++ b/backend/apple.c @@ -2064,7 +2064,8 @@ sane_control_option (SANE_Handle handle, SANE_Int option, v2 = SANE_UNFIX (f); DBG (FLOW_CONTROL, "Value %g (Fixed)\n", (action == SANE_ACTION_GET_VALUE) ? v1 : v2); - } + break; + } default: DBG (FLOW_CONTROL, "Value %u (Int).\n", (action == SANE_ACTION_GET_VALUE) diff --git a/backend/artec.c b/backend/artec.c index 2ba8d6d..395b4f1 100644 --- a/backend/artec.c +++ b/backend/artec.c @@ -1999,8 +1999,8 @@ attach (const char *devname, ARTEC_Device ** devp) DBG (6, "Found BlackWidow BW4800SP scanner, setting up like AT3\n"); /* setup the vendor and product to mimic the Artec/Ultima AT3 */ - strncpy (result + 8, "ULTIMA", 6); - strncpy (result + 16, "AT3 ", 16); + memcpy (result + 8, "ULTIMA", 6); + memcpy (result + 16, "AT3 ", 16); } /* @@ -2013,8 +2013,8 @@ attach (const char *devname, ARTEC_Device ** devp) DBG (6, "Found Plustek 19200S scanner, setting up like AM12S\n"); /* setup the vendor and product to mimic the Artec/Ultima AM12S */ - strncpy (result + 8, "ULTIMA", 6); - strncpy (result + 16, "AM12S ", 16); + memcpy (result + 8, "ULTIMA", 6); + memcpy (result + 16, "AM12S ", 16); } /* diff --git a/backend/artec_eplus48u.c b/backend/artec_eplus48u.c index 0e81b06..c5eb225 100644 --- a/backend/artec_eplus48u.c +++ b/backend/artec_eplus48u.c @@ -2956,7 +2956,7 @@ init_options (Artec48U_Scanner * s) SANE_I18N ("If enabled, only the shading correction is " "performed during calibration. The default values " "for gain, offset and exposure time, " - "either build-in or from the configuration file, " + "either built-in or from the configuration file, " "are used."); s->opt[OPT_CALIBRATE_SHADING].type = SANE_TYPE_BOOL; s->opt[OPT_CALIBRATE_SHADING].unit = SANE_UNIT_NONE; diff --git a/backend/as6e.c b/backend/as6e.c index 37a6d3b..47d8c90 100644 --- a/backend/as6e.c +++ b/backend/as6e.c @@ -797,7 +797,6 @@ check_for_driver (const char *devname) struct stat statbuf; mode_t modes; char *path; - char fullname[NAMESIZE]; char dir[NAMESIZE]; int count = 0, offset = 0, valid; @@ -806,7 +805,6 @@ check_for_driver (const char *devname) return 0; while (path[count] != '\0') { - memset (fullname, '\0', sizeof (fullname)); memset (dir, '\0', sizeof (dir)); valid = 1; while ((path[count] != ':') && (path[count] != '\0')) @@ -819,19 +817,19 @@ check_for_driver (const char *devname) count++; } if (valid == 1) - { - /* use sizeof(fullname)-1 to make sure there is at least one padded null byte */ - strncpy (fullname, dir, sizeof(fullname)-1); - /* take into account that fullname already contains non-null bytes */ - strncat (fullname, "/", sizeof(fullname)-strlen(fullname)-1); - strncat (fullname, devname, sizeof(fullname)-strlen(fullname)-1); - if (!stat (fullname, &statbuf)) - { - modes = statbuf.st_mode; - if (S_ISREG (modes)) - return (1); /* found as6edriver */ - } - } + { + char fullname[NAMESIZE]; + int len = snprintf(fullname, sizeof(fullname), "%s/%s", dir, devname); + if ((len > 0) && (len <= (int)sizeof(fullname))) + { + if (!stat (fullname, &statbuf)) + { + modes = statbuf.st_mode; + if (S_ISREG (modes)) + return (1); /* found as6edriver */ + } + } + } if (path[count] == '\0') return (0); /* end of path --no driver found */ count++; diff --git a/backend/avision.c b/backend/avision.c index e9f0145..55b5f4f 100644 --- a/backend/avision.c +++ b/backend/avision.c @@ -7921,7 +7921,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle) However, I was told Cygwin (et al.) takes care of it. */ strncpy(s->duplex_rear_fname, "/tmp/avision-rear-XXXXXX", PATH_MAX); - if (! mktemp(s->duplex_rear_fname) ) { + if (! mkstemp(s->duplex_rear_fname) ) { DBG (1, "sane_open: failed to generate temporary fname for duplex scans\n"); return SANE_STATUS_NO_MEM; } diff --git a/backend/avision.h b/backend/avision.h index 3f42ff6..58552c0 100644 --- a/backend/avision.h +++ b/backend/avision.h @@ -780,7 +780,7 @@ typedef struct acceleration_info #define SANE_NAME_DUPLEX "duplex" #define SANE_TITLE_DUPLEX SANE_I18N("Duplex scan") -#define SANE_DESC_DUPLEX SANE_I18N("Duplex scan provide a scan of the front and back side of the document") +#define SANE_DESC_DUPLEX SANE_I18N("Duplex scan provides a scan of the front and back side of the document") #ifdef AVISION_ENHANCED_SANE #warning "Compiled Avision backend will violate the SANE standard" diff --git a/backend/canon-sane.c b/backend/canon-sane.c index 5d9ec99..cd75719 100644 --- a/backend/canon-sane.c +++ b/backend/canon-sane.c @@ -1125,9 +1125,9 @@ sane_start (SANE_Handle handle) if (thistmpfile != NULL) { - if (mktemp(thistmpfile) == 0) + if (!mkstemp(thistmpfile)) { - DBG(1, "mktemp(thistmpfile) is failed\n"); + DBG(1, "mkstemp(thistmpfile) is failed\n"); return (SANE_STATUS_INVAL); } } diff --git a/backend/canon.c b/backend/canon.c index ad738e8..4a5a2a2 100644 --- a/backend/canon.c +++ b/backend/canon.c @@ -457,7 +457,7 @@ sense_handler (int scsi_fd, u_char * result, void *arg) status = SANE_STATUS_UNSUPPORTED; break; case 0x8002: - sense_str = SANE_I18N("option not connect"); + sense_str = SANE_I18N("option not correct"); status = SANE_STATUS_UNSUPPORTED; break; default: diff --git a/backend/canon630u-common.c b/backend/canon630u-common.c index 27c34ff..5cd0fcf 100644 --- a/backend/canon630u-common.c +++ b/backend/canon630u-common.c @@ -939,7 +939,7 @@ plugin_cal (CANON_Handle * s) { DBG (1, "No temp filename!\n"); s->fname = strdup ("/tmp/cal.XXXXXX"); - mktemp (s->fname); + mkstemp (s->fname); } s->width = 2551; s->height = 75; @@ -1583,7 +1583,7 @@ CANON_start_scan (CANON_Handle * scanner) /* choose a temp file name for scan data */ scanner->fname = strdup ("/tmp/scan.XXXXXX"); - if (!mktemp (scanner->fname)) + if (!mkstemp (scanner->fname)) return SANE_STATUS_IO_ERROR; /* calibrate if needed */ diff --git a/backend/canon_dr.c b/backend/canon_dr.c index 64aec31..f6cd5d4 100644 --- a/backend/canon_dr.c +++ b/backend/canon_dr.c @@ -3,7 +3,7 @@ This file is part of the SANE package, and implements a SANE backend for various Canon DR-series scanners. - Copyright (C) 2008-2016 m. allan noah + Copyright (C) 2008-2019 m. allan noah Yabarana Corp. www.yabarana.com provided significant funding EvriChart, Inc. www.evrichart.com provided funding and loaned equipment @@ -338,6 +338,8 @@ - initial support for P-150 v57 2019-02-24, manuarg - complete support for X-10, including hardware cropping + v58 2019-11-10, MAN + - adjust wait_scanner to set runRS only as a last resort, bug #154 SANE FLOW DIAGRAM @@ -388,7 +390,7 @@ #include "canon_dr.h" #define DEBUG 1 -#define BUILD 57 +#define BUILD 58 /* values for SANE_DEBUG_CANON_DR env var: - errors 5 @@ -7584,6 +7586,24 @@ wait_scanner(struct scanner *s) NULL, NULL ); + if (ret != SANE_STATUS_GOOD) { + DBG(5,"WARNING: Brain-dead scanner. Hitting with stick.\n"); + ret = do_cmd ( + s, 0, 1, + cmd, cmdLen, + NULL, 0, + NULL, NULL + ); + } + if (ret != SANE_STATUS_GOOD) { + DBG(5,"WARNING: Brain-dead scanner. Hitting with stick again.\n"); + ret = do_cmd ( + s, 0, 1, + cmd, cmdLen, + NULL, 0, + NULL, NULL + ); + } // some scanners (such as DR-F120) are OK but will not respond to commands // when in sleep mode. By checking the sense it wakes them up. if (ret != SANE_STATUS_GOOD) { @@ -7596,7 +7616,16 @@ wait_scanner(struct scanner *s) ); } if (ret != SANE_STATUS_GOOD) { - DBG(5,"WARNING: Brain-dead scanner. Hitting with stick instead.\n"); + DBG(5,"WARNING: Brain-dead scanner. Hitting with stick a third time.\n"); + ret = do_cmd ( + s, 0, 1, + cmd, cmdLen, + NULL, 0, + NULL, NULL + ); + } + if (ret != SANE_STATUS_GOOD) { + DBG(5,"WARNING: Brain-dead scanner. Hitting with stick a fourth time.\n"); ret = do_cmd ( s, 0, 1, cmd, cmdLen, diff --git a/backend/dc25.c b/backend/dc25.c index 3bb81f5..6188608 100644 --- a/backend/dc25.c +++ b/backend/dc25.c @@ -2030,7 +2030,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle) if (tmpname == NULL) { tmpname = tmpnamebuf; - if (mktemp (tmpname) == NULL) + if (!mkstemp (tmpname)) { DBG (1, "Unable to make temp file %s\n", tmpname); return SANE_STATUS_INVAL; diff --git a/backend/dll.c b/backend/dll.c index 8f0983d..73ffde4 100644 --- a/backend/dll.c +++ b/backend/dll.c @@ -89,6 +89,20 @@ posix_dlsym (void *handle, const char *func) } # pragma GCC diagnostic pop + /* Similar to the above, GCC also warns about conversion between + pointers to functions. The ISO C standard says that invoking a + converted pointer to a function whose type is not compatible with + the pointed-to type, the behavior is undefined. Although GCC is + correct to warn about this, the dll backend has been using these + conversions without issues for a very long time already. + + Rather than push/pop around every use, which would get very ugly + real fast, ignore this particular warning for the remainder of + the file. + */ +# pragma GCC diagnostic ignored "-Wpragmas" /* backward compatibility */ +# pragma GCC diagnostic ignored "-Wcast-function-type" + /* Older versions of dlopen() don't define RTLD_NOW and RTLD_LAZY. They all seem to use a mode of 1 to indicate RTLD_NOW and some do not support RTLD_LAZY at all. Hence, unless defined, we define @@ -139,6 +153,8 @@ posix_dlsym (void *handle, const char *func) #define DLL_CONFIG_FILE "dll.conf" #define DLL_ALIASES_FILE "dll.aliases" +#include "../include/sane/sanei_usb.h" + enum SANE_Ops { OP_INIT = 0, @@ -797,7 +813,8 @@ read_dlld (void) DIR *dlld; struct dirent *dllconf; struct stat st; - char conffile[PATH_MAX], dlldir[PATH_MAX]; + char dlldir[PATH_MAX]; + char conffile[PATH_MAX + strlen("/") + NAME_MAX]; size_t len, plen; const char *dir_list; char *copy, *next, *dir; @@ -849,7 +866,7 @@ read_dlld (void) || (dllconf->d_name[len-1] == '#')) continue; - snprintf (conffile, PATH_MAX, "%s/%s", dlldir, dllconf->d_name); + snprintf (conffile, sizeof(conffile), "%s/%s", dlldir, dllconf->d_name); DBG (5, "sane_init/read_dlld: considering %s\n", conffile); @@ -1177,18 +1194,73 @@ sane_open (SANE_String_Const full_name, SANE_Handle * meta_handle) } dev_name = strchr (full_name, ':'); + + int is_fakeusb = 0, is_fakeusbdev = 0, is_fakeusbout = 0; + if (dev_name) { - be_name = strndup(full_name, dev_name - full_name); - ++dev_name; /* skip colon */ + is_fakeusb = strncmp(full_name, "fakeusb", dev_name - full_name) == 0 && + dev_name - full_name == 7; + is_fakeusbdev = strncmp(full_name, "fakeusbdev", dev_name - full_name) == 0 && + dev_name - full_name == 10; + is_fakeusbout = strncmp(full_name, "fakeusbout", dev_name - full_name) == 0 && + dev_name - full_name == 10; + } + + if (is_fakeusb || is_fakeusbdev) + { + ++dev_name; // skip colon + status = sanei_usb_testing_enable_replay(dev_name, is_fakeusbdev); + if (status != SANE_STATUS_GOOD) + return status; + + be_name = sanei_usb_testing_get_backend(); + if (be_name == NULL) + { + DBG (0, "%s: unknown backend for testing\n", __func__); + return SANE_STATUS_ACCESS_DENIED; + } } else { - /* if no colon interpret full_name as the backend name; an empty - backend device name will cause us to open the first device of - that backend. */ - be_name = strdup(full_name); - dev_name = ""; + char* fakeusbout_path = NULL; + if (is_fakeusbout) + { + ++dev_name; // skip colon + + const char* path_end = strchr(dev_name, ':'); + if (path_end == NULL) + { + DBG (0, "%s: the device name does not contain path\n", __func__); + return SANE_STATUS_INVAL; + } + fakeusbout_path = strndup(dev_name, path_end - dev_name); + + full_name = path_end + 1; // skip colon + dev_name = strchr(full_name, ':'); + } + + if (dev_name) + { + be_name = strndup(full_name, dev_name - full_name); + ++dev_name; /* skip colon */ + } + else + { + /* if no colon interpret full_name as the backend name; an empty + backend device name will cause us to open the first device of + that backend. */ + be_name = strdup(full_name); + dev_name = ""; + } + + if (is_fakeusbout) + { + status = sanei_usb_testing_enable_record(fakeusbout_path, be_name); + free(fakeusbout_path); + if (status != SANE_STATUS_GOOD) + return status; + } } if (!be_name) diff --git a/backend/dll.conf.in b/backend/dll.conf.in index 8d459ab..92091cb 100644 --- a/backend/dll.conf.in +++ b/backend/dll.conf.in @@ -11,10 +11,10 @@ net abaton agfafocus apple -avision artec artec_eplus48u as6e +avision bh canon canon630u @@ -24,33 +24,35 @@ cardscan coolscan #coolscan2 coolscan3 -#dc25 #dc210 #dc240 +#dc25 dell1600n_net dmc epjitsu #epson epson2 epsonds +escl fujitsu -#gphoto2 genesys +#gphoto2 gt68xx hp -hp3900 -hpsj5s hp3500 +hp3900 hp4200 hp5400 hp5590 hpljm1005 +hpsj5s hs2p ibm kodak kodakaio kvs1025 kvs20xx +kvs40xx leo lexmark ma1509 @@ -66,6 +68,7 @@ nec niash #p5 pie +pieusb pint pixma plustek @@ -91,7 +94,7 @@ teco3 #test u12 umax -#umax_pp umax1220u +#umax_pp v4l xerox_mfp diff --git a/backend/epjitsu.c b/backend/epjitsu.c index bee4310..714bc0b 100644 --- a/backend/epjitsu.c +++ b/backend/epjitsu.c @@ -349,10 +349,21 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) continue; if ((strncmp ("firmware", lp, 8) == 0) && isspace (lp[8])) { + size_t firmware_len; + lp += 8; lp = sanei_config_skip_whitespace (lp); DBG (15, "sane_get_devices: firmware '%s'\n", lp); - strncpy((char *)global_firmware_filename,lp,PATH_MAX); + + firmware_len = strlen(lp); + if (firmware_len > sizeof(global_firmware_filename) - 1) + { + DBG (5, "sane_get_devices: firmware file too long. ignoring '%s'\n", lp); + } + else + { + strcpy((char *)global_firmware_filename, lp); + } } else if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3])) { DBG (15, "sane_get_devices: looking for '%s'\n", lp); diff --git a/backend/epson2.c b/backend/epson2.c index f119018..e6f6786 100644 --- a/backend/epson2.c +++ b/backend/epson2.c @@ -1889,12 +1889,11 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) case OPT_BR_X: case OPT_BR_Y: - sval->w = *((SANE_Word *) value); - if (SANE_UNFIX(sval->w) == 0) { + if (SANE_UNFIX(*((SANE_Word *) value)) == 0) { DBG(17, "invalid br-x or br-y\n"); return SANE_STATUS_INVAL; } - /* passthru */ + // fall through case OPT_TL_X: case OPT_TL_Y: sval->w = *((SANE_Word *) value); diff --git a/backend/epsonds.c b/backend/epsonds.c index d402f58..ff5d681 100644 --- a/backend/epsonds.c +++ b/backend/epsonds.c @@ -1050,12 +1050,11 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) case OPT_BR_X: case OPT_BR_Y: - sval->w = *((SANE_Word *) value); - if (SANE_UNFIX(sval->w) == 0) { + if (SANE_UNFIX(*((SANE_Word *) value)) == 0) { DBG(17, " invalid br-x or br-y\n"); return SANE_STATUS_INVAL; } - /* passthru */ + // fall through case OPT_TL_X: case OPT_TL_Y: sval->w = *((SANE_Word *) value); diff --git a/backend/escl.conf.in b/backend/escl.conf.in new file mode 100644 index 0000000..2aa6257 --- /dev/null +++ b/backend/escl.conf.in @@ -0,0 +1,17 @@ +# escl.conf -- ESCL configuration +# Lines starting with a # or a ; are comments. Comments must be on a +# line of their own. End-of-line comments are not supported. +# Explanation : if you can't detect your device but it's an eSCL device, modify this escl conf' file to use your device. +# -> uncomment the lines below, from '[device]' to 'port'. +# -> put your device name instead of 'EPSON X'. +# -> put your type of protocol instead of 'https' : http or https. +# -> put your device ip instead of '123.456.789.10'. +# -> put the port that you use instead of '88'. +# For example, the lines below are for one device, but if you have several devices to use, you can duplicate the lines below as many times as you have devices. + +#[device] + +#model EPSON X +#type https +#ip 123.456.789.10 +#port 88 diff --git a/backend/escl/escl.c b/backend/escl/escl.c new file mode 100644 index 0000000..8df6c5c --- /dev/null +++ b/backend/escl/escl.c @@ -0,0 +1,777 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#include "escl.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <setjmp.h> + +#include <curl/curl.h> + +#include "../include/sane/saneopts.h" +#include "../include/sane/sanei.h" +#include "../include/sane/sanei_backend.h" +#include "../include/sane/sanei_config.h" + +#define min(A,B) (((A)<(B)) ? (A) : (B)) +#define max(A,B) (((A)>(B)) ? (A) : (B)) +#define INPUT_BUFFER_SIZE 4096 + +static const SANE_Device **devlist = NULL; +static ESCL_Device *list_devices_primary = NULL; +static int num_devices = 0; + +typedef struct Handled { + struct Handled *next; + SANE_String_Const name; + char *result; + ESCL_ScanParam param; + SANE_Option_Descriptor opt[NUM_OPTIONS]; + Option_Value val[NUM_OPTIONS]; + capabilities_t *scanner; + SANE_Range x_range; + SANE_Range y_range; + SANE_Bool cancel; + SANE_Bool write_scan_data; + SANE_Bool decompress_scan_data; + SANE_Bool end_read; + SANE_Parameters ps; +} escl_sane_t; + +/** + * \fn static SANE_Status escl_add_in_list(ESCL_Device *current) + * \brief Function that adds all the element needed to my list : + * the port number, the model name, the ip address, and the type of url (http/https). + * Moreover, this function counts the number of devices found. + * + * \return SANE_STATUS_GOOD if everything is OK. + */ +static SANE_Status +escl_add_in_list(ESCL_Device *current) +{ + ++num_devices; + current->next = list_devices_primary; + list_devices_primary = current; + return (SANE_STATUS_GOOD); +} + +/** + * \fn SANE_Status escl_device_add(int port_nb, const char *model_name, char *ip_address, char *type) + * \brief Function that browses my list ('for' loop) and returns the "escl_add_in_list" function to + * adds all the element needed to my list : + * the port number, the model name, the ip address and the type of the url (http / https). + * + * \return escl_add_in_list(current) + */ +SANE_Status +escl_device_add(int port_nb, const char *model_name, char *ip_address, char *type) +{ + ESCL_Device *current = NULL; + DBG (10, "escl_device_add\n"); + for (current = list_devices_primary; current; current = current->next) { + if (strcmp(current->ip_address, ip_address) == 0 && current->port_nb == port_nb + && strcmp(current->type, type) == 0) + return (SANE_STATUS_GOOD); + } + current = malloc(sizeof(*current)); + if (current == NULL) + return (SANE_STATUS_NO_MEM); + memset(current, 0, sizeof(*current)); + current->port_nb = port_nb; + current->model_name = strdup(model_name); + current->ip_address = strdup(ip_address); + current->type = strdup(type); + return escl_add_in_list(current); +} + +/** + * \fn static inline size_t max_string_size(const SANE_String_Const strings[]) + * \brief Function that browses the string ('for' loop) and counts the number of character in the string. + * --> this allows to know the maximum size of the string. + * + * \return max_size + 1 (the size max) + */ +static inline size_t +max_string_size(const SANE_String_Const strings[]) +{ + size_t max_size = 0; + int i = 0; + + for (i = 0; strings[i]; ++i) { + size_t size = strlen (strings[i]); + if (size > max_size) + max_size = size; + } + return (max_size + 1); +} + +/** + * \fn static SANE_Device *convertFromESCLDev(ESCL_Device *cdev) + * \brief Function that checks if the url of the received scanner is secured or not (http / https). + * --> if the url is not secured, our own url will be composed like "http://'ip':'port'". + * --> else, our own url will be composed like "https://'ip':'port'". + * AND, it's in this function that we gather all the informations of the url (that were in our list) : + * the model_name, the port, the ip, and the type of url. + * SO, leaving this function, we have in memory the complete url. + * + * \return sdev (structure that contains the elements of the url) + */ +static SANE_Device * +convertFromESCLDev(ESCL_Device *cdev) +{ + SANE_Device *sdev = (SANE_Device*) calloc(1, sizeof(SANE_Device)); + char tmp[PATH_MAX] = { 0 }; + + if (strcmp(cdev->type, "_uscan._tcp") == 0 || strcmp(cdev->type, "http") == 0) + snprintf(tmp, sizeof(tmp), "http://%s:%d", cdev->ip_address, cdev->port_nb); + else + snprintf(tmp, sizeof(tmp), "https://%s:%d", cdev->ip_address, cdev->port_nb); + DBG( 1, "Escl add device : %s\n", tmp); + sdev->name = strdup(tmp); + sdev->model = strdup(cdev->model_name); + sdev->vendor = strdup("ESCL"); + sdev->type = strdup("flatbed scanner"); + return (sdev); +} + +/** + * \fn SANE_Status sane_init(SANE_Int *version_code, SANE_Auth_Callback authorize) + * \brief Function that's called before any other SANE function ; it's the first SANE function called. + * --> this function checks the SANE config. and can check the authentication of the user if + * 'authorize' value is more than SANE_TRUE. + * In this case, it will be necessary to define an authentication method. + * + * \return SANE_STATUS_GOOD (everything is OK) + */ +SANE_Status +sane_init(SANE_Int *version_code, SANE_Auth_Callback __sane_unused__ authorize) +{ + DBG_INIT(); + DBG (10, "escl sane_init\n"); + SANE_Status status = SANE_STATUS_GOOD; + curl_global_init(CURL_GLOBAL_ALL); + if (version_code != NULL) + *version_code = SANE_VERSION_CODE(1, 0, 0); + if (status != SANE_STATUS_GOOD) + return (status); + return (SANE_STATUS_GOOD); +} + +/** + * \fn void sane_exit(void) + * \brief Function that must be called to terminate use of a backend. + * This function will first close all device handles that still might be open. + * --> by freeing all the elements of my list. + * After this function, no function other than 'sane_init' may be called. + */ +void +sane_exit(void) +{ + DBG (10, "escl sane_exit\n"); + ESCL_Device *next = NULL; + + while (list_devices_primary != NULL) { + next = list_devices_primary->next; + free(list_devices_primary); + list_devices_primary = next; + } + if (devlist) + free (devlist); + list_devices_primary = NULL; + devlist = NULL; + curl_global_cleanup(); +} + +/** + * \fn static SANE_Status attach_one_config(SANEI_Config *config, const char *line) + * \brief Function that implements a configuration file to the user : + * if the user can't detect some devices, he will be able to force their detection with this config' file to use them. + * Thus, this function parses the config' file to use the device of the user with the information below : + * the type of protocol (http/https), the ip, the port number, and the model name. + * + * \return escl_add_in_list(escl_device) if the parsing worked, SANE_STATUS_GOOD otherwise. + */ +static SANE_Status +attach_one_config(SANEI_Config __sane_unused__ *config, const char *line) +{ + int port = 0; + static int count = 0; + static ESCL_Device *escl_device = NULL; + + if (strncmp(line, "[device]", 8) == 0) { + count = 0; + escl_device = (ESCL_Device*)calloc(1, sizeof(ESCL_Device)); + } + if (strncmp(line, "ip", 2) == 0) { + const char *ip_space = sanei_config_skip_whitespace(line + 2); + if (escl_device != NULL && ip_space != NULL) { + count++; + escl_device->ip_address = strdup(ip_space); + } + } + if (sscanf(line, "port %i", &port) == 1 && port != 0) { + const char *port_space = sanei_config_skip_whitespace(line + 4); + if (escl_device != NULL && port_space != NULL) { + count++; + escl_device->port_nb = port; + } + } + if (strncmp(line, "model", 5) == 0) { + const char *model_space = sanei_config_skip_whitespace(line + 5); + if (escl_device != NULL && model_space != NULL) { + count++; + escl_device->model_name = strdup(model_space); + } + } + if (strncmp(line, "type", 4) == 0) { + const char *type_space = sanei_config_skip_whitespace(line + 4); + if (escl_device != NULL && type_space != NULL) { + count++; + escl_device->type = strdup(type_space); + } + } + if (count == 4) + return (escl_add_in_list(escl_device)); + return (SANE_STATUS_GOOD); +} + +/** + * \fn SANE_Status sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only) + * \brief Function that searches for connected devices and places them in our 'device_list'. ('for' loop) + * If the attribute 'local_only' is worth SANE_FALSE, we only returns the connected devices locally. + * + * \return SANE_STATUS_GOOD if devlist != NULL ; SANE_STATUS_NO_MEM otherwise. + */ +SANE_Status +sane_get_devices(const SANE_Device ***device_list, SANE_Bool local_only) +{ + if (local_only) /* eSCL is a network-only protocol */ + return (device_list ? SANE_STATUS_GOOD : SANE_STATUS_INVAL); + + DBG (10, "escl sane_get_devices\n"); + ESCL_Device *dev = NULL; + static const SANE_Device **devlist = 0; + SANE_Status status; + + if (device_list == NULL) + return (SANE_STATUS_INVAL); + status = sanei_configure_attach(ESCL_CONFIG_FILE, NULL, attach_one_config); + if (status != SANE_STATUS_GOOD) + return (status); + escl_devices(&status); + if (status != SANE_STATUS_GOOD) + return (status); + if (devlist) + free(devlist); + devlist = (const SANE_Device **) calloc (num_devices + 1, sizeof (devlist[0])); + if (devlist == NULL) + return (SANE_STATUS_NO_MEM); + int i = 0; + for (dev = list_devices_primary; i < num_devices; dev = dev->next) { + SANE_Device *s_dev = convertFromESCLDev(dev); + devlist[i] = s_dev; + i++; + } + devlist[i] = 0; + *device_list = devlist; + return (devlist) ? SANE_STATUS_GOOD : SANE_STATUS_NO_MEM; +} + +/** + * \fn static SANE_Status init_options(SANE_String_Const name, escl_sane_t *s) + * \brief Function thzt initializes all the needed options of the received scanner + * (the resolution / the color / the margins) thanks to the informations received with + * the 'escl_capabilities' function, called just before. + * + * \return status (if everything is OK, status = SANE_STATUS_GOOD) + */ +static SANE_Status +init_options(SANE_String_Const name, escl_sane_t *s) +{ + DBG (10, "escl init_options\n"); + SANE_Status status = SANE_STATUS_GOOD; + int i = 0; + + if (name == NULL) + return (SANE_STATUS_INVAL); + memset (s->opt, 0, sizeof (s->opt)); + memset (s->val, 0, sizeof (s->val)); + for (i = 0; i < NUM_OPTIONS; ++i) { + s->opt[i].size = sizeof (SANE_Word); + s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; + } + s->x_range.min = 0; + s->x_range.max = s->scanner->MaxWidth - s->scanner->MinWidth; + s->x_range.quant = 1; + s->y_range.min = 0; + s->y_range.max = s->scanner->MaxHeight - s->scanner->MinHeight; + s->y_range.quant = 1; + s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; + s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS; + s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT; + s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; + s->val[OPT_NUM_OPTS].w = NUM_OPTIONS; + + s->opt[OPT_MODE_GROUP].title = SANE_TITLE_SCAN_MODE; + s->opt[OPT_MODE_GROUP].desc = ""; + s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; + s->opt[OPT_MODE_GROUP].cap = 0; + s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE; + + s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE; + s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE; + s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE; + s->opt[OPT_MODE].type = SANE_TYPE_STRING; + s->opt[OPT_MODE].unit = SANE_UNIT_NONE; + s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST; + s->opt[OPT_MODE].constraint.string_list = s->scanner->ColorModes; + s->val[OPT_MODE].s = (char *)strdup(s->scanner->ColorModes[0]); + s->opt[OPT_MODE].size = max_string_size(s->scanner->ColorModes); + s->scanner->default_color = (char *)strdup(s->scanner->ColorModes[0]); + + s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; + s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; + s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; + s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT; + s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; + s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST; + s->opt[OPT_RESOLUTION].constraint.word_list = s->scanner->SupportedResolutions; + s->val[OPT_RESOLUTION].w = s->scanner->SupportedResolutions[1]; + s->scanner->default_resolution = s->scanner->SupportedResolutions[1]; + + s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; + s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW; + s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW; + s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT; + s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL; + s->val[OPT_PREVIEW].w = SANE_FALSE; + + s->opt[OPT_GRAY_PREVIEW].name = SANE_NAME_GRAY_PREVIEW; + s->opt[OPT_GRAY_PREVIEW].title = SANE_TITLE_GRAY_PREVIEW; + s->opt[OPT_GRAY_PREVIEW].desc = SANE_DESC_GRAY_PREVIEW; + s->opt[OPT_GRAY_PREVIEW].type = SANE_TYPE_BOOL; + s->val[OPT_GRAY_PREVIEW].w = SANE_FALSE; + + s->opt[OPT_GEOMETRY_GROUP].title = SANE_TITLE_GEOMETRY; + s->opt[OPT_GEOMETRY_GROUP].desc = ""; + s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; + s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED; + s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; + + s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; + s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; + s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; + s->opt[OPT_TL_X].type = SANE_TYPE_FIXED; + s->opt[OPT_TL_X].unit = SANE_UNIT_PIXEL; + s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; + s->opt[OPT_TL_X].constraint.range = &s->x_range; + s->val[OPT_TL_X].w = s->scanner->RiskyLeftMargin; + + s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; + s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; + s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; + s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; + s->opt[OPT_TL_Y].unit = SANE_UNIT_PIXEL; + s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; + s->opt[OPT_TL_Y].constraint.range = &s->y_range; + s->val[OPT_TL_Y].w = s->scanner->RiskyTopMargin; + + s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; + s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; + s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; + s->opt[OPT_BR_X].type = SANE_TYPE_FIXED; + s->opt[OPT_BR_X].unit = SANE_UNIT_PIXEL; + s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; + s->opt[OPT_BR_X].constraint.range = &s->x_range; + s->val[OPT_BR_X].w = s->scanner->MaxWidth; + + s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; + s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; + s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; + s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; + s->opt[OPT_BR_Y].unit = SANE_UNIT_PIXEL; + s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; + s->opt[OPT_BR_Y].constraint.range = &s->y_range; + s->val[OPT_BR_Y].w = s->scanner->MaxHeight; + return (status); +} + +/** + * \fn SANE_Status sane_open(SANE_String_Const name, SANE_Handle *h) + * \brief Function that establishes a connection with the device named by 'name', + * and returns a 'handler' using 'SANE_Handle *h', representing it. + * Thus, it's this function that calls the 'escl_status' function firstly, + * then the 'escl_capabilities' function, and, after, the 'init_options' function. + * + * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +sane_open(SANE_String_Const name, SANE_Handle *h) +{ + DBG (10, "escl sane_open\n"); + SANE_Status status; + escl_sane_t *handler = NULL; + + if (name == NULL) + return (SANE_STATUS_INVAL); + status = escl_status(name); + if (status != SANE_STATUS_GOOD) + return (status); + handler = (escl_sane_t *)calloc(1, sizeof(escl_sane_t)); + if (handler == NULL) + return (SANE_STATUS_NO_MEM); + handler->name = strdup(name); + handler->scanner = escl_capabilities(name, &status); + if (status != SANE_STATUS_GOOD) + return (status); + status = init_options(name, handler); + if (status != SANE_STATUS_GOOD) + return (status); + handler->ps.depth = 8; + handler->ps.last_frame = SANE_TRUE; + handler->ps.format = SANE_FRAME_RGB; + handler->ps.pixels_per_line = handler->val[OPT_BR_X].w; + handler->ps.lines = handler->val[OPT_BR_Y].w; + handler->ps.bytes_per_line = handler->ps.pixels_per_line * 3; + status = sane_get_parameters(handler, 0); + if (status != SANE_STATUS_GOOD) + return (status); + handler->cancel = SANE_FALSE; + handler->write_scan_data = SANE_FALSE; + handler->decompress_scan_data = SANE_FALSE; + handler->end_read = SANE_FALSE; + *h = handler; + return (status); +} + +/** + * \fn void sane_cancel(SANE_Handle h) + * \brief Function that's used to, immediately or as quickly as possible, cancel the currently + * pending operation of the device represented by 'SANE_Handle h'. + * This functions calls the 'escl_scanner' functions, that resets the scan operations. + */ +void +sane_cancel(SANE_Handle h) +{ + DBG (10, "escl sane_cancel\n"); + escl_sane_t *handler = h; + if (handler->scanner->tmp) + { + fclose(handler->scanner->tmp); + handler->scanner->tmp = NULL; + } + handler->cancel = SANE_TRUE; + escl_scanner(handler->name, handler->result); +} + +/** + * \fn void sane_close(SANE_Handle h) + * \brief Function that closes the communication with the device represented by 'SANE_Handle h'. + * This function must release the resources that were allocated to the opening of 'h'. + */ +void +sane_close(SANE_Handle h) +{ + DBG (10, "escl sane_close\n"); + if (h != NULL) { + free(h); + h = NULL; + } +} + +/** + * \fn const SANE_Option_Descriptor *sane_get_option_descriptor(SANE_Handle h, SANE_Int n) + * \brief Function that retrieves a descriptor from the n number option of the scanner + * represented by 'h'. + * The descriptor remains valid until the machine is closed. + * + * \return s->opt + n + */ +const SANE_Option_Descriptor * +sane_get_option_descriptor(SANE_Handle h, SANE_Int n) +{ + DBG (10, "escl sane_get_option_descriptor\n"); + escl_sane_t *s = h; + + if ((unsigned) n >= NUM_OPTIONS || n < 0) + return (0); + return (s->opt + n); +} + +/** + * \fn SANE_Status sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void *v, SANE_Int *i) + * \brief Function that defines the actions to perform for the 'n' option of the machine, + * represented by 'h', if the action is 'a'. + * There are 3 types of possible actions : + * --> SANE_ACTION_GET_VALUE: 'v' must be used to provide the value of the option. + * --> SANE_ACTION_SET_VALUE: The option must take the 'v' value. + * --> SANE_ACTION_SET_AUTO: The backend or machine must affect the option with an appropriate value. + * Moreover, the parameter 'i' is used to provide additional information about the state of + * 'n' option if SANE_ACTION_SET_VALUE has been performed. + * + * \return SANE_STATUS_GOOD if everything is OK, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL + */ +SANE_Status +sane_control_option(SANE_Handle h, SANE_Int n, SANE_Action a, void *v, SANE_Int *i) +{ + DBG (10, "escl sane_control_option\n"); + escl_sane_t *handler = h; + + if (i) + *i = 0; + if (n >= NUM_OPTIONS || n < 0) + return (SANE_STATUS_INVAL); + if (a == SANE_ACTION_GET_VALUE) { + switch (n) { + case OPT_NUM_OPTS: + case OPT_RESOLUTION: + case OPT_TL_X: + case OPT_TL_Y: + case OPT_BR_X: + case OPT_BR_Y: + case OPT_PREVIEW: + case OPT_GRAY_PREVIEW: + *(SANE_Word *) v = handler->val[n].w; + break; + case OPT_MODE: + strcpy (v, handler->val[n].s); + break; + case OPT_MODE_GROUP: + default: + break; + } + return (SANE_STATUS_GOOD); + } + if (a == SANE_ACTION_SET_VALUE) { + switch (n) { + case OPT_TL_X: + case OPT_TL_Y: + case OPT_BR_X: + case OPT_BR_Y: + case OPT_PREVIEW: + case OPT_GRAY_PREVIEW: + handler->val[n].w = *(SANE_Word *) v; + if (i && handler->val[n].w != *(SANE_Word *) v) + *i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT; + handler->val[n].w = *(SANE_Word *) v; + break; + case OPT_RESOLUTION: + handler->val[n].w = *(SANE_Word *) v; + if (i) + *i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT; + break; + case OPT_MODE: + if (handler->val[n].s) + free (handler->val[n].s); + handler->val[n].s = strdup (v); + if (i) + *i |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS | SANE_INFO_INEXACT; + break; + default: + break; + } + } + return (SANE_STATUS_GOOD); +} + +/** + * \fn SANE_Status sane_start(SANE_Handle h) + * \brief Function that initiates aquisition of an image from the device represented by handle 'h'. + * This function calls the "escl_newjob" function and the "escl_scan" function. + * + * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +sane_start(SANE_Handle h) +{ + DBG (10, "escl sane_start\n"); + SANE_Status status = SANE_STATUS_GOOD; + escl_sane_t *handler = h; + int w = 0; + int he = 0; + int bps = 0; + + if (handler->name == NULL) + return (SANE_STATUS_INVAL); + handler->cancel = SANE_FALSE; + handler->write_scan_data = SANE_FALSE; + handler->decompress_scan_data = SANE_FALSE; + handler->end_read = SANE_FALSE; + handler->scanner->height = handler->val[OPT_BR_Y].w; + handler->scanner->width = handler->val[OPT_BR_X].w; + handler->scanner->pos_x = handler->val[OPT_TL_X].w; + handler->scanner->pos_y = handler->val[OPT_TL_Y].w; + if(handler->scanner->default_color) + free(handler->scanner->default_color); + if (handler->val[OPT_PREVIEW].w == SANE_TRUE) + { + int i = 0, val = 9999;; + if (handler->val[OPT_GRAY_PREVIEW].w == SANE_TRUE || + !strncasecmp(handler->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY, 3)) + handler->scanner->default_color = strdup("Grayscale8"); + else + handler->scanner->default_color = strdup("RGB24"); + for (i = 1; i < handler->scanner->SupportedResolutionsSize; i++) + { + if (val > handler->scanner->SupportedResolutions[i]) + val = handler->scanner->SupportedResolutions[i]; + } + handler->scanner->default_resolution = val; + } + else + { + handler->scanner->default_resolution = handler->val[OPT_RESOLUTION].w; + if (!strncasecmp(handler->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY, 3)) + handler->scanner->default_color = strdup("Grayscale8"); + else + handler->scanner->default_color = strdup("RGB24"); + } + handler->result = escl_newjob(handler->scanner, handler->name, &status); + if (status != SANE_STATUS_GOOD) + return (status); + status = escl_scan(handler->scanner, handler->name, handler->result); + if (status != SANE_STATUS_GOOD) + return (status); + if (!strcmp(handler->scanner->default_format, "image/jpeg")) + { + status = get_JPEG_data(handler->scanner, &w, &he, &bps); + } + else if (!strcmp(handler->scanner->default_format, "image/png")) + { + status = get_PNG_data(handler->scanner, &w, &he, &bps); + } + else if (!strcmp(handler->scanner->default_format, "image/tiff")) + { + status = get_TIFF_data(handler->scanner, &w, &he, &bps); + } + else + return SANE_STATUS_INVAL; + + if (status != SANE_STATUS_GOOD) + return (status); + handler->ps.depth = 8; + handler->ps.pixels_per_line = w; + handler->ps.lines = he; + handler->ps.bytes_per_line = w * bps; + handler->ps.last_frame = SANE_TRUE; + handler->ps.format = SANE_FRAME_RGB; + return (status); +} + +/** + * \fn SANE_Status sane_get_parameters(SANE_Handle h, SANE_Parameters *p) + * \brief Function that retrieves the device parameters represented by 'h' and stores them in 'p'. + * This function is normally used after "sane_start". + * It's in this function that we choose to assign the default color. (Color or Monochrome) + * + * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +sane_get_parameters(SANE_Handle h, SANE_Parameters *p) +{ + DBG (10, "escl sane_get_parameters\n"); + SANE_Status status = SANE_STATUS_GOOD; + escl_sane_t *handler = h; + + if (status != SANE_STATUS_GOOD) + return (status); + if (p != NULL) { + p->depth = 8; + p->last_frame = SANE_TRUE; + p->format = SANE_FRAME_RGB; + p->pixels_per_line = handler->ps.pixels_per_line; + p->lines = handler->ps.lines; + p->bytes_per_line = handler->ps.bytes_per_line; + } + return (status); +} + + +/** + * \fn SANE_Status sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len) + * \brief Function that's used to read image data from the device represented by handle 'h'. + * The argument 'buf' is a pointer to a memory area that is at least 'maxlen' bytes long. + * The number of bytes returned is stored in '*len'. + * --> When the call succeeds, the number of bytes returned can be anywhere in the range from 0 to 'maxlen' bytes. + * + * \return SANE_STATUS_GOOD (if everything is OK, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len) +{ + DBG (10, "escl sane_read\n"); + escl_sane_t *handler = h; + SANE_Status status = SANE_STATUS_GOOD; + long readbyte; + + if (!handler | !buf | !len) + return (SANE_STATUS_INVAL); + if (handler->cancel) + return (SANE_STATUS_CANCELLED); + if (!handler->write_scan_data) + handler->write_scan_data = SANE_TRUE; + if (!handler->decompress_scan_data) { + if (status != SANE_STATUS_GOOD) + return (status); + handler->decompress_scan_data = SANE_TRUE; + } + if (handler->scanner->img_data == NULL) + return (SANE_STATUS_INVAL); + if (!handler->end_read) { + readbyte = min((handler->scanner->img_size - handler->scanner->img_read), maxlen); + memcpy(buf, handler->scanner->img_data + handler->scanner->img_read, readbyte); + handler->scanner->img_read = handler->scanner->img_read + readbyte; + *len = readbyte; + if (handler->scanner->img_read == handler->scanner->img_size) + handler->end_read = SANE_TRUE; + else if (handler->scanner->img_read > handler->scanner->img_size) { + *len = 0; + handler->end_read = SANE_TRUE; + free(handler->scanner->img_data); + handler->scanner->img_data = NULL; + return (SANE_STATUS_INVAL); + } + } + else { + *len = 0; + free(handler->scanner->img_data); + handler->scanner->img_data = NULL; + return (SANE_STATUS_EOF); + } + return (SANE_STATUS_GOOD); +} + +SANE_Status +sane_get_select_fd(SANE_Handle __sane_unused__ h, SANE_Int __sane_unused__ *fd) +{ + return (SANE_STATUS_UNSUPPORTED); +} + +SANE_Status +sane_set_io_mode(SANE_Handle __sane_unused__ handle, SANE_Bool __sane_unused__ non_blocking) +{ + return (SANE_STATUS_UNSUPPORTED); +} diff --git a/backend/escl/escl.h b/backend/escl/escl.h new file mode 100644 index 0000000..82910bd --- /dev/null +++ b/backend/escl/escl.h @@ -0,0 +1,171 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + + +#ifndef __ESCL_H__ +#define __ESCL_H__ + +#include "../include/sane/config.h" + +#if !(HAVE_LIBCURL && defined(WITH_AVAHI) && defined(HAVE_LIBXML2)) +#error "The escl backend requires libcurl, libavahi and libxml2" +#endif + +#ifndef HAVE_LIBJPEG +/* FIXME: Make JPEG support optional. + Support for PNG and PDF is to be added later but currently only + JPEG is supported. Absence of JPEG support makes the backend a + no-op at present. + */ +#error "The escl backend currently requires libjpeg" +#endif + +#include "../include/sane/sane.h" + +#include <stdio.h> + +#ifndef BACKEND_NAME +#define BACKEND_NAME escl +#endif + +#define DEBUG_NOT_STATIC +#include "../include/sane/sanei_debug.h" + +#ifndef DBG_LEVEL +#define DBG_LEVEL PASTE(sanei_debug_, BACKEND_NAME) +#endif +#ifndef NDEBUG +# define DBGDUMP(level, buf, size) \ + do { if (DBG_LEVEL >= (level)) sanei_escl_dbgdump(buf, size); } while (0) +#else +# define DBGDUMP(level, buf, size) +#endif + +#define ESCL_CONFIG_FILE "escl.conf" + +typedef struct { + int p1_0; + int p2_0; + int p3_3; + int DocumentType; + int p4_0; + int p5_0; + int p6_1; + int reserve[11]; +} ESCL_SCANOPTS; + + +typedef struct ESCL_Device { + struct ESCL_Device *next; + + char *model_name; + int port_nb; + char *ip_address; + char *type; +} ESCL_Device; + +typedef struct capabilities +{ + int height; + int width; + int pos_x; + int pos_y; + SANE_String default_color; + SANE_String default_format; + SANE_Int default_resolution; + int MinWidth; + int MaxWidth; + int MinHeight; + int MaxHeight; + int MaxScanRegions; + SANE_String_Const *ColorModes; + int ColorModesSize; + SANE_String_Const *ContentTypes; + int ContentTypesSize; + SANE_String_Const *DocumentFormats; + int DocumentFormatsSize; + SANE_Int *SupportedResolutions; + int SupportedResolutionsSize; + SANE_String_Const *SupportedIntents; + int SupportedIntentsSize; + SANE_String_Const SupportedIntentDefault; + int MaxOpticalXResolution; + int RiskyLeftMargin; + int RiskyRightMargin; + int RiskyTopMargin; + int RiskyBottomMargin; + FILE *tmp; + unsigned char *img_data; + long img_size; + long img_read; + int format_ext; +} capabilities_t; + +typedef struct { + int XRes; + int YRes; + int Left; + int Top; + int Right; + int Bottom; + int ScanMode; + int ScanMethod; + ESCL_SCANOPTS opts; +} ESCL_ScanParam; + + +enum +{ + OPT_NUM_OPTS = 0, + OPT_MODE_GROUP, + OPT_MODE, + OPT_RESOLUTION, + OPT_PREVIEW, + OPT_GRAY_PREVIEW, + + OPT_GEOMETRY_GROUP, + OPT_TL_X, + OPT_TL_Y, + OPT_BR_X, + OPT_BR_Y, + NUM_OPTIONS +}; + +ESCL_Device *escl_devices(SANE_Status *status); +SANE_Status escl_device_add(int port_nb, const char *model_name, char *ip_address, char *type); +SANE_Status escl_status(SANE_String_Const name); +capabilities_t *escl_capabilities(SANE_String_Const name, SANE_Status *status); +char *escl_newjob(capabilities_t *scanner, SANE_String_Const name, SANE_Status *status); +SANE_Status escl_scan(capabilities_t *scanner, SANE_String_Const name, char *result); +void escl_scanner(SANE_String_Const name, char *result); + +// JPEG +SANE_Status get_JPEG_data(capabilities_t *scanner, int *w, int *h, int *bps); + +// PNG +SANE_Status get_PNG_data(capabilities_t *scanner, int *w, int *h, int *bps); + +// TIFF +SANE_Status get_TIFF_data(capabilities_t *scanner, int *w, int *h, int *bps); + +#endif diff --git a/backend/escl/escl_capabilities.c b/backend/escl/escl_capabilities.c new file mode 100644 index 0000000..690ff1e --- /dev/null +++ b/backend/escl/escl_capabilities.c @@ -0,0 +1,377 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <curl/curl.h> +#include <libxml/parser.h> + +#include "../include/sane/saneopts.h" + +struct cap +{ + char *memory; + size_t size; +}; + +/** + * \fn static SANE_String_Const convert_elements(SANE_String_Const str) + * \brief Function that converts the 'color modes' of the scanner (color/gray) to be understood by SANE. + * + * \return SANE_VALUE_SCAN_MODE_GRAY / SANE_VALUE_SCAN_MODE_COLOR ; NULL otherwise + */ +static SANE_String_Const +convert_elements(SANE_String_Const str) +{ + if (strcmp(str, "Grayscale8") == 0) + return (SANE_VALUE_SCAN_MODE_GRAY); + else if (strcmp(str, "RGB24") == 0) + return (SANE_VALUE_SCAN_MODE_COLOR); + return (NULL); +} + +/** + * \fn static SANE_String_Const *char_to_array(SANE_String_Const *tab, int *tabsize, SANE_String_Const mode, int good_array) + * \brief Function that creates the character arrays to put inside : + * the 'color modes', the 'content types', the 'document formats' and the 'supported intents'. + * + * \return board (the allocated array) + */ +static SANE_String_Const * +char_to_array(SANE_String_Const *tab, int *tabsize, SANE_String_Const mode, int good_array) +{ + SANE_String_Const *board = NULL; + int i = 0; + SANE_String_Const convert = NULL; + + if (mode == NULL) + return (tab); + if (good_array != 0) { + convert = convert_elements(mode); + if (convert == NULL) + return (tab); + } + else + convert = mode; + for (i = 0; i < (*tabsize); i++) { + if (strcmp(tab[i], convert) == 0) + return (tab); + } + (*tabsize)++; + if (*tabsize == 1) + board = (SANE_String_Const *)malloc(sizeof(SANE_String_Const) * (*tabsize) + 1); + else + board = (SANE_String_Const *)realloc(tab, sizeof(SANE_String_Const) * (*tabsize) + 1); + board[*tabsize - 1] = (SANE_String_Const)strdup(convert); + board[*tabsize] = NULL; + return (board); +} + +/** + * \fn static SANE_Int *int_to_array(SANE_Int *tab, int *tabsize, int cont) + * \brief Function that creates the integer array to put inside the 'supported resolutions'. + * + * \return board (the allocated array) + */ +static SANE_Int * +int_to_array(SANE_Int *tab, int *tabsize, int cont) +{ + SANE_Int *board = NULL; + int i = 0; + + for (i = 0; i < (*tabsize); i++) { + if (tab[i] == cont) + return (tab); + } + (*tabsize)++; + if (*tabsize == 1) { + (*tabsize)++; + board = malloc(sizeof(SANE_Int *) * (*tabsize) + 1); + } + else + board = realloc(tab, sizeof(SANE_Int *) * (*tabsize) + 1); + board[0] = *tabsize - 1; + board[*tabsize - 1] = cont; + board[*tabsize] = -1; + return (board); +} + +/** + * \fn static size_t memory_callback_c(void *contents, size_t size, size_t nmemb, void *userp) + * \brief Callback function that stocks in memory the content of the scanner capabilities. + * + * \return realsize (size of the content needed -> the scanner capabilities) + */ +static size_t +memory_callback_c(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct cap *mem = (struct cap *)userp; + + char *str = realloc(mem->memory, mem->size + realsize + 1); + if (str == NULL) { + fprintf(stderr, "not enough memory (realloc returned NULL)\n"); + return (0); + } + mem->memory = str; + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size = mem->size + realsize; + mem->memory[mem->size] = 0; + return (realsize); +} + +/** + * \fn static int find_nodes_c(xmlNode *node) + * \brief Function that browses the xml file and parses it, to find the xml children node. + * --> to recover the scanner capabilities. + * + * \return 0 if a xml child node is found, 1 otherwise + */ +static int +find_nodes_c(xmlNode *node) +{ + xmlNode *child = node->children; + + while (child) { + if (child->type == XML_ELEMENT_NODE) + return (0); + child = child->next; + } + return (1); +} + +/** + * \fn static int find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner) + * \brief Function that searchs in the xml file if a scanner capabilitie stocked + * in one of the created array (character/integer array) is found. + * + * \return 0 + */ +static int +find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner) +{ + const char *name = (const char *)node->name; + if (strcmp(name, "ColorMode") == 0) + scanner->ColorModes = char_to_array(scanner->ColorModes, &scanner->ColorModesSize, (SANE_String_Const)xmlNodeGetContent(node), 1); + else if (strcmp(name, "ContentType") == 0) + scanner->ContentTypes = char_to_array(scanner->ContentTypes, &scanner->ContentTypesSize, (SANE_String_Const)xmlNodeGetContent(node), 0); + else if (strcmp(name, "DocumentFormat") == 0) + { + int i = 0; + scanner->DocumentFormats = char_to_array(scanner->DocumentFormats, &scanner->DocumentFormatsSize, (SANE_String_Const)xmlNodeGetContent(node), 0); + for(; i < scanner->DocumentFormatsSize; i++) + { + if (scanner->default_format == NULL && !strcmp(scanner->DocumentFormats[i], "image/jpeg")) + { + scanner->default_format = strdup("image/jpeg"); + } +#if(defined HAVE_LIBPNG) + else if(!strcmp(scanner->DocumentFormats[i], "image/png") && (scanner->default_format == NULL || strcmp(scanner->default_format, "image/tiff"))) + { + if (scanner->default_format) + free(scanner->default_format); + scanner->default_format = strdup("image/png"); + } +#endif +#if(defined HAVE_TIFFIO_H) + else if(!strcmp(scanner->DocumentFormats[i], "image/tiff")) + { + if (scanner->default_format) + free(scanner->default_format); + scanner->default_format = strdup("image/tiff"); + } +#endif + } + fprintf(stderr, "Capability : [%s]\n", scanner->default_format); + } + else if (strcmp(name, "DocumentFormatExt") == 0) + scanner->format_ext = 1; + else if (strcmp(name, "Intent") == 0) + scanner->SupportedIntents = char_to_array(scanner->SupportedIntents, &scanner->SupportedIntentsSize, (SANE_String_Const)xmlNodeGetContent(node), 0); + else if (strcmp(name, "XResolution") == 0) + scanner->SupportedResolutions = int_to_array(scanner->SupportedResolutions, &scanner->SupportedResolutionsSize, atoi((const char *)xmlNodeGetContent(node))); + return (0); +} + +/** + * \fn static int find_value_of_int_variables(xmlNode *node, capabilities_t *scanner) + * \brief Function that searchs in the xml file if a integer scanner capabilitie is found. + * The integer scanner capabilities that are interesting are : + * MinWidth, MaxWidth, MaxHeight, MinHeight, MaxScanRegions, MaxOpticalXResolution, + * RiskyLeftMargin, RiskyRightMargin, RiskyTopMargin, RiskyBottomMargin. + * + * \return 0 + */ +static int +find_value_of_int_variables(xmlNode *node, capabilities_t *scanner) +{ + int MaxWidth = 0; + int MaxHeight = 0; + const char *name = (const char *)node->name; + + if (strcmp(name, "MinWidth") == 0) + scanner->MinWidth = atoi((const char*)xmlNodeGetContent(node)); + else if (strcmp(name, "MaxWidth") == 0) { + MaxWidth = atoi((const char*)xmlNodeGetContent(node)); + if (scanner->MaxWidth == 0 || MaxWidth < scanner->MaxWidth) + scanner->MaxWidth = atoi((const char *)xmlNodeGetContent(node)); + } + else if (strcmp(name, "MinHeight") == 0) + scanner->MinHeight = atoi((const char*)xmlNodeGetContent(node)); + else if (strcmp(name, "MaxHeight") == 0) { + MaxHeight = atoi((const char*)xmlNodeGetContent(node)); + if (scanner->MaxHeight == 0 || MaxHeight < scanner->MaxHeight) + scanner->MaxHeight = atoi((const char *)xmlNodeGetContent(node)); + } + else if (strcmp(name, "MaxScanRegions") == 0) + scanner->MaxScanRegions = atoi((const char *)xmlNodeGetContent(node)); + else if (strcmp(name, "MaxOpticalXResolution") == 0) + scanner->MaxOpticalXResolution = atoi((const char *)xmlNodeGetContent(node)); + else if (strcmp(name, "RiskyLeftMargin") == 0) + scanner->RiskyLeftMargin = atoi((const char *)xmlNodeGetContent(node)); + else if (strcmp(name, "RiskyRightMargin") == 0) + scanner->RiskyRightMargin = atoi((const char *)xmlNodeGetContent(node)); + else if (strcmp(name, "RiskyTopMargin") == 0) + scanner->RiskyTopMargin = atoi((const char *)xmlNodeGetContent(node)); + else if (strcmp(name, "RiskyBottomMargin") == 0) + scanner->RiskyBottomMargin = atoi((const char *)xmlNodeGetContent(node)); + find_valor_of_array_variables(node, scanner); + return (0); +} + +/** + * \fn static int find_true_variables(xmlNode *node, capabilities_t *scanner) + * \brief Function that searchs in the xml file if we find a scanner capabilitie stocked + * in one of the created array (character/integer array), + * or, if we find a integer scanner capabilitie. + * + * \return 0 + */ +static int +find_true_variables(xmlNode *node, capabilities_t *scanner) +{ + const char *name = (const char *)node->name; + if (strcmp(name, "MinWidth") == 0 || + strcmp(name, "MaxWidth") == 0 || + strcmp(name, "MinHeight") == 0 || + strcmp(name, "MaxHeight") == 0 || + strcmp(name, "MaxScanRegions") == 0 || + strcmp(name, "ColorMode") == 0 || + strcmp(name, "ContentType") == 0 || + strcmp(name, "DocumentFormat") == 0 || + strcmp(name, "XResolution") == 0 || + strcmp(name, "Intent") == 0 || + strcmp(name, "MaxOpticalXResolution") == 0 || + strcmp(name, "RiskyLeftMargin") == 0 || + strcmp(name, "RiskyRightMargin") == 0 || + strcmp(name, "RiskyTopMargin") == 0 || + strcmp(name, "RiskyBottomMargin") == 0 || + strcmp(name, "DocumentFormatExt") == 0) + find_value_of_int_variables(node, scanner); + return (0); +} + +/** + * \fn static int print_xml_c(xmlNode *node, capabilities_t *scanner) + * \brief Function that browses the xml file, node by node. + * + * \return 0 + */ +static int +print_xml_c(xmlNode *node, capabilities_t *scanner) +{ + while (node) { + if (node->type == XML_ELEMENT_NODE) { + if (find_nodes_c(node)) + find_true_variables(node, scanner); + } + print_xml_c(node->children, scanner); + node = node->next; + } + return (0); +} + +/** + * \fn capabilities_t *escl_capabilities(SANE_String_Const name, SANE_Status *status) + * \brief Function that finally recovers all the capabilities of the scanner, using curl. + * This function is called in the 'sane_open' function and it's the equivalent of + * the following curl command : "curl http(s)://'ip':'port'/eSCL/ScannerCapabilities". + * + * \return scanner (the structure that stocks all the capabilities elements) + */ +capabilities_t * +escl_capabilities(SANE_String_Const name, SANE_Status *status) +{ + capabilities_t *scanner = (capabilities_t*)calloc(1, sizeof(capabilities_t)); + CURL *curl_handle = NULL; + struct cap *var = NULL; + xmlDoc *data = NULL; + xmlNode *node = NULL; + const char *scanner_capabilities = "/eSCL/ScannerCapabilities"; + char tmp[PATH_MAX] = { 0 }; + + *status = SANE_STATUS_GOOD; + if (name == NULL) + *status = SANE_STATUS_NO_MEM; + var = (struct cap *)calloc(1, sizeof(struct cap)); + if (var == NULL) + *status = SANE_STATUS_NO_MEM; + var->memory = malloc(1); + var->size = 0; + curl_handle = curl_easy_init(); + strcpy(tmp, name); + strcat(tmp, scanner_capabilities); + DBG( 1, "Get Capabilities : %s\n", tmp); + curl_easy_setopt(curl_handle, CURLOPT_URL, tmp); + if (strncmp(name, "https", 5) == 0) { + DBG( 1, "Ignoring safety certificates, use https\n"); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); + } + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_c); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var); + if (curl_easy_perform(curl_handle) != CURLE_OK) { + DBG( 1, "The scanner didn't respond.\n"); + *status = SANE_STATUS_INVAL; + } + data = xmlReadMemory(var->memory, var->size, "file.xml", NULL, 0); + if (data == NULL) + *status = SANE_STATUS_NO_MEM; + node = xmlDocGetRootElement(data); + if (node == NULL) + *status = SANE_STATUS_NO_MEM; + print_xml_c(node, scanner); + xmlFreeDoc(data); + xmlCleanupParser(); + xmlMemoryDump(); + curl_easy_cleanup(curl_handle); + free(var->memory); + return (scanner); +} diff --git a/backend/escl/escl_devices.c b/backend/escl/escl_devices.c new file mode 100644 index 0000000..7ecbe31 --- /dev/null +++ b/backend/escl/escl_devices.c @@ -0,0 +1,185 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <avahi-client/lookup.h> +#include <avahi-common/error.h> +#include <avahi-common/simple-watch.h> + +#include "../include/sane/sanei.h" + +static AvahiSimplePoll *simple_poll = NULL; + +/** + * \fn static void resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED + * AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, + * AvahiResolverEvent event, const char *name, + * const char *type, const char *domain, const char *host_name, + * const AvahiAddress *address, uint16_t port, + * AvahiStringList *txt, AvahiLookupResultFlags flags, + * void *userdata) + * \brief Callback function that will check if the selected scanner follows the escl + * protocol or not. + */ +static void +resolve_callback(AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiIfIndex interface, + AVAHI_GCC_UNUSED AvahiProtocol protocol, + AvahiResolverEvent event, const char *name, + const char __sane_unused__ *type, + const char __sane_unused__ *domain, + const char __sane_unused__ *host_name, + const AvahiAddress *address, uint16_t port, AvahiStringList *txt, + AvahiLookupResultFlags __sane_unused__ flags, + void __sane_unused__ *userdata) +{ + char a[AVAHI_ADDRESS_STR_MAX], *t; + assert(r); + switch (event) { + case AVAHI_RESOLVER_FAILURE: + break; + case AVAHI_RESOLVER_FOUND: + avahi_address_snprint(a, sizeof(a), address); + t = avahi_string_list_to_string(txt); + if (strstr(t, "\"rs=eSCL\"") || strstr(t, "\"rs=/eSCL\"")) + escl_device_add(port, name, a, (char*)type); + } +} + +/** + * \fn static void browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, + * AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, + * const char *type, const char *domain, + * AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) + * \brief Callback function that will browse tanks to 'avahi' the scanners + * connected in network. + */ +static void +browse_callback(AvahiServiceBrowser *b, AvahiIfIndex interface, + AvahiProtocol protocol, AvahiBrowserEvent event, + const char *name, const char *type, + const char *domain, + AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, + void* userdata) +{ + AvahiClient *c = userdata; + assert(b); + switch (event) { + case AVAHI_BROWSER_FAILURE: + avahi_simple_poll_quit(simple_poll); + return; + case AVAHI_BROWSER_NEW: + if (!(avahi_service_resolver_new(c, interface, protocol, name, + type, domain, + AVAHI_PROTO_UNSPEC, 0, + resolve_callback, c))) + break; + case AVAHI_BROWSER_REMOVE: + break; + case AVAHI_BROWSER_ALL_FOR_NOW: + case AVAHI_BROWSER_CACHE_EXHAUSTED: + if (event != AVAHI_BROWSER_CACHE_EXHAUSTED) + avahi_simple_poll_quit(simple_poll); + break; + } +} + +/** + * \fn static void client_callback(AvahiClient *c, AvahiClientState state, + * AVAHI_GCC_UNUSED void *userdata) + * \brief Callback Function that quit if it doesn't find a connected scanner, + * possible thanks the "Hello Protocol". + * --> Waiting for a answer by the scanner to continue the avahi process. + */ +static void +client_callback(AvahiClient *c, AvahiClientState state, + AVAHI_GCC_UNUSED void *userdata) +{ + assert(c); + if (state == AVAHI_CLIENT_FAILURE) + avahi_simple_poll_quit(simple_poll); +} + +/** + * \fn ESCL_Device *escl_devices(SANE_Status *status) + * \brief Function that calls all the avahi functions and then, recovers the + * connected eSCL devices. + * This function is called in the 'sane_get_devices' function. + * + * \return NULL (the eSCL devices found) + */ +ESCL_Device * +escl_devices(SANE_Status *status) +{ + AvahiClient *client = NULL; + AvahiServiceBrowser *sb = NULL; + int error; + + *status = SANE_STATUS_GOOD; + if (!(simple_poll = avahi_simple_poll_new())) { + DBG( 1, "Failed to create simple poll object.\n"); + *status = SANE_STATUS_INVAL; + goto fail; + } + client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, + client_callback, NULL, &error); + if (!client) { + DBG( 1, "Failed to create client: %s\n", avahi_strerror(error)); + *status = SANE_STATUS_INVAL; + goto fail; + } + if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, "_uscan._tcp", + NULL, 0, browse_callback, client))) { + DBG( 1, "Failed to create service browser: %s\n", + avahi_strerror(avahi_client_errno(client))); + *status = SANE_STATUS_INVAL; + goto fail; + } + if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_uscans._tcp", NULL, 0, + browse_callback, client))) { + DBG( 1, "Failed to create service browser: %s\n", + avahi_strerror(avahi_client_errno(client))); + *status = SANE_STATUS_INVAL; + goto fail; + } + avahi_simple_poll_loop(simple_poll); +fail: + if (sb) + avahi_service_browser_free(sb); + if (client) + avahi_client_free(client); + if (simple_poll) + avahi_simple_poll_free(simple_poll); + return (NULL); +} diff --git a/backend/escl/escl_jpeg.c b/backend/escl/escl_jpeg.c new file mode 100644 index 0000000..d6287ef --- /dev/null +++ b/backend/escl/escl_jpeg.c @@ -0,0 +1,230 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include "../include/sane/sanei.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if(defined HAVE_LIBJPEG) +# include <jpeglib.h> +#endif + +#include <setjmp.h> + +#define INPUT_BUFFER_SIZE 4096 + +#if(defined HAVE_LIBJPEG) +struct my_error_mgr +{ + struct jpeg_error_mgr errmgr; + jmp_buf escape; +}; + +typedef struct +{ + struct jpeg_source_mgr pub; + FILE *ctx; + unsigned char buffer[INPUT_BUFFER_SIZE]; +} my_source_mgr; + +/** + * \fn static boolean fill_input_buffer(j_decompress_ptr cinfo) + * \brief Called in the "skip_input_data" function. + * + * \return TRUE (everything is OK) + */ +static boolean +fill_input_buffer(j_decompress_ptr cinfo) +{ + my_source_mgr *src = (my_source_mgr *) cinfo->src; + int nbytes = 0; + + nbytes = fread(src->buffer, 1, INPUT_BUFFER_SIZE, src->ctx); + if (nbytes <= 0) { + src->buffer[0] = (unsigned char) 0xFF; + src->buffer[1] = (unsigned char) JPEG_EOI; + nbytes = 2; + } + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + return (TRUE); +} + +/** + * \fn static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) + * \brief Called in the "jpeg_RW_src" function. + */ +static void +skip_input_data(j_decompress_ptr cinfo, long num_bytes) +{ + my_source_mgr *src = (my_source_mgr *) cinfo->src; + + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) src->pub.fill_input_buffer(cinfo); + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void +term_source(j_decompress_ptr __sane_unused__ cinfo) +{ + return; +} + +static void +init_source(j_decompress_ptr __sane_unused__ cinfo) +{ + return; +} + +/** + * \fn static void jpeg_RW_src(j_decompress_ptr cinfo, FILE *ctx) + * \brief Called in the "escl_sane_decompressor" function. + */ +static void +jpeg_RW_src(j_decompress_ptr cinfo, FILE *ctx) +{ + my_source_mgr *src; + + if (cinfo->src == NULL) { + cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) + ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(my_source_mgr)); + src = (my_source_mgr *) cinfo->src; + } + src = (my_source_mgr *) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; + src->pub.term_source = term_source; + src->ctx = ctx; + src->pub.bytes_in_buffer = 0; + src->pub.next_input_byte = NULL; +} + +static void +my_error_exit(j_common_ptr cinfo) +{ + struct my_error_mgr *err = (struct my_error_mgr *)cinfo->err; + + longjmp(err->escape, 1); +} + +static void +output_no_message(j_common_ptr __sane_unused__ cinfo) +{ +} + +/** + * \fn SANE_Status escl_sane_decompressor(escl_sane_t *handler) + * \brief Function that aims to decompress the jpeg image to SANE be able to read the image. + * This function is called in the "sane_read" function. + * + * \return SANE_STATUS_GOOD (if everything is OK, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +get_JPEG_data(capabilities_t *scanner, int *w, int *h, int *bps) +{ + int start = 0; + struct jpeg_decompress_struct cinfo; + JSAMPROW rowptr[1]; + unsigned char *surface = NULL; + struct my_error_mgr jerr; + int lineSize = 0; + + if (scanner->tmp == NULL) + return (SANE_STATUS_INVAL); + fseek(scanner->tmp, SEEK_SET, 0); + start = ftell(scanner->tmp); + cinfo.err = jpeg_std_error(&jerr.errmgr); + jerr.errmgr.error_exit = my_error_exit; + jerr.errmgr.output_message = output_no_message; + if (setjmp(jerr.escape)) { + jpeg_destroy_decompress(&cinfo); + if (surface != NULL) + free(surface); + DBG( 1, "Escl Jpeg : Error reading jpeg\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + jpeg_create_decompress(&cinfo); + jpeg_RW_src(&cinfo, scanner->tmp); + jpeg_read_header(&cinfo, TRUE); + cinfo.out_color_space = JCS_RGB; + cinfo.quantize_colors = FALSE; + jpeg_calc_output_dimensions(&cinfo); + surface = malloc(cinfo.output_width * cinfo.output_height * cinfo.output_components); + if (surface == NULL) { + jpeg_destroy_decompress(&cinfo); + fseek(scanner->tmp, start, SEEK_SET); + DBG( 1, "Escl Jpeg : Memory allocation problem\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_NO_MEM); + } + lineSize = cinfo.output_width * cinfo.output_components; + jpeg_start_decompress(&cinfo); + while (cinfo.output_scanline < cinfo.output_height) { + rowptr[0] = (JSAMPROW)surface + (lineSize * cinfo.output_scanline); + jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1); + } + scanner->img_data = surface; + scanner->img_size = lineSize * cinfo.output_height; + scanner->img_read = 0; + *w = cinfo.output_width; + *h = cinfo.output_height; + *bps = cinfo.output_components; + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(scanner->tmp); + scanner->tmp = NULL; + return (SANE_STATUS_GOOD); +} +#else + +SANE_Status +get_JPEG_data(capabilities_t __sane_unused__ *scanner, + int __sane_unused__ *w, + int __sane_unused__ *h, + int __sane_unused__ *bps) +{ + return (SANE_STATUS_INVAL); +} + +#endif diff --git a/backend/escl/escl_newjob.c b/backend/escl/escl_newjob.c new file mode 100644 index 0000000..279b9df --- /dev/null +++ b/backend/escl/escl_newjob.c @@ -0,0 +1,241 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <curl/curl.h> + +#ifdef PATH_MAX +# undef PATH_MAX +#endif + +#define PATH_MAX 4096 + +struct uploading +{ + const char *read_data; + size_t size; +}; + +struct downloading +{ + char *memory; + size_t size; +}; + +static const char settings[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \ + "<scan:ScanSettings xmlns:pwg=\"http://www.pwg.org/schemas/2010/12/sm\" xmlns:scan=\"http://schemas.hp.com/imaging/escl/2011/05/03\">" \ + " <pwg:Version>2.0</pwg:Version>" \ + " <pwg:ScanRegions>" \ + " <pwg:ScanRegion>" \ + " <pwg:ContentRegionUnits>escl:ThreeHundredthsOfInches</pwg:ContentRegionUnits>" \ + " <pwg:Height>%d</pwg:Height>" \ + " <pwg:Width>%d</pwg:Width>" \ + " <pwg:XOffset>%d</pwg:XOffset>" \ + " <pwg:YOffset>%d</pwg:YOffset>" \ + " </pwg:ScanRegion>" \ + " </pwg:ScanRegions>" \ + " <pwg:DocumentFormat>%s</pwg:DocumentFormat>" \ + "%s" \ + " <scan:ColorMode>%s</scan:ColorMode>" \ + " <scan:XResolution>%d</scan:XResolution>" \ + " <scan:YResolution>%d</scan:YResolution>" \ + " <pwg:InputSource>Platen</pwg:InputSource>" \ + "</scan:ScanSettings>"; + +static char formatExtJPEG[] = + " <scan:DocumentFormatExt>image/jpeg</scan:DocumentFormatExt>"; + +static char formatExtPNG[] = + " <scan:DocumentFormatExt>image/png</scan:DocumentFormatExt>"; + +static char formatExtTIFF[] = + " <scan:DocumentFormatExt>image/tiff</scan:DocumentFormatExt>"; + +/** + * \fn static size_t download_callback(void *str, size_t size, size_t nmemb, void *userp) + * \brief Callback function that stocks in memory the content of the 'job'. Example below : + * "Trying 192.168.14.150... + * TCP_NODELAY set + * Connected to 192.168.14.150 (192.168.14.150) port 80 + * POST /eSCL/ScanJobs HTTP/1.1 + * Host: 192.168.14.150 + * User-Agent: curl/7.55.1 + * Accept: / + * Content-Length: 605 + * Content-Type: application/x-www-form-urlencoded + * upload completely sent off: 605 out of 605 bytes + * < HTTP/1.1 201 Created + * < MIME-Version: 1.0 + * < Location: http://192.168.14.150/eSCL/ScanJobs/22b54fd0-027b-1000-9bd0-f4a99726e2fa + * < Content-Length: 0 + * < Connection: close + * < + * Closing connection 0" + * + * \return realsize (size of the content needed -> the 'job') + */ +static size_t +download_callback(void *str, size_t size, size_t nmemb, void *userp) +{ + struct downloading *download = (struct downloading *)userp; + size_t realsize = size * nmemb; + char *content = realloc(download->memory, download->size + realsize + 1); + + if (content == NULL) { + DBG( 1, "Not enough memory (realloc returned NULL)\n"); + return (0); + } + download->memory = content; + memcpy(&(download->memory[download->size]), str, realsize); + download->size = download->size + realsize; + download->memory[download->size] = 0; + return (realsize); +} + +/** + * \fn char *escl_newjob (capabilities_t *scanner, SANE_String_Const name, SANE_Status *status) + * \brief Function that, using curl, uploads the data (composed by the scanner capabilities) to the + * server to download the 'job' and recover the 'new job' (char *result), in LOCATION. + * This function is called in the 'sane_start' function and it's the equivalent of the + * following curl command : "curl -v POST -d cap.xml http(s)://'ip':'port'/eSCL/ScanJobs". + * + * \return result (the 'new job', situated in LOCATION) + */ +char * +escl_newjob (capabilities_t *scanner, SANE_String_Const name, SANE_Status *status) +{ + CURL *curl_handle = NULL; + struct uploading *upload = NULL; + struct downloading *download = NULL; + const char *scan_jobs = "/eSCL/ScanJobs"; + char cap_data[PATH_MAX] = { 0 }; + char job_cmd[PATH_MAX] = { 0 }; + char *location = NULL; + char *result = NULL; + char *temporary = NULL; + char *f_ext = ""; + char *format_ext = NULL; + + *status = SANE_STATUS_GOOD; + if (name == NULL || scanner == NULL) { + *status = SANE_STATUS_NO_MEM; + DBG( 1, "Create NewJob : the name or the scan are invalid.\n"); + return (NULL); + } + upload = (struct uploading *)calloc(1, sizeof(struct uploading)); + if (upload == NULL) { + *status = SANE_STATUS_NO_MEM; + DBG( 1, "Create NewJob : memory allocation failure\n"); + return (NULL); + } + download = (struct downloading *)calloc(1, sizeof(struct downloading)); + if (download == NULL) { + free(upload); + DBG( 1, "Create NewJob : memory allocation failure\n"); + *status = SANE_STATUS_NO_MEM; + return (NULL); + } + curl_handle = curl_easy_init(); + if (scanner->format_ext == 1) + { + if (!strcmp(scanner->default_format, "image/jpeg")) + format_ext = formatExtJPEG; + else if (!strcmp(scanner->default_format, "image/png")) + format_ext = formatExtPNG; + else if (!strcmp(scanner->default_format, "image/tiff")) + format_ext = formatExtTIFF; + else + format_ext = f_ext; + } + else + format_ext = f_ext; + DBG( 1, "Create NewJob : %s\n", scanner->default_format); + if (curl_handle != NULL) { + snprintf(cap_data, sizeof(cap_data), settings, scanner->height, scanner->width, 0, 0, scanner->default_format, + format_ext, + scanner->default_color, scanner->default_resolution, scanner->default_resolution); + DBG( 1, "Create NewJob : %s\n", cap_data); + upload->read_data = strdup(cap_data); + upload->size = strlen(cap_data); + download->memory = malloc(1); + download->size = 0; + strcpy(job_cmd, name); + strcat(job_cmd, scan_jobs); + curl_easy_setopt(curl_handle, CURLOPT_URL, job_cmd); + if (strncmp(name, "https", 5) == 0) { + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); + } + curl_easy_setopt(curl_handle, CURLOPT_POST, 1L); + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, upload->read_data); + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, upload->size); + curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, download_callback); + curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)download); + if (curl_easy_perform(curl_handle) != CURLE_OK) { + DBG( 1, "Create NewJob : the scanner responded incorrectly.\n"); + *status = SANE_STATUS_INVAL; + } + else { + if (download->memory != NULL) { + if (strstr(download->memory, "Location:")) { + temporary = strrchr(download->memory, '/'); + if (temporary != NULL) { + location = strchr(temporary, '\r'); + if (location == NULL) + location = strchr(temporary, '\n'); + else { + *location = '\0'; + result = strdup(temporary); + } + DBG( 1, "Create NewJob : %s\n", result); + } + free(download->memory); + } + else { + DBG( 1, "Create NewJob : The creation of the failed job\n"); + *status = SANE_STATUS_INVAL; + } + } + else { + *status = SANE_STATUS_NO_MEM; + DBG( 1, "Create NewJob : The creation of the failed job\n"); + return (NULL); + } + } + curl_easy_cleanup(curl_handle); + } + if (upload != NULL) + free(upload); + if (download != NULL) + free(download); + return (result); +} diff --git a/backend/escl/escl_png.c b/backend/escl/escl_png.c new file mode 100644 index 0000000..18f6f35 --- /dev/null +++ b/backend/escl/escl_png.c @@ -0,0 +1,193 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include "../include/sane/sanei.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if(defined HAVE_LIBPNG) +#include <png.h> +#endif + +#include <setjmp.h> + + +#if(defined HAVE_LIBPNG) + +/** + * \fn SANE_Status escl_sane_decompressor(escl_sane_t *handler) + * \brief Function that aims to decompress the png image to SANE be able to read the image. + * This function is called in the "sane_read" function. + * + * \return SANE_STATUS_GOOD (if everything is OK, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +get_PNG_data(capabilities_t *scanner, int *w, int *h, int *components) +{ + unsigned int width = 0; /* largeur */ + unsigned int height = 0; /* hauteur */ + int bps = 3; /* composantes d'un texel */ + unsigned char *texels = NULL; /* données de l'image */ + unsigned int i = 0; + png_byte magic[8]; + + // read magic number + fread (magic, 1, sizeof (magic), scanner->tmp); + // check for valid magic number + if (!png_check_sig (magic, sizeof (magic))) + { + DBG( 1, "Escl Png : PNG error is not a valid PNG image!\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + // create a png read struct + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) + { + DBG( 1, "Escl Png : PNG error create a png read struct\n"); + if (scanner->tmp) + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + // create a png info struct + png_infop info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) + { + DBG( 1, "Escl Png : PNG error create a png info struct\n"); + png_destroy_read_struct (&png_ptr, NULL, NULL); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + // initialize the setjmp for returning properly after a libpng + // error occured + if (setjmp (png_jmpbuf (png_ptr))) + { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + if (texels) + free (texels); + fprintf(stderr,"PNG read error.\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + DBG( 1, "Escl Png : PNG read error.\n"); + return (SANE_STATUS_INVAL); + } + // setup libpng for using standard C fread() function + // with our FILE pointer + png_init_io (png_ptr, scanner->tmp); + // tell libpng that we have already read the magic number + png_set_sig_bytes (png_ptr, sizeof (magic)); + + // read png info + png_read_info (png_ptr, info_ptr); + + int bit_depth, color_type; + // get some usefull information from header + bit_depth = png_get_bit_depth (png_ptr, info_ptr); + color_type = png_get_color_type (png_ptr, info_ptr); + // convert index color images to RGB images + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb (png_ptr); + else if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA) + { + fprintf(stderr,"PNG format not supported.\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) + bps = 4; + else + bps = 3; + if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha (png_ptr); + if (bit_depth == 16) + png_set_strip_16 (png_ptr); + else if (bit_depth < 8) + png_set_packing (png_ptr); + // update info structure to apply transformations + png_read_update_info (png_ptr, info_ptr); + // retrieve updated information + png_get_IHDR (png_ptr, info_ptr, + (png_uint_32*)(&width), + (png_uint_32*)(&height), + &bit_depth, &color_type, + NULL, NULL, NULL); + + *w = (int)width; + *h = (int)height; + *components = bps; + // we can now allocate memory for storing pixel data + texels = (unsigned char *)malloc (sizeof (unsigned char) * width + * height * bps); + png_bytep *row_pointers; + // setup a pointer array. Each one points at the begening of a row. + row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * height); + for (i = 0; i < height; ++i) + { + row_pointers[i] = (png_bytep)(texels + + ((height - (i + 1)) * width * bps)); + } + // read pixel data using row pointers + png_read_image (png_ptr, row_pointers); + // we don't need row pointers anymore + scanner->img_data = texels; + scanner->img_size = (int)(width * height * bps); + scanner->img_read = 0; + free (row_pointers); + fclose(scanner->tmp); + scanner->tmp = NULL; + return (SANE_STATUS_GOOD); +} +#else + +SANE_Status +get_PNG_data(capabilities_t __sane_unused__ *scanner, + int __sane_unused__ *w, + int __sane_unused__ *h, + int __sane_unused__ *bps) +{ + return (SANE_STATUS_INVAL); +} + +#endif diff --git a/backend/escl/escl_reset.c b/backend/escl/escl_reset.c new file mode 100644 index 0000000..7722d89 --- /dev/null +++ b/backend/escl/escl_reset.c @@ -0,0 +1,75 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include <stdlib.h> +#include <string.h> + +#include <curl/curl.h> + +/** + * \fn void escl_scanner(SANE_String_Const name, char *result) + * \brief Function that resets the scanner after each scan, using curl. + * This function is called in the 'sane_cancel' function. + */ +void +escl_scanner(SANE_String_Const name, char *result) +{ + CURL *curl_handle = NULL; + const char *scan_jobs = "/eSCL/ScanJobs"; + const char *scanner_start = "/NextDocument"; + char scan_cmd[PATH_MAX] = { 0 }; + int i = 0; + long answer = 0; + + if (name == NULL || result == NULL) + return; +CURL_CALL: + curl_handle = curl_easy_init(); + if (curl_handle != NULL) { + strcpy(scan_cmd, name); + strcat(scan_cmd, scan_jobs); + strcat(scan_cmd, result); + strcat(scan_cmd, scanner_start); + curl_easy_setopt(curl_handle, CURLOPT_URL, scan_cmd); + DBG( 1, "Reset Job : %s.\n", scan_cmd); + if (strncmp(name, "https", 5) == 0) { + DBG( 1, "Ignoring safety certificates, use https\n"); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); + } + if (curl_easy_perform(curl_handle) == CURLE_OK) { + curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer); + if (i < 3 && answer == 503) { + curl_easy_cleanup(curl_handle); + i++; + goto CURL_CALL; + } + } + curl_easy_cleanup(curl_handle); + } +} diff --git a/backend/escl/escl_scan.c b/backend/escl/escl_scan.c new file mode 100644 index 0000000..8f077a1 --- /dev/null +++ b/backend/escl/escl_scan.c @@ -0,0 +1,99 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <curl/curl.h> + +#include "../include/sane/sanei.h" + +/** + * \fn static size_t write_callback(void *str, size_t size, size_t nmemb, void *userp) + * \brief Callback function that writes the image scanned into the temporary file. + * + * \return to_write (the result of the fwrite fonction) + */ +static size_t +write_callback(void *str, size_t size, size_t nmemb, void *userp) +{ + size_t to_write = fwrite(str, size, nmemb, (FILE *)userp); + + return (to_write); +} + +/** + * \fn SANE_Status escl_scan(capabilities_t *scanner, SANE_String_Const name, char *result) + * \brief Function that, after recovering the 'new job', scans the image writed in the + * temporary file, using curl. + * This function is called in the 'sane_start' function and it's the equivalent of + * the following curl command : "curl -s http(s)://'ip:'port'/eSCL/ScanJobs/'new job'/NextDocument > image.jpg". + * + * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +escl_scan(capabilities_t __sane_unused__ *scanner, SANE_String_Const name, char *result) +{ + CURL *curl_handle = NULL; + const char *scan_jobs = "/eSCL/ScanJobs"; + const char *scanner_start = "/NextDocument"; + char scan_cmd[PATH_MAX] = { 0 }; + SANE_Status status = SANE_STATUS_GOOD; + + if (name == NULL) + return (SANE_STATUS_NO_MEM); + curl_handle = curl_easy_init(); + if (curl_handle != NULL) { + strcpy(scan_cmd, name); + strcat(scan_cmd, scan_jobs); + strcat(scan_cmd, result); + strcat(scan_cmd, scanner_start); + curl_easy_setopt(curl_handle, CURLOPT_URL, scan_cmd); + DBG( 1, "Scan : %s.\n", scan_cmd); + if (strncmp(name, "https", 5) == 0) { + DBG( 1, "Ignoring safety certificates, use https\n"); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); + } + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback); + scanner->tmp = tmpfile(); + if (scanner->tmp != NULL) { + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, scanner->tmp); + if (curl_easy_perform(curl_handle) != CURLE_OK) { + status = SANE_STATUS_INVAL; + } + else + curl_easy_cleanup(curl_handle); + fseek(scanner->tmp, 0, SEEK_SET); + } + else + status = SANE_STATUS_NO_MEM; + } + return (status); +} diff --git a/backend/escl/escl_status.c b/backend/escl/escl_status.c new file mode 100644 index 0000000..68b51dc --- /dev/null +++ b/backend/escl/escl_status.c @@ -0,0 +1,176 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <curl/curl.h> +#include <libxml/parser.h> + +struct idle +{ + char *memory; + size_t size; +}; + +/** + * \fn static size_t memory_callback_s(void *contents, size_t size, size_t nmemb, void *userp) + * \brief Callback function that stocks in memory the content of the scanner status. + * + * \return realsize (size of the content needed -> the scanner status) + */ +static size_t +memory_callback_s(void *contents, size_t size, size_t nmemb, void *userp) +{ + size_t realsize = size * nmemb; + struct idle *mem = (struct idle *)userp; + + char *str = realloc(mem->memory, mem->size + realsize + 1); + if (str == NULL) { + DBG(1, "not enough memory (realloc returned NULL)\n"); + return (0); + } + mem->memory = str; + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size = mem->size + realsize; + mem->memory[mem->size] = 0; + return (realsize); +} + +/** + * \fn static int find_nodes_s(xmlNode *node) + * \brief Function that browses the xml file and parses it, to find the xml children node. + * --> to recover the scanner status. + * + * \return 0 if a xml child node is found, 1 otherwise + */ +static int +find_nodes_s(xmlNode *node) +{ + xmlNode *child = node->children; + + while (child) { + if (child->type == XML_ELEMENT_NODE) + return (0); + child = child->next; + } + return (1); +} + +/** + * \fn static void print_xml_s(xmlNode *node, SANE_Status *status) + * \brief Function that browses the xml file, node by node. + * If the node 'State' is found, we are expecting to found in this node the 'Idle' + * content (if the scanner is ready to use) and then 'status' = SANE_STATUS_GOOD. + * Otherwise, this means that the scanner isn't ready to use. + */ +static void +print_xml_s(xmlNode *node, SANE_Status *status) +{ + int x = 0; + + while (node) { + if (node->type == XML_ELEMENT_NODE) { + if (find_nodes_s(node)) { + if (strcmp((const char *)node->name, "State") == 0) + x = 1; + } + if (x == 1 && strcmp((const char *)xmlNodeGetContent(node), "Idle") == 0) + *status = SANE_STATUS_GOOD; + } + print_xml_s(node->children, status); + node = node->next; + } +} + +/** + * \fn SANE_Status escl_status(SANE_String_Const name) + * \brief Function that finally recovers the scanner status ('Idle', or not), using curl. + * This function is called in the 'sane_open' function and it's the equivalent of + * the following curl command : "curl http(s)://'ip':'port'/eSCL/ScannerStatus". + * + * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +escl_status(SANE_String_Const name) +{ + SANE_Status status; + CURL *curl_handle = NULL; + struct idle *var = NULL; + xmlDoc *data = NULL; + xmlNode *node = NULL; + const char *scanner_status = "/eSCL/ScannerStatus"; + char tmp[PATH_MAX] = { 0 }; + + if (name == NULL) + return (SANE_STATUS_NO_MEM); + var = (struct idle*)calloc(1, sizeof(struct idle)); + if (var == NULL) + return (SANE_STATUS_NO_MEM); + var->memory = malloc(1); + var->size = 0; + curl_handle = curl_easy_init(); + strcpy(tmp, name); + strcat(tmp, scanner_status); + curl_easy_setopt(curl_handle, CURLOPT_URL, tmp); + DBG( 1, "Get Status : %s.\n", tmp); + if (strncmp(name, "https", 5) == 0) { + DBG( 1, "Ignoring safety certificates, use https\n"); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L); + } + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_s); + curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var); + if (curl_easy_perform(curl_handle) != CURLE_OK) { + DBG( 1, "The scanner didn't respond.\n"); + status = SANE_STATUS_INVAL; + goto clean_data; + } + data = xmlReadMemory(var->memory, var->size, "file.xml", NULL, 0); + if (data == NULL) { + status = SANE_STATUS_NO_MEM; + goto clean_data; + } + node = xmlDocGetRootElement(data); + if (node == NULL) { + status = SANE_STATUS_NO_MEM; + goto clean; + } + status = SANE_STATUS_DEVICE_BUSY; + print_xml_s(node, &status); +clean: + xmlFreeDoc(data); +clean_data: + xmlCleanupParser(); + xmlMemoryDump(); + curl_easy_cleanup(curl_handle); + free(var->memory); + free(var); + return (status); +} diff --git a/backend/escl/escl_tiff.c b/backend/escl/escl_tiff.c new file mode 100644 index 0000000..52aec20 --- /dev/null +++ b/backend/escl/escl_tiff.c @@ -0,0 +1,119 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Touboul Nathane + Copyright (C) 2019 Thierry HUCHARD <thierry@ordissimo.com> + + This file is part of the SANE package. + + SANE is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + SANE is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with sane; see the file COPYING. If not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This file implements a SANE backend for eSCL scanners. */ + +#define DEBUG_DECLARE_ONLY +#include "../include/sane/config.h" + +#include "escl.h" + +#include "../include/sane/sanei.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#if(defined HAVE_TIFFIO_H) +#include <tiffio.h> +#endif + +#include <setjmp.h> + + +#if(defined HAVE_TIFFIO_H) + +/** + * \fn SANE_Status escl_sane_decompressor(escl_sane_t *handler) + * \brief Function that aims to decompress the png image to SANE be able to read the image. + * This function is called in the "sane_read" function. + * + * \return SANE_STATUS_GOOD (if everything is OK, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL) + */ +SANE_Status +get_TIFF_data(capabilities_t *scanner, int *w, int *h, int *components) +{ + TIFF* tif = NULL; + uint32 width = 0; /* largeur */ + uint32 height = 0; /* hauteur */ + unsigned char *raster = NULL; /* données de l'image */ + int bps = 4; + uint32 npixels = 0; + + lseek(fileno(scanner->tmp), 0, SEEK_SET); + tif = TIFFFdOpen(fileno(scanner->tmp), "temp", "r"); + if (!tif) { + DBG( 1, "Escl Tiff : Can not open, or not a TIFF file.\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); + npixels = width * height; + raster = (unsigned char*) malloc(npixels * sizeof (uint32)); + if (raster != NULL) + { + DBG( 1, "Escl Tiff : Memory allocation problem.\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + + if (!TIFFReadRGBAImage(tif, width, height, (uint32 *)raster, 0)) + { + DBG( 1, "Escl Tiff : Problem reading image data.\n"); + if (scanner->tmp) { + fclose(scanner->tmp); + scanner->tmp = NULL; + } + return (SANE_STATUS_INVAL); + } + *w = (int)width; + *h = (int)height; + *components = bps; + // we don't need row pointers anymore + scanner->img_data = raster; + scanner->img_size = (int)(width * height * bps); + scanner->img_read = 0; + TIFFClose(tif); + fclose(scanner->tmp); + scanner->tmp = NULL; + return (SANE_STATUS_GOOD); +} +#else + +SANE_Status +get_TIFF_data(capabilities_t __sane_unused__ *scanner, + int __sane_unused__ *w, + int __sane_unused__ *h, + int __sane_unused__ *bps) +{ + return (SANE_STATUS_INVAL); +} + +#endif diff --git a/backend/fujitsu.c b/backend/fujitsu.c index 3ac4c8e..5dc466c 100644 --- a/backend/fujitsu.c +++ b/backend/fujitsu.c @@ -6,7 +6,7 @@ Copyright (C) 2000 Randolph Bentson Copyright (C) 2001 Frederik Ramm Copyright (C) 2001-2004 Oliver Schirrmeister - Copyright (C) 2003-2016 m. allan noah + Copyright (C) 2003-2019 m. allan noah JPEG output and low memory usage support funded by: Archivista GmbH, www.archivista.ch @@ -603,6 +603,8 @@ v134 2019-02-23, MAN - rewrite init_vpd for scanners which fail to report overscan correctly + v135 2019-11-10, MAN + - set has_MS_lamp=0 for fi-72x0, bug #134 SANE FLOW DIAGRAM @@ -2404,6 +2406,8 @@ init_model (struct fujitsu *s) else if (strstr (s->model_name,"fi-7280") || strstr (s->model_name,"fi-7260")){ + /* locks up scanner if we try to auto detect */ + s->has_MS_lamp = 0; /* weirdness */ /* these machines have longer max paper at lower res */ @@ -4377,7 +4381,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_TOP){ opt->name = "top-edge"; opt->title = SANE_I18N ("Top edge"); - opt->desc = SANE_I18N ("Paper is pulled partly into adf"); + opt->desc = SANE_I18N ("Paper is pulled partly into ADF"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) @@ -6935,7 +6939,7 @@ sane_start (SANE_Handle handle) else{ ret = scanner_control(s, SC_function_adf); if (ret != SANE_STATUS_GOOD) { - DBG (5, "sane_start: ERROR: cannot control adf, ignoring\n"); + DBG (5, "sane_start: ERROR: cannot control ADF, ignoring\n"); } } diff --git a/backend/fujitsu.conf.in b/backend/fujitsu.conf.in index cb33f15..4f2b1a9 100644 --- a/backend/fujitsu.conf.in +++ b/backend/fujitsu.conf.in @@ -252,3 +252,6 @@ usb 0x04c5 0x1521 #fi-7700S usb 0x04c5 0x1522 + +#ScanSnap iX1500 +usb 0x04c5 0x159f diff --git a/backend/genesys.conf.in b/backend/genesys.conf.in index b1a0861..786ccd5 100644 --- a/backend/genesys.conf.in +++ b/backend/genesys.conf.in @@ -11,7 +11,7 @@ # Hewlett Packard ScanJet 2400c usb 0x03f0 0x0a01 -# Hewlett Packard ScanJet 3670c/3690c +# Hewlett Packard ScanJet 3670/3690c usb 0x03f0 0x1405 # Plustek OpticPro ST24 @@ -51,9 +51,6 @@ usb 0x04a9 0x1909 # Canon LiDE 200 usb 0x04a9 0x1905 -# Canon 5600F -usb 0x04a9 0x1906 - # Canon LiDE 700F usb 0x04a9 0x1907 @@ -66,9 +63,12 @@ usb 0x04a9 0x190e # Canon LiDE 220 usb 0x04a9 0x190f -# Canon 5600f +# Canon 5600F usb 0x04a9 0x1906 +# Canon 8400F +usb 0x04a9 0x221e + # Canon 8600F usb 0x04a9 0x2229 @@ -124,6 +124,15 @@ usb 0x03f0 0x4605 # Plustek OpticBook 3600 usb 0x07b3 0x0900 +# Plustek OpticFilm 7200i +usb 0x07b3 0x0c04 + +# Plustek OpticFilm 7300 +usb 0x07b3 0x0c12 + +# Plustek OpticFilm 7500i +usb 0x07b3 0x0c13 + # Primax Electronics, Ltd Xerox 2400 Onetouch usb 0x0461 0x038b diff --git a/backend/genesys/buffer.cpp b/backend/genesys/buffer.cpp new file mode 100644 index 0000000..f17e361 --- /dev/null +++ b/backend/genesys/buffer.cpp @@ -0,0 +1,102 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#include "buffer.h" +#include <cstring> +#include <stdexcept> + +namespace genesys { + +void Genesys_Buffer::alloc(std::size_t size) +{ + buffer_.resize(size); + avail_ = 0; + pos_ = 0; +} + +void Genesys_Buffer::clear() +{ + buffer_.clear(); + avail_ = 0; + pos_ = 0; +} + +void Genesys_Buffer::reset() +{ + avail_ = 0; + pos_ = 0; +} + +std::uint8_t* Genesys_Buffer::get_write_pos(std::size_t size) +{ + if (avail_ + size > buffer_.size()) + return nullptr; + if (pos_ + avail_ + size > buffer_.size()) + { + std::memmove(buffer_.data(), buffer_.data() + pos_, avail_); + pos_ = 0; + } + return buffer_.data() + pos_ + avail_; +} + +std::uint8_t* Genesys_Buffer::get_read_pos() +{ + return buffer_.data() + pos_; +} + +void Genesys_Buffer::produce(std::size_t size) +{ + if (size > buffer_.size() - avail_) + throw std::runtime_error("buffer size exceeded"); + avail_ += size; +} + +void Genesys_Buffer::consume(std::size_t size) +{ + if (size > avail_) + throw std::runtime_error("no more data in buffer"); + avail_ -= size; + pos_ += size; +} + +} // namespace genesys diff --git a/backend/genesys/buffer.h b/backend/genesys/buffer.h new file mode 100644 index 0000000..e9c889b --- /dev/null +++ b/backend/genesys/buffer.h @@ -0,0 +1,89 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_BUFFER_H +#define BACKEND_GENESYS_BUFFER_H + +#include <vector> +#include <cstddef> +#include <cstdint> + +namespace genesys { + +/* A FIFO buffer. Note, that this is _not_ a ringbuffer. + if we need a block which does not fit at the end of our available data, + we move the available data to the beginning. +*/ +struct Genesys_Buffer +{ + Genesys_Buffer() = default; + + std::size_t size() const { return buffer_.size(); } + std::size_t avail() const { return avail_; } + std::size_t pos() const { return pos_; } + + // TODO: refactor code that uses this function to no longer use it + void set_pos(std::size_t pos) { pos_ = pos; } + + void alloc(std::size_t size); + void clear(); + + void reset(); + + std::uint8_t* get_write_pos(std::size_t size); + std::uint8_t* get_read_pos(); // TODO: mark as const + + void produce(std::size_t size); + void consume(std::size_t size); + +private: + std::vector<std::uint8_t> buffer_; + // current position in read buffer + std::size_t pos_ = 0; + // data bytes currently in buffer + std::size_t avail_ = 0; +}; + +} // namespace genesys + +#endif // BACKEND_GENESYS_BUFFER_H diff --git a/backend/genesys/calibration.h b/backend/genesys/calibration.h new file mode 100644 index 0000000..f14aaa3 --- /dev/null +++ b/backend/genesys/calibration.h @@ -0,0 +1,108 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_CALIBRATION_H +#define BACKEND_GENESYS_CALIBRATION_H + +#include "sensor.h" +#include "settings.h" +#include <ctime> + +namespace genesys { + +struct Genesys_Calibration_Cache +{ + Genesys_Calibration_Cache() = default; + ~Genesys_Calibration_Cache() = default; + + // used to check if entry is compatible + SetupParams params; + + std::time_t last_calibration = 0; + + Genesys_Frontend frontend; + Genesys_Sensor sensor; + + size_t calib_pixels = 0; + size_t calib_channels = 0; + size_t average_size = 0; + std::vector<std::uint16_t> white_average_data; + std::vector<std::uint16_t> dark_average_data; + + bool operator==(const Genesys_Calibration_Cache& other) const + { + return params == other.params && + last_calibration == other.last_calibration && + frontend == other.frontend && + sensor == other.sensor && + calib_pixels == other.calib_pixels && + calib_channels == other.calib_channels && + average_size == other.average_size && + white_average_data == other.white_average_data && + dark_average_data == other.dark_average_data; + } +}; + +template<class Stream> +void serialize(Stream& str, Genesys_Calibration_Cache& x) +{ + serialize(str, x.params); + serialize_newline(str); + serialize(str, x.last_calibration); + serialize_newline(str); + serialize(str, x.frontend); + serialize_newline(str); + serialize(str, x.sensor); + serialize_newline(str); + serialize(str, x.calib_pixels); + serialize(str, x.calib_channels); + serialize(str, x.average_size); + serialize_newline(str); + serialize(str, x.white_average_data); + serialize_newline(str); + serialize(str, x.dark_average_data); +} + +} // namespace genesys + +#endif // BACKEND_GENESYS_CALIBRATION_H diff --git a/backend/genesys/command_set.h b/backend/genesys/command_set.h new file mode 100644 index 0000000..ab3a4b6 --- /dev/null +++ b/backend/genesys/command_set.h @@ -0,0 +1,166 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_COMMAND_SET_H +#define BACKEND_GENESYS_COMMAND_SET_H + +#include "device.h" +#include "fwd.h" +#include <cstdint> + +namespace genesys { + + +/** Scanner command set description. + + This description contains parts which are common to all scanners with the + same command set, but may have different optical resolution and other + parameters. + */ +class CommandSet +{ +public: + virtual ~CommandSet() = default; + + virtual bool needs_home_before_init_regs_for_scan(Genesys_Device* dev) const = 0; + + virtual void init(Genesys_Device* dev) const = 0; + + virtual void init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const = 0; + + virtual void init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const = 0; + virtual void init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const = 0; + virtual void init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const = 0; + + /** Set up registers for a scan. Similar to init_regs_for_scan except that the session is + already computed from the session + */ + virtual void init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const= 0; + + virtual void set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, std::uint8_t set) const = 0; + virtual void set_powersaving(Genesys_Device* dev, int delay) const = 0; + virtual void save_power(Genesys_Device* dev, bool enable) const = 0; + + virtual void begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, bool start_motor) const = 0; + virtual void end_scan(Genesys_Device* dev, Genesys_Register_Set* regs, + bool check_stop) const = 0; + + + /** + * Send gamma tables to ASIC + */ + virtual void send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const = 0; + + virtual void search_start_position(Genesys_Device* dev) const = 0; + virtual void offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const = 0; + virtual void coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const = 0; + virtual SensorExposure led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const = 0; + + virtual void wait_for_motor_stop(Genesys_Device* dev) const = 0; + virtual void move_back_home(Genesys_Device* dev, bool wait_until_home) const = 0; + + // Updates hardware sensor information in Genesys_Scanner.val[]. + virtual void update_hardware_sensors(struct Genesys_Scanner* s) const = 0; + + /** Whether the scanner needs to call update_home_sensor_gpio before reading the status of the + home sensor. On some chipsets this is unreliable until update_home_sensor_gpio() is called. + */ + virtual bool needs_update_home_sensor_gpio() const { return false; } + + /** Needed on some chipsets before reading the status of the home sensor to make this operation + reliable. + */ + virtual void update_home_sensor_gpio(Genesys_Device& dev) const { (void) dev; } + + // functions for sheetfed scanners + + // load document into scanner + virtual void load_document(Genesys_Device* dev) const = 0; + + /** Detects is the scanned document has left scanner. In this case it updates the amount of + data to read and set up flags in the dev struct + */ + virtual void detect_document_end(Genesys_Device* dev) const = 0; + + /// eject document from scanner + virtual void eject_document(Genesys_Device* dev) const = 0; + /** + * search for an black or white area in forward or reverse + * direction */ + virtual void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const = 0; + + /// move scanning head to transparency adapter + virtual void move_to_ta(Genesys_Device* dev) const = 0; + + /// write shading data calibration to ASIC + virtual void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + std::uint8_t* data, int size) const = 0; + + virtual bool has_send_shading_data() const + { + return true; + } + + /// calculate an instance of ScanSession for scanning with the given settings + virtual ScanSession calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const = 0; + + /// cold boot init function + virtual void asic_boot(Genesys_Device* dev, bool cold) const = 0; +}; + +} // namespace genesys + +#endif // BACKEND_GENESYS_COMMAND_SET_H diff --git a/backend/genesys/conv.cpp b/backend/genesys/conv.cpp new file mode 100644 index 0000000..a87c463 --- /dev/null +++ b/backend/genesys/conv.cpp @@ -0,0 +1,238 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2005, 2006 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> + Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "conv.h" +#include "sane/sanei_magic.h" + +namespace genesys { + +/** + * uses the threshold/threshold_curve to control software binarization + * This code was taken from the epjistsu backend by m. allan noah + * @param dev device set up for the scan + * @param src pointer to raw data + * @param dst pointer where to store result + * @param width width of the processed line + * */ +void binarize_line(Genesys_Device* dev, std::uint8_t* src, std::uint8_t* dst, int width) +{ + DBG_HELPER(dbg); + int j, windowX, sum = 0; + int thresh; + int offset, addCol, dropCol; + unsigned char mask; + + int x; + std::uint8_t min, max; + + /* normalize line */ + min = 255; + max = 0; + for (x = 0; x < width; x++) + { + if (src[x] > max) + { + max = src[x]; + } + if (src[x] < min) + { + min = src[x]; + } + } + + /* safeguard against dark or white areas */ + if(min>80) + min=0; + if(max<80) + max=255; + for (x = 0; x < width; x++) + { + src[x] = ((src[x] - min) * 255) / (max - min); + } + + /* ~1mm works best, but the window needs to have odd # of pixels */ + windowX = (6 * dev->settings.xres) / 150; + if (!(windowX % 2)) + windowX++; + + /* second, prefill the sliding sum */ + for (j = 0; j < windowX; j++) + sum += src[j]; + + /* third, walk the input buffer, update the sliding sum, */ + /* determine threshold, output bits */ + for (j = 0; j < width; j++) + { + /* output image location */ + offset = j % 8; + mask = 0x80 >> offset; + thresh = dev->settings.threshold; + + /* move sum/update threshold only if there is a curve */ + if (dev->settings.threshold_curve) + { + addCol = j + windowX / 2; + dropCol = addCol - windowX; + + if (dropCol >= 0 && addCol < width) + { + sum -= src[dropCol]; + sum += src[addCol]; + } + thresh = dev->lineart_lut[sum / windowX]; + } + + /* use average to lookup threshold */ + if (src[j] > thresh) + *dst &= ~mask; /* white */ + else + *dst |= mask; /* black */ + + if (offset == 7) + dst++; + } +} + +/** + * software lineart using data from a 8 bit gray scan. We assume true gray + * or monochrome scan as input. + */ +void genesys_gray_lineart(Genesys_Device* dev, + std::uint8_t* src_data, std::uint8_t* dst_data, + std::size_t pixels, std::size_t lines, std::uint8_t threshold) +{ + DBG_HELPER(dbg); + std::size_t y; + + DBG(DBG_io2, "%s: converting %zu lines of %zu pixels\n", __func__, lines, pixels); + DBG(DBG_io2, "%s: threshold=%d\n", __func__, threshold); + + for (y = 0; y < lines; y++) + { + binarize_line (dev, src_data + y * pixels, dst_data, pixels); + dst_data += pixels / 8; + } +} + +/** Look in image for likely left/right/bottom paper edges, then crop image. + */ +void genesys_crop(Genesys_Scanner* s) +{ + DBG_HELPER(dbg); + Genesys_Device *dev = s->dev; + int top = 0; + int bottom = 0; + int left = 0; + int right = 0; + + // first find edges if any + TIE(sanei_magic_findEdges(&s->params, dev->img_buffer.data(), + dev->settings.xres, dev->settings.yres, + &top, &bottom, &left, &right)); + + DBG (DBG_io, "%s: t:%d b:%d l:%d r:%d\n", __func__, top, bottom, left, + right); + + // now crop the image + TIE(sanei_magic_crop (&(s->params), dev->img_buffer.data(), top, bottom, left, right)); + + /* update counters to new image size */ + dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines; +} + +/** Look in image for likely upper and left paper edges, then rotate + * image so that upper left corner of paper is upper left of image. + */ +void genesys_deskew(Genesys_Scanner *s, const Genesys_Sensor& sensor) +{ + DBG_HELPER(dbg); + Genesys_Device *dev = s->dev; + + int x = 0, y = 0, bg; + double slope = 0; + + bg=0; + if(s->params.format==SANE_FRAME_GRAY && s->params.depth == 1) + { + bg=0xff; + } + TIE(sanei_magic_findSkew(&s->params, dev->img_buffer.data(), + sensor.optical_res, sensor.optical_res, + &x, &y, &slope)); + + DBG(DBG_info, "%s: slope=%f => %f\n", __func__, slope, slope * 180 / M_PI); + + // rotate image slope is in [-PI/2,PI/2]. Positive values rotate trigonometric direction wise + TIE(sanei_magic_rotate(&s->params, dev->img_buffer.data(), + x, y, slope, bg)); +} + +/** remove lone dots + */ +void genesys_despeck(Genesys_Scanner* s) +{ + DBG_HELPER(dbg); + TIE(sanei_magic_despeck(&s->params, s->dev->img_buffer.data(), s->despeck)); +} + +/** Look if image needs rotation and apply it + * */ +void genesys_derotate(Genesys_Scanner* s) +{ + DBG_HELPER(dbg); + int angle = 0; + + TIE(sanei_magic_findTurn(&s->params, s->dev->img_buffer.data(), + s->resolution, s->resolution, &angle)); + + // apply rotation angle found + TIE(sanei_magic_turn(&s->params, s->dev->img_buffer.data(), angle)); + + // update counters to new image size + s->dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines; +} + +} // namespace genesys diff --git a/backend/genesys/conv.h b/backend/genesys/conv.h new file mode 100644 index 0000000..446a80d --- /dev/null +++ b/backend/genesys/conv.h @@ -0,0 +1,69 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_CONV_H +#define BACKEND_GENESYS_CONV_H + +#include "device.h" +#include "sensor.h" +#include "genesys.h" + +namespace genesys { + +void binarize_line(Genesys_Device* dev, std::uint8_t* src, std::uint8_t* dst, int width); + +void genesys_gray_lineart(Genesys_Device* dev, + std::uint8_t* src_data, std::uint8_t* dst_data, + std::size_t pixels, size_t lines, std::uint8_t threshold); + +void genesys_crop(Genesys_Scanner* s); + +void genesys_deskew(Genesys_Scanner *s, const Genesys_Sensor& sensor); + +void genesys_despeck(Genesys_Scanner* s); + +void genesys_derotate(Genesys_Scanner* s); + +} // namespace genesys + +#endif // BACKEND_GENESYS_CONV_H diff --git a/backend/genesys/device.cpp b/backend/genesys/device.cpp new file mode 100644 index 0000000..ba035fd --- /dev/null +++ b/backend/genesys/device.cpp @@ -0,0 +1,272 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "device.h" +#include "command_set.h" +#include "low.h" +#include "utilities.h" + +namespace genesys { + +std::vector<unsigned> MethodResolutions::get_resolutions() const +{ + std::vector<unsigned> ret; + std::copy(resolutions_x.begin(), resolutions_x.end(), std::back_inserter(ret)); + std::copy(resolutions_y.begin(), resolutions_y.end(), std::back_inserter(ret)); + // sort in decreasing order + + std::sort(ret.begin(), ret.end(), std::greater<unsigned>()); + ret.erase(std::unique(ret.begin(), ret.end()), ret.end()); + return ret; +} + +const MethodResolutions& Genesys_Model::get_resolution_settings(ScanMethod method) const +{ + for (const auto& res_for_method : resolutions) { + for (auto res_method : res_for_method.methods) { + if (res_method == method) { + return res_for_method; + } + } + } + throw SaneException("Could not find resolution settings for method %d", + static_cast<unsigned>(method)); +} + +std::vector<unsigned> Genesys_Model::get_resolutions(ScanMethod method) const +{ + return get_resolution_settings(method).get_resolutions(); +} + +Genesys_Device::~Genesys_Device() +{ + clear(); +} + +void Genesys_Device::clear() +{ + read_buffer.clear(); + binarize_buffer.clear(); + local_buffer.clear(); + + calib_file.clear(); + + calibration_cache.clear(); + + white_average_data.clear(); + dark_average_data.clear(); +} + +ImagePipelineNodeBytesSource& Genesys_Device::get_pipeline_source() +{ + return static_cast<ImagePipelineNodeBytesSource&>(pipeline.front()); +} + +bool Genesys_Device::is_head_pos_known(ScanHeadId scan_head) const +{ + switch (scan_head) { + case ScanHeadId::PRIMARY: return is_head_pos_primary_known_; + case ScanHeadId::SECONDARY: return is_head_pos_secondary_known_; + case ScanHeadId::ALL: return is_head_pos_primary_known_ && is_head_pos_secondary_known_; + default: + throw SaneException("Unknown scan head ID"); + } +} +unsigned Genesys_Device::head_pos(ScanHeadId scan_head) const +{ + switch (scan_head) { + case ScanHeadId::PRIMARY: return head_pos_primary_; + case ScanHeadId::SECONDARY: return head_pos_secondary_; + default: + throw SaneException("Unknown scan head ID"); + } +} + +void Genesys_Device::set_head_pos_unknown() +{ + is_head_pos_primary_known_ = false; + is_head_pos_secondary_known_ = false; +} + +void Genesys_Device::set_head_pos_zero(ScanHeadId scan_head) +{ + if ((scan_head & ScanHeadId::PRIMARY) != ScanHeadId::NONE) { + head_pos_primary_ = 0; + is_head_pos_primary_known_ = true; + } + if ((scan_head & ScanHeadId::SECONDARY) != ScanHeadId::NONE) { + head_pos_secondary_ = 0; + is_head_pos_secondary_known_ = true; + } +} + +void Genesys_Device::advance_head_pos_by_session(ScanHeadId scan_head) +{ + int motor_steps = session.params.starty + + (session.params.lines * motor.base_ydpi) / session.params.yres; + auto direction = has_flag(session.params.flags, ScanFlag::REVERSE) ? Direction::BACKWARD + : Direction::FORWARD; + advance_head_pos_by_steps(scan_head, direction, motor_steps); +} + +static void advance_pos(unsigned& pos, Direction direction, unsigned offset) +{ + if (direction == Direction::FORWARD) { + pos += offset; + } else { + if (pos < offset) { + throw SaneException("Trying to advance head behind the home sensor"); + } + pos -= offset; + } +} + +void Genesys_Device::advance_head_pos_by_steps(ScanHeadId scan_head, Direction direction, + unsigned steps) +{ + if ((scan_head & ScanHeadId::PRIMARY) != ScanHeadId::NONE) { + if (!is_head_pos_primary_known_) { + throw SaneException("Trying to advance head while scanhead position is not known"); + } + advance_pos(head_pos_primary_, direction, steps); + } + if ((scan_head & ScanHeadId::SECONDARY) != ScanHeadId::NONE) { + if (!is_head_pos_secondary_known_) { + throw SaneException("Trying to advance head while scanhead position is not known"); + } + advance_pos(head_pos_secondary_, direction, steps); + } +} + +void print_scan_position(std::ostream& out, const Genesys_Device& dev, ScanHeadId scan_head) +{ + if (dev.is_head_pos_known(scan_head)) { + out << dev.head_pos(scan_head); + } else { + out <<"(unknown)"; + } +} + +std::ostream& operator<<(std::ostream& out, const Genesys_Device& dev) +{ + StreamStateSaver state_saver{out}; + + out << "Genesys_Device{\n" + << std::hex + << " vendorId: 0x" << dev.vendorId << '\n' + << " productId: 0x" << dev.productId << '\n' + << std::dec + << " usb_mode: " << dev.usb_mode << '\n' + << " file_name: " << dev.file_name << '\n' + << " calib_file: " << dev.calib_file << '\n' + << " force_calibration: " << dev.force_calibration << '\n' + << " ignore_offsets: " << dev.ignore_offsets << '\n' + << " model: (not printed)\n" + << " reg: " << format_indent_braced_list(4, dev.reg) << '\n' + << " calib_reg: " << format_indent_braced_list(4, dev.calib_reg) << '\n' + << " settings: " << format_indent_braced_list(4, dev.settings) << '\n' + << " frontend: " << format_indent_braced_list(4, dev.frontend) << '\n' + << " frontend_initial: " << format_indent_braced_list(4, dev.frontend_initial) << '\n' + << " frontend_is_init: " << dev.frontend_is_init << '\n' + << " gpo.regs: " << format_indent_braced_list(4, dev.gpo.regs) << '\n' + << " motor: " << format_indent_braced_list(4, dev.motor) << '\n' + << " control[0..6]: " << std::hex + << static_cast<unsigned>(dev.control[0]) << ' ' + << static_cast<unsigned>(dev.control[1]) << ' ' + << static_cast<unsigned>(dev.control[2]) << ' ' + << static_cast<unsigned>(dev.control[3]) << ' ' + << static_cast<unsigned>(dev.control[4]) << ' ' + << static_cast<unsigned>(dev.control[5]) << '\n' << std::dec + << " average_size: " << dev.average_size << '\n' + << " calib_pixels: " << dev.calib_pixels << '\n' + << " calib_lines: " << dev.calib_lines << '\n' + << " calib_channels: " << dev.calib_channels << '\n' + << " calib_resolution: " << dev.calib_resolution << '\n' + << " calib_total_bytes_to_read: " << dev.calib_total_bytes_to_read << '\n' + << " calib_session: " << format_indent_braced_list(4, dev.calib_session) << '\n' + << " calib_pixels_offset: " << dev.calib_pixels_offset << '\n' + << " gamma_override_tables[0].size(): " << dev.gamma_override_tables[0].size() << '\n' + << " gamma_override_tables[1].size(): " << dev.gamma_override_tables[1].size() << '\n' + << " gamma_override_tables[2].size(): " << dev.gamma_override_tables[2].size() << '\n' + << " white_average_data.size(): " << dev.white_average_data.size() << '\n' + << " dark_average_data.size(): " << dev.dark_average_data.size() << '\n' + << " already_initialized: " << dev.already_initialized << '\n' + << " scanhead_position[PRIMARY]: "; + print_scan_position(out, dev, ScanHeadId::PRIMARY); + out << '\n' + << " scanhead_position[SECONDARY]: "; + print_scan_position(out, dev, ScanHeadId::SECONDARY); + out << '\n' + << " read_active: " << dev.read_active << '\n' + << " parking: " << dev.parking << '\n' + << " document: " << dev.document << '\n' + << " read_buffer.size(): " << dev.read_buffer.size() << '\n' + << " binarize_buffer.size(): " << dev.binarize_buffer.size() << '\n' + << " local_buffer.size(): " << dev.local_buffer.size() << '\n' + << " oe_buffer.size(): " << dev.oe_buffer.size() << '\n' + << " total_bytes_read: " << dev.total_bytes_read << '\n' + << " total_bytes_to_read: " << dev.total_bytes_to_read << '\n' + << " session: " << format_indent_braced_list(4, dev.session) << '\n' + << " lineart_lut: (not printed)\n" + << " calibration_cache: (not printed)\n" + << " line_count: " << dev.line_count << '\n' + << " segment_order: " + << format_indent_braced_list(4, format_vector_unsigned(4, dev.segment_order)) << '\n' + << " buffer_image: " << dev.buffer_image << '\n' + << " img_buffer.size(): " << dev.img_buffer.size() << '\n' + << '}'; + return out; +} + +void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs) +{ + for (const auto& reg : regs) { + uint8_t val = dev.interface->read_register(reg.address); + val = (val & ~reg.mask) | (reg.value & reg.mask); + dev.interface->write_register(reg.address, val); + } +} + +} // namespace genesys diff --git a/backend/genesys/device.h b/backend/genesys/device.h new file mode 100644 index 0000000..6c744c9 --- /dev/null +++ b/backend/genesys/device.h @@ -0,0 +1,387 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_DEVICE_H +#define BACKEND_GENESYS_DEVICE_H + +#include "calibration.h" +#include "command_set.h" +#include "buffer.h" +#include "enums.h" +#include "image_pipeline.h" +#include "motor.h" +#include "settings.h" +#include "sensor.h" +#include "register.h" +#include "usb_device.h" +#include "scanner_interface.h" +#include <vector> + +namespace genesys { + +struct Genesys_Gpo +{ + Genesys_Gpo() = default; + + // Genesys_Gpo + GpioId id = GpioId::UNKNOWN; + + /* GL646 and possibly others: + - have the value registers at 0x66 and 0x67 + - have the enable registers at 0x68 and 0x69 + + GL841, GL842, GL843, GL846, GL848 and possibly others: + - have the value registers at 0x6c and 0x6d. + - have the enable registers at 0x6e and 0x6f. + */ + GenesysRegisterSettingSet regs; +}; + +/// Stores a SANE_Fixed value which is automatically converted from and to floating-point values +class FixedFloat +{ +public: + FixedFloat() = default; + FixedFloat(const FixedFloat&) = default; + FixedFloat(double number) : value_{SANE_FIX(number)} {} + FixedFloat& operator=(const FixedFloat&) = default; + FixedFloat& operator=(double number) { value_ = SANE_FIX(number); return *this; } + + operator double() const { return value(); } + + double value() const { return SANE_UNFIX(value_); } + +private: + SANE_Fixed value_ = 0; +}; + +struct MethodResolutions +{ + std::vector<ScanMethod> methods; + std::vector<unsigned> resolutions_x; + std::vector<unsigned> resolutions_y; + + unsigned get_min_resolution_x() const + { + return *std::min_element(resolutions_x.begin(), resolutions_x.end()); + } + + unsigned get_min_resolution_y() const + { + return *std::min_element(resolutions_y.begin(), resolutions_y.end()); + } + + std::vector<unsigned> get_resolutions() const; +}; + +/** @brief structure to describe a scanner model + * This structure describes a model. It is composed of information on the + * sensor, the motor, scanner geometry and flags to drive operation. + */ +struct Genesys_Model +{ + Genesys_Model() = default; + + const char* name = nullptr; + const char* vendor = nullptr; + const char* model = nullptr; + ModelId model_id = ModelId::UNKNOWN; + + AsicType asic_type = AsicType::UNKNOWN; + + // possible x and y resolutions for each method supported by the scanner + std::vector<MethodResolutions> resolutions; + + // possible depths in gray mode + std::vector<unsigned> bpp_gray_values; + // possible depths in color mode + std::vector<unsigned> bpp_color_values; + + // the default scanning method. This is used when moving the head for example + ScanMethod default_method = ScanMethod::FLATBED; + + // All offsets below are with respect to the sensor home position + + // Start of scan area in mm + FixedFloat x_offset = 0; + + // Start of scan area in mm (Amount of feeding needed to get to the medium) + FixedFloat y_offset = 0; + + // Size of scan area in mm + FixedFloat x_size = 0; + + // Size of scan area in mm + FixedFloat y_size = 0; + + // Start of white strip in mm + FixedFloat y_offset_calib_white = 0; + + // Start of black mark in mm + FixedFloat x_offset_calib_black = 0; + + // Start of scan area in transparency mode in mm + FixedFloat x_offset_ta = 0; + + // Start of scan area in transparency mode in mm + FixedFloat y_offset_ta = 0; + + // Size of scan area in transparency mode in mm + FixedFloat x_size_ta = 0; + + // Size of scan area in transparency mode in mm + FixedFloat y_size_ta = 0; + + // The position of the sensor when it's aligned with the lamp for transparency scanning + FixedFloat y_offset_sensor_to_ta = 0; + + // Start of white strip in transparency mode in mm + FixedFloat y_offset_calib_white_ta = 0; + + // Start of black strip in transparency mode in mm + FixedFloat y_offset_calib_black_ta = 0; + + // Size of scan area after paper sensor stop sensing document in mm + FixedFloat post_scan = 0; + + // Amount of feeding needed to eject document after finishing scanning in mm + FixedFloat eject_feed = 0; + + // Line-distance correction (in pixel at optical_ydpi) for CCD scanners + SANE_Int ld_shift_r = 0; + SANE_Int ld_shift_g = 0; + SANE_Int ld_shift_b = 0; + + // Order of the CCD/CIS colors + ColorOrder line_mode_color_order = ColorOrder::RGB; + + // Is this a CIS or CCD scanner? + bool is_cis = false; + + // Is this sheetfed scanner? + bool is_sheetfed = false; + + // sensor type + SensorId sensor_id = SensorId::UNKNOWN; + // Analog-Digital converter type + AdcId adc_id = AdcId::UNKNOWN; + // General purpose output type + GpioId gpio_id = GpioId::UNKNOWN; + // stepper motor type + MotorId motor_id = MotorId::UNKNOWN; + + // Which hacks are needed for this scanner? + SANE_Word flags = 0; + + // Button flags, described existing buttons for the model + SANE_Word buttons = 0; + + // how many lines are used for shading calibration + SANE_Int shading_lines = 0; + // how many lines are used for shading calibration in TA mode + SANE_Int shading_ta_lines = 0; + // how many lines are used to search start position + SANE_Int search_lines = 0; + + const MethodResolutions& get_resolution_settings(ScanMethod method) const; + + std::vector<unsigned> get_resolutions(ScanMethod method) const; +}; + +/** + * Describes the current device status for the backend + * session. This should be more accurately called + * Genesys_Session . + */ +struct Genesys_Device +{ + Genesys_Device() = default; + ~Genesys_Device(); + + using Calibration = std::vector<Genesys_Calibration_Cache>; + + // frees commonly used data + void clear(); + + SANE_Word vendorId = 0; /**< USB vendor identifier */ + SANE_Word productId = 0; /**< USB product identifier */ + + // USB mode: + // 0: not set + // 1: USB 1.1 + // 2: USB 2.0 + SANE_Int usb_mode = 0; + + std::string file_name; + std::string calib_file; + + // if enabled, no calibration data will be loaded or saved to files + SANE_Int force_calibration = 0; + // if enabled, will ignore the scan offsets and start scanning at true origin. This allows + // acquiring the positions of the black and white strips and the actual scan area + bool ignore_offsets = false; + + Genesys_Model *model = nullptr; + + // pointers to low level functions + std::unique_ptr<CommandSet> cmd_set; + + Genesys_Register_Set reg; + Genesys_Register_Set calib_reg; + Genesys_Settings settings; + Genesys_Frontend frontend, frontend_initial; + + // whether the frontend is initialized. This is currently used just to preserve historical + // behavior + bool frontend_is_init = false; + + Genesys_Gpo gpo; + Genesys_Motor motor; + std::uint8_t control[6] = {}; + + size_t average_size = 0; + // number of pixels used during shading calibration + size_t calib_pixels = 0; + // number of lines used during shading calibration + size_t calib_lines = 0; + size_t calib_channels = 0; + size_t calib_resolution = 0; + // bytes to read from USB when calibrating. If 0, this is not set + size_t calib_total_bytes_to_read = 0; + + // the session that was configured for calibration + ScanSession calib_session; + + // certain scanners support much higher resolution when scanning transparency, but we can't + // read whole width of the scanner as a single line at that resolution. Thus for stuff like + // calibration we want to read only the possible calibration area. + size_t calib_pixels_offset = 0; + + // gamma overrides. If a respective array is not empty then it means that the gamma for that + // color is overridden. + std::vector<std::uint16_t> gamma_override_tables[3]; + + std::vector<std::uint16_t> white_average_data; + std::vector<std::uint16_t> dark_average_data; + + bool already_initialized = false; + + bool read_active = false; + // signal wether the park command has been issued + bool parking = false; + + // for sheetfed scanner's, is TRUE when there is a document in the scanner + bool document = false; + + Genesys_Buffer read_buffer; + + // buffer for digital lineart from gray data + Genesys_Buffer binarize_buffer; + // local buffer for gray data during dynamix lineart + Genesys_Buffer local_buffer; + + // total bytes read sent to frontend + size_t total_bytes_read = 0; + // total bytes read to be sent to frontend + size_t total_bytes_to_read = 0; + + // contains computed data for the current setup + ScanSession session; + + // look up table used in dynamic rasterization + unsigned char lineart_lut[256] = {}; + + Calibration calibration_cache; + + // number of scan lines used during scan + int line_count = 0; + + // array describing the order of the sub-segments of the sensor + std::vector<unsigned> segment_order; + + // buffer to handle even/odd data + Genesys_Buffer oe_buffer = {}; + + // stores information about how the input image should be processed + ImagePipelineStack pipeline; + + // an buffer that allows reading from `pipeline` in chunks of any size + ImageBuffer pipeline_buffer; + + // when true the scanned picture is first buffered to allow software image enhancements + bool buffer_image = false; + + // image buffer where the scanned picture is stored + std::vector<std::uint8_t> img_buffer; + + ImagePipelineNodeBytesSource& get_pipeline_source(); + + std::unique_ptr<ScannerInterface> interface; + + bool is_head_pos_known(ScanHeadId scan_head) const; + unsigned head_pos(ScanHeadId scan_head) const; + void set_head_pos_unknown(); + void set_head_pos_zero(ScanHeadId scan_head); + void advance_head_pos_by_session(ScanHeadId scan_head); + void advance_head_pos_by_steps(ScanHeadId scan_head, Direction direction, unsigned steps); + +private: + // the position of the primary scan head in motor->base_dpi units + unsigned head_pos_primary_ = 0; + bool is_head_pos_primary_known_ = true; + + // the position of the secondary scan head in motor->base_dpi units. Only certain scanners + // have a secondary scan head. + unsigned head_pos_secondary_ = 0; + bool is_head_pos_secondary_known_ = true; + + friend class ScannerInterfaceUsb; +}; + +std::ostream& operator<<(std::ostream& out, const Genesys_Device& dev); + +void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs); + +} // namespace genesys + +#endif diff --git a/backend/genesys/enums.cpp b/backend/genesys/enums.cpp new file mode 100644 index 0000000..f515cfd --- /dev/null +++ b/backend/genesys/enums.cpp @@ -0,0 +1,131 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "enums.h" +#include "genesys.h" +#include <iomanip> + +namespace genesys { + +const char* scan_method_to_option_string(ScanMethod method) +{ + switch (method) { + case ScanMethod::FLATBED: return STR_FLATBED; + case ScanMethod::TRANSPARENCY: return STR_TRANSPARENCY_ADAPTER; + case ScanMethod::TRANSPARENCY_INFRARED: return STR_TRANSPARENCY_ADAPTER_INFRARED; + } + throw SaneException("Unknown scan method %d", static_cast<unsigned>(method)); +} + +ScanMethod option_string_to_scan_method(const std::string& str) +{ + if (str == STR_FLATBED) { + return ScanMethod::FLATBED; + } else if (str == STR_TRANSPARENCY_ADAPTER) { + return ScanMethod::TRANSPARENCY; + } else if (str == STR_TRANSPARENCY_ADAPTER_INFRARED) { + return ScanMethod::TRANSPARENCY_INFRARED; + } + throw SaneException("Unknown scan method option %s", str.c_str()); +} + +const char* scan_color_mode_to_option_string(ScanColorMode mode) +{ + switch (mode) { + case ScanColorMode::COLOR_SINGLE_PASS: return SANE_VALUE_SCAN_MODE_COLOR; + case ScanColorMode::GRAY: return SANE_VALUE_SCAN_MODE_GRAY; + case ScanColorMode::HALFTONE: return SANE_VALUE_SCAN_MODE_HALFTONE; + case ScanColorMode::LINEART: return SANE_VALUE_SCAN_MODE_LINEART; + } + throw SaneException("Unknown scan mode %d", static_cast<unsigned>(mode)); +} + +ScanColorMode option_string_to_scan_color_mode(const std::string& str) +{ + if (str == SANE_VALUE_SCAN_MODE_COLOR) { + return ScanColorMode::COLOR_SINGLE_PASS; + } else if (str == SANE_VALUE_SCAN_MODE_GRAY) { + return ScanColorMode::GRAY; + } else if (str == SANE_VALUE_SCAN_MODE_HALFTONE) { + return ScanColorMode::HALFTONE; + } else if (str == SANE_VALUE_SCAN_MODE_LINEART) { + return ScanColorMode::LINEART; + } + throw SaneException("Unknown scan color mode %s", str.c_str()); +} + + +std::ostream& operator<<(std::ostream& out, ColorFilter mode) +{ + switch (mode) { + case ColorFilter::RED: out << "RED"; break; + case ColorFilter::GREEN: out << "GREEN"; break; + case ColorFilter::BLUE: out << "BLUE"; break; + case ColorFilter::NONE: out << "NONE"; break; + default: out << static_cast<unsigned>(mode); break; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, StepType type) +{ + switch (type) { + case StepType::FULL: out << "1/1"; break; + case StepType::HALF: out << "1/2"; break; + case StepType::QUARTER: out << "1/4"; break; + case StepType::EIGHTH: out << "1/8"; break; + default: out << static_cast<unsigned>(type); break; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, ScanFlag flags) +{ + StreamStateSaver state_saver{out}; + out << "0x" << std::hex << static_cast<unsigned>(flags); + return out; +} + +} // namespace genesys diff --git a/backend/genesys/enums.h b/backend/genesys/enums.h new file mode 100644 index 0000000..810c4ca --- /dev/null +++ b/backend/genesys/enums.h @@ -0,0 +1,530 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_ENUMS_H +#define BACKEND_GENESYS_ENUMS_H + +#include <iostream> +#include "serialize.h" + +namespace genesys { + +enum class ScanMethod : unsigned { + // normal scan method + FLATBED = 0, + // scan using transparency adaptor + TRANSPARENCY = 1, + // scan using transparency adaptor via infrared channel + TRANSPARENCY_INFRARED = 2 +}; + +inline std::ostream& operator<<(std::ostream& out, ScanMethod mode) +{ + switch (mode) { + case ScanMethod::FLATBED: out << "FLATBED"; return out; + case ScanMethod::TRANSPARENCY: out << "TRANSPARENCY"; return out; + case ScanMethod::TRANSPARENCY_INFRARED: out << "TRANSPARENCY_INFRARED"; return out; + } + return out; +} + +inline void serialize(std::istream& str, ScanMethod& x) +{ + unsigned value; + serialize(str, value); + x = static_cast<ScanMethod>(value); +} + +inline void serialize(std::ostream& str, ScanMethod& x) +{ + unsigned value = static_cast<unsigned>(x); + serialize(str, value); +} + +const char* scan_method_to_option_string(ScanMethod method); +ScanMethod option_string_to_scan_method(const std::string& str); + +enum class ScanColorMode : unsigned { + LINEART = 0, + HALFTONE, + GRAY, + COLOR_SINGLE_PASS +}; + +inline std::ostream& operator<<(std::ostream& out, ScanColorMode mode) +{ + switch (mode) { + case ScanColorMode::LINEART: out << "LINEART"; return out; + case ScanColorMode::HALFTONE: out << "HALFTONE"; return out; + case ScanColorMode::GRAY: out << "GRAY"; return out; + case ScanColorMode::COLOR_SINGLE_PASS: out << "COLOR_SINGLE_PASS"; return out; + } + return out; +} + +inline void serialize(std::istream& str, ScanColorMode& x) +{ + unsigned value; + serialize(str, value); + x = static_cast<ScanColorMode>(value); +} + +inline void serialize(std::ostream& str, ScanColorMode& x) +{ + unsigned value = static_cast<unsigned>(x); + serialize(str, value); +} + +const char* scan_color_mode_to_option_string(ScanColorMode mode); +ScanColorMode option_string_to_scan_color_mode(const std::string& str); + + +enum class ScanHeadId : unsigned { + NONE = 0, + PRIMARY = 1 << 0, + SECONDARY = 1 << 1, + ALL = PRIMARY | SECONDARY, +}; + +inline ScanHeadId operator|(ScanHeadId left, ScanHeadId right) +{ + return static_cast<ScanHeadId>(static_cast<unsigned>(left) | static_cast<unsigned>(right)); +} + +inline ScanHeadId operator&(ScanHeadId left, ScanHeadId right) +{ + return static_cast<ScanHeadId>(static_cast<unsigned>(left) & static_cast<unsigned>(right)); +} + + +enum class ColorFilter : unsigned { + RED = 0, + GREEN, + BLUE, + NONE +}; + +std::ostream& operator<<(std::ostream& out, ColorFilter mode); + +inline void serialize(std::istream& str, ColorFilter& x) +{ + unsigned value; + serialize(str, value); + x = static_cast<ColorFilter>(value); +} + +inline void serialize(std::ostream& str, ColorFilter& x) +{ + unsigned value = static_cast<unsigned>(x); + serialize(str, value); +} + +enum class ColorOrder +{ + RGB, + GBR, + BGR, +}; + +/* Enum value naming conventions: + Full name must be included with the following exceptions: + + Canon scanners omit "Canoscan" if present +*/ +enum class ModelId : unsigned +{ + UNKNOWN = 0, + CANON_4400F, + CANON_5600F, + CANON_8400F, + CANON_8600F, + CANON_IMAGE_FORMULA_101, + CANON_LIDE_50, + CANON_LIDE_60, + CANON_LIDE_80, + CANON_LIDE_100, + CANON_LIDE_110, + CANON_LIDE_120, + CANON_LIDE_200, + CANON_LIDE_210, + CANON_LIDE_220, + CANON_LIDE_700F, + DCT_DOCKETPORT_487, + HP_SCANJET_2300C, + HP_SCANJET_2400C, + HP_SCANJET_3670, + HP_SCANJET_4850C, + HP_SCANJET_G4010, + HP_SCANJET_G4050, + HP_SCANJET_N6310, + MEDION_MD5345, + PANASONIC_KV_SS080, + PENTAX_DSMOBILE_600, + PLUSTEK_OPTICBOOK_3800, + PLUSTEK_OPTICFILM_7200I, + PLUSTEK_OPTICFILM_7300, + PLUSTEK_OPTICFILM_7500I, + PLUSTEK_OPTICPRO_3600, + PLUSTEK_OPTICPRO_ST12, + PLUSTEK_OPTICPRO_ST24, + SYSCAN_DOCKETPORT_465, + SYSCAN_DOCKETPORT_467, + SYSCAN_DOCKETPORT_485, + SYSCAN_DOCKETPORT_665, + SYSCAN_DOCKETPORT_685, + UMAX_ASTRA_4500, + VISIONEER_7100, + VISIONEER_ROADWARRIOR, + VISIONEER_STROBE_XP100_REVISION3, + VISIONEER_STROBE_XP200, + VISIONEER_STROBE_XP300, + XEROX_2400, + XEROX_TRAVELSCANNER_100, +}; + +enum class SensorId : unsigned +{ + UNKNOWN = 0, + CCD_5345, + CCD_CANON_4400F, + CCD_CANON_8400F, + CCD_CANON_8600F, + CCD_DP665, + CCD_DP685, + CCD_DSMOBILE600, + CCD_G4050, + CCD_HP2300, + CCD_HP2400, + CCD_HP3670, + CCD_HP_N6310, + CCD_HP_4850C, + CCD_IMG101, + CCD_KVSS080, + CCD_PLUSTEK_OPTICBOOK_3800, + CCD_PLUSTEK_OPTICFILM_7200I, + CCD_PLUSTEK_OPTICFILM_7300, + CCD_PLUSTEK_OPTICFILM_7500I, + CCD_PLUSTEK_OPTICPRO_3600, + CCD_ROADWARRIOR, + CCD_ST12, // SONY ILX548: 5340 Pixel ??? + CCD_ST24, // SONY ILX569: 10680 Pixel ??? + CCD_UMAX, + CCD_XP300, + CIS_CANON_LIDE_35, + CIS_CANON_LIDE_80, + CIS_CANON_LIDE_100, + CIS_CANON_LIDE_110, + CIS_CANON_LIDE_120, + CIS_CANON_LIDE_200, + CIS_CANON_LIDE_210, + CIS_CANON_LIDE_220, + CIS_CANON_LIDE_700F, + CIS_XP200, +}; + +inline void serialize(std::istream& str, SensorId& x) +{ + unsigned value; + serialize(str, value); + x = static_cast<SensorId>(value); +} + +inline void serialize(std::ostream& str, SensorId& x) +{ + unsigned value = static_cast<unsigned>(x); + serialize(str, value); +} + + +enum class AdcId : unsigned +{ + UNKNOWN = 0, + AD_XP200, + CANON_LIDE_35, + CANON_LIDE_80, + CANON_LIDE_110, + CANON_LIDE_120, + CANON_LIDE_200, + CANON_LIDE_700F, + CANON_4400F, + CANON_8400F, + CANON_8600F, + G4050, + IMG101, + KVSS080, + PLUSTEK_OPTICBOOK_3800, + PLUSTEK_OPTICFILM_7200I, + PLUSTEK_OPTICFILM_7300, + PLUSTEK_OPTICFILM_7500I, + PLUSTEK_OPTICPRO_3600, + WOLFSON_5345, + WOLFSON_DSM600, + WOLFSON_HP2300, + WOLFSON_HP2400, + WOLFSON_HP3670, + WOLFSON_ST12, + WOLFSON_ST24, + WOLFSON_UMAX, + WOLFSON_XP300, +}; + +inline void serialize(std::istream& str, AdcId& x) +{ + unsigned value; + serialize(str, value); + x = static_cast<AdcId>(value); +} + +inline void serialize(std::ostream& str, AdcId& x) +{ + unsigned value = static_cast<unsigned>(x); + serialize(str, value); +} + +enum class GpioId : unsigned +{ + UNKNOWN = 0, + CANON_LIDE_35, + CANON_LIDE_80, + CANON_LIDE_110, + CANON_LIDE_120, + CANON_LIDE_200, + CANON_LIDE_210, + CANON_LIDE_700F, + CANON_4400F, + CANON_8400F, + CANON_8600F, + DP665, + DP685, + G4050, + HP2300, + HP2400, + HP3670, + HP_N6310, + IMG101, + KVSS080, + MD_5345, + PLUSTEK_OPTICBOOK_3800, + PLUSTEK_OPTICFILM_7200I, + PLUSTEK_OPTICFILM_7300, + PLUSTEK_OPTICFILM_7500I, + PLUSTEK_OPTICPRO_3600, + ST12, + ST24, + UMAX, + XP200, + XP300, +}; + +enum class MotorId : unsigned +{ + UNKNOWN = 0, + CANON_LIDE_100, + CANON_LIDE_110, + CANON_LIDE_120, + CANON_LIDE_200, + CANON_LIDE_210, + CANON_LIDE_35, + CANON_LIDE_700, + CANON_LIDE_80, + CANON_4400F, + CANON_8400F, + CANON_8600F, + DP665, + DSMOBILE_600, + G4050, + HP2300, + HP2400, + HP3670, + IMG101, + KVSS080, + MD_5345, + PLUSTEK_OPTICBOOK_3800, + PLUSTEK_OPTICFILM_7200I, + PLUSTEK_OPTICFILM_7300, + PLUSTEK_OPTICFILM_7500I, + PLUSTEK_OPTICPRO_3600, + ROADWARRIOR, + ST24, + UMAX, + XP200, + XP300, +}; + +enum class StepType : unsigned +{ + FULL = 0, + HALF = 1, + QUARTER = 2, + EIGHTH = 3, +}; + +std::ostream& operator<<(std::ostream& out, StepType type); + +inline bool operator<(StepType lhs, StepType rhs) +{ + return static_cast<unsigned>(lhs) < static_cast<unsigned>(rhs); +} +inline bool operator<=(StepType lhs, StepType rhs) +{ + return static_cast<unsigned>(lhs) <= static_cast<unsigned>(rhs); +} +inline bool operator>(StepType lhs, StepType rhs) +{ + return static_cast<unsigned>(lhs) > static_cast<unsigned>(rhs); +} +inline bool operator>=(StepType lhs, StepType rhs) +{ + return static_cast<unsigned>(lhs) >= static_cast<unsigned>(rhs); +} + +enum class AsicType : unsigned +{ + UNKNOWN = 0, + GL646, + GL841, + GL843, + GL845, + GL846, + GL847, + GL124, +}; + + +enum class ScanFlag : unsigned +{ + NONE = 0, + SINGLE_LINE = 1 << 0, + DISABLE_SHADING = 1 << 1, + DISABLE_GAMMA = 1 << 2, + DISABLE_BUFFER_FULL_MOVE = 1 << 3, + IGNORE_LINE_DISTANCE = 1 << 4, + DISABLE_LAMP = 1 << 5, + CALIBRATION = 1 << 6, + FEEDING = 1 << 7, + USE_XPA = 1 << 8, + ENABLE_LEDADD = 1 << 9, + USE_XCORRECTION = 1 << 10, + REVERSE = 1 << 11, +}; + +inline ScanFlag operator|(ScanFlag left, ScanFlag right) +{ + return static_cast<ScanFlag>(static_cast<unsigned>(left) | static_cast<unsigned>(right)); +} + +inline ScanFlag& operator|=(ScanFlag& left, ScanFlag right) +{ + left = left | right; + return left; +} + +inline ScanFlag operator&(ScanFlag left, ScanFlag right) +{ + return static_cast<ScanFlag>(static_cast<unsigned>(left) & static_cast<unsigned>(right)); +} + +inline bool has_flag(ScanFlag flags, ScanFlag which) +{ + return (flags & which) == which; +} + +inline void serialize(std::istream& str, ScanFlag& x) +{ + unsigned value; + serialize(str, value); + x = static_cast<ScanFlag>(value); +} + +inline void serialize(std::ostream& str, ScanFlag& x) +{ + unsigned value = static_cast<unsigned>(x); + serialize(str, value); +} + +std::ostream& operator<<(std::ostream& out, ScanFlag flags); + + + +enum class MotorFlag : unsigned +{ + NONE = 0, + AUTO_GO_HOME = 1 << 0, + DISABLE_BUFFER_FULL_MOVE = 1 << 2, + FEED = 1 << 3, + USE_XPA = 1 << 4, + REVERSE = 1 << 5, +}; + +inline MotorFlag operator|(MotorFlag left, MotorFlag right) +{ + return static_cast<MotorFlag>(static_cast<unsigned>(left) | static_cast<unsigned>(right)); +} + +inline MotorFlag& operator|=(MotorFlag& left, MotorFlag right) +{ + left = left | right; + return left; +} + +inline MotorFlag operator&(MotorFlag left, MotorFlag right) +{ + return static_cast<MotorFlag>(static_cast<unsigned>(left) & static_cast<unsigned>(right)); +} + +inline bool has_flag(MotorFlag flags, MotorFlag which) +{ + return (flags & which) == which; +} + + +enum class Direction : unsigned +{ + FORWARD = 0, + BACKWARD = 1 +}; + + +} // namespace genesys + +#endif // BACKEND_GENESYS_ENUMS_H diff --git a/backend/genesys_error.cc b/backend/genesys/error.cpp index c98a490..6c921c1 100644 --- a/backend/genesys_error.cc +++ b/backend/genesys/error.cpp @@ -43,12 +43,13 @@ #define DEBUG_DECLARE_ONLY -#include "genesys_error.h" +#include "error.h" #include <cstdarg> -#include <cstdio> + +namespace genesys { extern "C" void sanei_debug_msg(int level, int max_level, const char *be, const char *fmt, - va_list ap); + std::va_list ap); #if (defined(__GNUC__) || defined(__CLANG__)) && (defined(__linux__) || defined(__APPLE__)) extern "C" char* __cxa_get_globals(); @@ -69,6 +70,73 @@ static unsigned num_uncaught_exceptions() #endif } +SaneException::SaneException(SANE_Status status) : status_(status) +{ + set_msg(); +} + +SaneException::SaneException(SANE_Status status, const char* format, ...) : status_(status) +{ + std::va_list args; + va_start(args, format); + set_msg(format, args); + va_end(args); +} + +SaneException::SaneException(const char* format, ...) : status_(SANE_STATUS_INVAL) +{ + std::va_list args; + va_start(args, format); + set_msg(format, args); + va_end(args); +} + +SANE_Status SaneException::status() const +{ + return status_; +} + +const char* SaneException::what() const noexcept +{ + return msg_.c_str(); +} + +void SaneException::set_msg() +{ + const char* status_msg = sane_strstatus(status_); + std::size_t status_msg_len = std::strlen(status_msg); + msg_.reserve(status_msg_len); + msg_ = status_msg; +} + +void SaneException::set_msg(const char* format, std::va_list vlist) +{ + const char* status_msg = sane_strstatus(status_); + std::size_t status_msg_len = std::strlen(status_msg); + + std::va_list vlist2; + va_copy(vlist2, vlist); + int msg_len = std::vsnprintf(nullptr, 0, format, vlist2); + va_end(vlist2); + + if (msg_len < 0) { + const char* formatting_error_msg = "(error formatting arguments)"; + msg_.reserve(std::strlen(formatting_error_msg) + 3 + status_msg_len); + msg_ = formatting_error_msg; + msg_ += " : "; + msg_ += status_msg; + return; + } + + msg_.reserve(msg_len + status_msg_len + 3); + msg_.resize(msg_len + 1, ' '); + std::vsnprintf(&msg_[0], msg_len + 1, format, vlist); + msg_.resize(msg_len, ' '); + + msg_ += " : "; + msg_ += status_msg; +} + DebugMessageHelper::DebugMessageHelper(const char* func) { func_ = func; @@ -113,3 +181,35 @@ void DebugMessageHelper::vstatus(const char* format, ...) std::vsnprintf(msg_, MAX_BUF_SIZE, format, args); va_end(args); } + +void DebugMessageHelper::log(unsigned level, const char* msg) +{ + DBG(level, "%s: %s\n", func_, msg); +} + +void DebugMessageHelper::vlog(unsigned level, const char* format, ...) +{ + std::string msg; + + std::va_list args; + + va_start(args, format); + int msg_len = std::vsnprintf(nullptr, 0, format, args); + va_end(args); + + if (msg_len < 0) { + DBG(level, "%s: error formatting error message: %s\n", func_, format); + return; + } + msg.resize(msg_len + 1, ' '); + + va_start(args, format); + std::vsnprintf(&msg.front(), msg.size(), format, args); + va_end(args); + + msg.resize(msg_len, ' '); // strip the null character + + DBG(level, "%s: %s\n", func_, msg.c_str()); +} + +} // namespace genesys diff --git a/backend/genesys_error.h b/backend/genesys/error.h index d456581..5aba8cf 100644 --- a/backend/genesys_error.h +++ b/backend/genesys/error.h @@ -49,8 +49,10 @@ #include "../include/sane/sanei_backend.h" #include <stdexcept> +#include <cstdarg> #include <cstring> #include <string> +#include <new> #define DBG_error0 0 /* errors/warnings printed even with devuglevel 0 */ #define DBG_error 1 /* fatal errors */ @@ -62,71 +64,44 @@ #define DBG_io2 7 /* io functions that are called very often */ #define DBG_data 8 /* log image data */ -class SaneException : std::exception { -public: - SaneException(SANE_Status status) : status_(status) - { - set_msg(nullptr); - } +namespace genesys { - SaneException(SANE_Status status, const char* msg) : status_(status) - { - set_msg(msg); - } +class SaneException : public std::exception { +public: + SaneException(SANE_Status status); + SaneException(SANE_Status status, const char* format, ...) + #ifdef __GNUC__ + __attribute__((format(printf, 3, 4))) + #endif + ; - SaneException(const char* msg) : SaneException(SANE_STATUS_INVAL, msg) {} + SaneException(const char* format, ...) + #ifdef __GNUC__ + __attribute__((format(printf, 2, 3))) + #endif + ; - SANE_Status status() const { return status_; } - virtual const char* what() const noexcept override { return msg_.c_str(); } + SANE_Status status() const; + const char* what() const noexcept override; private: - void set_msg(const char* msg) - { - const char* status_msg = sane_strstatus(status_); - std::size_t status_msg_len = std::strlen(status_msg); - - if (msg) { - std::size_t msg_len = std::strlen(msg); - msg_.reserve(msg_len + status_msg_len + 3); - msg_ = msg; - msg_ += " : "; - msg_ += status_msg; - return; - } - - msg_.reserve(status_msg_len); - msg_ = status_msg; - } + void set_msg(); + void set_msg(const char* format, std::va_list vlist); std::string msg_; SANE_Status status_; }; -/** - * call a function and return on error - */ -#define RIE(function) \ - do { status = function; \ - if (status != SANE_STATUS_GOOD) \ - { \ - DBG(DBG_error, "%s: %s\n", __func__, sane_strstatus (status)); \ - return status; \ - } \ - } while (SANE_FALSE) - // call a function and throw an exception on error #define TIE(function) \ do { \ SANE_Status tmp_status = function; \ if (tmp_status != SANE_STATUS_GOOD) { \ - throw SaneException(tmp_status); \ + throw ::genesys::SaneException(tmp_status); \ } \ } while (false) -#define DBGSTART DBG (DBG_proc, "%s start\n", __func__); -#define DBGCOMPLETED DBG (DBG_proc, "%s completed\n", __func__); - class DebugMessageHelper { public: static constexpr unsigned MAX_BUF_SIZE = 120; @@ -149,23 +124,43 @@ public: void clear() { msg_[0] = '\n'; } + void log(unsigned level, const char* msg); + void vlog(unsigned level, const char* format, ...) + #ifdef __GNUC__ + __attribute__((format(printf, 3, 4))) + #endif + ; + private: const char* func_ = nullptr; char msg_[MAX_BUF_SIZE]; unsigned num_exceptions_on_enter_ = 0; }; -#define DBG_HELPER(var) DebugMessageHelper var(__func__) -#define DBG_HELPER_ARGS(var, ...) DebugMessageHelper var(__func__, __VA_ARGS__) + +#if defined(__GNUC__) || defined(__clang__) +#define GENESYS_CURRENT_FUNCTION __PRETTY_FUNCTION__ +#elif defined(__FUNCSIG__) +#define GENESYS_CURRENT_FUNCTION __FUNCSIG__ +#else +#define GENESYS_CURRENT_FUNCTION __func__ +#endif + +#define DBG_HELPER(var) DebugMessageHelper var(GENESYS_CURRENT_FUNCTION) +#define DBG_HELPER_ARGS(var, ...) DebugMessageHelper var(GENESYS_CURRENT_FUNCTION, __VA_ARGS__) template<class F> SANE_Status wrap_exceptions_to_status_code(const char* func, F&& function) { try { - return function(); + function(); + return SANE_STATUS_GOOD; } catch (const SaneException& exc) { + DBG(DBG_error, "%s: got error: %s\n", func, exc.what()); return exc.status(); } catch (const std::bad_alloc& exc) { + (void) exc; + DBG(DBG_error, "%s: failed to allocate memory\n", func); return SANE_STATUS_NO_MEM; } catch (const std::exception& exc) { DBG(DBG_error, "%s: got uncaught exception: %s\n", func, exc.what()); @@ -199,4 +194,6 @@ inline void wrap_status_code_to_exception(SANE_Status status) throw SaneException(status); } +} // namespace genesys + #endif // BACKEND_GENESYS_ERROR_H diff --git a/backend/genesys/fwd.h b/backend/genesys/fwd.h new file mode 100644 index 0000000..2d55f98 --- /dev/null +++ b/backend/genesys/fwd.h @@ -0,0 +1,132 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_FWD_H +#define BACKEND_GENESYS_FWD_H + +namespace genesys { + +// buffer.h +struct Genesys_Buffer; + +// calibration.h +struct Genesys_Calibration_Cache; + +// command_set.h +class CommandSet; + +// device.h +class FixedFloat; +struct Genesys_Gpo; +struct MethodResolutions; +struct Genesys_Model; +struct Genesys_Device; + +// error.h +class DebugMessageHelper; +class SaneException; + +// genesys.h +class GenesysButton; +struct Genesys_Scanner; + +// image.h +class Image; + +// image_buffer.h +class ImageBuffer; +class FakeBufferModel; +class ImageBufferGenesysUsb; + +// image_pipeline.h +class ImagePipelineNode; +// ImagePipelineNode* skipped +class ImagePipelineStack; + +// image_pixel.h +struct Pixel; +struct RawPixel; + +// low.h +struct Genesys_USB_Device_Entry; +struct Motor_Profile; + +// motor.h +struct Genesys_Motor; +struct MotorSlope; +struct MotorSlopeTable; + +// register.h +class Genesys_Register_Set; +struct GenesysRegisterSetState; + +// row_buffer.h +class RowBuffer; + +// usb_device.h +class IUsbDevice; +class UsbDevice; + +// scanner_interface.h +class ScannerInterface; +class ScannerInterfaceUsb; +class TestScannerInterface; + +// sensor.h +class ResolutionFilter; +struct GenesysFrontendLayout; +struct Genesys_Frontend; +struct SensorExposure; +struct Genesys_Sensor; + +// settings.h +struct Genesys_Settings; +struct SetupParams; +struct ScanSession; + +// test_usb_device.h +class TestUsbDevice; + +} // namespace genesys + +#endif diff --git a/backend/genesys.cc b/backend/genesys/genesys.cpp index 0368e21..7c25168 100644 --- a/backend/genesys.cc +++ b/backend/genesys/genesys.cpp @@ -61,35 +61,66 @@ #define DEBUG_NOT_STATIC #include "genesys.h" -#include "genesys_sanei.h" +#include "conv.h" +#include "gl124_registers.h" +#include "gl841_registers.h" +#include "gl843_registers.h" +#include "gl846_registers.h" +#include "gl847_registers.h" +#include "usb_device.h" +#include "utilities.h" +#include "scanner_interface_usb.h" +#include "test_scanner_interface.h" +#include "test_settings.h" #include "../include/sane/sanei_config.h" #include "../include/sane/sanei_magic.h" -#include "genesys_devices.cc" +#include <array> +#include <cmath> #include <cstring> #include <fstream> +#include <iterator> #include <list> +#include <numeric> #include <exception> #include <vector> -StaticInit<std::list<Genesys_Scanner>> s_scanners; -StaticInit<std::vector<SANE_Device>> s_sane_devices; -StaticInit<std::vector<SANE_Device*>> s_sane_devices_ptrs; -StaticInit<std::list<Genesys_Device>> s_devices; +#ifndef SANE_GENESYS_API_LINKAGE +#define SANE_GENESYS_API_LINKAGE extern "C" +#endif + +namespace genesys { + +// Data that we allocate to back SANE_Device objects in s_sane_devices +struct SANE_Device_Data +{ + std::string name; +}; + +namespace { + StaticInit<std::list<Genesys_Scanner>> s_scanners; + StaticInit<std::vector<SANE_Device>> s_sane_devices; + StaticInit<std::vector<SANE_Device_Data>> s_sane_devices_data; + StaticInit<std::vector<SANE_Device*>> s_sane_devices_ptrs; + StaticInit<std::list<Genesys_Device>> s_devices; + + // Maximum time for lamp warm-up + constexpr unsigned WARMUP_TIME = 65; +} // namespace static SANE_String_Const mode_list[] = { SANE_VALUE_SCAN_MODE_COLOR, SANE_VALUE_SCAN_MODE_GRAY, /* SANE_TITLE_HALFTONE, currently unused */ SANE_VALUE_SCAN_MODE_LINEART, - 0 + nullptr }; static SANE_String_Const color_filter_list[] = { SANE_I18N ("Red"), SANE_I18N ("Green"), SANE_I18N ("Blue"), - 0 + nullptr }; static SANE_String_Const cis_color_filter_list[] = { @@ -97,20 +128,7 @@ static SANE_String_Const cis_color_filter_list[] = { SANE_I18N ("Green"), SANE_I18N ("Blue"), SANE_I18N ("None"), - 0 -}; - -static SANE_String_Const source_list[] = { - SANE_I18N (STR_FLATBED), - SANE_I18N (STR_TRANSPARENCY_ADAPTER), - 0 -}; - -static const char* source_list_infrared[] = { - SANE_I18N(STR_FLATBED), - SANE_I18N(STR_TRANSPARENCY_ADAPTER), - SANE_I18N(STR_TRANSPARENCY_ADAPTER_INFRARED), - 0 + nullptr }; static SANE_Range swdespeck_range = { @@ -173,565 +191,156 @@ static const SANE_Range expiration_range = { 1 /* quantization */ }; -Genesys_Sensor& sanei_genesys_find_sensor_any_for_write(Genesys_Device* dev) +const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev) { - for (auto& sensor : *s_sensors) { - if (dev->model->ccd_type == sensor.sensor_id) { + DBG_HELPER(dbg); + for (const auto& sensor : *s_sensors) { + if (dev->model->sensor_id == sensor.sensor_id) { return sensor; } } throw std::runtime_error("Given device does not have sensor defined"); } -const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev) +Genesys_Sensor* find_sensor_impl(Genesys_Device* dev, unsigned dpi, unsigned channels, + ScanMethod scan_method) { - for (const auto& sensor : *s_sensors) { - if (dev->model->ccd_type == sensor.sensor_id) { - return sensor; + DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels, + static_cast<unsigned>(scan_method)); + for (auto& sensor : *s_sensors) { + if (dev->model->sensor_id == sensor.sensor_id && sensor.resolutions.matches(dpi) && + sensor.matches_channel_count(channels) && sensor.method == scan_method) + { + return &sensor; } } - throw std::runtime_error("Given device does not have sensor defined"); + return nullptr; +} + +bool sanei_genesys_has_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels, + ScanMethod scan_method) +{ + DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels, + static_cast<unsigned>(scan_method)); + return find_sensor_impl(dev, dpi, channels, scan_method) != nullptr; } -const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, int dpi, +const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels, ScanMethod scan_method) { - for (const auto& sensor : *s_sensors) { - if (dev->model->ccd_type == sensor.sensor_id && - (sensor.min_resolution == -1 || dpi >= sensor.min_resolution) && - (sensor.max_resolution == -1 || dpi <= sensor.max_resolution) && - sensor.method == scan_method) { - return sensor; - } - } + DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels, + static_cast<unsigned>(scan_method)); + const auto* sensor = find_sensor_impl(dev, dpi, channels, scan_method); + if (sensor) + return *sensor; throw std::runtime_error("Given device does not have sensor defined"); } -Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, int dpi, +Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigned dpi, + unsigned channels, ScanMethod scan_method) { + DBG_HELPER_ARGS(dbg, "dpi: %d, channels: %d, scan_method: %d", dpi, channels, + static_cast<unsigned>(scan_method)); + auto* sensor = find_sensor_impl(dev, dpi, channels, scan_method); + if (sensor) + return *sensor; + throw std::runtime_error("Given device does not have sensor defined"); +} + + +std::vector<std::reference_wrapper<const Genesys_Sensor>> + sanei_genesys_find_sensors_all(Genesys_Device* dev, ScanMethod scan_method) +{ + DBG_HELPER_ARGS(dbg, "scan_method: %d", static_cast<unsigned>(scan_method)); + std::vector<std::reference_wrapper<const Genesys_Sensor>> ret; + for (const Genesys_Sensor& sensor : sanei_genesys_find_sensors_all_for_write(dev, scan_method)) { + ret.push_back(sensor); + } + return ret; +} + +std::vector<std::reference_wrapper<Genesys_Sensor>> + sanei_genesys_find_sensors_all_for_write(Genesys_Device* dev, ScanMethod scan_method) +{ + DBG_HELPER_ARGS(dbg, "scan_method: %d", static_cast<unsigned>(scan_method)); + std::vector<std::reference_wrapper<Genesys_Sensor>> ret; for (auto& sensor : *s_sensors) { - if (dev->model->ccd_type == sensor.sensor_id && - (sensor.min_resolution == -1 || dpi >= sensor.min_resolution) && - (sensor.max_resolution == -1 || dpi <= sensor.max_resolution) && - sensor.method == scan_method) { - return sensor; + if (dev->model->sensor_id == sensor.sensor_id && sensor.method == scan_method) { + ret.push_back(sensor); } } - throw std::runtime_error("Given device does not have sensor defined"); + return ret; } - -void -sanei_genesys_init_structs (Genesys_Device * dev) +void sanei_genesys_init_structs (Genesys_Device * dev) { - unsigned int i, gpo_ok = 0, motor_ok = 0; + DBG_HELPER(dbg); + + bool gpo_ok = false; + bool motor_ok = false; bool fe_ok = false; /* initialize the GPO data stuff */ - for (i = 0; i < sizeof (Gpo) / sizeof (Genesys_Gpo); i++) - { - if (dev->model->gpo_type == Gpo[i].gpo_id) - { - dev->gpo = Gpo[i]; - gpo_ok = 1; - } + for (const auto& gpo : *s_gpo) { + if (dev->model->gpio_id == gpo.id) { + dev->gpo = gpo; + gpo_ok = true; + break; + } } - /* initialize the motor data stuff */ - for (i = 0; i < sizeof (Motor) / sizeof (Genesys_Motor); i++) - { - if (dev->model->motor_type == Motor[i].motor_id) - { - dev->motor = Motor[i]; - motor_ok = 1; - } + // initialize the motor data stuff + for (const auto& motor : *s_motors) { + if (dev->model->motor_id == motor.id) { + dev->motor = motor; + motor_ok = true; + break; + } } for (const auto& frontend : *s_frontends) { - if (dev->model->dac_type == frontend.fe_id) { + if (dev->model->adc_id == frontend.id) { dev->frontend_initial = frontend; + dev->frontend = frontend; fe_ok = true; break; } } - /* sanity check */ - if (motor_ok == 0 || gpo_ok == 0 || !fe_ok) - { - DBG(DBG_error0, "%s: bad description(s) for fe/gpo/motor=%d/%d/%d\n", __func__, - dev->model->ccd_type, dev->model->gpo_type, dev->model->motor_type); + if (!motor_ok || !gpo_ok || !fe_ok) { + throw SaneException("bad description(s) for fe/gpo/motor=%d/%d/%d\n", + static_cast<unsigned>(dev->model->sensor_id), + static_cast<unsigned>(dev->model->gpio_id), + static_cast<unsigned>(dev->model->motor_id)); } - - /* set up initial line distance shift */ - dev->ld_shift_r = dev->model->ld_shift_r; - dev->ld_shift_g = dev->model->ld_shift_g; - dev->ld_shift_b = dev->model->ld_shift_b; -} - -/* main function for slope creation */ -/** - * This function generates a slope table using the given slope - * truncated at the given exposure time or step count, whichever comes first. - * The reached step time is then stored in final_exposure and used for the rest - * of the table. The summed time of the acceleration steps is returned, and the - * number of accerelation steps is put into used_steps. - * - * @param slope_table Table to write to - * @param max_steps Size of slope_table in steps - * @param use_steps Maximum number of steps to use for acceleration - * @param stop_at Minimum step time to use - * @param vstart Start step time of default slope - * @param vend End step time of default slope - * @param steps Step count of default slope - * @param g Power for default slope - * @param used_steps Final number of steps is stored here - * @param vfinal Final step time is stored here - * @return Time for acceleration - * @note All times in pixel time. Correction for other motor timings is not - * done. - */ -SANE_Int -sanei_genesys_generate_slope_table (uint16_t * slope_table, - unsigned int max_steps, - unsigned int use_steps, - uint16_t stop_at, - uint16_t vstart, - uint16_t vend, - unsigned int steps, - double g, - unsigned int *used_steps, - unsigned int *vfinal) -{ - double t; - SANE_Int sum = 0; - unsigned int i; - unsigned int c = 0; - uint16_t t2; - unsigned int dummy; - unsigned int _vfinal; - if (!used_steps) - used_steps = &dummy; - if (!vfinal) - vfinal = &_vfinal; - - DBG(DBG_proc, "%s: table size: %d\n", __func__, max_steps); - - DBG(DBG_proc, "%s: stop at time: %d, use %d steps max\n", __func__, stop_at, use_steps); - - DBG(DBG_proc, "%s: target slope: vstart: %d, vend: %d, steps: %d, g: %g\n", __func__, vstart, - vend, steps, g); - - sum = 0; - c = 0; - *used_steps = 0; - - if (use_steps < 1) - use_steps = 1; - - if (stop_at < vstart) - { - t2 = vstart; - for (i = 0; i < steps && i < use_steps - 1 && i < max_steps; i++, c++) - { - t = pow (((double) i) / ((double) (steps - 1)), g); - t2 = vstart * (1 - t) + t * vend; - if (t2 < stop_at) - break; - *slope_table++ = t2; - /* DBG (DBG_io, "slope_table[%3d] = %5d\n", c, t2); */ - sum += t2; - } - if (t2 > stop_at) - { - DBG(DBG_warn, "Can not reach target speed(%d) in %d steps.\n", stop_at, use_steps); - DBG(DBG_warn, "Expect image to be distorted. Ignore this if only feeding.\n"); - } - *vfinal = t2; - *used_steps += i; - max_steps -= i; - } - else - *vfinal = stop_at; - - for (i = 0; i < max_steps; i++, c++) - { - *slope_table++ = *vfinal; - /* DBG (DBG_io, "slope_table[%3d] = %5d\n", c, *vfinal); */ - } - - (*used_steps)++; - sum += *vfinal; - - DBG(DBG_proc, "%s: returns sum=%d, used %d steps, completed\n", __func__, sum, *used_steps); - - return sum; } /* Generate slope table for motor movement */ /** * This function generates a slope table using the slope from the motor struct * truncated at the given exposure time or step count, whichever comes first. - * The reached step time is then stored in final_exposure and used for the rest - * of the table. The summed time of the acceleration steps is returned, and the + * The summed time of the acceleration steps is returned, and the * number of accerelation steps is put into used_steps. * * @param dev Device struct * @param slope_table Table to write to - * @param max_step Size of slope_table in steps - * @param use_steps Maximum number of steps to use for acceleration * @param step_type Generate table for this step_type. 0=>full, 1=>half, * 2=>quarter * @param exposure_time Minimum exposure time of a scan line * @param yres Resolution of a scan line * @param used_steps Final number of steps is stored here - * @param final_exposure Final step time is stored here - * @param power_mode Power mode (related to the Vref used) of the motor - * @return Time for acceleration + * @return Motor slope table * @note all times in pixel time */ -SANE_Int -sanei_genesys_create_slope_table3 (Genesys_Device * dev, - uint16_t * slope_table, - int max_step, - unsigned int use_steps, - int step_type, - int exposure_time, - double yres, - unsigned int *used_steps, - unsigned int *final_exposure, - int power_mode) -{ - unsigned int sum_time = 0; - unsigned int vtarget; - unsigned int vend; - unsigned int vstart; - unsigned int vfinal; - - DBG(DBG_proc, "%s: step_type = %d, exposure_time = %d, yres = %g, power_mode = %d\n", __func__, - step_type, exposure_time, yres, power_mode); - - /* final speed */ - vtarget = (exposure_time * yres) / dev->motor.base_ydpi; - - vstart = dev->motor.slopes[power_mode][step_type].maximum_start_speed; - vend = dev->motor.slopes[power_mode][step_type].maximum_speed; - - vtarget >>= step_type; - if (vtarget > 65535) - vtarget = 65535; - - vstart >>= step_type; - if (vstart > 65535) - vstart = 65535; - - vend >>= step_type; - if (vend > 65535) - vend = 65535; - - sum_time = sanei_genesys_generate_slope_table (slope_table, - max_step, - use_steps, - vtarget, - vstart, - vend, - dev->motor.slopes[power_mode][step_type].minimum_steps << step_type, - dev->motor.slopes[power_mode][step_type].g, - used_steps, - &vfinal); - - if (final_exposure) - *final_exposure = (vfinal * dev->motor.base_ydpi) / yres; - - DBG(DBG_proc, "%s: returns sum_time=%d, completed\n", __func__, sum_time); - - return sum_time; -} - - -/* alternate slope table creation function */ -/* the hardcoded values (g and vstart) will go in a motor struct */ -static SANE_Int -genesys_create_slope_table2 (Genesys_Device * dev, - uint16_t * slope_table, int steps, - int step_type, int exposure_time, - SANE_Bool same_speed, double yres, - int power_mode) -{ - double t, g; - SANE_Int sum = 0; - int vstart, vend; - int i; - - DBG(DBG_proc, "%s: %d steps, step_type = %d, " - "exposure_time = %d, same_speed = %d, yres = %.2f, power_mode = %d\n", __func__, steps, - step_type, exposure_time, same_speed, yres, power_mode); - - /* start speed */ - if (dev->model->motor_type == MOTOR_5345) - { - if (yres < dev->motor.base_ydpi / 6) - vstart = 2500; - else - vstart = 2000; - } - else - { - if (steps == 2) - vstart = exposure_time; - else if (steps == 3) - vstart = 2 * exposure_time; - else if (steps == 4) - vstart = 1.5 * exposure_time; - else if (steps == 120) - vstart = 1.81674 * exposure_time; - else - vstart = exposure_time; - } - - /* final speed */ - vend = (exposure_time * yres) / (dev->motor.base_ydpi * (1 << step_type)); - - /* - type=1 : full - type=2 : half - type=4 : quarter - vend * type * base_ydpi / exposure = yres - */ - - /* acceleration */ - switch (steps) - { - case 255: - /* test for special case: fast moving slope */ - /* todo: a 'fast' boolean parameter should be better */ - if (vstart == 2000) - g = 0.2013; - else - g = 0.1677; - break; - case 120: - g = 0.5; - break; - case 67: - g = 0.5; - break; - case 64: - g = 0.2555; - break; - case 44: - g = 0.5; - break; - case 4: - g = 0.5; - break; - case 3: - g = 1; - break; - case 2: - vstart = vend; - g = 1; - break; - default: - g = 0.2635; - } - - /* if same speed, no 'g' */ - sum = 0; - if (same_speed) - { - for (i = 0; i < 255; i++) - { - slope_table[i] = vend; - sum += slope_table[i]; - DBG (DBG_io, "slope_table[%3d] = %5d\n", i, slope_table[i]); - } - } - else - { - for (i = 0; i < steps; i++) - { - t = pow (((double) i) / ((double) (steps - 1)), g); - slope_table[i] = vstart * (1 - t) + t * vend; - DBG (DBG_io, "slope_table[%3d] = %5d\n", i, slope_table[i]); - sum += slope_table[i]; - } - for (i = steps; i < 255; i++) - { - slope_table[i] = vend; - DBG (DBG_io, "slope_table[%3d] = %5d\n", i, slope_table[i]); - sum += slope_table[i]; - } - } - - DBG(DBG_proc, "%s: returns sum=%d, completed\n", __func__, sum); - - return sum; -} - -/* Generate slope table for motor movement */ -/* todo: check details */ -SANE_Int -sanei_genesys_create_slope_table (Genesys_Device * dev, - uint16_t * slope_table, int steps, - int step_type, int exposure_time, - SANE_Bool same_speed, double yres, - int power_mode) +MotorSlopeTable sanei_genesys_create_slope_table3(AsicType asic_type, const Genesys_Motor& motor, + StepType step_type, int exposure_time, + unsigned yres) { - double t; - double start_speed; - double g; - uint32_t time_period; - int sum_time = 0; - int i, divider; - int same_step; - - if (dev->model->motor_type == MOTOR_5345 - || dev->model->motor_type == MOTOR_HP2300 - || dev->model->motor_type == MOTOR_HP2400) - return genesys_create_slope_table2 (dev, slope_table, steps, - step_type, exposure_time, - same_speed, yres, power_mode); - - DBG(DBG_proc, "%s: %d steps, step_type = %d, exposure_time = %d, same_speed =%d\n", __func__, - steps, step_type, exposure_time, same_speed); - DBG(DBG_proc, "%s: yres = %.2f\n", __func__, yres); - - g = 0.6; - start_speed = 0.01; - same_step = 4; - divider = 1 << step_type; - - time_period = - (uint32_t) (yres * exposure_time / dev->motor.base_ydpi /*MOTOR_GEAR */ ); - if ((time_period < 2000) && (same_speed)) - same_speed = SANE_FALSE; - - time_period = time_period / divider; - - if (same_speed) - { - for (i = 0; i < steps; i++) - { - slope_table[i] = (uint16_t) time_period; - sum_time += time_period; + unsigned target_speed_w = (exposure_time * yres) / motor.base_ydpi; - DBG (DBG_io, "slope_table[%d] = %d\n", i, time_period); - } - DBG(DBG_info, "%s: returns sum_time=%d, completed\n", __func__, sum_time); - return sum_time; - } - - if (time_period > MOTOR_SPEED_MAX * 5) - { - g = 1.0; - start_speed = 0.05; - same_step = 2; - } - else if (time_period > MOTOR_SPEED_MAX * 4) - { - g = 0.8; - start_speed = 0.04; - same_step = 2; - } - else if (time_period > MOTOR_SPEED_MAX * 3) - { - g = 0.7; - start_speed = 0.03; - same_step = 2; - } - else if (time_period > MOTOR_SPEED_MAX * 2) - { - g = 0.6; - start_speed = 0.02; - same_step = 3; - } - - if (dev->model->motor_type == MOTOR_ST24) - { - steps = 255; - switch ((int) yres) - { - case 2400: - g = 0.1672; - start_speed = 1.09; - break; - case 1200: - g = 1; - start_speed = 6.4; - break; - case 600: - g = 0.1672; - start_speed = 1.09; - break; - case 400: - g = 0.2005; - start_speed = 20.0 / 3.0 /*7.5 */ ; - break; - case 300: - g = 0.253; - start_speed = 2.182; - break; - case 150: - g = 0.253; - start_speed = 4.367; - break; - default: - g = 0.262; - start_speed = 7.29; - } - same_step = 1; - } - - if (steps <= same_step) - { - time_period = - (uint32_t) (yres * exposure_time / - dev->motor.base_ydpi /*MOTOR_GEAR */ ); - time_period = time_period / divider; - - if (time_period > 65535) - time_period = 65535; - - for (i = 0; i < same_step; i++) - { - slope_table[i] = (uint16_t) time_period; - sum_time += time_period; - - DBG (DBG_io, "slope_table[%d] = %d\n", i, time_period); - } - - DBG(DBG_proc, "%s: returns sum_time=%d, completed\n", __func__, sum_time); - return sum_time; - } - - for (i = 0; i < steps; i++) - { - double j = ((double) i) - same_step + 1; /* start from 1/16 speed */ - - if (j <= 0) - t = 0; - else - t = pow (j / (steps - same_step), g); - - time_period = /* time required for full steps */ - (uint32_t) (yres * exposure_time / - dev->motor.base_ydpi /*MOTOR_GEAR */ * - (start_speed + (1 - start_speed) * t)); - - time_period = time_period / divider; - if (time_period > 65535) - time_period = 65535; - - slope_table[i] = (uint16_t) time_period; - sum_time += time_period; - - DBG (DBG_io, "slope_table[%d] = %d\n", i, slope_table[i]); - } - - DBG(DBG_proc, "%s: returns sum_time=%d, completed\n", __func__, sum_time); - - return sum_time; + return create_slope_table(motor.get_slope(step_type), target_speed_w, step_type, 1, 1, + get_slope_table_max_size(asic_type)); } /** @brief computes gamma table @@ -758,10 +367,11 @@ sanei_genesys_create_gamma_table (std::vector<uint16_t>& gamma_table, int size, maximum, gamma_max, gamma); for (i = 0; i < size; i++) { - value = gamma_max * pow ((float) i / size, 1.0 / gamma); - if (value > maximum) - value = maximum; - gamma_table[i] = value; + value = static_cast<float>(gamma_max * std::pow(static_cast<double>(i) / size, 1.0 / gamma)); + if (value > maximum) { + value = maximum; + } + gamma_table[i] = static_cast<std::uint16_t>(value); } DBG(DBG_proc, "%s: completed\n", __func__); } @@ -771,13 +381,18 @@ void sanei_genesys_create_default_gamma_table(Genesys_Device* dev, { int size = 0; int max = 0; - if (dev->model->asic_type == GENESYS_GL646) { + if (dev->model->asic_type == AsicType::GL646) { if (dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) { size = 16384; } else { size = 4096; } max = size - 1; + } else if (dev->model->asic_type == AsicType::GL124 || + dev->model->asic_type == AsicType::GL846 || + dev->model->asic_type == AsicType::GL847) { + size = 257; + max = 65535; } else { size = 256; max = 65535; @@ -796,15 +411,12 @@ void sanei_genesys_create_default_gamma_table(Genesys_Device* dev, Note: The enhance option of the scanners does _not_ help. It only halves the amount of pixels transfered. */ -SANE_Int -sanei_genesys_exposure_time2 (Genesys_Device * dev, float ydpi, - int step_type, int endpixel, - int exposure_by_led, int power_mode) +SANE_Int sanei_genesys_exposure_time2(Genesys_Device * dev, float ydpi, + StepType step_type, int endpixel, int exposure_by_led) { int exposure_by_ccd = endpixel + 32; - int exposure_by_motor = - (dev->motor.slopes[power_mode][step_type].maximum_speed - * dev->motor.base_ydpi) / ydpi; + unsigned max_speed_motor_w = dev->motor.get_slope(step_type).max_speed_w; + int exposure_by_motor = static_cast<int>((max_speed_motor_w * dev->motor.base_ydpi) / ydpi); int exposure = exposure_by_ccd; @@ -814,122 +426,12 @@ sanei_genesys_exposure_time2 (Genesys_Device * dev, float ydpi, if (exposure < exposure_by_led && dev->model->is_cis) exposure = exposure_by_led; - DBG(DBG_info, "%s: ydpi=%d, step=%d, endpixel=%d led=%d, power=%d => exposure=%d\n", __func__, - (int)ydpi, step_type, endpixel, exposure_by_led, power_mode, exposure); + DBG(DBG_info, "%s: ydpi=%d, step=%d, endpixel=%d led=%d => exposure=%d\n", __func__, + static_cast<int>(ydpi), static_cast<unsigned>(step_type), endpixel, + exposure_by_led, exposure); return exposure; } -/* computes the exposure_time on the basis of the given horizontal dpi */ -/* we will clean/simplify it by using constants from a future motor struct */ -SANE_Int -sanei_genesys_exposure_time (Genesys_Device * dev, Genesys_Register_Set * reg, - int xdpi) -{ - if (dev->model->motor_type == MOTOR_5345) - { - if (dev->model->cmd_set->get_filter_bit (reg)) - { - /* monochrome */ - switch (xdpi) - { - case 600: - return 8500; - case 500: - case 400: - case 300: - case 250: - case 200: - case 150: - return 5500; - case 100: - return 6500; - case 50: - return 12000; - default: - return 11000; - } - } - else - { - /* color scan */ - switch (xdpi) - { - case 300: - case 250: - case 200: - return 5500; - case 50: - return 12000; - default: - return 11000; - } - } - } - else if (dev->model->motor_type == MOTOR_HP2400) - { - if (dev->model->cmd_set->get_filter_bit (reg)) - { - /* monochrome */ - switch (xdpi) - { - case 200: - return 7210; - default: - return 11111; - } - } - else - { - /* color scan */ - switch (xdpi) - { - case 600: - return 8751; /*11902; 19200 */ - default: - return 11111; - } - } - } - else if (dev->model->motor_type == MOTOR_HP2300) - { - if (dev->model->cmd_set->get_filter_bit (reg)) - { - /* monochrome */ - switch (xdpi) - { - case 600: - return 8699; /* 3200; */ - case 300: - return 3200; /*10000;, 3200 -> too dark */ - case 150: - return 4480; /* 3200 ???, warmup needs 4480 */ - case 75: - return 5500; - default: - return 11111; - } - } - else - { - /* color scan */ - switch (xdpi) - { - case 600: - return 8699; - case 300: - return 4349; - case 150: - case 75: - return 4480; - default: - return 11111; - } - } - } - return 11000; -} - - /* Sends a block of shading information to the scanner. The data is placed at address 0x0000 for color mode, gray mode and @@ -940,25 +442,19 @@ sanei_genesys_exposure_time (Genesys_Device * dev, Genesys_Register_Set * reg, The data needs to be of size "size", and in little endian byte order. */ -static SANE_Status -genesys_send_offset_and_shading (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, - int size) +static void genesys_send_offset_and_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + uint8_t* data, int size) { + DBG_HELPER_ARGS(dbg, "(size = %d)", size); int dpihw; int start_address; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s: (size = %d)\n", __func__, size); /* ASIC higher than gl843 doesn't have register 2A/2B, so we route to * a per ASIC shading data loading function if available. * It is also used for scanners using SHDAREA */ - if(dev->model->cmd_set->send_shading_data!=NULL) - { - status=dev->model->cmd_set->send_shading_data(dev, sensor, data, size); - DBGCOMPLETED; - return status; + if (dev->cmd_set->has_send_shading_data()) { + dev->cmd_set->send_shading_data(dev, sensor, data, size); + return; } /* gl646, gl84[123] case */ @@ -969,71 +465,57 @@ genesys_send_offset_and_shading (Genesys_Device * dev, const Genesys_Sensor& sen /* many scanners send coefficient for lineart/gray like in color mode */ if ((dev->settings.scan_mode == ScanColorMode::LINEART || dev->settings.scan_mode == ScanColorMode::HALFTONE) - && dev->model->ccd_type != CCD_PLUSTEK3800 - && dev->model->ccd_type != CCD_KVSS080 - && dev->model->ccd_type != CCD_G4050 - && dev->model->ccd_type != CCD_CS4400F - && dev->model->ccd_type != CCD_CS8400F - && dev->model->ccd_type != CCD_CS8600F - && dev->model->ccd_type != CCD_DSMOBILE600 - && dev->model->ccd_type != CCD_XP300 - && dev->model->ccd_type != CCD_DP665 - && dev->model->ccd_type != CCD_DP685 - && dev->model->ccd_type != CIS_CANONLIDE80 - && dev->model->ccd_type != CCD_ROADWARRIOR - && dev->model->ccd_type != CCD_HP2300 - && dev->model->ccd_type != CCD_HP2400 - && dev->model->ccd_type != CCD_HP3670 - && dev->model->ccd_type != CCD_5345) /* lineart, halftone */ - { - if (dpihw == 0) /* 600 dpi */ - start_address = 0x02a00; - else if (dpihw == 1) /* 1200 dpi */ - start_address = 0x05500; - else if (dpihw == 2) /* 2400 dpi */ - start_address = 0x0a800; - else /* reserved */ - return SANE_STATUS_INVAL; - } - else /* color */ - start_address = 0x00; - - status = sanei_genesys_set_buffer_address (dev, start_address); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; + && dev->model->sensor_id != SensorId::CCD_PLUSTEK_OPTICBOOK_3800 + && dev->model->sensor_id != SensorId::CCD_KVSS080 + && dev->model->sensor_id != SensorId::CCD_G4050 + && dev->model->sensor_id != SensorId::CCD_HP_4850C + && dev->model->sensor_id != SensorId::CCD_CANON_4400F + && dev->model->sensor_id != SensorId::CCD_CANON_8400F + && dev->model->sensor_id != SensorId::CCD_CANON_8600F + && dev->model->sensor_id != SensorId::CCD_DSMOBILE600 + && dev->model->sensor_id != SensorId::CCD_XP300 + && dev->model->sensor_id != SensorId::CCD_DP665 + && dev->model->sensor_id != SensorId::CCD_DP685 + && dev->model->sensor_id != SensorId::CIS_CANON_LIDE_80 + && dev->model->sensor_id != SensorId::CCD_ROADWARRIOR + && dev->model->sensor_id != SensorId::CCD_HP2300 + && dev->model->sensor_id != SensorId::CCD_HP2400 + && dev->model->sensor_id != SensorId::CCD_HP3670 + && dev->model->sensor_id != SensorId::CCD_5345) /* lineart, halftone */ + { + if (dpihw == 0) { /* 600 dpi */ + start_address = 0x02a00; + } else if (dpihw == 1) { /* 1200 dpi */ + start_address = 0x05500; + } else if (dpihw == 2) { /* 2400 dpi */ + start_address = 0x0a800; + } else { /* reserved */ + throw SaneException("unknown dpihw"); + } } - - status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, data, size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading table: %s\n", __func__, sane_strstatus(status)); - return status; + else { // color + start_address = 0x00; } - DBGCOMPLETED; - - return SANE_STATUS_GOOD; + dev->interface->write_buffer(0x3c, start_address, data, size); } -/* ? */ -SANE_Status -sanei_genesys_init_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - int pixels_per_line) +// ? +void sanei_genesys_init_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + int pixels_per_line) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER_ARGS(dbg, "pixels_per_line: %d", pixels_per_line); + + if (dev->model->flags & GENESYS_FLAG_CALIBRATION_HOST_SIDE) { + return; + } + int channels; int i; - /* these models don't need to init shading data due to the use of specific send shading data - function */ - if (dev->model->ccd_type==CCD_KVSS080 - || dev->model->ccd_type==CCD_G4050 - || dev->model->ccd_type==CCD_CS4400F - || dev->model->ccd_type==CCD_CS8400F - || dev->model->cmd_set->send_shading_data!=NULL) - return SANE_STATUS_GOOD; + if (dev->cmd_set->has_send_shading_data()) { + return; + } DBG(DBG_proc, "%s (pixels_per_line = %d)\n", __func__, pixels_per_line); @@ -1059,56 +541,49 @@ sanei_genesys_init_shading_data (Genesys_Device * dev, const Genesys_Sensor& sen *shading_data_ptr++ = 0x40; /* white hi -> 0x4000 */ } - status = genesys_send_offset_and_shading (dev, sensor, - shading_data.data(), - pixels_per_line * 4 * channels); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading data: %s\n", __func__, - sane_strstatus (status)); - } - - DBGCOMPLETED; - return status; + genesys_send_offset_and_shading(dev, sensor, shading_data.data(), + pixels_per_line * 4 * channels); } -/* Find the position of the reference point: - takes gray level 8 bits data and find - first CCD usable pixel and top of scanning area */ -SANE_Status -sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sensor, - uint8_t * data, - int start_pixel, int dpi, int width, - int height) +// Find the position of the reference point: takes gray level 8 bits data and find +// first CCD usable pixel and top of scanning area +void sanei_genesys_search_reference_point(Genesys_Device* dev, Genesys_Sensor& sensor, + const uint8_t* src_data, int start_pixel, int dpi, + int width, int height) { + DBG_HELPER(dbg); int x, y; int current, left, top = 0; int size, count; int level = 80; /* edge threshold level */ - /*sanity check */ - if ((width < 3) || (height < 3)) - return SANE_STATUS_INVAL; + // sanity check + if ((width < 3) || (height < 3)) { + throw SaneException("invalid width or height"); + } /* transformed image data */ size = width * height; + std::vector<uint8_t> image2(size, 0); std::vector<uint8_t> image(size, 0); /* laplace filter to denoise picture */ - memcpy(image.data(), data, size); // to initialize unprocessed part of the image buffer - for (y = 1; y < height - 1; y++) - for (x = 1; x < width - 1; x++) - { - image[y * width + x] = - (data[(y - 1) * width + x + 1] + 2 * data[(y - 1) * width + x] + - data[(y - 1) * width + x - 1] + 2 * data[y * width + x + 1] + - 4 * data[y * width + x] + 2 * data[y * width + x - 1] + - data[(y + 1) * width + x + 1] + 2 * data[(y + 1) * width + x] + - data[(y + 1) * width + x - 1]) / 16; - } + std::memcpy(image2.data(), src_data, size); + std::memcpy(image.data(), src_data, size); // to initialize unprocessed part of the image buffer + + for (y = 1; y < height - 1; y++) { + for (x = 1; x < width - 1; x++) { + image[y * width + x] = + (image2[(y - 1) * width + x + 1] + 2 * image2[(y - 1) * width + x] + + image2[(y - 1) * width + x - 1] + 2 * image2[y * width + x + 1] + + 4 * image2[y * width + x] + 2 * image2[y * width + x - 1] + + image2[(y + 1) * width + x + 1] + 2 * image2[(y + 1) * width + x] + + image2[(y + 1) * width + x - 1]) / 16; + } + } - memcpy (data, image.data(), size); + image2 = image; if (DBG_LEVEL >= DBG_data) sanei_genesys_write_pnm_file("gl_laplace.pnm", image.data(), 8, 1, width, height); @@ -1119,13 +594,11 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens and finds threshold level */ level = 0; - for (y = 2; y < height - 2; y++) - for (x = 2; x < width - 2; x++) - { - current = - data[(y - 1) * width + x + 1] - data[(y - 1) * width + x - 1] + - 2 * data[y * width + x + 1] - 2 * data[y * width + x - 1] + - data[(y + 1) * width + x + 1] - data[(y + 1) * width + x - 1]; + for (y = 2; y < height - 2; y++) { + for (x = 2; x < width - 2; x++) { + current = image2[(y - 1) * width + x + 1] - image2[(y - 1) * width + x - 1] + + 2 * image2[y * width + x + 1] - 2 * image2[y * width + x - 1] + + image2[(y + 1) * width + x + 1] - image2[(y + 1) * width + x - 1]; if (current < 0) current = -current; if (current > 255) @@ -1133,7 +606,8 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens image[y * width + x] = current; if (current > level) level = current; - } + } + } if (DBG_LEVEL >= DBG_data) sanei_genesys_write_pnm_file("gl_xsobel.pnm", image.data(), 8, 1, width, height); @@ -1160,8 +634,8 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens sanei_genesys_write_pnm_file("gl_detected-xsobel.pnm", image.data(), 8, 1, width, height); left = left / count; - /* turn it in CCD pixel at full sensor optical resolution */ - sensor.CCD_start_xoffset = start_pixel + (left * sensor.optical_res) / dpi; + // turn it in CCD pixel at full sensor optical resolution + sensor.ccd_start_xoffset = start_pixel + (left * sensor.optical_res) / dpi; /* find top edge by detecting black strip */ /* apply Y direction sobel filter @@ -1170,13 +644,11 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens 1 2 1 */ level = 0; - for (y = 2; y < height - 2; y++) - for (x = 2; x < width - 2; x++) - { - current = - -data[(y - 1) * width + x + 1] - 2 * data[(y - 1) * width + x] - - data[(y - 1) * width + x - 1] + data[(y + 1) * width + x + 1] + - 2 * data[(y + 1) * width + x] + data[(y + 1) * width + x - 1]; + for (y = 2; y < height - 2; y++) { + for (x = 2; x < width - 2; x++) { + current = -image2[(y - 1) * width + x + 1] - 2 * image2[(y - 1) * width + x] - + image2[(y - 1) * width + x - 1] + image2[(y + 1) * width + x + 1] + + 2 * image2[(y + 1) * width + x] + image2[(y + 1) * width + x - 1]; if (current < 0) current = -current; if (current > 255) @@ -1185,6 +657,7 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens if (current > level) level = current; } + } if (DBG_LEVEL >= DBG_data) sanei_genesys_write_pnm_file("gl_ysobel.pnm", image.data(), 8, 1, width, height); @@ -1192,8 +665,8 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens level = level / 3; /* search top of horizontal black stripe : TODO yet another flag */ - if (dev->model->ccd_type == CCD_5345 - && dev->model->motor_type == MOTOR_5345) + if (dev->model->sensor_id == SensorId::CCD_5345 + && dev->model->motor_id == MotorId::MD_5345) { top = 0; count = 0; @@ -1215,18 +688,15 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens /* bottom of black stripe is of fixed witdh, this hardcoded value * will be moved into device struct if more such values are needed */ top += 10; - dev->model->y_offset_calib = SANE_FIX ((top * MM_PER_INCH) / dpi); - DBG(DBG_info, "%s: black stripe y_offset = %f mm \n", __func__, - SANE_UNFIX (dev->model->y_offset_calib)); + dev->model->y_offset_calib_white = (top * MM_PER_INCH) / dpi; + DBG(DBG_info, "%s: black stripe y_offset = %f mm \n", __func__, + dev->model->y_offset_calib_white.value()); } /* find white corner in dark area : TODO yet another flag */ - if ((dev->model->ccd_type == CCD_HP2300 - && dev->model->motor_type == MOTOR_HP2300) - || (dev->model->ccd_type == CCD_HP2400 - && dev->model->motor_type == MOTOR_HP2400) - || (dev->model->ccd_type == CCD_HP3670 - && dev->model->motor_type == MOTOR_HP3670)) + if ((dev->model->sensor_id == SensorId::CCD_HP2300 && dev->model->motor_id == MotorId::HP2300) || + (dev->model->sensor_id == SensorId::CCD_HP2400 && dev->model->motor_id == MotorId::HP2400) || + (dev->model->sensor_id == SensorId::CCD_HP3670 && dev->model->motor_id == MotorId::HP3670)) { top = 0; count = 0; @@ -1239,92 +709,617 @@ sanei_genesys_search_reference_point (Genesys_Device * dev, Genesys_Sensor& sens count++; } top = top / count; - dev->model->y_offset_calib = SANE_FIX ((top * MM_PER_INCH) / dpi); - DBG(DBG_info, "%s: white corner y_offset = %f mm\n", __func__, - SANE_UNFIX (dev->model->y_offset_calib)); + dev->model->y_offset_calib_white = (top * MM_PER_INCH) / dpi; + DBG(DBG_info, "%s: white corner y_offset = %f mm\n", __func__, + dev->model->y_offset_calib_white.value()); } - DBG(DBG_proc, "%s: CCD_start_xoffset = %d, left = %d, top = %d\n", __func__, - sensor.CCD_start_xoffset, left, top); + DBG(DBG_proc, "%s: ccd_start_xoffset = %d, left = %d, top = %d\n", __func__, + sensor.ccd_start_xoffset, left, top); +} - return SANE_STATUS_GOOD; +namespace gl843 { + void gl843_park_xpa_lamp(Genesys_Device* dev); + void gl843_set_xpa_motor_power(Genesys_Device* dev, Genesys_Register_Set& regs, bool set); +} // namespace gl843 + +namespace gl124 { + void gl124_setup_scan_gpio(Genesys_Device* dev, int resolution); +} // namespace gl124 + +void scanner_clear_scan_and_feed_counts(Genesys_Device& dev) +{ + switch (dev.model->asic_type) { + case AsicType::GL843: { + dev.interface->write_register(gl843::REG_0x0D, + gl843::REG_0x0D_CLRLNCNT | gl843::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL845: + case AsicType::GL846: { + dev.interface->write_register(gl846::REG_0x0D, + gl846::REG_0x0D_CLRLNCNT | gl846::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL847:{ + dev.interface->write_register(gl847::REG_0x0D, + gl847::REG_0x0D_CLRLNCNT | gl847::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL124:{ + dev.interface->write_register(gl124::REG_0x0D, + gl124::REG_0x0D_CLRLNCNT | gl124::REG_0x0D_CLRMCNT); + break; + } + default: + throw SaneException("Unsupported asic type"); + } } +void scanner_clear_scan_and_feed_counts2(Genesys_Device& dev) +{ + // FIXME: switch to scanner_clear_scan_and_feed_counts when updating tests + switch (dev.model->asic_type) { + case AsicType::GL843: { + dev.interface->write_register(gl843::REG_0x0D, gl843::REG_0x0D_CLRLNCNT); + dev.interface->write_register(gl843::REG_0x0D, gl843::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL845: + case AsicType::GL846: { + dev.interface->write_register(gl846::REG_0x0D, gl846::REG_0x0D_CLRLNCNT); + dev.interface->write_register(gl846::REG_0x0D, gl846::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL847: { + dev.interface->write_register(gl847::REG_0x0D, gl847::REG_0x0D_CLRLNCNT); + dev.interface->write_register(gl847::REG_0x0D, gl847::REG_0x0D_CLRMCNT); + break; + } + case AsicType::GL124: { + dev.interface->write_register(gl124::REG_0x0D, gl124::REG_0x0D_CLRLNCNT); + dev.interface->write_register(gl124::REG_0x0D, gl124::REG_0x0D_CLRMCNT); + break; + } + default: + throw SaneException("Unsupported asic type"); + } +} -void -sanei_genesys_calculate_zmode2 (SANE_Bool two_table, - uint32_t exposure_time, - uint16_t * slope_table, - int reg21, - int move, int reg22, uint32_t * z1, - uint32_t * z2) +bool scanner_is_motor_stopped(Genesys_Device& dev) { - int i; - int sum; - DBG(DBG_info, "%s: two_table=%d\n", __func__, two_table); + switch (dev.model->asic_type) { + case AsicType::GL646: { + auto status = scanner_read_status(dev); + return !status.is_motor_enabled && status.is_feeding_finished; + } + case AsicType::GL841: { + auto reg = dev.interface->read_register(gl841::REG_0x40); - /* acceleration total time */ - sum = 0; - for (i = 0; i < reg21; i++) - sum += slope_table[i]; - - /* compute Z1MOD */ - /* c=sum(slope_table;reg21) - d=reg22*cruising speed - Z1MOD=(c+d) % exposure_time */ - *z1 = (sum + reg22 * slope_table[reg21 - 1]) % exposure_time; - - /* compute Z2MOD */ - /* a=sum(slope_table;reg21), b=move or 1 if 2 tables */ - /* Z2MOD=(a+b) % exposure_time */ - if (!two_table) - sum = sum + (move * slope_table[reg21 - 1]); - else - sum = sum + slope_table[reg21 - 1]; - *z2 = sum % exposure_time; + return (!(reg & gl841::REG_0x40_DATAENB) && !(reg & gl841::REG_0x40_MOTMFLG)); + } + case AsicType::GL843: { + auto status = scanner_read_status(dev); + auto reg = dev.interface->read_register(gl843::REG_0x40); + + return (!(reg & gl843::REG_0x40_DATAENB) && !(reg & gl843::REG_0x40_MOTMFLG) && + !status.is_motor_enabled); + } + case AsicType::GL845: + case AsicType::GL846: { + auto status = scanner_read_status(dev); + auto reg = dev.interface->read_register(gl846::REG_0x40); + + return (!(reg & gl846::REG_0x40_DATAENB) && !(reg & gl846::REG_0x40_MOTMFLG) && + !status.is_motor_enabled); + } + case AsicType::GL847: { + auto status = scanner_read_status(dev); + auto reg = dev.interface->read_register(gl847::REG_0x40); + + return (!(reg & gl847::REG_0x40_DATAENB) && !(reg & gl847::REG_0x40_MOTMFLG) && + !status.is_motor_enabled); + } + case AsicType::GL124: { + auto status = scanner_read_status(dev); + auto reg = dev.interface->read_register(gl124::REG_0x100); + + return (!(reg & gl124::REG_0x100_DATAENB) && !(reg & gl124::REG_0x100_MOTMFLG) && + !status.is_motor_enabled); + } + default: + throw SaneException("Unsupported asic type"); + } } +void scanner_stop_action(Genesys_Device& dev) +{ + DBG_HELPER(dbg); + + switch (dev.model->asic_type) { + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + case AsicType::GL124: + break; + default: + throw SaneException("Unsupported asic type"); + } -/* huh? */ -/* todo: double check */ -/* Z1 and Z2 seem to be a time to synchronize with clock or a phase correction */ -/* steps_sum is the result of create_slope_table */ -/* last_speed is the last entry of the slope_table */ -/* feedl is registers 3d,3e,3f */ -/* fastfed is register 02 bit 3 */ -/* scanfed is register 1f */ -/* fwdstep is register 22 */ -/* tgtime is register 6c bit 6+7 >> 6 */ + if (dev.cmd_set->needs_update_home_sensor_gpio()) { + dev.cmd_set->update_home_sensor_gpio(dev); + } -void -sanei_genesys_calculate_zmode (uint32_t exposure_time, - uint32_t steps_sum, uint16_t last_speed, - uint32_t feedl, uint8_t fastfed, - uint8_t scanfed, uint8_t fwdstep, - uint8_t tgtime, uint32_t * z1, uint32_t * z2) + if (scanner_is_motor_stopped(dev)) { + DBG(DBG_info, "%s: already stopped\n", __func__); + return; + } + + scanner_stop_action_no_move(dev, dev.reg); + + if (is_testing_mode()) { + return; + } + + for (unsigned i = 0; i < 10; ++i) { + if (scanner_is_motor_stopped(dev)) { + return; + } + + dev.interface->sleep_ms(100); + } + + throw SaneException(SANE_STATUS_IO_ERROR, "could not stop motor"); +} + +void scanner_stop_action_no_move(Genesys_Device& dev, genesys::Genesys_Register_Set& regs) +{ + switch (dev.model->asic_type) { + case AsicType::GL646: + case AsicType::GL841: + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + case AsicType::GL124: + break; + default: + throw SaneException("Unsupported asic type"); + } + + regs_set_optical_off(dev.model->asic_type, regs); + // same across all supported ASICs + dev.interface->write_register(0x01, regs.get8(0x01)); + + // looks like certain scanners lock up if we try to scan immediately after stopping previous + // action. + dev.interface->sleep_ms(100); +} + +void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, Direction direction) { - uint8_t exposure_factor; + DBG_HELPER_ARGS(dbg, "steps=%d direction=%d", steps, static_cast<unsigned>(direction)); - exposure_factor = pow (2, tgtime); /* todo: originally, this is always 2^0 ! */ + auto local_reg = dev.reg; - /* Z1 is for buffer-full backward forward moving */ - *z1 = - exposure_factor * ((steps_sum + fwdstep * last_speed) % exposure_time); + unsigned resolution = dev.model->get_resolution_settings(scan_method).get_min_resolution_y(); - /* Z2 is for acceleration before scan */ - if (fastfed) /* two curve mode */ + const auto& sensor = sanei_genesys_find_sensor(&dev, resolution, 3, scan_method); + + bool uses_secondary_head = (scan_method == ScanMethod::TRANSPARENCY || + scan_method == ScanMethod::TRANSPARENCY_INFRARED); + bool uses_secondary_pos = uses_secondary_head && + dev.model->default_method == ScanMethod::FLATBED; + + if (!dev.is_head_pos_known(ScanHeadId::PRIMARY)) { + throw SaneException("Unknown head position"); + } + if (uses_secondary_pos && !dev.is_head_pos_known(ScanHeadId::SECONDARY)) { + throw SaneException("Unknown head position"); + } + if (direction == Direction::BACKWARD && steps > dev.head_pos(ScanHeadId::PRIMARY)) { + throw SaneException("Trying to feed behind the home position %d %d", + steps, dev.head_pos(ScanHeadId::PRIMARY)); + } + if (uses_secondary_pos && direction == Direction::BACKWARD && + steps > dev.head_pos(ScanHeadId::SECONDARY)) { - *z2 = - exposure_factor * ((steps_sum + scanfed * last_speed) % - exposure_time); + throw SaneException("Trying to feed behind the home position %d %d", + steps, dev.head_pos(ScanHeadId::SECONDARY)); + } + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 0; + session.params.starty = steps; + session.params.pixels = 100; + session.params.lines = 3; + session.params.depth = 8; + session.params.channels = 3; + session.params.scan_method = scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + if (dev.model->asic_type == AsicType::GL843) { + session.params.color_filter = ColorFilter::RED; + } else { + session.params.color_filter = dev.settings.color_filter; + } + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::FEEDING | + ScanFlag::IGNORE_LINE_DISTANCE; + + if (dev.model->asic_type == AsicType::GL124) { + session.params.flags |= ScanFlag::DISABLE_BUFFER_FULL_MOVE; + } + + if (direction == Direction::BACKWARD) { + session.params.flags |= ScanFlag::REVERSE; + } + + compute_session(&dev, session, sensor); + + dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session); + + if (dev.model->asic_type != AsicType::GL843) { + regs_set_exposure(dev.model->asic_type, local_reg, {0, 0, 0}); + } + scanner_clear_scan_and_feed_counts2(dev); + + dev.interface->write_registers(local_reg); + if (uses_secondary_head) { + gl843::gl843_set_xpa_motor_power(&dev, local_reg, true); } - else /* one curve mode */ + + try { + scanner_start_action(dev, true); + } catch (...) { + catch_all_exceptions(__func__, [&]() { + gl843::gl843_set_xpa_motor_power(&dev, local_reg, false); + }); + catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); }); + // restore original registers + catch_all_exceptions(__func__, [&]() { dev.interface->write_registers(dev.reg); }); + throw; + } + + if (is_testing_mode()) { + dev.interface->test_checkpoint("feed"); + + dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, direction, steps); + if (uses_secondary_pos) { + dev.advance_head_pos_by_steps(ScanHeadId::SECONDARY, direction, steps); + } + + // FIXME: why don't we stop the scanner like on other ASICs + if (dev.model->asic_type != AsicType::GL843) { + scanner_stop_action(dev); + } + if (uses_secondary_head) { + gl843::gl843_set_xpa_motor_power(&dev, local_reg, false); + } + return; + } + + // wait until feed count reaches the required value + // FIXME: should porbably wait for some timeout + Status status; + for (unsigned i = 0;; ++i) { + status = scanner_read_status(dev); + if (status.is_feeding_finished || ( + direction == Direction::BACKWARD && status.is_at_home)) + { + break; + } + dev.interface->sleep_ms(10); + } + + // FIXME: why don't we stop the scanner like on other ASICs + if (dev.model->asic_type != AsicType::GL843) { + scanner_stop_action(dev); + } + if (uses_secondary_head) { + gl843::gl843_set_xpa_motor_power(&dev, local_reg, false); + } + + dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, direction, steps); + if (uses_secondary_pos) { + dev.advance_head_pos_by_steps(ScanHeadId::SECONDARY, direction, steps); + } + + // looks like certain scanners lock up if we scan immediately after feeding + dev.interface->sleep_ms(100); +} + +void scanner_move_back_home(Genesys_Device& dev, bool wait_until_home) +{ + DBG_HELPER_ARGS(dbg, "wait_until_home = %d", wait_until_home); + + switch (dev.model->asic_type) { + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + case AsicType::GL124: + break; + default: + throw SaneException("Unsupported asic type"); + } + + // FIXME: also check whether the scanner actually has a secondary head + if (!dev.is_head_pos_known(ScanHeadId::SECONDARY) || + dev.head_pos(ScanHeadId::SECONDARY) > 0 || + dev.settings.scan_method == ScanMethod::TRANSPARENCY || + dev.settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + scanner_move_back_home_ta(dev); + } + + if (dev.is_head_pos_known(ScanHeadId::PRIMARY) && + dev.head_pos(ScanHeadId::PRIMARY) > 1000) { - *z2 = - exposure_factor * ((steps_sum + feedl * last_speed) % exposure_time); + // leave 500 steps for regular slow back home + scanner_move(dev, dev.model->default_method, dev.head_pos(ScanHeadId::PRIMARY) - 500, + Direction::BACKWARD); + } + + if (dev.cmd_set->needs_update_home_sensor_gpio()) { + dev.cmd_set->update_home_sensor_gpio(dev); } + + auto status = scanner_read_reliable_status(dev); + + if (status.is_at_home) { + dbg.log(DBG_info, "already at home"); + dev.set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + + if (dev.model->model_id == ModelId::CANON_LIDE_210) { + // move the head back a little first + if (dev.is_head_pos_known(ScanHeadId::PRIMARY) && + dev.head_pos(ScanHeadId::PRIMARY) > 30) + { + scanner_move(dev, dev.model->default_method, 20, Direction::BACKWARD); + } + } + + Genesys_Register_Set local_reg = dev.reg; + unsigned resolution = sanei_genesys_get_lowest_ydpi(&dev); + + const auto& sensor = sanei_genesys_find_sensor(&dev, resolution, 1, dev.model->default_method); + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 100; + if (dev.model->asic_type == AsicType::GL843) { + session.params.starty = 40000; + } else { + session.params.starty = 30000; + } + session.params.pixels = 100; + session.params.lines = 100; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = dev.settings.scan_method; + if (dev.model->asic_type == AsicType::GL843) { + session.params.scan_mode = ScanColorMode::LINEART; + session.params.color_filter = dev.settings.color_filter; + } else { + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::RED; + } + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::REVERSE; + if (dev.model->asic_type == AsicType::GL843) { + session.params.flags |= ScanFlag::DISABLE_BUFFER_FULL_MOVE; + } + + compute_session(&dev, session, sensor); + + dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session); + + scanner_clear_scan_and_feed_counts(dev); + + dev.interface->write_registers(local_reg); + + if (dev.model->asic_type == AsicType::GL124) { + gl124::gl124_setup_scan_gpio(&dev, resolution); + } + + try { + scanner_start_action(dev, true); + } catch (...) { + catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); }); + // restore original registers + catch_all_exceptions(__func__, [&]() + { + dev.interface->write_registers(dev.reg); + }); + throw; + } + + if (dev.cmd_set->needs_update_home_sensor_gpio()) { + dev.cmd_set->update_home_sensor_gpio(dev); + } + + if (is_testing_mode()) { + dev.interface->test_checkpoint("move_back_home"); + dev.set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + + if (wait_until_home) { + for (unsigned i = 0; i < 300; ++i) { + auto status = scanner_read_status(dev); + + if (status.is_at_home) { + dbg.log(DBG_info, "reached home position"); + if (dev.model->asic_type == AsicType::GL846 || + dev.model->asic_type == AsicType::GL847) + { + scanner_stop_action(dev); + } + dev.set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + + dev.interface->sleep_ms(100); + } + + // when we come here then the scanner needed too much time for this, so we better stop + // the motor + catch_all_exceptions(__func__, [&](){ scanner_stop_action(dev); }); + dev.set_head_pos_unknown(); + throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); + } + dbg.log(DBG_info, "scanhead is still moving"); } +void scanner_move_back_home_ta(Genesys_Device& dev) +{ + DBG_HELPER(dbg); + + switch (dev.model->asic_type) { + case AsicType::GL843: + break; + default: + throw SaneException("Unsupported asic type"); + } + + Genesys_Register_Set local_reg = dev.reg; + + auto scan_method = ScanMethod::TRANSPARENCY; + unsigned resolution = dev.model->get_resolution_settings(scan_method).get_min_resolution_y(); + + const auto& sensor = sanei_genesys_find_sensor(&dev, resolution, 1, scan_method); + + if (dev.is_head_pos_known(ScanHeadId::SECONDARY) && + dev.head_pos(ScanHeadId::SECONDARY) > 1000) + { + // leave 500 steps for regular slow back home + scanner_move(dev, scan_method, dev.head_pos(ScanHeadId::SECONDARY) - 500, + Direction::BACKWARD); + } + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 100; + session.params.starty = 30000; + session.params.pixels = 100; + session.params.lines = 100; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::REVERSE; + + compute_session(&dev, session, sensor); + + dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session); + + scanner_clear_scan_and_feed_counts(dev); + + dev.interface->write_registers(local_reg); + gl843::gl843_set_xpa_motor_power(&dev, local_reg, true); + + try { + scanner_start_action(dev, true); + } catch (...) { + catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); }); + // restore original registers + catch_all_exceptions(__func__, [&]() { dev.interface->write_registers(dev.reg); }); + throw; + } + + if (is_testing_mode()) { + dev.interface->test_checkpoint("move_back_home_ta"); + + if (dev.is_head_pos_known(ScanHeadId::PRIMARY)) { + if (dev.head_pos(ScanHeadId::PRIMARY) > dev.head_pos(ScanHeadId::SECONDARY)) { + dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::BACKWARD, + dev.head_pos(ScanHeadId::SECONDARY)); + } else { + dev.set_head_pos_zero(ScanHeadId::PRIMARY); + } + dev.set_head_pos_zero(ScanHeadId::SECONDARY); + } + + scanner_stop_action(dev); + gl843::gl843_set_xpa_motor_power(&dev, local_reg, false); + return; + } + + for (unsigned i = 0; i < 1200; ++i) { + + auto status = scanner_read_status(dev); + + if (status.is_at_home) { + dbg.log(DBG_info, "TA reached home position"); + + if (dev.is_head_pos_known(ScanHeadId::PRIMARY)) { + if (dev.head_pos(ScanHeadId::PRIMARY) > dev.head_pos(ScanHeadId::SECONDARY)) { + dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::BACKWARD, + dev.head_pos(ScanHeadId::SECONDARY)); + } else { + dev.set_head_pos_zero(ScanHeadId::PRIMARY); + } + dev.set_head_pos_zero(ScanHeadId::SECONDARY); + } + + scanner_stop_action(dev); + gl843::gl843_set_xpa_motor_power(&dev, local_reg, false); + return; + } + + dev.interface->sleep_ms(100); + } + + throw SaneException("Timeout waiting for XPA lamp to park"); +} + +void sanei_genesys_calculate_zmod(bool two_table, + uint32_t exposure_time, + const std::vector<uint16_t>& slope_table, + unsigned acceleration_steps, + unsigned move_steps, + unsigned buffer_acceleration_steps, + uint32_t* out_z1, uint32_t* out_z2) +{ + DBG(DBG_info, "%s: two_table=%d\n", __func__, two_table); + + // acceleration total time + unsigned sum = std::accumulate(slope_table.begin(), slope_table.begin() + acceleration_steps, + 0, std::plus<unsigned>()); + + /* Z1MOD: + c = sum(slope_table; reg_stepno) + d = reg_fwdstep * <cruising speed> + Z1MOD = (c+d) % exposure_time + */ + *out_z1 = (sum + buffer_acceleration_steps * slope_table[acceleration_steps - 1]) % exposure_time; + + /* Z2MOD: + a = sum(slope_table; reg_stepno) + b = move_steps or 1 if 2 tables + Z1MOD = (a+b) % exposure_time + */ + if (!two_table) { + sum = sum + (move_steps * slope_table[acceleration_steps - 1]); + } else { + sum = sum + slope_table[acceleration_steps - 1]; + } + *out_z2 = sum % exposure_time; +} static uint8_t genesys_adjust_gain(double* applied_multi, double multi, uint8_t gain) { @@ -1338,7 +1333,7 @@ static uint8_t genesys_adjust_gain(double* applied_multi, double multi, uint8_t voltage *= multi; - new_gain = (uint8_t) ((voltage - 0.5) * 4); + new_gain = static_cast<std::uint8_t>((voltage - 0.5) * 4); if (new_gain > 0x0e) new_gain = 0x0e; @@ -1353,23 +1348,25 @@ static uint8_t genesys_adjust_gain(double* applied_multi, double multi, uint8_t } -/* todo: is return status necessary (unchecked?) */ -static SANE_Status -genesys_average_white (Genesys_Device * dev, Genesys_Sensor& sensor, int channels, int channel, - uint8_t * data, int size, int *max_average) +// todo: is return status necessary (unchecked?) +static void genesys_average_white(Genesys_Device* dev, Genesys_Sensor& sensor, int channels, + int channel, uint8_t* data, int size, int *max_average) { + + DBG_HELPER_ARGS(dbg, "channels=%d, channel=%d, size=%d", channels, channel, size); int gain_white_ref, sum, range; int average; int i; - DBG(DBG_proc, "%s: channels=%d, channel=%d, size=%d\n", __func__, channels, channel, size); - range = size / 50; - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) /* transparency mode */ - gain_white_ref = sensor.fau_gain_white_ref * 256; - else - gain_white_ref = sensor.gain_white_ref * 256; + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + gain_white_ref = sensor.fau_gain_white_ref * 256; + } else { + gain_white_ref = sensor.gain_white_ref * 256; + } if (range < 1) range = 1; @@ -1399,9 +1396,7 @@ genesys_average_white (Genesys_Device * dev, Genesys_Sensor& sensor, int channel gain_white_ref); if (*max_average >= gain_white_ref) - return SANE_STATUS_INVAL; - - return SANE_STATUS_GOOD; + throw SaneException(SANE_STATUS_INVAL); } /* todo: understand, values are too high */ @@ -1437,49 +1432,36 @@ genesys_average_black (Genesys_Device * dev, int channel, DBG(DBG_proc, "%s = %d\n", __func__, sum / pixels); - return (int) (sum / pixels); + return sum / pixels; } -/* todo: check; it works but the lines 1, 2, and 3 are too dark even with the - same offset and gain settings? */ -static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) +// todo: check; it works but the lines 1, 2, and 3 are too dark even with the +// same offset and gain settings? +static void genesys_coarse_calibration(Genesys_Device* dev, Genesys_Sensor& sensor) { - int size; + DBG_HELPER_ARGS(dbg, "scan_mode = %d", static_cast<unsigned>(dev->settings.scan_mode)); int black_pixels; int white_average; - int channels; - SANE_Status status = SANE_STATUS_GOOD; uint8_t offset[4] = { 0xa0, 0x00, 0xa0, 0x40 }; /* first value isn't used */ uint16_t white[12], dark[12]; int i, j; - DBG(DBG_info, "%s (scan_mode = %d)\n", __func__, static_cast<unsigned>(dev->settings.scan_mode)); - black_pixels = sensor.black_pixels * dev->settings.xres / sensor.optical_res; - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; + unsigned channels = dev->settings.get_channels(); - DBG(DBG_info, "channels %d y_size %d xres %d\n", channels, dev->model->y_size, + DBG(DBG_info, "channels %d y_size %f xres %d\n", channels, dev->model->y_size.value(), dev->settings.xres); - size = - channels * 2 * SANE_UNFIX (dev->model->y_size) * dev->settings.xres / - 25.4; + unsigned size = static_cast<unsigned>(channels * 2 * dev->model->y_size * dev->settings.xres / + MM_PER_INCH); /* 1 1 mm 1/inch inch/mm */ std::vector<uint8_t> calibration_data(size); std::vector<uint8_t> all_data(size * 4, 1); - status = dev->model->cmd_set->set_fe(dev, sensor, AFE_INIT); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->set_fe(dev, sensor, AFE_INIT); dev->frontend.set_gain(0, 2); dev->frontend.set_gain(1, 2); @@ -1502,11 +1484,15 @@ static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sens double applied_multi; double gain_white_ref; - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) /* Transparency */ - gain_white_ref = sensor.fau_gain_white_ref * 256; - else - gain_white_ref = sensor.gain_white_ref * 256; - /* white and black are defined downwards */ + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + gain_white_ref = sensor.fau_gain_white_ref * 256; + } else { + gain_white_ref = sensor.gain_white_ref * 256; + } + + // white and black are defined downwards uint8_t gain0 = genesys_adjust_gain(&applied_multi, gain_white_ref / (white[0] - dark[0]), @@ -1526,29 +1512,9 @@ static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sens dev->frontend.set_gain(1, 2); dev->frontend.set_gain(2, 2); - status = - sanei_genesys_fe_write_data(dev, 0x28, dev->frontend.get_gain(0)); - if (status != SANE_STATUS_GOOD) /* todo: this was 0x28 + 3 ? */ - { - DBG(DBG_error, "%s: Failed to write gain[0]: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x29, dev->frontend.get_gain(1)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to write gain[1]: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x2a, dev->frontend.get_gain(2)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to write gain[2]: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->interface->write_fe_register(0x28, dev->frontend.get_gain(0)); + dev->interface->write_fe_register(0x29, dev->frontend.get_gain(1)); + dev->interface->write_fe_register(0x2a, dev->frontend.get_gain(2)); } if (i == 3) /* last line */ @@ -1558,8 +1524,7 @@ static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sens for (j = 0; j < 3; j++) { - x = - (double) (dark[(i - 2) * 3 + j] - + x = static_cast<double>(dark[(i - 2) * 3 + j] - dark[(i - 1) * 3 + j]) * 254 / (offset[i - 1] / 2 - offset[i - 2] / 2); y = x - x * (offset[i - 1] / 2) / 254 - dark[(i - 1) * 3 + j]; @@ -1574,29 +1539,9 @@ static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sens dev->frontend.set_offset(j, curr_offset); } } - status = - sanei_genesys_fe_write_data(dev, 0x20, dev->frontend.get_offset(0)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to write offset[0]: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x21, dev->frontend.get_offset(1)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to write offset[1]: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x22, dev->frontend.get_offset(2)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to write offset[2]: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->interface->write_fe_register(0x20, dev->frontend.get_offset(0)); + dev->interface->write_fe_register(0x21, dev->frontend.get_offset(1)); + dev->interface->write_fe_register(0x22, dev->frontend.get_offset(2)); DBG(DBG_info, "%s: doing scan: gain: %d/%d/%d, offset: %d/%d/%d\n", __func__, @@ -1607,51 +1552,35 @@ static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sens dev->frontend.get_offset(1), dev->frontend.get_offset(2)); - status = - dev->model->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = - sanei_genesys_read_data_from_scanner (dev, calibration_data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, false); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("coarse_calibration"); + dev->cmd_set->end_scan(dev, &dev->calib_reg, true); + return; + } + sanei_genesys_read_data_from_scanner(dev, calibration_data.data(), size); std::memcpy(all_data.data() + i * size, calibration_data.data(), size); if (i == 3) /* last line */ { std::vector<uint8_t> all_data_8(size * 4 / 2); unsigned int count; - for (count = 0; count < (unsigned int) (size * 4 / 2); count++) - all_data_8[count] = all_data[count * 2 + 1]; - status = - sanei_genesys_write_pnm_file("gl_coarse.pnm", all_data_8.data(), 8, channels, size / 6, 4); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed: %s\n", __func__, sane_strstatus(status)); - return status; - } + for (count = 0; count < static_cast<unsigned>(size * 4 / 2); count++) { + all_data_8[count] = all_data[count * 2 + 1]; + } + sanei_genesys_write_pnm_file("gl_coarse.pnm", all_data_8.data(), 8, channels, size / 6, 4); } - status = dev->model->cmd_set->end_scan(dev, &dev->calib_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->end_scan(dev, &dev->calib_reg, true); + if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) { for (j = 0; j < 3; j++) { - genesys_average_white (dev, sensor, 3, j, calibration_data.data(), size, - &white_average); + genesys_average_white(dev, sensor, 3, j, calibration_data.data(), size, &white_average); white[i * 3 + j] = white_average; dark[i * 3 + j] = genesys_average_black (dev, j, calibration_data.data(), @@ -1662,54 +1591,12 @@ static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sens } else /* one color-component modes */ { - genesys_average_white (dev, sensor, 1, 0, calibration_data.data(), size, - &white_average); + genesys_average_white(dev, sensor, 1, 0, calibration_data.data(), size, &white_average); white[i * 3 + 0] = white[i * 3 + 1] = white[i * 3 + 2] = white_average; dark[i * 3 + 0] = dark[i * 3 + 1] = dark[i * 3 + 2] = genesys_average_black (dev, 0, calibration_data.data(), black_pixels); } - - if (i == 3) - { - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - { - /* todo: huh? */ - dev->dark[0] = - (uint16_t) (1.6925 * dark[i * 3 + 0] + 0.1895 * 256); - dev->dark[1] = - (uint16_t) (1.4013 * dark[i * 3 + 1] + 0.3147 * 256); - dev->dark[2] = - (uint16_t) (1.2931 * dark[i * 3 + 2] + 0.1558 * 256); - } - else /* one color-component modes */ - { - switch (dev->settings.color_filter) - { - case ColorFilter::RED: - default: - dev->dark[0] = - (uint16_t) (1.6925 * dark[i * 3 + 0] + - (1.1895 - 1.0) * 256); - dev->dark[1] = dev->dark[2] = dev->dark[0]; - break; - - case ColorFilter::GREEN: - dev->dark[1] = - (uint16_t) (1.4013 * dark[i * 3 + 1] + - (1.3147 - 1.0) * 256); - dev->dark[0] = dev->dark[2] = dev->dark[1]; - break; - - case ColorFilter::BLUE: - dev->dark[2] = - (uint16_t) (1.2931 * dark[i * 3 + 2] + - (1.1558 - 1.0) * 256); - dev->dark[0] = dev->dark[1] = dev->dark[2]; - break; - } - } - } } /* for (i = 0; i < 4; i++) */ DBG(DBG_info, "%s: final: gain: %d/%d/%d, offset: %d/%d/%d\n", __func__, @@ -1719,150 +1606,130 @@ static SANE_Status genesys_coarse_calibration(Genesys_Device * dev, Genesys_Sens dev->frontend.get_offset(0), dev->frontend.get_offset(1), dev->frontend.get_offset(2)); - DBGCOMPLETED; - - return status; -} - -/* Averages image data. - average_data and calibration_data are little endian 16 bit words. - */ -static void -genesys_average_data (uint8_t * average_data, - uint8_t * calibration_data, - uint32_t lines, - uint32_t pixel_components_per_line) -{ - uint32_t x, y; - uint32_t sum; - - for (x = 0; x < pixel_components_per_line; x++) - { - sum = 0; - for (y = 0; y < lines; y++) - { - sum += calibration_data[(x + y * pixel_components_per_line) * 2]; - sum += - calibration_data[(x + y * pixel_components_per_line) * 2 + - 1] * 256; - } - sum /= lines; - *average_data++ = sum & 255; - *average_data++ = sum / 256; - } } /** * scans a white area with motor and lamp off to get the per CCD pixel offset * that will be used to compute shading coefficient * @param dev scanner's device - * @return SANE_STATUS_GOOD if OK, else an error */ -static SANE_Status -genesys_dark_shading_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor) +static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_Sensor& sensor, + std::vector<std::uint16_t>& out_average_data, + bool is_dark, const std::string& log_filename_prefix) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER(dbg); + + debug_dump(DBG_info, dev->calib_session); + size_t size; uint32_t pixels_per_line; uint8_t channels; - SANE_Bool motor; - - DBGSTART; /* end pixel - start pixel */ pixels_per_line = dev->calib_pixels; channels = dev->calib_channels; uint32_t out_pixels_per_line = pixels_per_line + dev->calib_pixels_offset; - dev->average_size = channels * 2 * out_pixels_per_line; - dev->dark_average_data.clear(); - dev->dark_average_data.resize(dev->average_size); + // FIXME: we set this during both dark and white calibration. A cleaner approach should + // probably be used + dev->average_size = channels * out_pixels_per_line; + + out_average_data.clear(); + out_average_data.resize(dev->average_size); + + if (is_dark && dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { + // FIXME: dark shading currently not supported on infrared transparency scans + return; + } - // FIXME: the current calculation is likely incorrect on non-GENESYS_GL843 implementations, + // FIXME: the current calculation is likely incorrect on non-GL843 implementations, // but this needs checking if (dev->calib_total_bytes_to_read > 0) { size = dev->calib_total_bytes_to_read; - } else if (dev->model->asic_type == GENESYS_GL843) { + } else if (dev->model->asic_type == AsicType::GL843) { size = channels * 2 * pixels_per_line * dev->calib_lines; } else { size = channels * 2 * pixels_per_line * (dev->calib_lines + 1); } - std::vector<uint8_t> calibration_data(size); + std::vector<uint16_t> calibration_data(size / 2); - motor=SANE_TRUE; + bool motor = true; if (dev->model->flags & GENESYS_FLAG_SHADING_NO_MOVE) { - motor=SANE_FALSE; + motor = false; } - /* turn off motor and lamp power for flatbed scanners, but not for sheetfed scanners - * because they have a calibration sheet with a sufficient black strip */ - if (dev->model->is_sheetfed == SANE_FALSE) - { + // turn off motor and lamp power for flatbed scanners, but not for sheetfed scanners + // because they have a calibration sheet with a sufficient black strip + if (is_dark && !dev->model->is_sheetfed) { sanei_genesys_set_lamp_power(dev, sensor, dev->calib_reg, false); sanei_genesys_set_motor_power(dev->calib_reg, motor); - } - else - { + } else { sanei_genesys_set_lamp_power(dev, sensor, dev->calib_reg, true); sanei_genesys_set_motor_power(dev->calib_reg, motor); } - status = - dev->model->cmd_set->bulk_write_register(dev, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; + dev->interface->write_registers(dev->calib_reg); + + if (is_dark) { + // wait some time to let lamp to get dark + dev->interface->sleep_ms(200); + } else if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION) { + // make sure lamp is bright again + // FIXME: what about scanners that take a long time to warm the lamp? + dev->interface->sleep_ms(500); } - // wait some time to let lamp to get dark - sanei_genesys_sleep_ms(200); + bool start_motor = !is_dark; + dev->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, start_motor); - status = dev->model->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_read_data_from_scanner (dev, calibration_data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; + if (is_testing_mode()) { + dev->interface->test_checkpoint(is_dark ? "dark_shading_calibration" + : "white_shading_calibration"); + dev->cmd_set->end_scan(dev, &dev->calib_reg, true); + return; } - status = dev->model->cmd_set->end_scan(dev, &dev->calib_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; + sanei_genesys_read_data_from_scanner(dev, reinterpret_cast<std::uint8_t*>(calibration_data.data()), + size); + + dev->cmd_set->end_scan(dev, &dev->calib_reg, true); + + if (dev->model->flags & GENESYS_FLAG_16BIT_DATA_INVERTED) { + for (std::size_t i = 0; i < size / 2; ++i) { + auto value = calibration_data[i]; + value = ((value >> 8) & 0xff) | ((value << 8) & 0xff00); + calibration_data[i] = value; + } } - std::fill(dev->dark_average_data.begin(), - dev->dark_average_data.begin() + dev->calib_pixels_offset * channels, - 0x00); + std::fill(out_average_data.begin(), + out_average_data.begin() + dev->calib_pixels_offset * channels, 0); - genesys_average_data(dev->dark_average_data.data() + dev->calib_pixels_offset * channels, - calibration_data.data(), - dev->calib_lines, pixels_per_line * channels); + compute_array_percentile_approx(out_average_data.data() + dev->calib_pixels_offset * channels, + calibration_data.data(), + dev->calib_lines, pixels_per_line * channels, + 0.5f); - if (DBG_LEVEL >= DBG_data) - { - sanei_genesys_write_pnm_file("gl_black_shading.pnm", calibration_data.data(), 16, - channels, pixels_per_line, dev->calib_lines); - sanei_genesys_write_pnm_file("gl_black_average.pnm", dev->dark_average_data.data(), 16, - channels, out_pixels_per_line, 1); + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file16((log_filename_prefix + "_shading.pnm").c_str(), + calibration_data.data(), + channels, pixels_per_line, dev->calib_lines); + sanei_genesys_write_pnm_file16((log_filename_prefix + "_average.pnm").c_str(), + out_average_data.data(), + channels, out_pixels_per_line, 1); } +} - DBGCOMPLETED; - return SANE_STATUS_GOOD; +static void genesys_dark_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor) +{ + DBG_HELPER(dbg); + genesys_shading_calibration_impl(dev, sensor, dev->dark_average_data, true, "gl_black_"); } - /* * this function builds dummy dark calibration data so that we can * compute shading coefficient in a clean way @@ -1870,22 +1737,20 @@ genesys_dark_shading_calibration(Genesys_Device * dev, const Genesys_Sensor& sen * can be computed from previous calibration data (when doing offset * calibration ?) */ -static SANE_Status -genesys_dummy_dark_shading (Genesys_Device * dev, const Genesys_Sensor& sensor) +static void genesys_dummy_dark_shading(Genesys_Device* dev, const Genesys_Sensor& sensor) { + DBG_HELPER(dbg); uint32_t pixels_per_line; uint8_t channels; - uint32_t x, skip, xend; + uint32_t skip, xend; int dummy1, dummy2, dummy3; /* dummy black average per channel */ - DBGSTART; - pixels_per_line = dev->calib_pixels; channels = dev->calib_channels; uint32_t out_pixels_per_line = pixels_per_line + dev->calib_pixels_offset; - dev->average_size = channels * 2 * out_pixels_per_line; + dev->average_size = channels * out_pixels_per_line; dev->dark_average_data.clear(); dev->dark_average_data.resize(dev->average_size, 0); @@ -1901,10 +1766,11 @@ genesys_dummy_dark_shading (Genesys_Device * dev, const Genesys_Sensor& sensor) skip = 4; xend = 68; } - if (dev->model->ccd_type==CCD_G4050 - || dev->model->ccd_type==CCD_CS4400F - || dev->model->ccd_type==CCD_CS8400F - || dev->model->ccd_type==CCD_KVSS080) + if (dev->model->sensor_id==SensorId::CCD_G4050 || + dev->model->sensor_id==SensorId::CCD_HP_4850C + || dev->model->sensor_id==SensorId::CCD_CANON_4400F + || dev->model->sensor_id==SensorId::CCD_CANON_8400F + || dev->model->sensor_id==SensorId::CCD_KVSS080) { skip = 2; xend = sensor.black_pixels; @@ -1915,20 +1781,12 @@ genesys_dummy_dark_shading (Genesys_Device * dev, const Genesys_Sensor& sensor) dummy2 = 0; dummy3 = 0; - for (x = skip + 1; x <= xend; x++) - { - dummy1 += - dev->white_average_data[channels * 2 * x] + - 256 * dev->white_average_data[channels * 2 * x + 1]; - if (channels > 1) - { - dummy2 += - (dev->white_average_data[channels * 2 * x + 2] + - 256 * dev->white_average_data[channels * 2 * x + 3]); - dummy3 += - (dev->white_average_data[channels * 2 * x + 4] + - 256 * dev->white_average_data[channels * 2 * x + 5]); - } + for (unsigned x = skip + 1; x <= xend; x++) { + dummy1 += dev->white_average_data[channels * x]; + if (channels > 1) { + dummy2 += dev->white_average_data[channels * x + 1]; + dummy3 += dev->white_average_data[channels * x + 2]; + } } dummy1 /= (xend - skip); @@ -1940,176 +1798,63 @@ genesys_dummy_dark_shading (Genesys_Device * dev, const Genesys_Sensor& sensor) DBG(DBG_proc, "%s: dummy1=%d, dummy2=%d, dummy3=%d \n", __func__, dummy1, dummy2, dummy3); /* fill dark_average */ - for (x = 0; x < out_pixels_per_line; x++) - { - dev->dark_average_data[channels * 2 * x] = dummy1 & 0xff; - dev->dark_average_data[channels * 2 * x + 1] = dummy1 >> 8; - if (channels > 1) - { - dev->dark_average_data[channels * 2 * x + 2] = dummy2 & 0xff; - dev->dark_average_data[channels * 2 * x + 3] = dummy2 >> 8; - dev->dark_average_data[channels * 2 * x + 4] = dummy3 & 0xff; - dev->dark_average_data[channels * 2 * x + 5] = dummy3 >> 8; - } + for (unsigned x = 0; x < out_pixels_per_line; x++) { + dev->dark_average_data[channels * x] = dummy1; + if (channels > 1) { + dev->dark_average_data[channels * x + 1] = dummy2; + dev->dark_average_data[channels * x + 2] = dummy3; + } } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; } -static SANE_Status -genesys_white_shading_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor) +static void genesys_repark_sensor_before_shading(Genesys_Device* dev) { - SANE_Status status = SANE_STATUS_GOOD; - size_t size; - uint32_t pixels_per_line; - uint8_t channels; - SANE_Bool motor; - - DBG(DBG_proc, "%s (lines = %d)\n", __func__, (unsigned int)dev->calib_lines); - - pixels_per_line = dev->calib_pixels; - channels = dev->calib_channels; - - uint32_t out_pixels_per_line = pixels_per_line + dev->calib_pixels_offset; - - dev->white_average_data.clear(); - dev->white_average_data.resize(channels * 2 * out_pixels_per_line); - - // FIXME: the current calculation is likely incorrect on non-GENESYS_GL843 implementations, - // but this needs checking - if (dev->calib_total_bytes_to_read > 0) { - size = dev->calib_total_bytes_to_read; - } else if (dev->model->asic_type == GENESYS_GL843) { - size = channels * 2 * pixels_per_line * dev->calib_lines; - } else { - size = channels * 2 * pixels_per_line * (dev->calib_lines + 1); - } - - std::vector<uint8_t> calibration_data(size); - - motor=SANE_TRUE; - if (dev->model->flags & GENESYS_FLAG_SHADING_NO_MOVE) - { - motor=SANE_FALSE; - } - - // turn on motor and lamp power - sanei_genesys_set_lamp_power(dev, sensor, dev->calib_reg, true); - sanei_genesys_set_motor_power(dev->calib_reg, motor); + DBG_HELPER(dbg); + if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK) { + dev->cmd_set->move_back_home(dev, true); - /* if needed, go back before doing next scan */ - if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK) - { - /* rewind keeps registers and slopes table intact from previous - scan but is not available on all supported chipsets (or may - cause scan artifacts, see #7) */ - status = (dev->model->cmd_set->rewind - ? dev->model->cmd_set->rewind (dev) - : dev->model->cmd_set->slow_back_home (dev, SANE_TRUE)); - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { - dev->model->cmd_set->move_to_ta(dev); + dev->cmd_set->move_to_ta(dev); } } +} - status = - dev->model->cmd_set->bulk_write_register(dev, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION) - sanei_genesys_sleep_ms(500); // make sure lamp is bright again - - status = dev->model->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_read_data_from_scanner (dev, calibration_data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = dev->model->cmd_set->end_scan(dev, &dev->calib_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl_white_shading.pnm", calibration_data.data(), 16, - channels, pixels_per_line, dev->calib_lines); - - std::fill(dev->dark_average_data.begin(), - dev->dark_average_data.begin() + dev->calib_pixels_offset * channels, - 0x00); - - genesys_average_data (dev->white_average_data.data() + dev->calib_pixels_offset * channels, - calibration_data.data(), dev->calib_lines, - pixels_per_line * channels); - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl_white_average.pnm", dev->white_average_data.data(), 16, - channels, out_pixels_per_line, 1); - - /* in case we haven't done dark calibration, build dummy data from white_average */ - if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)) - { - status = genesys_dummy_dark_shading(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do dummy dark shading calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } - - if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK) - { - status = dev->model->cmd_set->slow_back_home (dev, SANE_TRUE); +static void genesys_repark_sensor_after_white_shading(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + if (dev->model->flags & GENESYS_FLAG_SHADING_REPARK) { + dev->cmd_set->move_back_home(dev, true); } +} - DBGCOMPLETED; - - return status; +static void genesys_white_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor) +{ + DBG_HELPER(dbg); + genesys_shading_calibration_impl(dev, sensor, dev->white_average_data, false, "gl_white_"); } -/* This calibration uses a scan over the calibration target, comprising a - * black and a white strip. (So the motor must be on.) - */ -static SANE_Status -genesys_dark_white_shading_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor) +// This calibration uses a scan over the calibration target, comprising a black and a white strip. +// (So the motor must be on.) +static void genesys_dark_white_shading_calibration(Genesys_Device* dev, + const Genesys_Sensor& sensor) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER_ARGS(dbg, "lines = %zu", dev->calib_lines); size_t size; uint32_t pixels_per_line; - uint8_t *average_white, *average_dark; uint8_t channels; unsigned int x; - int y; uint32_t dark, white, dark_sum, white_sum, dark_count, white_count, col, dif; - SANE_Bool motor; - - - DBG(DBG_proc, "%s: (lines = %d)\n", __func__, (unsigned int)dev->calib_lines); pixels_per_line = dev->calib_pixels; channels = dev->calib_channels; uint32_t out_pixels_per_line = pixels_per_line + dev->calib_pixels_offset; - dev->average_size = channels * 2 * out_pixels_per_line; + dev->average_size = channels * out_pixels_per_line; dev->white_average_data.clear(); dev->white_average_data.resize(dev->average_size); @@ -2124,45 +1869,29 @@ genesys_dark_white_shading_calibration(Genesys_Device * dev, const Genesys_Senso std::vector<uint8_t> calibration_data(size); - motor=SANE_TRUE; + bool motor = true; if (dev->model->flags & GENESYS_FLAG_SHADING_NO_MOVE) { - motor=SANE_FALSE; + motor = false; } // turn on motor and lamp power sanei_genesys_set_lamp_power(dev, sensor, dev->calib_reg, true); sanei_genesys_set_motor_power(dev->calib_reg, motor); - status = - dev->model->cmd_set->bulk_write_register(dev, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->interface->write_registers(dev->calib_reg); - status = dev->model->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, SANE_FALSE); + dev->cmd_set->begin_scan(dev, sensor, &dev->calib_reg, false); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; + if (is_testing_mode()) { + dev->interface->test_checkpoint("dark_white_shading_calibration"); + dev->cmd_set->end_scan(dev, &dev->calib_reg, true); + return; } - status = sanei_genesys_read_data_from_scanner (dev, calibration_data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } + sanei_genesys_read_data_from_scanner(dev, calibration_data.data(), size); - status = dev->model->cmd_set->end_scan(dev, &dev->calib_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->end_scan(dev, &dev->calib_reg, true); if (DBG_LEVEL >= DBG_data) { @@ -2181,22 +1910,20 @@ genesys_dark_white_shading_calibration(Genesys_Device * dev, const Genesys_Senso } - std::fill(dev->dark_average_data.begin(), - dev->dark_average_data.begin() + dev->calib_pixels_offset * channels, - 0x00); - std::fill(dev->white_average_data.begin(), - dev->white_average_data.begin() + dev->calib_pixels_offset * channels, - 0x00); + std::fill(dev->dark_average_data.begin(), + dev->dark_average_data.begin() + dev->calib_pixels_offset * channels, 0); + std::fill(dev->white_average_data.begin(), + dev->white_average_data.begin() + dev->calib_pixels_offset * channels, 0); - average_white = dev->white_average_data.data() + dev->calib_pixels_offset * channels; - average_dark = dev->dark_average_data.data() + dev->calib_pixels_offset * channels; + uint16_t* average_white = dev->white_average_data.data() + dev->calib_pixels_offset * channels; + uint16_t* average_dark = dev->dark_average_data.data() + dev->calib_pixels_offset * channels; for (x = 0; x < pixels_per_line * channels; x++) { dark = 0xffff; white = 0; - for (y = 0; y < (int)dev->calib_lines; y++) + for (std::size_t y = 0; y < dev->calib_lines; y++) { col = calibration_data[(x + y * pixels_per_line * channels) * 2]; col |= @@ -2220,7 +1947,7 @@ genesys_dark_white_shading_calibration(Genesys_Device * dev, const Genesys_Senso white_count = 0; white_sum = 0; - for (y = 0; y < (int)dev->calib_lines; y++) + for (std::size_t y = 0; y < dev->calib_lines; y++) { col = calibration_data[(x + y * pixels_per_line * channels) * 2]; col |= @@ -2243,26 +1970,16 @@ genesys_dark_white_shading_calibration(Genesys_Device * dev, const Genesys_Senso dark_sum /= dark_count; white_sum /= white_count; - *average_dark++ = dark_sum & 255; - *average_dark++ = dark_sum >> 8; - - *average_white++ = white_sum & 255; - *average_white++ = white_sum >> 8; + *average_dark++ = dark_sum; + *average_white++ = white_sum; } - if (DBG_LEVEL >= DBG_data) - { - sanei_genesys_write_pnm_file("gl_white_average.pnm", - dev->white_average_data.data(), 16, channels, - out_pixels_per_line, 1); - sanei_genesys_write_pnm_file("gl_dark_average.pnm", - dev->dark_average_data.data(), 16, channels, - out_pixels_per_line, 1); + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file16("gl_white_average.pnm", dev->white_average_data.data(), + channels, out_pixels_per_line, 1); + sanei_genesys_write_pnm_file16("gl_dark_average.pnm", dev->dark_average_data.data(), + channels, out_pixels_per_line, 1); } - - DBGCOMPLETED; - - return SANE_STATUS_GOOD; } /* computes one coefficient given bright-dark value @@ -2393,8 +2110,7 @@ compute_averaged_planar (Genesys_Device * dev, const Genesys_Sensor& sensor, avgpixels = 15; /* LiDE80 packs shading data */ - if(dev->model->ccd_type != CIS_CANONLIDE80) - { + if (dev->model->sensor_id != SensorId::CIS_CANON_LIDE_80) { factor=1; fill=avgpixels; } @@ -2420,21 +2136,10 @@ compute_averaged_planar (Genesys_Device * dev, const Genesys_Sensor& sensor, br = 0; for (i = 0; i < avgpixels; i++) { - /* dark data */ - dk += - (dev->dark_average_data[(x + i + - pixels_per_line * j) * - 2] | - (dev->dark_average_data - [(x + i + pixels_per_line * j) * 2 + 1] << 8)); - - /* white data */ - br += - (dev->white_average_data[(x + i + - pixels_per_line * j) * - 2] | - (dev->white_average_data - [(x + i + pixels_per_line * j) * 2 + 1] << 8)); + // dark data + dk += dev->dark_average_data[(x + i + pixels_per_line * j)]; + // white data + br += dev->white_average_data[(x + i + pixels_per_line * j)]; } br /= avgpixels; @@ -2490,6 +2195,16 @@ compute_averaged_planar (Genesys_Device * dev, const Genesys_Sensor& sensor, } } +static std::array<unsigned, 3> color_order_to_cmat(ColorOrder color_order) +{ + switch (color_order) { + case ColorOrder::RGB: return {0, 1, 2}; + case ColorOrder::GBR: return {2, 0, 1}; + default: + throw std::logic_error("Unknown color order"); + } +} + /** * Computes shading coefficient using formula in data sheet. 16bit data values * manipulated here are little endian. For now we assume deletion scanning type @@ -2503,12 +2218,11 @@ compute_averaged_planar (Genesys_Device * dev, const Genesys_Sensor& sensor, * @param coeff 4000h or 2000h depending on fast scan mode or not * @param target value of the target code */ -static void -compute_coefficients (Genesys_Device * dev, +static void compute_coefficients(Genesys_Device * dev, uint8_t * shading_data, unsigned int pixels_per_line, unsigned int channels, - unsigned int cmat[3], + ColorOrder color_order, int offset, unsigned int coeff, unsigned int target) @@ -2520,6 +2234,8 @@ compute_coefficients (Genesys_Device * dev, DBG(DBG_io, "%s: pixels_per_line=%d, coeff=0x%04x\n", __func__, pixels_per_line, coeff); + auto cmat = color_order_to_cmat(color_order); + /* compute start & end values depending of the offset */ if (offset < 0) { @@ -2539,13 +2255,11 @@ compute_coefficients (Genesys_Device * dev, /* TODO if channels=1 , use filter to know the base addr */ ptr = shading_data + 4 * ((x + offset) * channels + cmat[c]); - /* dark data */ - dk = dev->dark_average_data[x * 2 * channels + c * 2]; - dk += 256 * dev->dark_average_data[x * 2 * channels + c * 2 + 1]; + // dark data + dk = dev->dark_average_data[x * channels + c]; - /* white data */ - br = dev->white_average_data[x * 2 * channels + c * 2]; - br += 256 * dev->white_average_data[x * 2 * channels + c * 2 + 1]; + // white data + br = dev->white_average_data[x * channels + c]; /* compute coeff */ val=compute_coefficient(coeff,target,br-dk); @@ -2576,14 +2290,13 @@ compute_coefficients (Genesys_Device * dev, * @param coeff 4000h or 2000h depending on fast scan mode or not * @param target white target value */ -static void -compute_planar_coefficients (Genesys_Device * dev, +static void compute_planar_coefficients(Genesys_Device * dev, uint8_t * shading_data, unsigned int factor, unsigned int pixels_per_line, unsigned int words_per_color, unsigned int channels, - unsigned int cmat[3], + ColorOrder color_order, unsigned int offset, unsigned int coeff, unsigned int target) @@ -2592,6 +2305,8 @@ compute_planar_coefficients (Genesys_Device * dev, uint32_t x, c, i; uint32_t val, dk, br; + auto cmat = color_order_to_cmat(color_order); + DBG(DBG_io, "%s: factor=%d, pixels_per_line=%d, words=0x%X, coeff=0x%04x\n", __func__, factor, pixels_per_line, words_per_color, coeff); for (c = 0; c < channels; c++) @@ -2609,12 +2324,8 @@ compute_planar_coefficients (Genesys_Device * dev, /* average case */ for(i=0;i<factor;i++) { - dk += - 256 * dev->dark_average_data[((x+i) + pixels_per_line * c) * 2 + 1]; - dk += dev->dark_average_data[((x+i) + pixels_per_line * c) * 2]; - br += - 256 * dev->white_average_data[((x+i) + pixels_per_line * c) * 2 + 1]; - br += dev->white_average_data[((x+i) + pixels_per_line * c) * 2]; + dk += dev->dark_average_data[((x+i) + pixels_per_line * c)]; + br += dev->white_average_data[((x+i) + pixels_per_line * c)]; } dk /= factor; br /= factor; @@ -2650,7 +2361,7 @@ compute_shifted_coefficients (Genesys_Device * dev, uint8_t * shading_data, unsigned int pixels_per_line, unsigned int channels, - unsigned int cmat[3], + ColorOrder color_order, int offset, unsigned int coeff, unsigned int target_dark, @@ -2662,6 +2373,8 @@ compute_shifted_coefficients (Genesys_Device * dev, uint8_t *ptr = shading_data + offset * 3 * 4; /* contain 16bit words in little endian */ unsigned int patch_cnt = offset * 3; /* at start, offset of first patch */ + auto cmat = color_order_to_cmat(color_order); + x = dev->settings.xres; if (sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres) > 1) x *= 2; /* scanner is using half-ccd mode */ @@ -2691,10 +2404,8 @@ compute_shifted_coefficients (Genesys_Device * dev, for (i = 0; i < avgpixels; i++) { for (j = 0; j < channels; j++) { - br_tmp[j] += (dev->white_average_data[((x + i) * channels + j) * 2] | - (dev->white_average_data[((x + i) * channels + j) * 2 + 1] << 8)); - dk_tmp[i] += (dev->dark_average_data[((x + i) * channels + j) * 2] | - (dev->dark_average_data[((x + i) * channels + j) * 2 + 1] << 8)); + br_tmp[j] += dev->white_average_data[((x + i) * channels + j)]; + dk_tmp[i] += dev->dark_average_data[((x + i) * channels + j)]; } } for (j = 0; j < channels; j++) { @@ -2736,20 +2447,21 @@ compute_shifted_coefficients (Genesys_Device * dev, } } -static SANE_Status -genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sensor) +static void genesys_send_shading_coefficient(Genesys_Device* dev, const Genesys_Sensor& sensor) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER(dbg); + + if (dev->model->flags & GENESYS_FLAG_CALIBRATION_HOST_SIDE) { + return; + } + uint32_t pixels_per_line; uint8_t channels; int o; unsigned int length; /**> number of shading calibration data words */ unsigned int factor; - unsigned int cmat[3]; /**> matrix of color channels */ unsigned int coeff, target_code, words_per_color = 0; - DBGSTART; - pixels_per_line = dev->calib_pixels + dev->calib_pixels_offset; channels = dev->calib_channels; @@ -2781,7 +2493,7 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen /* special case, memory is aligned on 0x5400, this has yet to be explained */ /* could be 0xa800 because sensor is truly 2400 dpi, then halved because * we only set 1200 dpi */ - if(dev->model->ccd_type==CIS_CANONLIDE80) + if(dev->model->sensor_id==SensorId::CIS_CANON_LIDE_80) { words_per_color = 0x5400; } @@ -2797,10 +2509,11 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen Wn = white average for column n Dn = dark average for column n */ - if (dev->model->cmd_set->get_gain4_bit(&dev->calib_reg)) - coeff = 0x4000; - else - coeff = 0x2000; + if (get_registers_gain4_bit(dev->model->asic_type, dev->calib_reg)) { + coeff = 0x4000; + } else { + coeff = 0x2000; + } /* compute avg factor */ if(dev->settings.xres>sensor.optical_res) @@ -2812,24 +2525,21 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen factor=sensor.optical_res/dev->settings.xres; } - /* for GL646, shading data is planar if REG01_FASTMOD is set and + /* for GL646, shading data is planar if REG_0x01_FASTMOD is set and * chunky if not. For now we rely on the fact that we know that * each sensor is used only in one mode. Currently only the CIS_XP200 - * sets REG01_FASTMOD. + * sets REG_0x01_FASTMOD. */ /* TODO setup a struct in genesys_devices that * will handle these settings instead of having this switch growing up */ - cmat[0] = 0; - cmat[1] = 1; - cmat[2] = 2; - switch (dev->model->ccd_type) + switch (dev->model->sensor_id) { - case CCD_XP300: - case CCD_ROADWARRIOR: - case CCD_DP665: - case CCD_DP685: - case CCD_DSMOBILE600: + case SensorId::CCD_XP300: + case SensorId::CCD_ROADWARRIOR: + case SensorId::CCD_DP665: + case SensorId::CCD_DP685: + case SensorId::CCD_DSMOBILE600: target_code = 0xdc00; o = 4; compute_planar_coefficients (dev, @@ -2838,29 +2548,26 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen pixels_per_line, words_per_color, channels, - cmat, + ColorOrder::RGB, o, coeff, target_code); break; - case CIS_XP200: + case SensorId::CIS_XP200: target_code = 0xdc00; o = 2; - cmat[0] = 2; /* red is last */ - cmat[1] = 0; /* green is first */ - cmat[2] = 1; /* blue is second */ compute_planar_coefficients (dev, shading_data.data(), 1, pixels_per_line, words_per_color, channels, - cmat, + ColorOrder::GBR, o, coeff, target_code); break; - case CCD_HP2300: + case SensorId::CCD_HP2300: target_code = 0xdc00; o = 2; if(dev->settings.xres<=sensor.optical_res/2) @@ -2871,12 +2578,12 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen shading_data.data(), pixels_per_line, 3, - cmat, + ColorOrder::RGB, o, coeff, target_code); break; - case CCD_5345: + case SensorId::CCD_5345: target_code = 0xe000; o = 4; if(dev->settings.xres<=sensor.optical_res/2) @@ -2887,22 +2594,24 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen shading_data.data(), pixels_per_line, 3, - cmat, + ColorOrder::RGB, o, coeff, target_code); break; - case CCD_HP3670: - case CCD_HP2400: + case SensorId::CCD_HP3670: + case SensorId::CCD_HP2400: target_code = 0xe000; - /* offset is cksel dependent, but we can't use this in common code */ + // offset is dependent on ccd_pixels_per_system_pixel(), but we couldn't use this in + // common code previously. + // FIXME: use sensor.ccd_pixels_per_system_pixel() if(dev->settings.xres<=300) { - o = -10; /* OK for <=300 */ + o = -10; } else if(dev->settings.xres<=600) { - o = -6; /* ok at 600 */ + o = -6; } else { @@ -2912,47 +2621,49 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen shading_data.data(), pixels_per_line, 3, - cmat, + ColorOrder::RGB, o, coeff, target_code); break; - case CCD_KVSS080: - case CCD_PLUSTEK3800: - case CCD_G4050: - case CCD_CS4400F: - case CCD_CS8400F: - case CCD_CS8600F: + case SensorId::CCD_KVSS080: + case SensorId::CCD_PLUSTEK_OPTICBOOK_3800: + case SensorId::CCD_G4050: + case SensorId::CCD_HP_4850C: + case SensorId::CCD_CANON_4400F: + case SensorId::CCD_CANON_8400F: + case SensorId::CCD_CANON_8600F: + case SensorId::CCD_PLUSTEK_OPTICFILM_7200I: + case SensorId::CCD_PLUSTEK_OPTICFILM_7300: + case SensorId::CCD_PLUSTEK_OPTICFILM_7500I: target_code = 0xe000; o = 0; compute_coefficients (dev, shading_data.data(), pixels_per_line, 3, - cmat, + ColorOrder::RGB, o, coeff, target_code); break; - case CIS_CANONLIDE700: - case CIS_CANONLIDE100: - case CIS_CANONLIDE200: - case CIS_CANONLIDE110: - case CIS_CANONLIDE120: - case CIS_CANONLIDE210: - case CIS_CANONLIDE220: + case SensorId::CIS_CANON_LIDE_700F: + case SensorId::CIS_CANON_LIDE_100: + case SensorId::CIS_CANON_LIDE_200: + case SensorId::CIS_CANON_LIDE_110: + case SensorId::CIS_CANON_LIDE_120: + case SensorId::CIS_CANON_LIDE_210: + case SensorId::CIS_CANON_LIDE_220: /* TODO store this in a data struct so we avoid * growing this switch */ - switch(dev->model->ccd_type) + switch(dev->model->sensor_id) { - case CIS_CANONLIDE110: - case CIS_CANONLIDE120: - case CIS_CANONLIDE210: - case CIS_CANONLIDE220: - target_code = 0xf000; - break; - case CIS_CANONLIDE700: - target_code = 0xc000; /* from experimentation */ + case SensorId::CIS_CANON_LIDE_110: + case SensorId::CIS_CANON_LIDE_120: + case SensorId::CIS_CANON_LIDE_210: + case SensorId::CIS_CANON_LIDE_220: + case SensorId::CIS_CANON_LIDE_700F: + target_code = 0xc000; break; default: target_code = 0xdc00; @@ -2967,12 +2678,12 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen pixels_per_line, words_per_color, channels, - cmat, + ColorOrder::RGB, 0, coeff, target_code); break; - case CCD_CANONLIDE35: + case SensorId::CIS_CANON_LIDE_35: compute_averaged_planar (dev, sensor, shading_data.data(), pixels_per_line, @@ -2983,7 +2694,7 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen 0xe000, 0x0a00); break; - case CIS_CANONLIDE80: + case SensorId::CIS_CANON_LIDE_80: compute_averaged_planar (dev, sensor, shading_data.data(), pixels_per_line, @@ -2994,12 +2705,12 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen 0xe000, 0x0800); break; - case CCD_PLUSTEK_3600: + case SensorId::CCD_PLUSTEK_OPTICPRO_3600: compute_shifted_coefficients (dev, sensor, shading_data.data(), pixels_per_line, channels, - cmat, + ColorOrder::RGB, 12, /* offset */ coeff, 0x0001, /* target_dark */ @@ -3007,21 +2718,13 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen 256); /* patch_size: contigous extent */ break; default: - DBG (DBG_error, "%s: sensor %d not supported\n", __func__, dev->model->ccd_type); - return SANE_STATUS_UNSUPPORTED; + throw SaneException(SANE_STATUS_UNSUPPORTED, "sensor %d not supported", + static_cast<unsigned>(dev->model->sensor_id)); break; } - /* do the actual write of shading calibration data to the scanner */ - status = genesys_send_offset_and_shading (dev, sensor, shading_data.data(), length); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to send shading data: %s\n", __func__, - sane_strstatus (status)); - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; + // do the actual write of shading calibration data to the scanner + genesys_send_offset_and_shading(dev, sensor, shading_data.data(), length); } @@ -3035,20 +2738,21 @@ genesys_send_shading_coefficient(Genesys_Device * dev, const Genesys_Sensor& sen static bool genesys_restore_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) { - DBGSTART; + DBG_HELPER(dbg); + + // if no cache or no function to evaluate cache entry ther can be no match/ + if (dev->calibration_cache.empty()) { + return false; + } - /* if no cache or no function to evaluate cache entry ther can be no match */ - if (!dev->model->cmd_set->is_compatible_calibration - || dev->calibration_cache.empty()) - return false; + auto session = dev->cmd_set->calculate_scan_session(dev, sensor, dev->settings); /* we walk the link list of calibration cache in search for a * matching one */ for (auto& cache : dev->calibration_cache) { - if (dev->model->cmd_set->is_compatible_calibration(dev, sensor, &cache, SANE_FALSE)) - { - dev->frontend = cache.frontend; + if (sanei_genesys_is_compatible_calibration(dev, session, &cache, false)) { + dev->frontend = cache.frontend; /* we don't restore the gamma fields */ sensor.exposure = cache.sensor.exposure; @@ -3059,9 +2763,8 @@ genesys_restore_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) dev->dark_average_data = cache.dark_average_data; dev->white_average_data = cache.white_average_data; - if(dev->model->cmd_set->send_shading_data==NULL) - { - TIE(genesys_send_shading_coefficient(dev, sensor)); + if (!dev->cmd_set->has_send_shading_data()) { + genesys_send_shading_coefficient(dev, sensor); } DBG(DBG_proc, "%s: restored\n", __func__); @@ -3073,26 +2776,22 @@ genesys_restore_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) } -static SANE_Status -genesys_save_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor) +static void genesys_save_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor) { + DBG_HELPER(dbg); #ifdef HAVE_SYS_TIME_H struct timeval time; #endif - DBGSTART; - - if (!dev->model->cmd_set->is_compatible_calibration) - return SANE_STATUS_UNSUPPORTED; + auto session = dev->cmd_set->calculate_scan_session(dev, sensor, dev->settings); auto found_cache_it = dev->calibration_cache.end(); for (auto cache_it = dev->calibration_cache.begin(); cache_it != dev->calibration_cache.end(); cache_it++) { - if (dev->model->cmd_set->is_compatible_calibration(dev, sensor, &*cache_it, SANE_TRUE)) - { - found_cache_it = cache_it; - break; + if (sanei_genesys_is_compatible_calibration(dev, session, &*cache_it, true)) { + found_cache_it = cache_it; + break; } } @@ -3109,7 +2808,7 @@ genesys_save_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor) found_cache_it->dark_average_data = dev->dark_average_data; found_cache_it->white_average_data = dev->white_average_data; - found_cache_it->used_setup = dev->current_setup; + found_cache_it->params = session.params; found_cache_it->frontend = dev->frontend; found_cache_it->sensor = sensor; @@ -3117,12 +2816,9 @@ genesys_save_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor) found_cache_it->calib_channels = dev->calib_channels; #ifdef HAVE_SYS_TIME_H - gettimeofday(&time,NULL); + gettimeofday(&time, nullptr); found_cache_it->last_calibration = time.tv_sec; #endif - - DBGCOMPLETED; - return SANE_STATUS_GOOD; } /** @@ -3131,194 +2827,145 @@ genesys_save_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor) * - gain calibration * - shading calibration * @param dev device to calibrate - * @return SANE_STATUS_GOOD if everything when all right, else the error code. */ -static SANE_Status -genesys_flatbed_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) +static void genesys_flatbed_calibration(Genesys_Device* dev, Genesys_Sensor& sensor) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER(dbg); uint32_t pixels_per_line; - int yres; - DBG(DBG_info, "%s\n", __func__); + unsigned coarse_res = sensor.optical_res; + if (dev->settings.yres <= sensor.optical_res / 2) { + coarse_res /= 2; + } - yres = sensor.optical_res; - if (dev->settings.yres <= sensor.optical_res / 2) - yres /= 2; + if (dev->model->model_id == ModelId::CANON_8400F) { + coarse_res = 1600; + } - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - yres = 1200; + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8600F) + { + coarse_res = 1200; + } /* do offset calibration if needed */ if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION) { - status = dev->model->cmd_set->offset_calibration(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: offset calibration failed: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->interface->record_progress_message("offset_calibration"); + dev->cmd_set->offset_calibration(dev, sensor, dev->calib_reg); /* since all the registers are set up correctly, just use them */ - status = dev->model->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, yres); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: coarse gain calibration: %s\n", __func__, sane_strstatus(status)); - return status; - } - - } - else + dev->interface->record_progress_message("coarse_gain_calibration"); + dev->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, coarse_res); + } else { /* since we have 2 gain calibration proc, skip second if first one was used. */ - { - status = dev->model->cmd_set->init_regs_for_coarse_calibration(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send calibration registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - status = genesys_coarse_calibration(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do coarse gain calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } + dev->interface->record_progress_message("init_regs_for_coarse_calibration"); + dev->cmd_set->init_regs_for_coarse_calibration(dev, sensor, dev->calib_reg); + dev->interface->record_progress_message("genesys_coarse_calibration"); + genesys_coarse_calibration(dev, sensor); } if (dev->model->is_cis) { /* the afe now sends valid data for doing led calibration */ - status = dev->model->cmd_set->led_calibration(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: led calibration failed: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->interface->record_progress_message("led_calibration"); + switch (dev->model->asic_type) { + case AsicType::GL124: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: { + auto calib_exposure = dev->cmd_set->led_calibration(dev, sensor, dev->calib_reg); + for (auto& sensor_update : + sanei_genesys_find_sensors_all_for_write(dev, sensor.method)) { + sensor_update.get().exposure = calib_exposure; + } + sensor.exposure = calib_exposure; + break; + } + default: { + sensor.exposure = dev->cmd_set->led_calibration(dev, sensor, dev->calib_reg); + } + } + /* calibrate afe again to match new exposure */ - if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION) - { - status = dev->model->cmd_set->offset_calibration(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: offset calibration failed: %s\n", __func__, sane_strstatus(status)); - return status; - } + if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION) { + dev->interface->record_progress_message("offset_calibration"); + dev->cmd_set->offset_calibration(dev, sensor, dev->calib_reg); - /* since all the registers are set up correctly, just use them */ + // since all the registers are set up correctly, just use them - status = dev->model->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, yres); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: coarse gain calibration: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - else - /* since we have 2 gain calibration proc, skip second if first one was - used. */ - { - status = dev->model->cmd_set->init_regs_for_coarse_calibration(dev, sensor, - dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send calibration registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } + dev->interface->record_progress_message("coarse_gain_calibration"); + dev->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, coarse_res); + } else { + // since we have 2 gain calibration proc, skip second if first one was used + dev->interface->record_progress_message("init_regs_for_coarse_calibration"); + dev->cmd_set->init_regs_for_coarse_calibration(dev, sensor, dev->calib_reg); - status = genesys_coarse_calibration(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do static calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } + dev->interface->record_progress_message("genesys_coarse_calibration"); + genesys_coarse_calibration(dev, sensor); + } } /* we always use sensor pixel number when the ASIC can't handle multi-segments sensor */ if (!(dev->model->flags & GENESYS_FLAG_SIS_SENSOR)) { - pixels_per_line = (SANE_UNFIX (dev->model->x_size) * dev->settings.xres) / MM_PER_INCH; + pixels_per_line = static_cast<std::uint32_t>((dev->model->x_size * dev->settings.xres) / + MM_PER_INCH); } else { pixels_per_line = sensor.sensor_pixels; } - /* send default shading data */ - status = sanei_genesys_init_shading_data(dev, sensor, pixels_per_line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to init shading process: %s\n", __func__, sane_strstatus(status)); - return status; - } + // send default shading data + dev->interface->record_progress_message("sanei_genesys_init_shading_data"); + sanei_genesys_init_shading_data(dev, sensor, pixels_per_line); - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { - RIE(dev->model->cmd_set->move_to_ta(dev)); + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + dev->cmd_set->move_to_ta(dev); } - /* shading calibration */ - status = dev->model->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } + // shading calibration + if (dev->model->flags & GENESYS_FLAG_DARK_WHITE_CALIBRATION) { + dev->interface->record_progress_message("init_regs_for_shading"); + dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); - if (dev->model->flags & GENESYS_FLAG_DARK_WHITE_CALIBRATION) - { - status = genesys_dark_white_shading_calibration (dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do dark+white shading calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } - else - { - if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION) - { - status = genesys_dark_shading_calibration(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do dark shading calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } + dev->interface->record_progress_message("genesys_dark_white_shading_calibration"); + genesys_dark_white_shading_calibration(dev, sensor); + } else { + DBG(DBG_proc, "%s : genesys_dark_shading_calibration dev->calib_reg ", __func__); + debug_dump(DBG_proc, dev->calib_reg); - status = genesys_white_shading_calibration (dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do white shading calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } + if (dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION) { + dev->interface->record_progress_message("init_regs_for_shading"); + dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); - if(dev->model->cmd_set->send_shading_data==NULL) - { - status = genesys_send_shading_coefficient(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading calibration coefficients: %s\n", __func__, - sane_strstatus(status)); - return status; + dev->interface->record_progress_message("genesys_dark_shading_calibration"); + genesys_dark_shading_calibration(dev, sensor); + genesys_repark_sensor_before_shading(dev); } - } - DBG(DBG_info, "%s: completed\n", __func__); + dev->interface->record_progress_message("init_regs_for_shading2"); + dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); - return SANE_STATUS_GOOD; + dev->interface->record_progress_message("genesys_white_shading_calibration"); + genesys_white_shading_calibration(dev, sensor); + genesys_repark_sensor_after_white_shading(dev); + + if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)) { + genesys_dummy_dark_shading(dev, sensor); + } + } + + if (!dev->cmd_set->has_send_shading_data()) { + dev->interface->record_progress_message("genesys_send_shading_coefficient"); + genesys_send_shading_coefficient(dev, sensor); + } } /** @@ -3329,104 +2976,56 @@ genesys_flatbed_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) * During calibration a predefined calibration sheet with specific black and white * areas is used. * @param dev device to calibrate - * @return SANE_STATUS_GOOD if everything when all right, else the error code. */ -static SANE_Status genesys_sheetfed_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) +static void genesys_sheetfed_calibration(Genesys_Device* dev, Genesys_Sensor& sensor) { - SANE_Status status = SANE_STATUS_GOOD; - SANE_Bool forward = SANE_TRUE; - int xres; - - DBGSTART; - if (dev->model->cmd_set->search_strip == NULL) - { - DBG(DBG_error, "%s: no strip searching function available\n", __func__); - return SANE_STATUS_UNSUPPORTED; - } - - /* first step, load document */ - status = dev->model->cmd_set->load_document (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to load document: %s\n", __func__, sane_strstatus(status)); - return status; - } - + DBG_HELPER(dbg); + bool forward = true; - DBG(DBG_info, "%s\n", __func__); + // first step, load document + dev->cmd_set->load_document(dev); /* led, offset and gain calibration are influenced by scan * settings. So we set it to sensor resolution */ - xres = sensor.optical_res; dev->settings.xres = sensor.optical_res; /* XP200 needs to calibrate a full and half sensor's resolution */ - if (dev->model->ccd_type == CIS_XP200 - && dev->settings.xres <= sensor.optical_res / 2) - dev->settings.xres /= 2; + if (dev->model->sensor_id == SensorId::CIS_XP200 && + dev->settings.xres <= sensor.optical_res / 2) + { + dev->settings.xres /= 2; + } /* the afe needs to sends valid data even before calibration */ /* go to a white area */ try { - status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_FALSE); - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: failed to find white strip: %s\n", __func__, - sane_strstatus(status)); - dev->model->cmd_set->eject_document (dev); - return status; - } + dev->cmd_set->search_strip(dev, sensor, forward, false); } catch (...) { - dev->model->cmd_set->eject_document(dev); + catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); }); throw; } if (dev->model->is_cis) { - status = dev->model->cmd_set->led_calibration(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: led calibration failed: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->led_calibration(dev, sensor, dev->calib_reg); } /* calibrate afe */ if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION) { - status = dev->model->cmd_set->offset_calibration(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: offset calibration failed: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->offset_calibration(dev, sensor, dev->calib_reg); /* since all the registers are set up correctly, just use them */ - status = dev->model->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, xres); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: coarse gain calibration: %s\n", __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, sensor.optical_res); } else /* since we have 2 gain calibration proc, skip second if first one was used. */ { - status = dev->model->cmd_set->init_regs_for_coarse_calibration(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send calibration registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } + dev->cmd_set->init_regs_for_coarse_calibration(dev, sensor, dev->calib_reg); - status = genesys_coarse_calibration(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do static calibration: %s\n", __func__, sane_strstatus(status)); - return status; - } + genesys_coarse_calibration(dev, sensor); } /* search for a full width black strip and then do a 16 bit scan to @@ -3435,81 +3034,49 @@ static SANE_Status genesys_sheetfed_calibration(Genesys_Device * dev, Genesys_Se { /* seek black/white reverse/forward */ try { - status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_TRUE); - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: failed to find black strip: %s\n", __func__, - sane_strstatus(status)); - dev->model->cmd_set->eject_document(dev); - return status; - } + dev->cmd_set->search_strip(dev, sensor, forward, true); } catch (...) { - dev->model->cmd_set->eject_document(dev); + catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); }); throw; } - status = dev->model->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do set up registers for shading calibration: %s\n", - __func__, sane_strstatus(status)); - return status; - } + dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); + try { - status = genesys_dark_shading_calibration(dev, sensor); - if (status != SANE_STATUS_GOOD) { - dev->model->cmd_set->eject_document(dev); - DBG(DBG_error, "%s: failed to do dark shading calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } + genesys_dark_shading_calibration(dev, sensor); } catch (...) { - dev->model->cmd_set->eject_document(dev); + catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); }); throw; } - forward = SANE_FALSE; + forward = false; } /* go to a white area */ try { - status = dev->model->cmd_set->search_strip(dev, sensor, forward, SANE_FALSE); - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: failed to find white strip: %s\n", __func__, - sane_strstatus(status)); - dev->model->cmd_set->eject_document (dev); - return status; - } + dev->cmd_set->search_strip(dev, sensor, forward, false); } catch (...) { - dev->model->cmd_set->eject_document (dev); + catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); }); throw; } - status = dev->model->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do set up registers for shading calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } + genesys_repark_sensor_before_shading(dev); + + dev->cmd_set->init_regs_for_shading(dev, sensor, dev->calib_reg); try { - status = genesys_white_shading_calibration(dev, sensor); - if (status != SANE_STATUS_GOOD) { - dev->model->cmd_set->eject_document(dev); - DBG(DBG_error, "%s: failed eject target: %s\n", __func__, sane_strstatus(status)); - return status; - } + genesys_white_shading_calibration(dev, sensor); + genesys_repark_sensor_after_white_shading(dev); } catch (...) { - dev->model->cmd_set->eject_document (dev); + catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); }); throw; } - /* in case we haven't black shading data, build it from black pixels - * of white calibration */ - if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)) - { + // in case we haven't black shading data, build it from black pixels of white calibration + // FIXME: shouldn't we use genesys_dummy_dark_shading() ? + if (!(dev->model->flags & GENESYS_FLAG_DARK_CALIBRATION)) { dev->dark_average_data.clear(); - dev->dark_average_data.resize(dev->average_size, 0x0f); + dev->dark_average_data.resize(dev->average_size, 0x0f0f); /* XXX STEF XXX * with black point in white shading, build an average black * pixel and use it to fill the dark_average @@ -3521,78 +3088,33 @@ static SANE_Status genesys_sheetfed_calibration(Genesys_Device * dev, Genesys_Se /* send the shading coefficient when doing whole line shading * but not when using SHDAREA like GL124 */ - if(dev->model->cmd_set->send_shading_data==NULL) - { - status = genesys_send_shading_coefficient(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading calibration coefficients: %s\n", __func__, - sane_strstatus(status)); - return status; - } + if (!dev->cmd_set->has_send_shading_data()) { + genesys_send_shading_coefficient(dev, sensor); } - /* save the calibration data */ - genesys_save_calibration (dev, sensor); + // save the calibration data + genesys_save_calibration(dev, sensor); - /* and finally eject calibration sheet */ - status = dev->model->cmd_set->eject_document (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to eject document: %s\n", __func__, sane_strstatus(status)); - return status; - } + // and finally eject calibration sheet + dev->cmd_set->eject_document(dev); - /* resotre settings */ - dev->settings.xres = xres; - DBGCOMPLETED; - return SANE_STATUS_GOOD; + // restore settings + dev->settings.xres = sensor.optical_res; } /** * does the calibration process for a device * @param dev device to calibrate */ -static SANE_Status -genesys_scanner_calibration(Genesys_Device * dev, Genesys_Sensor& sensor) +static void genesys_scanner_calibration(Genesys_Device* dev, Genesys_Sensor& sensor) { - if (dev->model->is_sheetfed == SANE_FALSE) - { - return genesys_flatbed_calibration (dev, sensor); - } - return genesys_sheetfed_calibration(dev, sensor); -} - -/* unused function kept in case it may be usefull in the futur */ -#if 0 -static SANE_Status -genesys_wait_not_moving (Genesys_Device * dev, int mseconds) -{ - uint8_t value; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s: waiting %d mseconds for motor to stop\n", __func__, mseconds); - while (mseconds > 0) - { - RIE (sanei_genesys_get_status (dev, &value)); - - if (dev->model->cmd_set->test_motor_flag_bit (value)) - { - sanei_genesys_sleep_ms(100); - mseconds -= 100; - DBG(DBG_io, "%s: motor is moving, %d mseconds to go\n", __func__, mseconds); - } - else - { - DBG(DBG_info, "%s: motor is not moving, exiting\n", __func__); - return SANE_STATUS_GOOD; - } - + DBG_HELPER(dbg); + if (!dev->model->is_sheetfed) { + genesys_flatbed_calibration(dev, sensor); + return; } - DBG(DBG_error, "%s: motor is still moving, timeout exceeded\n", __func__); - return SANE_STATUS_DEVICE_BUSY; + genesys_sheetfed_calibration(dev, sensor); } -#endif /* ------------------------------------------------------------------------ */ @@ -3603,73 +3125,60 @@ genesys_wait_not_moving (Genesys_Device * dev, int mseconds) * wait lamp to be warm enough by scanning the same line until * differences between two scans are below a threshold */ -static SANE_Status -genesys_warmup_lamp (Genesys_Device * dev) +static void genesys_warmup_lamp(Genesys_Device* dev) { - int seconds = 0; + DBG_HELPER(dbg); + unsigned seconds = 0; int pixel; int channels, total_size; double first_average = 0; double second_average = 0; int difference = 255; - int empty, lines = 3; - SANE_Status status = SANE_STATUS_IO_ERROR; - - DBGSTART; - - /* check if the current chipset implements warmup */ - if(dev->model->cmd_set->init_regs_for_warmup==NULL) - { - DBG(DBG_error,"%s: init_regs_for_warmup not implemented\n", __func__); - return status; - } + int lines = 3; const auto& sensor = sanei_genesys_find_sensor_any(dev); - dev->model->cmd_set->init_regs_for_warmup(dev, sensor, &dev->reg, &channels, &total_size); + dev->cmd_set->init_regs_for_warmup(dev, sensor, &dev->reg, &channels, &total_size); std::vector<uint8_t> first_line(total_size); std::vector<uint8_t> second_line(total_size); do { DBG(DBG_info, "%s: one more loop\n", __func__); - RIE(dev->model->cmd_set->begin_scan(dev, sensor, &dev->reg, SANE_FALSE)); - do - { - sanei_genesys_test_buffer_empty (dev, &empty); - } - while (empty); + dev->cmd_set->begin_scan(dev, sensor, &dev->reg, false); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("warmup_lamp"); + dev->cmd_set->end_scan(dev, &dev->reg, true); + return; + } + + wait_until_buffer_non_empty(dev); try { - status = sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size); - if (status != SANE_STATUS_GOOD) { - RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size)); - } + sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size); } catch (...) { - RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size)); + // FIXME: document why this retry is here + sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size); } - RIE(dev->model->cmd_set->end_scan(dev, &dev->reg, SANE_TRUE)); + dev->cmd_set->end_scan(dev, &dev->reg, true); - sanei_genesys_sleep_ms(1000); + dev->interface->sleep_ms(1000); seconds++; - RIE(dev->model->cmd_set->begin_scan(dev, sensor, &dev->reg, SANE_FALSE)); - do - { - sanei_genesys_test_buffer_empty (dev, &empty); - sanei_genesys_sleep_ms(100); - } - while (empty); - RIE(sanei_genesys_read_data_from_scanner (dev, second_line.data(), total_size)); - RIE(dev->model->cmd_set->end_scan(dev, &dev->reg, SANE_TRUE)); + dev->cmd_set->begin_scan(dev, sensor, &dev->reg, false); + + wait_until_buffer_non_empty(dev); + + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + dev->cmd_set->end_scan(dev, &dev->reg, true); /* compute difference between the two scans */ for (pixel = 0; pixel < total_size; pixel++) { - /* 16 bit data */ - if (dev->model->cmd_set->get_bitset_bit(&dev->reg)) - { + // 16 bit data + if (dev->session.params.depth == 16) { first_average += (first_line[pixel] + first_line[pixel + 1] * 256); second_average += (second_line[pixel] + second_line[pixel + 1] * 256); pixel++; @@ -3680,11 +3189,10 @@ genesys_warmup_lamp (Genesys_Device * dev) second_average += second_line[pixel]; } } - if (dev->model->cmd_set->get_bitset_bit(&dev->reg)) - { + if (dev->session.params.depth == 16) { first_average /= pixel; second_average /= pixel; - difference = fabs (first_average - second_average); + difference = static_cast<int>(std::fabs(first_average - second_average)); DBG(DBG_info, "%s: average = %.2f, diff = %.3f\n", __func__, 100 * ((second_average) / (256 * 256)), 100 * (difference / second_average)); @@ -3713,162 +3221,93 @@ genesys_warmup_lamp (Genesys_Device * dev) } /* sleep another second before next loop */ - sanei_genesys_sleep_ms(1000); - seconds++; - } - while (seconds < WARMUP_TIME); + dev->interface->sleep_ms(1000); + seconds++; + } while (seconds < WARMUP_TIME); if (seconds >= WARMUP_TIME) { - DBG(DBG_error, "%s: warmup timed out after %d seconds. Lamp defective?\n", __func__, seconds); - status = SANE_STATUS_IO_ERROR; + throw SaneException(SANE_STATUS_IO_ERROR, + "warmup timed out after %d seconds. Lamp defective?", seconds); } else { DBG(DBG_info, "%s: warmup succeeded after %d seconds\n", __func__, seconds); } - - DBGCOMPLETED; - - return status; } -/* High-level start of scanning */ -static SANE_Status -genesys_start_scan (Genesys_Device * dev, SANE_Bool lamp_off) +// High-level start of scanning +static void genesys_start_scan(Genesys_Device* dev, bool lamp_off) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER(dbg); unsigned int steps, expected; - SANE_Bool empty; - - DBGSTART; /* since not all scanners are set ot wait for head to park * we check we are not still parking before starting a new scan */ - if (dev->parking == SANE_TRUE) - { - status = sanei_genesys_wait_for_home (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to wait for head to park: %s\n", __func__, - sane_strstatus(status)); - return status; - } + if (dev->parking) { + sanei_genesys_wait_for_home(dev); } - /* disable power saving*/ - status = dev->model->cmd_set->save_power (dev, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to disable power saving mode: %s\n", __func__, - sane_strstatus(status)); - return status; - } + // disable power saving + dev->cmd_set->save_power(dev, false); /* wait for lamp warmup : until a warmup for TRANSPARENCY is designed, skip * it when scanning from XPA. */ if (!(dev->model->flags & GENESYS_FLAG_SKIP_WARMUP) && (dev->settings.scan_method == ScanMethod::FLATBED)) { - RIE (genesys_warmup_lamp (dev)); + genesys_warmup_lamp(dev); } /* set top left x and y values by scanning the internals if flatbed scanners */ - if (dev->model->is_sheetfed == SANE_FALSE) - { + if (!dev->model->is_sheetfed) { /* do the geometry detection only once */ if ((dev->model->flags & GENESYS_FLAG_SEARCH_START) - && (dev->model->y_offset_calib == 0)) + && (dev->model->y_offset_calib_white == 0)) { - status = dev->model->cmd_set->search_start_position (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to search start position: %s\n", __func__, - sane_strstatus(status)); - return status; - } + dev->cmd_set->search_start_position (dev); - dev->parking = SANE_FALSE; - status = dev->model->cmd_set->slow_back_home (dev, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move scanhead to home position: %s\n", __func__, - sane_strstatus(status)); - return status; - } - dev->scanhead_position_in_steps = 0; + dev->parking = false; + dev->cmd_set->move_back_home(dev, true); } else { /* Go home */ /* TODO: check we can drop this since we cannot have the scanner's head wandering here */ - dev->parking = SANE_FALSE; - status = dev->model->cmd_set->slow_back_home (dev, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move scanhead to home position: %s\n", __func__, - sane_strstatus(status)); - return status; - } - dev->scanhead_position_in_steps = 0; + dev->parking = false; + dev->cmd_set->move_back_home(dev, true); } } /* move to calibration area for transparency adapter */ - if ((dev->settings.scan_method == ScanMethod::TRANSPARENCY) - && dev->model->cmd_set->move_to_ta != NULL) + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { - status=dev->model->cmd_set->move_to_ta(dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move to start of transparency adapter: %s\n", __func__, - sane_strstatus(status)); - return status; - } + dev->cmd_set->move_to_ta(dev); } /* load document if needed (for sheetfed scanner for instance) */ - if (dev->model->is_sheetfed == SANE_TRUE - && dev->model->cmd_set->load_document != NULL) - { - status = dev->model->cmd_set->load_document (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to load document: %s\n", __func__, sane_strstatus(status)); - return status; - } + if (dev->model->is_sheetfed) { + dev->cmd_set->load_document(dev); } auto& sensor = sanei_genesys_find_sensor_for_write(dev, dev->settings.xres, + dev->settings.get_channels(), dev->settings.scan_method); - /* send gamma tables. They have been set to device or user value - * when setting option value */ - status = dev->model->cmd_set->send_gamma_table(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to init gamma table: %s\n", __func__, sane_strstatus(status)); - return status; - } + // send gamma tables. They have been set to device or user value + // when setting option value */ + dev->cmd_set->send_gamma_table(dev, sensor); /* try to use cached calibration first */ if (!genesys_restore_calibration (dev, sensor)) { /* calibration : sheetfed scanners can't calibrate before each scan */ /* and also those who have the NO_CALIBRATION flag */ - if (!(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION) - &&dev->model->is_sheetfed == SANE_FALSE) - { - status = genesys_scanner_calibration(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do scanner calibration: %s\n", __func__, - sane_strstatus(status)); - return status; - } - + if (!(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION) && !dev->model->is_sheetfed) { + genesys_scanner_calibration(dev, sensor); genesys_save_calibration (dev, sensor); } else @@ -3878,76 +3317,47 @@ genesys_start_scan (Genesys_Device * dev, SANE_Bool lamp_off) } /* build look up table for dynamic lineart */ - if(dev->settings.dynamic_lineart==SANE_TRUE) - { - status = sanei_genesys_load_lut(dev->lineart_lut, 8, 8, 50, 205, - dev->settings.threshold_curve, - dev->settings.threshold-127); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to build lut\n", __func__); - return status; - } + if (dev->settings.scan_mode == ScanColorMode::LINEART) { + sanei_genesys_load_lut(dev->lineart_lut, 8, 8, 50, 205, dev->settings.threshold_curve, + dev->settings.threshold-127); } - if (dev->model->cmd_set->wait_for_motor_stop) { - dev->model->cmd_set->wait_for_motor_stop(dev); - } - - if (dev->model->cmd_set->needs_home_before_init_regs_for_scan && - dev->model->cmd_set->needs_home_before_init_regs_for_scan(dev) && - dev->model->cmd_set->slow_back_home) - { - RIE(dev->model->cmd_set->slow_back_home(dev, SANE_TRUE)); - } + dev->cmd_set->wait_for_motor_stop(dev); - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { - RIE(dev->model->cmd_set->move_to_ta(dev)); + if (dev->cmd_set->needs_home_before_init_regs_for_scan(dev)) { + dev->cmd_set->move_back_home(dev, true); } - status = dev->model->cmd_set->init_regs_for_scan(dev, sensor); - if (status != SANE_STATUS_GOOD) + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { - DBG(DBG_error, "%s: failed to do init registers for scan: %s\n", __func__, - sane_strstatus(status)); - return status; + dev->cmd_set->move_to_ta(dev); } + dev->cmd_set->init_regs_for_scan(dev, sensor); + /* no lamp during scan */ - if(lamp_off == SANE_TRUE) - { + if (lamp_off) { sanei_genesys_set_lamp_power(dev, sensor, dev->reg, false); } /* GL124 is using SHDAREA, so we have to wait for scan to be set up before * sending shading data */ - if( (dev->model->cmd_set->send_shading_data!=NULL) - && !(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) + if (dev->cmd_set->has_send_shading_data() && + !(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) { - status = genesys_send_shading_coefficient(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading calibration coefficients: %s\n", __func__, - sane_strstatus(status)); - return status; - } + genesys_send_shading_coefficient(dev, sensor); } - /* now send registers for scan */ - status = - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers, status = %d\n", __func__, status); - return status; - } + // now send registers for scan + dev->interface->write_registers(dev->reg); - /* start effective scan */ - status = dev->model->cmd_set->begin_scan(dev, sensor, &dev->reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; + // start effective scan + dev->cmd_set->begin_scan(dev, sensor, &dev->reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("start_scan"); + return; } /*do we really need this? the valid data check should be sufficent -- pierre*/ @@ -3957,348 +3367,36 @@ genesys_start_scan (Genesys_Device * dev, SANE_Bool lamp_off) + dev->reg.get8(0x3f); do { - // wait some time between each test to avoid overloading USB and CPU - sanei_genesys_sleep_ms(100); - status = sanei_genesys_read_feed_steps (dev, &steps); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to read feed steps: %s\n", __func__, sane_strstatus(status)); - return status; - } + // wait some time between each test to avoid overloading USB and CPU + dev->interface->sleep_ms(100); + sanei_genesys_read_feed_steps (dev, &steps); } while (steps < expected); - /* wait for buffers to be filled */ - do - { - RIE (sanei_genesys_test_buffer_empty (dev, &empty)); - } - while (empty); - - /* when doing one or two-table movement, let the motor settle to scanning speed */ - /* and scanning start before reading data */ -/* the valid data check already waits until the scanner delivers data. this here leads to unnecessary buffer full conditions in the scanner. - if (dev->model->cmd_set->get_fast_feed_bit (dev->reg)) - sanei_genesys_sleep_ms(1000); - else - sanei_genesys_sleep_ms(500); -*/ - /* then we wait for at least one word of valid scan data + wait_until_buffer_non_empty(dev); - this is also done in sanei_genesys_read_data_from_scanner -- pierre */ - if (dev->model->is_sheetfed == SANE_FALSE) - { - do - { - sanei_genesys_sleep_ms(100); - status = sanei_genesys_read_valid_words (dev, &steps); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read valid words: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } + // we wait for at least one word of valid scan data + // this is also done in sanei_genesys_read_data_from_scanner -- pierre + if (!dev->model->is_sheetfed) { + do { + dev->interface->sleep_ms(100); + sanei_genesys_read_valid_words(dev, &steps); + } while (steps < 1); } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* this is _not_ a ringbuffer. - if we need a block which does not fit at the end of our available data, - we move the available data to the beginning. - */ - -void Genesys_Buffer::alloc(size_t size) -{ - buffer_.resize(size); - avail_ = 0; - pos_ = 0; -} - -void Genesys_Buffer::clear() -{ - buffer_.clear(); - avail_ = 0; - pos_ = 0; -} - -void Genesys_Buffer::reset() -{ - avail_ = 0; - pos_ = 0; -} - -uint8_t* Genesys_Buffer::get_write_pos(size_t size) -{ - if (avail_ + size > buffer_.size()) - return nullptr; - if (pos_ + avail_ + size > buffer_.size()) - { - std::memmove(buffer_.data(), buffer_.data() + pos_, avail_); - pos_ = 0; - } - return buffer_.data() + pos_ + avail_; -} - -uint8_t* Genesys_Buffer::get_read_pos() -{ - return buffer_.data() + pos_; } -void Genesys_Buffer::produce(size_t size) +static void genesys_fill_read_buffer(Genesys_Device* dev) { - if (size > buffer_.size() - avail_) - throw std::runtime_error("buffer size exceeded"); - avail_ += size; -} - -void Genesys_Buffer::consume(size_t size) -{ - if (size > avail_) - throw std::runtime_error("no more data in buffer"); - avail_ -= size; - pos_ += size; -} - - -#include "genesys_conv.cc" - -static SANE_Status accurate_line_read(Genesys_Device * dev, - Genesys_Buffer& buffer) -{ - buffer.reset(); - - SANE_Status status = SANE_STATUS_GOOD; - status = dev->model->cmd_set->bulk_read_data(dev, 0x45, buffer.get_write_pos(buffer.size()), - buffer.size()); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read %lu bytes (%s)\n", __func__, (u_long) buffer.size(), - sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - - buffer.produce(buffer.size()); - return status; -} - -/** @brief fill buffer while reducing vertical resolution - * This function fills a read buffer with scanned data from a sensor - * which puts odd and even pixels in 2 different data segment. So a complete - * must be read and bytes interleaved to get usable by the other stages - * of the backend - */ -static SANE_Status -genesys_fill_line_interp_buffer (Genesys_Device * dev, uint8_t *work_buffer_dst, size_t size) -{ - size_t count; - SANE_Status status = SANE_STATUS_GOOD; - - /* fill buffer if needed */ - if (dev->oe_buffer.avail() == 0) - { - status = accurate_line_read(dev, dev->oe_buffer); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read %lu bytes (%s)\n", __func__, - (u_long) dev->oe_buffer.size(), sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - } - - /* copy size bytes of data, copying from a line when line count matches */ - count = 0; - while (count < size) - { - /* line counter */ - /* dev->line_interp holds the number of lines scanned for one line of data sent */ - if(((dev->line_count/dev->current_setup.channels) % dev->line_interp)==0) - { - /* copy pixel when line matches */ - work_buffer_dst[count] = dev->oe_buffer.get_read_pos()[dev->cur]; - count++; - } - - /* always update pointer so we skip uncopied data */ - dev->cur++; - - /* go to next line if needed */ - if (dev->cur == dev->len) - { - dev->oe_buffer.set_pos(dev->oe_buffer.pos() + dev->bpl); - dev->cur = 0; - dev->line_count++; - } - - /* read a new buffer if needed */ - if (dev->oe_buffer.pos() >= dev->oe_buffer.avail()) - { - status = accurate_line_read(dev, dev->oe_buffer); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read %lu bytes (%s)\n", __func__, - (u_long) dev->oe_buffer.size(), sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - } - } - - return SANE_STATUS_GOOD; -} - -/** @brief fill buffer for segmented sensors - * This function fills a read buffer with scanned data from a sensor segmented - * in several parts (multi-lines sensors). Data of the same valid area is read - * back to back and must be interleaved to get usable by the other stages - * of the backend - */ -static SANE_Status -genesys_fill_segmented_buffer (Genesys_Device * dev, uint8_t *work_buffer_dst, size_t size) -{ - size_t count; - SANE_Status status = SANE_STATUS_GOOD; - int depth,i,n,k; - - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART && dev->settings.dynamic_lineart==SANE_FALSE) - depth = 1; - - /* fill buffer if needed */ - if (dev->oe_buffer.avail() == 0) - { - status = accurate_line_read(dev, dev->oe_buffer); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read %lu bytes (%s)\n", __func__, - (u_long) dev->oe_buffer.size(), sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - } - - /* copy size bytes of data, copying from a subwindow of each line - * when last line of buffer is exhausted, read another one */ - count = 0; - while (count < size) - { - if (depth==1) { - while (dev->cur < dev->len && count < size) { - for (n=0; n<dev->segnb; n++) { - work_buffer_dst[count+n] = 0; - } - /* interleaving is at bit level */ - for (i=0;i<8;i++) { - k=count+(i*dev->segnb)/8; - for (n=0;n<dev->segnb;n++) { - work_buffer_dst[k] = work_buffer_dst[k] << 1; - if ((dev->oe_buffer.get_read_pos()[dev->cur + dev->skip + dev->dist*dev->order[n]])&(128>>i)) { - work_buffer_dst[k] |= 1; - } - } - } - - /* update counter and pointer */ - count += dev->segnb; - dev->cur++; - } - } - if (depth==8) { - while (dev->cur < dev->len && count < size) { - for (n=0;n<dev->segnb;n++) { - work_buffer_dst[count+n] = dev->oe_buffer.get_read_pos()[dev->cur + dev->skip + dev->dist*dev->order[n]]; - } - /* update counter and pointer */ - count += dev->segnb; - dev->cur++; - } - } - if (depth==16) { - while (dev->cur < dev->len && count < size) { - for (n=0;n<dev->segnb;n++) { - work_buffer_dst[count+n*2] = dev->oe_buffer.get_read_pos()[dev->cur + dev->skip + dev->dist*dev->order[n]]; - work_buffer_dst[count+n*2+1] = dev->oe_buffer.get_read_pos()[dev->cur + dev->skip + dev->dist*dev->order[n] + 1]; - } - /* update counter and pointer */ - count += dev->segnb*2; - dev->cur+=2; - } - } - - /* go to next line if needed */ - if (dev->cur == dev->len) - { - dev->oe_buffer.set_pos(dev->oe_buffer.pos() + dev->bpl); - dev->cur = 0; - } - - /* read a new buffer if needed */ - if (dev->oe_buffer.pos() >= dev->oe_buffer.avail()) - { - status = accurate_line_read(dev, dev->oe_buffer); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read %lu bytes (%s)\n", __func__, - (u_long) dev->oe_buffer.size(), sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - } - } - - return SANE_STATUS_GOOD; -} - -/** - * - */ -static SANE_Status -genesys_fill_read_buffer (Genesys_Device * dev) -{ - size_t size; - size_t space; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t *work_buffer_dst; - - DBGSTART; + DBG_HELPER(dbg); /* for sheetfed scanner, we must check is document is shorter than * the requested scan */ - if (dev->model->is_sheetfed == SANE_TRUE) - { - status = dev->model->cmd_set->detect_document_end (dev); - if (status != SANE_STATUS_GOOD) - return status; - } - - space = dev->read_buffer.size() - dev->read_buffer.avail(); - - work_buffer_dst = dev->read_buffer.get_write_pos(space); - - size = space; - - /* never read an odd number. exception: last read - the chip internal counter does not count half words. */ - size &= ~1; - /* Some setups need the reads to be multiples of 256 bytes */ - size &= ~0xff; - - if (dev->read_bytes_left < size) - { - size = dev->read_bytes_left; - /*round up to a multiple of 256 bytes */ - size += (size & 0xff) ? 0x100 : 0x00; - size &= ~0xff; + if (dev->model->is_sheetfed) { + dev->cmd_set->detect_document_end(dev); } - /* early out if our remaining buffer capacity is too low */ - if (size == 0) - return SANE_STATUS_GOOD; - - DBG(DBG_io, "%s: reading %lu bytes\n", __func__, (u_long) size); - - /* size is already maxed to our needs. for most models bulk_read_data - will read as much data as requested. */ + std::size_t size = dev->read_buffer.size() - dev->read_buffer.avail(); /* due to sensors and motors, not all data can be directly used. It * may have to be read from another intermediate buffer and then processed. @@ -4310,159 +3408,46 @@ genesys_fill_read_buffer (Genesys_Device * dev) * * This is also the place where full duplex data will be handled. */ - if (dev->line_interp>0) - { - /* line interpolation */ - status = genesys_fill_line_interp_buffer (dev, work_buffer_dst, size); - } - else if (dev->segnb>1) - { - /* multi-segment sensors processing */ - status = genesys_fill_segmented_buffer (dev, work_buffer_dst, size); - } - else /* regular case with no extra copy */ - { - status = dev->model->cmd_set->bulk_read_data (dev, 0x45, work_buffer_dst, size); - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read %lu bytes (%s)\n", __func__, (u_long) size, - sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - - if (size > dev->read_bytes_left) - size = dev->read_bytes_left; - - dev->read_bytes_left -= size; + dev->pipeline_buffer.get_data(size, dev->read_buffer.get_write_pos(size)); - dev->read_buffer.produce(size); - - DBGCOMPLETED; - - return SANE_STATUS_GOOD; + dev->read_buffer.produce(size); } /* this function does the effective data read in a manner that suits the scanner. It does data reordering and resizing if need. It also manages EOF and I/O errors, and line distance correction. - */ -static SANE_Status -genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination, - size_t * len) + Returns true on success, false on end-of-file. +*/ +static void genesys_read_ordered_data(Genesys_Device* dev, SANE_Byte* destination, size_t* len) { - SANE_Status status = SANE_STATUS_GOOD; - size_t bytes, extra; - unsigned int channels, depth, src_pixels; - unsigned int ccd_shift[12], shift_count; + DBG_HELPER(dbg); + size_t bytes = 0; uint8_t *work_buffer_src; - uint8_t *work_buffer_dst; - unsigned int dst_lines; - unsigned int step_1_mode; - unsigned int needs_reorder; - unsigned int needs_ccd; - unsigned int needs_shrink; - unsigned int needs_reverse; Genesys_Buffer *src_buffer; - Genesys_Buffer *dst_buffer; - DBGSTART; - if (dev->read_active != SANE_TRUE) - { - DBG(DBG_error, "%s: read not active!\n", __func__); + if (!dev->read_active) { *len = 0; - return SANE_STATUS_INVAL; + throw SaneException("read is not active"); } - DBG(DBG_info, "%s: ", __func__); - debug_dump(DBG_info, dev->current_setup); - - /* prepare conversion */ - /* current settings */ - channels = dev->current_setup.channels; - depth = dev->current_setup.depth; - - src_pixels = dev->current_setup.pixels; - - needs_reorder = 1; - if (channels != 3 && depth != 16) - needs_reorder = 0; -#ifndef WORDS_BIGENDIAN - if (channels != 3 && depth == 16) - needs_reorder = 0; - if (channels == 3 && depth == 16 && !dev->model->is_cis && - dev->model->line_mode_color_order == COLOR_ORDER_RGB) - needs_reorder = 0; -#endif - if (channels == 3 && depth == 8 && !dev->model->is_cis && - dev->model->line_mode_color_order == COLOR_ORDER_RGB) - needs_reorder = 0; + DBG(DBG_info, "%s: frontend requested %zu bytes\n", __func__, *len); + DBG(DBG_info, "%s: bytes_to_read=%zu, total_bytes_read=%zu\n", __func__, + dev->total_bytes_to_read, dev->total_bytes_read); - needs_ccd = dev->current_setup.max_shift > 0; - needs_shrink = dev->settings.pixels != src_pixels; - needs_reverse = depth == 1; - - DBG(DBG_info, "%s: using filters:%s%s%s%s\n", __func__, - needs_reorder ? " reorder" : "", - needs_ccd ? " ccd" : "", - needs_shrink ? " shrink" : "", - needs_reverse ? " reverse" : ""); - - DBG(DBG_info, "%s: frontend requested %lu bytes\n", __func__, (u_long) * len); - - DBG(DBG_info, "%s: bytes_to_read=%lu, total_bytes_read=%lu\n", __func__, - (u_long) dev->total_bytes_to_read, (u_long) dev->total_bytes_read); /* is there data left to scan */ if (dev->total_bytes_read >= dev->total_bytes_to_read) { - DBG(DBG_proc, "%s: nothing more to scan: EOF\n", __func__); - *len = 0; - /* issue park command immediatly in case scanner can handle it * so we save time */ - if (dev->model->is_sheetfed == SANE_FALSE - && !(dev->model->flags & GENESYS_FLAG_MUST_WAIT) - && dev->parking == SANE_FALSE) + if (!dev->model->is_sheetfed && !(dev->model->flags & GENESYS_FLAG_MUST_WAIT) && + !dev->parking) { - dev->model->cmd_set->slow_back_home (dev, SANE_FALSE); - dev->parking = SANE_TRUE; + dev->cmd_set->move_back_home(dev, false); + dev->parking = true; } - return SANE_STATUS_EOF; - } - - DBG(DBG_info, "%s: %lu lines left by output\n", __func__, - ((dev->total_bytes_to_read - dev->total_bytes_read) * 8UL) / - (dev->settings.pixels * channels * depth)); - DBG(DBG_info, "%s: %lu lines left by input\n", __func__, - ((dev->read_bytes_left + dev->read_buffer.avail()) * 8UL) / - (src_pixels * channels * depth)); - - if (channels == 1) - { - ccd_shift[0] = 0; - ccd_shift[1] = dev->current_setup.stagger; - shift_count = 2; - } - else - { - ccd_shift[0] = - ((dev->ld_shift_r * dev->settings.yres) / - dev->motor.base_ydpi); - ccd_shift[1] = - ((dev->ld_shift_g * dev->settings.yres) / - dev->motor.base_ydpi); - ccd_shift[2] = - ((dev->ld_shift_b * dev->settings.yres) / - dev->motor.base_ydpi); - - ccd_shift[3] = ccd_shift[0] + dev->current_setup.stagger; - ccd_shift[4] = ccd_shift[1] + dev->current_setup.stagger; - ccd_shift[5] = ccd_shift[2] + dev->current_setup.stagger; - - shift_count = 6; + throw SaneException(SANE_STATUS_EOF, "nothing more to scan: EOF"); } - /* convert data */ /* 0. fill_read_buffer @@ -4490,317 +3475,46 @@ Problems with the first approach: total_bytes_to_read and total_bytes_read help in that case. */ - status = genesys_fill_read_buffer (dev); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: genesys_fill_read_buffer failed\n", __func__); - return status; - } - - src_buffer = &(dev->read_buffer); - -/* maybe reorder components/bytes */ - if (needs_reorder) - { -/*not implemented for depth == 1.*/ - if (depth == 1) - { - DBG(DBG_error, "Can't reorder single bit data\n"); - return SANE_STATUS_INVAL; - } - - dst_buffer = &(dev->lines_buffer); - - work_buffer_src = src_buffer->get_read_pos(); - bytes = src_buffer->avail(); - -/*how many bytes can be processed here?*/ -/*we are greedy. we work as much as possible*/ - if (bytes > dst_buffer->size() - dst_buffer->avail()) - bytes = dst_buffer->size() - dst_buffer->avail(); - - dst_lines = (bytes * 8) / (src_pixels * channels * depth); - bytes = (dst_lines * src_pixels * channels * depth) / 8; - - work_buffer_dst = dst_buffer->get_write_pos(bytes); - - DBG(DBG_info, "%s: reordering %d lines\n", __func__, dst_lines); - - if (dst_lines != 0) - { - - if (channels == 3) - { - step_1_mode = 0; - - if (depth == 16) - step_1_mode |= 1; - - if (dev->model->is_cis) - step_1_mode |= 2; - - if (dev->model->line_mode_color_order == COLOR_ORDER_BGR) - step_1_mode |= 4; - - switch (step_1_mode) - { - case 1: /* RGB, chunky, 16 bit */ -#ifdef WORDS_BIGENDIAN - status = - genesys_reorder_components_endian_16 (work_buffer_src, - work_buffer_dst, - dst_lines, - src_pixels, 3); - break; -#endif /*WORDS_BIGENDIAN */ - case 0: /* RGB, chunky, 8 bit */ - status = SANE_STATUS_GOOD; - break; - case 2: /* RGB, cis, 8 bit */ - status = - genesys_reorder_components_cis_8 (work_buffer_src, - work_buffer_dst, - dst_lines, src_pixels); - break; - case 3: /* RGB, cis, 16 bit */ - status = - genesys_reorder_components_cis_16 (work_buffer_src, - work_buffer_dst, - dst_lines, src_pixels); - break; - case 4: /* BGR, chunky, 8 bit */ - status = - genesys_reorder_components_bgr_8 (work_buffer_src, - work_buffer_dst, - dst_lines, src_pixels); - break; - case 5: /* BGR, chunky, 16 bit */ - status = - genesys_reorder_components_bgr_16 (work_buffer_src, - work_buffer_dst, - dst_lines, src_pixels); - break; - case 6: /* BGR, cis, 8 bit */ - status = - genesys_reorder_components_cis_bgr_8 (work_buffer_src, - work_buffer_dst, - dst_lines, - src_pixels); - break; - case 7: /* BGR, cis, 16 bit */ - status = - genesys_reorder_components_cis_bgr_16 (work_buffer_src, - work_buffer_dst, - dst_lines, - src_pixels); - break; - } - } - else - { -#ifdef WORDS_BIGENDIAN - if (depth == 16) - { - status = - genesys_reorder_components_endian_16 (work_buffer_src, - work_buffer_dst, - dst_lines, - src_pixels, 1); - } - else - { - status = SANE_STATUS_GOOD; - } -#else /*!WORDS_BIGENDIAN */ - status = SANE_STATUS_GOOD; -#endif /*WORDS_BIGENDIAN */ - } - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to convert byte ordering(%s)\n", __func__, - sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - - dst_buffer->produce(bytes); - src_buffer->consume(bytes); - } - src_buffer = dst_buffer; - } - -/* maybe reverse effects of ccd layout */ - if (needs_ccd) - { -/*should not happen with depth == 1.*/ - if (depth == 1) - { - DBG(DBG_error, "Can't reverse ccd for single bit data\n"); - return SANE_STATUS_INVAL; - } - - dst_buffer = &(dev->shrink_buffer); - - work_buffer_src = src_buffer->get_read_pos(); - bytes = src_buffer->avail(); - - extra = - (dev->current_setup.max_shift * src_pixels * channels * depth) / 8; - -/*extra bytes are reserved, and should not be consumed*/ - if (bytes < extra) - bytes = 0; - else - bytes -= extra; - -/*how many bytes can be processed here?*/ -/*we are greedy. we work as much as possible*/ - if (bytes > dst_buffer->size() - dst_buffer->avail()) - bytes = dst_buffer->size() - dst_buffer->avail(); - - dst_lines = (bytes * 8) / (src_pixels * channels * depth); - bytes = (dst_lines * src_pixels * channels * depth) / 8; - - work_buffer_dst = dst_buffer->get_write_pos(bytes); - - DBG(DBG_info, "%s: un-ccd-ing %d lines\n", __func__, dst_lines); - - if (dst_lines != 0) - { - - if (depth == 8) - status = genesys_reverse_ccd_8 (work_buffer_src, work_buffer_dst, - dst_lines, - src_pixels * channels, - ccd_shift, shift_count); - else - status = genesys_reverse_ccd_16 (work_buffer_src, work_buffer_dst, - dst_lines, - src_pixels * channels, - ccd_shift, shift_count); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to reverse ccd effects(%s)\n", __func__, - sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - - dst_buffer->produce(bytes); - src_buffer->consume(bytes); - } - src_buffer = dst_buffer; - } - -/* maybe shrink(or enlarge) lines */ - if (needs_shrink) - { - - dst_buffer = &(dev->out_buffer); - - work_buffer_src = src_buffer->get_read_pos(); - bytes = src_buffer->avail(); - -/*lines in input*/ - dst_lines = (bytes * 8) / (src_pixels * channels * depth); - - /* how many lines can be processed here? */ - /* we are greedy. we work as much as possible */ - bytes = dst_buffer->size() - dst_buffer->avail(); - - if (dst_lines > (bytes * 8) / (dev->settings.pixels * channels * depth)) - dst_lines = (bytes * 8) / (dev->settings.pixels * channels * depth); - - bytes = (dst_lines * dev->settings.pixels * channels * depth) / 8; - - work_buffer_dst = dst_buffer->get_write_pos(bytes); + if (is_testing_mode()) { + if (dev->total_bytes_read + *len > dev->total_bytes_to_read) { + *len = dev->total_bytes_to_read - dev->total_bytes_read; + } + dev->total_bytes_read += *len; + } else { + genesys_fill_read_buffer(dev); - DBG(DBG_info, "%s: shrinking %d lines\n", __func__, dst_lines); + src_buffer = &(dev->read_buffer); - if (dst_lines != 0) - { - if (depth == 1) - status = genesys_shrink_lines_1 (work_buffer_src, - work_buffer_dst, - dst_lines, - src_pixels, - dev->settings.pixels, - channels); - else if (depth == 8) - status = genesys_shrink_lines_8 (work_buffer_src, - work_buffer_dst, - dst_lines, - src_pixels, - dev->settings.pixels, channels); - else - status = genesys_shrink_lines_16 (work_buffer_src, - work_buffer_dst, - dst_lines, - src_pixels, - dev->settings.pixels, channels); + /* move data to destination */ + bytes = std::min(src_buffer->avail(), *len); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to shrink lines(%s)\n", __func__, sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } + work_buffer_src = src_buffer->get_read_pos(); - /* we just consumed this many bytes*/ - bytes = (dst_lines * src_pixels * channels * depth) / 8; - src_buffer->consume(bytes); + std::memcpy(destination, work_buffer_src, bytes); + *len = bytes; - /* we just created this many bytes*/ - bytes = (dst_lines * dev->settings.pixels * channels * depth) / 8; - dst_buffer->produce(bytes); - } - src_buffer = dst_buffer; - } + /* avoid signaling some extra data because we have treated a full block + * on the last block */ + if (dev->total_bytes_read + *len > dev->total_bytes_to_read) { + *len = dev->total_bytes_to_read - dev->total_bytes_read; + } - /* move data to destination */ - bytes = src_buffer->avail(); - if (bytes > *len) - bytes = *len; - work_buffer_src = src_buffer->get_read_pos(); + /* count bytes sent to frontend */ + dev->total_bytes_read += *len; - if (needs_reverse) - { - status = genesys_reverse_bits (work_buffer_src, destination, bytes); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to reverse bits(%s)\n", __func__, sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - *len = bytes; + src_buffer->consume(bytes); } - else - { - memcpy (destination, work_buffer_src, bytes); - *len = bytes; - } - - /* avoid signaling some extra data because we have treated a full block - * on the last block */ - if (dev->total_bytes_read + *len > dev->total_bytes_to_read) - *len = dev->total_bytes_to_read - dev->total_bytes_read; - - /* count bytes sent to frontend */ - dev->total_bytes_read += *len; - - src_buffer->consume(bytes); /* end scan if all needed data have been read */ if(dev->total_bytes_read >= dev->total_bytes_to_read) { - dev->model->cmd_set->end_scan(dev, &dev->reg, SANE_TRUE); - if (dev->model->is_sheetfed == SANE_TRUE) - { - dev->model->cmd_set->eject_document (dev); + dev->cmd_set->end_scan(dev, &dev->reg, true); + if (dev->model->is_sheetfed) { + dev->cmd_set->eject_document (dev); } } - DBG(DBG_proc, "%s: completed, %lu bytes read\n", __func__, (u_long) bytes); - return SANE_STATUS_GOOD; + DBG(DBG_proc, "%s: completed, %zu bytes read\n", __func__, bytes); } @@ -4824,10 +3538,47 @@ max_string_size (const SANE_String_Const strings[]) return max_size; } -static SANE_Status -calc_parameters (Genesys_Scanner * s) +static std::size_t max_string_size(const std::vector<const char*>& strings) +{ + std::size_t max_size = 0; + for (const auto& s : strings) { + if (!s) { + continue; + } + max_size = std::max(max_size, std::strlen(s)); + } + return max_size; +} + +static unsigned pick_resolution(const std::vector<unsigned>& resolutions, unsigned resolution, + const char* direction) +{ + DBG_HELPER(dbg); + + if (resolutions.empty()) + throw SaneException("Empty resolution list"); + + unsigned best_res = resolutions.front(); + unsigned min_diff = abs_diff(best_res, resolution); + + for (auto it = std::next(resolutions.begin()); it != resolutions.end(); ++it) { + unsigned curr_diff = abs_diff(*it, resolution); + if (curr_diff < min_diff) { + min_diff = curr_diff; + best_res = *it; + } + } + + if (best_res != resolution) { + DBG(DBG_warn, "%s: using resolution %d that is nearest to %d for direction %s\n", + __func__, best_res, resolution, direction); + } + return best_res; +} + +static void calc_parameters(Genesys_Scanner* s) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER(dbg); double tl_x = 0, tl_y = 0, br_x = 0, br_y = 0; tl_x = SANE_UNFIX(s->pos_top_left_x); @@ -4835,7 +3586,7 @@ calc_parameters (Genesys_Scanner * s) br_x = SANE_UNFIX(s->pos_bottom_right_x); br_y = SANE_UNFIX(s->pos_bottom_right_y); - s->params.last_frame = SANE_TRUE; /* only single pass scanning supported */ + s->params.last_frame = true; /* only single pass scanning supported */ if (s->mode == SANE_VALUE_SCAN_MODE_GRAY || s->mode == SANE_VALUE_SCAN_MODE_LINEART) { s->params.format = SANE_FRAME_GRAY; @@ -4849,6 +3600,9 @@ calc_parameters (Genesys_Scanner * s) s->params.depth = s->bit_depth; } + s->dev->settings.scan_method = s->scan_method; + const auto& resolutions = s->dev->model->get_resolution_settings(s->dev->settings.scan_method); + s->dev->settings.depth = s->bit_depth; /* interpolation */ @@ -4858,86 +3612,93 @@ calc_parameters (Genesys_Scanner * s) const auto& sensor = sanei_genesys_find_sensor_any(s->dev); // hardware settings - if (s->resolution > sensor.optical_res && s->dev->settings.disable_interpolation) { + if (static_cast<unsigned>(s->resolution) > sensor.optical_res && + s->dev->settings.disable_interpolation) + { s->dev->settings.xres = sensor.optical_res; } else { s->dev->settings.xres = s->resolution; } s->dev->settings.yres = s->resolution; - s->params.lines = ((br_y - tl_y) * s->dev->settings.yres) / MM_PER_INCH; - s->params.pixels_per_line = ((br_x - tl_x) * s->resolution) / MM_PER_INCH; + s->dev->settings.xres = pick_resolution(resolutions.resolutions_x, s->dev->settings.xres, "X"); + s->dev->settings.yres = pick_resolution(resolutions.resolutions_y, s->dev->settings.yres, "Y"); + + s->params.lines = static_cast<unsigned>(((br_y - tl_y) * s->dev->settings.yres) / + MM_PER_INCH); + unsigned pixels_per_line = static_cast<unsigned>(((br_x - tl_x) * s->dev->settings.xres) / + MM_PER_INCH); /* we need an even pixels number * TODO invert test logic or generalize behaviour across all ASICs */ - if ((s->dev->model->flags & GENESYS_FLAG_SIS_SENSOR) - || s->dev->model->asic_type == GENESYS_GL847 - || s->dev->model->asic_type == GENESYS_GL124 - || s->dev->model->asic_type == GENESYS_GL845 - || s->dev->model->asic_type == GENESYS_GL846 - || s->dev->model->asic_type == GENESYS_GL843) - { - if (s->dev->settings.xres <= 1200) - s->params.pixels_per_line = (s->params.pixels_per_line/4)*4; - else - s->params.pixels_per_line = (s->params.pixels_per_line/16)*16; + if ((s->dev->model->flags & GENESYS_FLAG_SIS_SENSOR) || + s->dev->model->asic_type == AsicType::GL847 || + s->dev->model->asic_type == AsicType::GL124 || + s->dev->model->asic_type == AsicType::GL845 || + s->dev->model->asic_type == AsicType::GL846 || + s->dev->model->asic_type == AsicType::GL843) + { + if (s->dev->settings.xres <= 1200) { + pixels_per_line = (pixels_per_line / 4) * 4; + } else if (s->dev->settings.xres < s->dev->settings.yres) { + // BUG: this is an artifact of the fact that the resolution was twice as large than + // the actual resolution when scanning above the supported scanner X resolution + pixels_per_line = (pixels_per_line / 8) * 8; + } else { + pixels_per_line = (pixels_per_line / 16) * 16; + } } /* corner case for true lineart for sensor with several segments * or when xres is doubled to match yres */ - if (s->dev->settings.xres >= 1200 - && ( s->dev->model->asic_type == GENESYS_GL124 - || s->dev->model->asic_type == GENESYS_GL847 - || s->dev->current_setup.xres < s->dev->current_setup.yres - ) - ) - { - s->params.pixels_per_line = (s->params.pixels_per_line/16)*16; + if (s->dev->settings.xres >= 1200 && ( + s->dev->model->asic_type == AsicType::GL124 || + s->dev->model->asic_type == AsicType::GL847 || + s->dev->session.params.xres < s->dev->session.params.yres)) + { + if (s->dev->settings.xres < s->dev->settings.yres) { + // FIXME: this is an artifact of the fact that the resolution was twice as large than + // the actual resolution when scanning above the supported scanner X resolution + pixels_per_line = (pixels_per_line / 8) * 8; + } else { + pixels_per_line = (pixels_per_line / 16) * 16; + } } - s->params.bytes_per_line = s->params.pixels_per_line; + unsigned xres_factor = s->resolution / s->dev->settings.xres; + + unsigned bytes_per_line = 0; + if (s->params.depth > 8) { s->params.depth = 16; - s->params.bytes_per_line *= 2; + bytes_per_line = 2 * pixels_per_line; } else if (s->params.depth == 1) { - s->params.bytes_per_line /= 8; - /* round down pixel number - really? rounding down means loss of at most 7 pixels! -- pierre */ - s->params.pixels_per_line = 8 * s->params.bytes_per_line; + // round down pixel number. This will is lossy operation, at most 7 pixels will be lost + pixels_per_line = (pixels_per_line / 8) * 8; + bytes_per_line = pixels_per_line / 8; + } else { + bytes_per_line = pixels_per_line; } if (s->params.format == SANE_FRAME_RGB) { - s->params.bytes_per_line *= 3; - } - - if (s->mode == SANE_VALUE_SCAN_MODE_COLOR) { - s->dev->settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - } else if (s->mode == SANE_VALUE_SCAN_MODE_GRAY) { - s->dev->settings.scan_mode = ScanColorMode::GRAY; - } else if (s->mode == SANE_TITLE_HALFTONE) { - s->dev->settings.scan_mode = ScanColorMode::HALFTONE; - } else { /* Lineart */ - s->dev->settings.scan_mode = ScanColorMode::LINEART; + bytes_per_line *= 3; } - if (s->source == STR_FLATBED) { - s->dev->settings.scan_method = ScanMethod::FLATBED; - } else if (s->source == STR_TRANSPARENCY_ADAPTER) { - s->dev->settings.scan_method = ScanMethod::TRANSPARENCY; - } else if (s->source == STR_TRANSPARENCY_ADAPTER_INFRARED) { - s->dev->settings.scan_method = ScanMethod::TRANSPARENCY_INFRARED; - } + s->dev->settings.scan_mode = option_string_to_scan_color_mode(s->mode); s->dev->settings.lines = s->params.lines; - s->dev->settings.pixels = s->params.pixels_per_line; + s->dev->settings.pixels = pixels_per_line; + s->dev->settings.requested_pixels = pixels_per_line * xres_factor; + s->params.pixels_per_line = pixels_per_line * xres_factor; + s->params.bytes_per_line = bytes_per_line * xres_factor; s->dev->settings.tl_x = tl_x; s->dev->settings.tl_y = tl_y; // threshold setting - s->dev->settings.threshold = 2.55 * (SANE_UNFIX(s->threshold)); + s->dev->settings.threshold = static_cast<int>(2.55 * (SANE_UNFIX(s->threshold))); // color filter if (s->color_filter == "Red") { @@ -4957,23 +3718,6 @@ calc_parameters (Genesys_Scanner * s) s->dev->settings.true_gray = 0; } - /* dynamic lineart */ - s->dev->settings.dynamic_lineart = SANE_FALSE; - s->dev->settings.threshold_curve=0; - if (!s->disable_dynamic_lineart && s->dev->settings.scan_mode == ScanColorMode::LINEART) { - s->dev->settings.dynamic_lineart = SANE_TRUE; - } - - /* hardware lineart works only when we don't have interleave data - * for GL847 scanners, ie up to 600 DPI, then we have to rely on - * dynamic_lineart */ - if(s->dev->settings.xres > 600 - && s->dev->model->asic_type==GENESYS_GL847 - && s->dev->settings.scan_mode == ScanColorMode::LINEART) - { - s->dev->settings.dynamic_lineart = SANE_TRUE; - } - // threshold curve for dynamic rasterization s->dev->settings.threshold_curve = s->threshold_curve; @@ -4984,11 +3728,11 @@ calc_parameters (Genesys_Scanner * s) && (!s->preview) && (s->bit_depth <= 8)) { - s->dev->buffer_image=SANE_TRUE; + s->dev->buffer_image = true; } else { - s->dev->buffer_image=SANE_FALSE; + s->dev->buffer_image = false; } /* brigthness and contrast only for for 8 bit scans */ @@ -5005,24 +3749,13 @@ calc_parameters (Genesys_Scanner * s) /* cache expiration time */ s->dev->settings.expiration_time = s->expiration_time; - - return status; } -static SANE_Status -create_bpp_list (Genesys_Scanner * s, SANE_Int * bpp) +static void create_bpp_list (Genesys_Scanner * s, const std::vector<unsigned>& bpp) { - int count; - - for (count = 0; bpp[count] != 0; count++) - ; - s->bpp_list[0] = count; - for (count = 0; bpp[count] != 0; count++) - { - s->bpp_list[s->bpp_list[0] - count] = bpp[count]; - } - return SANE_STATUS_GOOD; + s->bpp_list[0] = bpp.size(); + std::reverse_copy(bpp.begin(), bpp.end(), s->bpp_list + 1); } /** @brief this function initialize a gamma vector based on the ASIC: @@ -5042,8 +3775,7 @@ init_gamma_vector_option (Genesys_Scanner * scanner, int option) scanner->opt[option].cap |= SANE_CAP_INACTIVE | SANE_CAP_ADVANCED; scanner->opt[option].unit = SANE_UNIT_NONE; scanner->opt[option].constraint_type = SANE_CONSTRAINT_RANGE; - if (scanner->dev->model->asic_type == GENESYS_GL646) - { + if (scanner->dev->model->asic_type == AsicType::GL646) { if ((scanner->dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) != 0) { scanner->opt[option].size = 16384 * sizeof (SANE_Word); @@ -5065,20 +3797,15 @@ init_gamma_vector_option (Genesys_Scanner * scanner, int option) /** * allocate a geometry range * @param size maximum size of the range - * @return a pointer to a valid range or NULL + * @return a pointer to a valid range or nullptr */ -static SANE_Range *create_range(SANE_Fixed size) +static SANE_Range create_range(float size) { -SANE_Range *range=NULL; - - range=(SANE_Range *)malloc(sizeof(SANE_Range)); - if(range!=NULL) - { - range->min = SANE_FIX (0.0); - range->max = size; - range->quant = SANE_FIX (0.0); - } - return range; + SANE_Range range; + range.min = SANE_FIX(0.0); + range.max = SANE_FIX(size); + range.quant = SANE_FIX(0.0); + return range; } /** @brief generate calibration cache file nam @@ -5091,21 +3818,15 @@ SANE_Range *range=NULL; * @param currdev current scanner device * @return an allocated string containing a file name */ -static char *calibration_filename(Genesys_Device *currdev) +static std::string calibration_filename(Genesys_Device *currdev) { - char *tmpstr; - char *ptr; + std::string ret; + ret.resize(PATH_MAX); + char filename[80]; unsigned int count; unsigned int i; - /* allocate space for result */ - tmpstr = (char*) malloc(PATH_MAX); - if(tmpstr==NULL) - { - return NULL; - } - /* first compute the DIR where we can store cache: * 1 - home dir * 2 - $TMPDIR @@ -5114,18 +3835,15 @@ static char *calibration_filename(Genesys_Device *currdev) * 5 - temp dir * 6 - then resort to current dir */ - ptr = getenv ("HOME"); - if(ptr==NULL) - { - ptr = getenv ("USERPROFILE"); + char* ptr = std::getenv("HOME"); + if (ptr == nullptr) { + ptr = std::getenv("USERPROFILE"); } - if(ptr==NULL) - { - ptr = getenv ("TMPDIR"); + if (ptr == nullptr) { + ptr = std::getenv("TMPDIR"); } - if(ptr==NULL) - { - ptr = getenv ("TMP"); + if (ptr == nullptr) { + ptr = std::getenv("TMP"); } /* now choose filename: @@ -5144,7 +3862,7 @@ static char *calibration_filename(Genesys_Device *currdev) } if(count>1) { - snprintf(filename,sizeof(filename),"%s.cal",currdev->file_name); + std::snprintf(filename, sizeof(filename), "%s.cal", currdev->file_name.c_str()); for(i=0;i<strlen(filename);i++) { if(filename[i]==':'||filename[i]==PATH_SEP) @@ -5159,36 +3877,75 @@ static char *calibration_filename(Genesys_Device *currdev) } /* build final final name : store dir + filename */ - if (NULL == ptr) - { - snprintf (tmpstr, PATH_MAX, "%s", filename); + if (ptr == nullptr) { + int size = std::snprintf(&ret.front(), ret.size(), "%s", filename); + ret.resize(size); } else { + int size = 0; #ifdef HAVE_MKDIR - /* make sure .sane directory exists in existing store dir */ - snprintf (tmpstr, PATH_MAX, "%s%c.sane", ptr, PATH_SEP); - mkdir(tmpstr,0700); + /* make sure .sane directory exists in existing store dir */ + size = std::snprintf(&ret.front(), ret.size(), "%s%c.sane", ptr, PATH_SEP); + ret.resize(size); + mkdir(ret.c_str(), 0700); + + ret.resize(PATH_MAX); #endif - snprintf (tmpstr, PATH_MAX, "%s%c.sane%c%s", ptr, PATH_SEP, PATH_SEP, filename); + size = std::snprintf(&ret.front(), ret.size(), "%s%c.sane%c%s", + ptr, PATH_SEP, PATH_SEP, filename); + ret.resize(size); } - DBG(DBG_info, "%s: calibration filename >%s<\n", __func__, tmpstr); + DBG(DBG_info, "%s: calibration filename >%s<\n", __func__, ret.c_str()); - return tmpstr; + return ret; } +static void set_resolution_option_values(Genesys_Scanner& s, bool reset_resolution_value) +{ + auto resolutions = s.dev->model->get_resolutions(s.scan_method); + + s.opt_resolution_values.resize(resolutions.size() + 1, 0); + s.opt_resolution_values[0] = resolutions.size(); + std::copy(resolutions.begin(), resolutions.end(), s.opt_resolution_values.begin() + 1); -static SANE_Status -init_options (Genesys_Scanner * s) + s.opt[OPT_RESOLUTION].constraint.word_list = s.opt_resolution_values.data(); + + if (reset_resolution_value) { + s.resolution = *std::min_element(resolutions.begin(), resolutions.end()); + } +} + +static void set_xy_range_option_values(Genesys_Scanner& s) { - SANE_Int option, count, min_dpi; - SANE_Status status = SANE_STATUS_GOOD; - SANE_Word *dpi_list; - Genesys_Model *model = s->dev->model; - SANE_Range *x_range, *y_range; + if (s.scan_method == ScanMethod::FLATBED) + { + s.opt_x_range = create_range(static_cast<float>(s.dev->model->x_size)); + s.opt_y_range = create_range(static_cast<float>(s.dev->model->y_size)); + } + else + { + s.opt_x_range = create_range(static_cast<float>(s.dev->model->x_size_ta)); + s.opt_y_range = create_range(static_cast<float>(s.dev->model->y_size_ta)); + } + + s.opt[OPT_TL_X].constraint.range = &s.opt_x_range; + s.opt[OPT_TL_Y].constraint.range = &s.opt_y_range; + s.opt[OPT_BR_X].constraint.range = &s.opt_x_range; + s.opt[OPT_BR_Y].constraint.range = &s.opt_y_range; + + s.pos_top_left_x = 0; + s.pos_top_left_y = 0; + s.pos_bottom_right_x = s.opt_x_range.max; + s.pos_bottom_right_y = s.opt_y_range.max; +} - DBGSTART; +static void init_options(Genesys_Scanner* s) +{ + DBG_HELPER(dbg); + SANE_Int option; + Genesys_Model *model = s->dev->model; memset (s->opt, 0, sizeof (s->opt)); @@ -5204,6 +3961,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT; /* "Mode" group: */ + s->opt[OPT_MODE_GROUP].name = "scanmode-group"; s->opt[OPT_MODE_GROUP].title = SANE_I18N ("Scan Mode"); s->opt[OPT_MODE_GROUP].desc = ""; s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP; @@ -5222,26 +3980,25 @@ init_options (Genesys_Scanner * s) s->mode = SANE_VALUE_SCAN_MODE_GRAY; /* scan source */ + s->opt_source_values.clear(); + for (const auto& resolution_setting : model->resolutions) { + for (auto method : resolution_setting.methods) { + s->opt_source_values.push_back(scan_method_to_option_string(method)); + } + } + s->opt_source_values.push_back(nullptr); + s->opt[OPT_SOURCE].name = SANE_NAME_SCAN_SOURCE; s->opt[OPT_SOURCE].title = SANE_TITLE_SCAN_SOURCE; s->opt[OPT_SOURCE].desc = SANE_DESC_SCAN_SOURCE; s->opt[OPT_SOURCE].type = SANE_TYPE_STRING; s->opt[OPT_SOURCE].constraint_type = SANE_CONSTRAINT_STRING_LIST; - s->opt[OPT_SOURCE].size = max_string_size (source_list); - s->opt[OPT_SOURCE].constraint.string_list = source_list; - s->source = STR_FLATBED; - if (model->flags & GENESYS_FLAG_HAS_UTA) - { - ENABLE (OPT_SOURCE); - if (model->flags & GENESYS_FLAG_HAS_UTA_INFRARED) { - s->opt[OPT_SOURCE].size = max_string_size(source_list_infrared); - s->opt[OPT_SOURCE].constraint.string_list = source_list_infrared; - } - } - else - { - DISABLE (OPT_SOURCE); + s->opt[OPT_SOURCE].size = max_string_size(s->opt_source_values); + s->opt[OPT_SOURCE].constraint.string_list = s->opt_source_values.data(); + if (s->opt_source_values.size() < 2) { + throw SaneException("No scan methods specified for scanner"); } + s->scan_method = model->default_method; /* preview */ s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW; @@ -5259,38 +4016,21 @@ init_options (Genesys_Scanner * s) s->opt[OPT_BIT_DEPTH].type = SANE_TYPE_INT; s->opt[OPT_BIT_DEPTH].constraint_type = SANE_CONSTRAINT_WORD_LIST; s->opt[OPT_BIT_DEPTH].size = sizeof (SANE_Word); - s->opt[OPT_BIT_DEPTH].constraint.word_list = 0; s->opt[OPT_BIT_DEPTH].constraint.word_list = s->bpp_list; create_bpp_list (s, model->bpp_gray_values); - s->bit_depth = 8; - if (s->opt[OPT_BIT_DEPTH].constraint.word_list[0] < 2) - DISABLE (OPT_BIT_DEPTH); + s->bit_depth = model->bpp_gray_values[0]; - /* resolution */ - min_dpi=200000; - for (count = 0; model->xdpi_values[count] != 0; count++) - { - if(model->xdpi_values[count]<min_dpi) - { - min_dpi=model->xdpi_values[count]; - } - } - dpi_list = (SANE_Word*) malloc((count + 1) * sizeof(SANE_Word)); - if (!dpi_list) - return SANE_STATUS_NO_MEM; - dpi_list[0] = count; - for (count = 0; model->xdpi_values[count] != 0; count++) - dpi_list[count + 1] = model->xdpi_values[count]; + // resolution s->opt[OPT_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION; s->opt[OPT_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION; s->opt[OPT_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION; s->opt[OPT_RESOLUTION].type = SANE_TYPE_INT; s->opt[OPT_RESOLUTION].unit = SANE_UNIT_DPI; s->opt[OPT_RESOLUTION].constraint_type = SANE_CONSTRAINT_WORD_LIST; - s->opt[OPT_RESOLUTION].constraint.word_list = dpi_list; - s->resolution = min_dpi; + set_resolution_option_values(*s, true); /* "Geometry" group: */ + s->opt[OPT_GEOMETRY_GROUP].name = SANE_NAME_GEOMETRY; s->opt[OPT_GEOMETRY_GROUP].title = SANE_I18N ("Geometry"); s->opt[OPT_GEOMETRY_GROUP].desc = ""; s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP; @@ -5298,59 +4038,42 @@ init_options (Genesys_Scanner * s) s->opt[OPT_GEOMETRY_GROUP].size = 0; s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE; - x_range=create_range(model->x_size); - if(x_range==NULL) - { - return SANE_STATUS_NO_MEM; - } - - y_range=create_range(model->y_size); - if(y_range==NULL) - { - return SANE_STATUS_NO_MEM; - } + s->opt_x_range = create_range(static_cast<float>(model->x_size)); + s->opt_y_range = create_range(static_cast<float>(model->y_size)); - /* top-left x */ + // scan area s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X; s->opt[OPT_TL_X].type = SANE_TYPE_FIXED; s->opt[OPT_TL_X].unit = SANE_UNIT_MM; s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_TL_X].constraint.range = x_range; - s->pos_top_left_x = 0; - /* top-left y */ s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y; s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y; s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y; s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED; s->opt[OPT_TL_Y].unit = SANE_UNIT_MM; s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_TL_Y].constraint.range = y_range; - s->pos_top_left_y = 0; - /* bottom-right x */ s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X; s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X; s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X; s->opt[OPT_BR_X].type = SANE_TYPE_FIXED; s->opt[OPT_BR_X].unit = SANE_UNIT_MM; s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_BR_X].constraint.range = x_range; - s->pos_bottom_right_x = x_range->max; - /* bottom-right y */ s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y; s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y; s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y; s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED; s->opt[OPT_BR_Y].unit = SANE_UNIT_MM; s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE; - s->opt[OPT_BR_Y].constraint.range = y_range; - s->pos_bottom_right_y = y_range->max; + + set_xy_range_option_values(*s); /* "Enhancement" group: */ + s->opt[OPT_ENHANCEMENT_GROUP].name = SANE_NAME_ENHANCEMENT; s->opt[OPT_ENHANCEMENT_GROUP].title = SANE_I18N ("Enhancement"); s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP; @@ -5483,6 +4206,7 @@ init_options (Genesys_Scanner * s) s->contrast = 0; // disable by default /* "Extras" group: */ + s->opt[OPT_EXTRAS_GROUP].name = "extras-group"; s->opt[OPT_EXTRAS_GROUP].title = SANE_I18N ("Extras"); s->opt[OPT_EXTRAS_GROUP].desc = ""; s->opt[OPT_EXTRAS_GROUP].type = SANE_TYPE_GROUP; @@ -5510,23 +4234,6 @@ init_options (Genesys_Scanner * s) s->opt[OPT_THRESHOLD_CURVE].constraint.range = &threshold_curve_range; s->threshold_curve = 50; - /* dynamic linart */ - s->opt[OPT_DISABLE_DYNAMIC_LINEART].name = "disable-dynamic-lineart"; - s->opt[OPT_DISABLE_DYNAMIC_LINEART].title = SANE_I18N ("Disable dynamic lineart"); - s->opt[OPT_DISABLE_DYNAMIC_LINEART].desc = - SANE_I18N ("Disable use of a software adaptive algorithm to generate lineart relying instead on hardware lineart."); - s->opt[OPT_DISABLE_DYNAMIC_LINEART].type = SANE_TYPE_BOOL; - s->opt[OPT_DISABLE_DYNAMIC_LINEART].unit = SANE_UNIT_NONE; - s->opt[OPT_DISABLE_DYNAMIC_LINEART].constraint_type = SANE_CONSTRAINT_NONE; - s->disable_dynamic_lineart = false; - - /* fastmod is required for hw lineart to work */ - if ((s->dev->model->asic_type == GENESYS_GL646) - &&(s->dev->model->motor_type != MOTOR_XP200)) - { - s->opt[OPT_DISABLE_DYNAMIC_LINEART].cap = SANE_CAP_INACTIVE; - } - /* disable_interpolation */ s->opt[OPT_DISABLE_INTERPOLATION].name = "disable-interpolation"; s->opt[OPT_DISABLE_INTERPOLATION].title = @@ -5549,8 +4256,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_COLOR_FILTER].type = SANE_TYPE_STRING; s->opt[OPT_COLOR_FILTER].constraint_type = SANE_CONSTRAINT_STRING_LIST; /* true gray not yet supported for GL847 and GL124 scanners */ - if(!model->is_cis || model->asic_type==GENESYS_GL847 || model->asic_type==GENESYS_GL124) - { + if (!model->is_cis || model->asic_type==AsicType::GL847 || model->asic_type==AsicType::GL124) { s->opt[OPT_COLOR_FILTER].size = max_string_size (color_filter_list); s->opt[OPT_COLOR_FILTER].constraint.string_list = color_filter_list; s->color_filter = s->opt[OPT_COLOR_FILTER].constraint.string_list[1]; @@ -5563,9 +4269,8 @@ init_options (Genesys_Scanner * s) s->color_filter = s->opt[OPT_COLOR_FILTER].constraint.string_list[3]; } - /* no support for color filter for cis+gl646 scanners */ - if (model->asic_type == GENESYS_GL646 && model->is_cis) - { + // no support for color filter for cis+gl646 scanners + if (model->asic_type == AsicType::GL646 && model->is_cis) { DISABLE (OPT_COLOR_FILTER); } @@ -5620,6 +4325,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_LAMP_OFF].constraint_type = SANE_CONSTRAINT_NONE; s->lamp_off = false; + s->opt[OPT_SENSOR_GROUP].name = SANE_NAME_SENSORS; s->opt[OPT_SENSOR_GROUP].title = SANE_TITLE_SENSORS; s->opt[OPT_SENSOR_GROUP].desc = SANE_DESC_SENSORS; s->opt[OPT_SENSOR_GROUP].type = SANE_TYPE_GROUP; @@ -5721,7 +4427,7 @@ init_options (Genesys_Scanner * s) /* calibration needed */ s->opt[OPT_NEED_CALIBRATION_SW].name = "need-calibration"; - s->opt[OPT_NEED_CALIBRATION_SW].title = SANE_I18N ("Need calibration"); + s->opt[OPT_NEED_CALIBRATION_SW].title = SANE_I18N ("Needs calibration"); s->opt[OPT_NEED_CALIBRATION_SW].desc = SANE_I18N ("The scanner needs calibration for the current settings"); s->opt[OPT_NEED_CALIBRATION_SW].type = SANE_TYPE_BOOL; s->opt[OPT_NEED_CALIBRATION_SW].unit = SANE_UNIT_NONE; @@ -5732,6 +4438,7 @@ init_options (Genesys_Scanner * s) s->opt[OPT_NEED_CALIBRATION_SW].cap = SANE_CAP_INACTIVE; /* button group */ + s->opt[OPT_BUTTON_GROUP].name = "buttons"; s->opt[OPT_BUTTON_GROUP].title = SANE_I18N ("Buttons"); s->opt[OPT_BUTTON_GROUP].desc = ""; s->opt[OPT_BUTTON_GROUP].type = SANE_TYPE_GROUP; @@ -5775,50 +4482,75 @@ init_options (Genesys_Scanner * s) s->opt[OPT_FORCE_CALIBRATION].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED; - RIE (calc_parameters (s)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; + // ignore offsets option + s->opt[OPT_IGNORE_OFFSETS].name = "ignore-internal-offsets"; + s->opt[OPT_IGNORE_OFFSETS].title = SANE_I18N("Ignore internal offsets"); + s->opt[OPT_IGNORE_OFFSETS].desc = + SANE_I18N("Acquires the image including the internal calibration areas of the scanner"); + s->opt[OPT_IGNORE_OFFSETS].type = SANE_TYPE_BUTTON; + s->opt[OPT_IGNORE_OFFSETS].unit = SANE_UNIT_NONE; + s->opt[OPT_IGNORE_OFFSETS].size = 0; + s->opt[OPT_IGNORE_OFFSETS].constraint_type = SANE_CONSTRAINT_NONE; + s->opt[OPT_IGNORE_OFFSETS].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | + SANE_CAP_ADVANCED; + + calc_parameters(s); } -static SANE_Bool present; +static bool present; // this function is passed to C API, it must not throw static SANE_Status check_present (SANE_String_Const devname) noexcept { - present=SANE_TRUE; - DBG(DBG_io, "%s: %s detected.\n", __func__, devname); + DBG_HELPER_ARGS(dbg, "%s detected.", devname); + present = true; return SANE_STATUS_GOOD; } -static SANE_Status -attach (SANE_String_Const devname, Genesys_Device ** devp, SANE_Bool may_wait) +static Genesys_Device* attach_usb_device(const char* devname, + std::uint16_t vendor_id, std::uint16_t product_id) { - DBG_HELPER(dbg); - - Genesys_Device *dev = 0; - unsigned int i; + Genesys_USB_Device_Entry* found_usb_dev = nullptr; + for (auto& usb_dev : *s_usb_devices) { + if (usb_dev.vendor == vendor_id && + usb_dev.product == product_id) + { + found_usb_dev = &usb_dev; + break; + } + } + if (found_usb_dev == nullptr) { + throw SaneException("vendor 0x%xd product 0x%xd is not supported by this backend", + vendor_id, product_id); + } - DBG(DBG_proc, "%s: start: devp %s NULL, may_wait = %d\n", __func__, devp ? "!=" : "==", may_wait); + s_devices->emplace_back(); + Genesys_Device* dev = &s_devices->back(); + dev->file_name = devname; + + dev->model = &found_usb_dev->model; + dev->vendorId = found_usb_dev->vendor; + dev->productId = found_usb_dev->product; + dev->usb_mode = 0; // i.e. unset + dev->already_initialized = false; + return dev; +} - if (devp) - *devp = 0; +static Genesys_Device* attach_device_by_name(SANE_String_Const devname, bool may_wait) +{ + DBG_HELPER_ARGS(dbg, " devname: %s, may_wait = %d", devname, may_wait); - if (!devname) - { - DBG(DBG_error, "%s: devname == NULL\n", __func__); - return SANE_STATUS_INVAL; + if (!devname) { + throw SaneException("devname must not be nullptr"); } for (auto& dev : *s_devices) { - if (strcmp(dev.file_name, devname) == 0) { - if (devp) - *devp = &dev; - DBG(DBG_info, "%s: device `%s' was already in device list\n", __func__, devname); - return SANE_STATUS_GOOD; - } + if (dev.file_name == devname) { + DBG(DBG_info, "%s: device `%s' was already in device list\n", __func__, devname); + return &dev; + } } DBG(DBG_info, "%s: trying to open device `%s'\n", __func__, devname); @@ -5830,78 +4562,35 @@ attach (SANE_String_Const devname, Genesys_Device ** devp, SANE_Bool may_wait) int vendor, product; usb_dev.get_vendor_product(vendor, product); + usb_dev.close(); /* KV-SS080 is an auxiliary device which requires a master device to be here */ if(vendor == 0x04da && product == 0x100f) { - present=SANE_FALSE; + present = false; sanei_usb_find_devices (vendor, 0x1006, check_present); sanei_usb_find_devices (vendor, 0x1007, check_present); sanei_usb_find_devices (vendor, 0x1010, check_present); - if (present == SANE_FALSE) { + if (present == false) { throw SaneException("master device not present"); } } - bool found_dev = false; - for (i = 0; i < MAX_SCANNERS && genesys_usb_device_list[i].model != 0; i++) - { - if (vendor == genesys_usb_device_list[i].vendor && - product == genesys_usb_device_list[i].product) - { - found_dev = true; - break; - } - } - - if (!found_dev) { - DBG(DBG_error, "%s: vendor 0x%xd product 0x%xd is not supported by this backend\n", __func__, - vendor, product); - return SANE_STATUS_INVAL; - } - - char* new_devname = strdup (devname); - if (!new_devname) { - return SANE_STATUS_NO_MEM; - } - - s_devices->emplace_back(); - dev = &s_devices->back(); - dev->file_name = new_devname; - - dev->model = genesys_usb_device_list[i].model; - dev->vendorId = genesys_usb_device_list[i].vendor; - dev->productId = genesys_usb_device_list[i].product; - dev->usb_mode = 0; /* i.e. unset */ - dev->already_initialized = SANE_FALSE; + Genesys_Device* dev = attach_usb_device(devname, vendor, product); - DBG(DBG_info, "%s: found %s flatbed scanner %s at %s\n", __func__, dev->model->vendor, - dev->model->model, dev->file_name); + DBG(DBG_info, "%s: found %s flatbed scanner %s at %s\n", __func__, dev->model->vendor, + dev->model->model, dev->file_name.c_str()); - if (devp) { - *devp = dev; - } - - usb_dev.close(); - return SANE_STATUS_GOOD; + return dev; } -static SANE_Status -attach_one_device_impl(SANE_String_Const devname) -{ - Genesys_Device *dev; - SANE_Status status = SANE_STATUS_GOOD; - - RIE (attach (devname, &dev, SANE_FALSE)); - - return SANE_STATUS_GOOD; -} - -static SANE_Status attach_one_device(SANE_String_Const devname) +// this function is passed to C API and must not throw +static SANE_Status attach_one_device(SANE_String_Const devname) noexcept { + DBG_HELPER(dbg); return wrap_exceptions_to_status_code(__func__, [=]() { - return attach_one_device_impl(devname); + attach_device_by_name(devname, false); }); } @@ -5920,28 +4609,25 @@ config_attach_genesys(SANEI_Config __sane_unused__ *config, const char *devname) } /* probes for scanner to attach to the backend */ -static SANE_Status -probe_genesys_devices (void) +static void probe_genesys_devices() { - SANEI_Config config; - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER(dbg); + if (is_testing_mode()) { + attach_usb_device(get_testing_device_name().c_str(), + get_testing_vendor_id(), get_testing_product_id()); + return; + } - DBGSTART; + SANEI_Config config; - /* set configuration options structure : no option for this backend */ - config.descriptors = NULL; - config.values = NULL; + // set configuration options structure : no option for this backend + config.descriptors = nullptr; + config.values = nullptr; config.count = 0; - /* generic configure and attach function */ - status = sanei_configure_attach (GENESYS_CONFIG_FILE, &config, - config_attach_genesys); + TIE(sanei_configure_attach(GENESYS_CONFIG_FILE, &config, config_attach_genesys)); - DBG(DBG_info, "%s: %d devices currently attached\n", __func__, (int) s_devices->size()); - - DBGCOMPLETED; - - return status; + DBG(DBG_info, "%s: %zu devices currently attached\n", __func__, s_devices->size()); } /** @@ -5951,11 +4637,13 @@ probe_genesys_devices (void) of Genesys_Calibration_Cache as is. */ static const char* CALIBRATION_IDENT = "sane_genesys"; -static const int CALIBRATION_VERSION = 2; +static const int CALIBRATION_VERSION = 21; bool read_calibration(std::istream& str, Genesys_Device::Calibration& calibration, const std::string& path) { + DBG_HELPER(dbg); + std::string ident; serialize(str, ident); @@ -6022,10 +4710,9 @@ static void write_calibration(Genesys_Device::Calibration& calibration, const st * In order to allow digital processing, we must be able to put all the * scanned picture in a buffer. */ -static SANE_Status -genesys_buffer_image(Genesys_Scanner *s) +static void genesys_buffer_image(Genesys_Scanner *s) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER(dbg); size_t maximum; /**> maximum bytes size of the scan */ size_t len; /**> length of scanned data read */ size_t total; /**> total of butes read */ @@ -6041,16 +4728,14 @@ genesys_buffer_image(Genesys_Scanner *s) } else { - lines = - (SANE_UNFIX (dev->model->y_size) * dev->settings.yres) / MM_PER_INCH; + lines = static_cast<int>((dev->model->y_size * dev->settings.yres) / MM_PER_INCH); } DBG(DBG_info, "%s: buffering %d lines of %d bytes\n", __func__, lines, s->params.bytes_per_line); /* maximum bytes to read */ maximum = s->params.bytes_per_line * lines; - if(s->dev->settings.dynamic_lineart==SANE_TRUE) - { + if (s->dev->settings.scan_mode == ScanColorMode::LINEART) { maximum *= 8; } @@ -6064,46 +4749,45 @@ genesys_buffer_image(Genesys_Scanner *s) dev->img_buffer.resize(size); /* loop reading data until we reach maximum or EOF */ - total = 0; - while (total < maximum && status != SANE_STATUS_EOF) - { + total = 0; + while (total < maximum) { len = size - maximum; if (len > read_size) { len = read_size; } - status = genesys_read_ordered_data(dev, dev->img_buffer.data() + total, &len); - if (status != SANE_STATUS_EOF && status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: %s buffering failed\n", __func__, sane_strstatus(status)); - return status; - } + try { + genesys_read_ordered_data(dev, dev->img_buffer.data() + total, &len); + } catch (const SaneException& e) { + if (e.status() == SANE_STATUS_EOF) { + // ideally we shouldn't end up here, but because computations are duplicated and + // slightly different everywhere in the genesys backend, we have no other choice + break; + } + throw; + } total += len; - /* do we need to enlarge read buffer ? */ - if (total + read_size > size && status != SANE_STATUS_EOF) - { - size += read_size; - dev->img_buffer.resize(size); - } + // do we need to enlarge read buffer ? + if (total + read_size > size) { + size += read_size; + dev->img_buffer.resize(size); + } } /* since digital processing is going to take place, * issue head parking command so that the head move while * computing so we can save time */ - if (dev->model->is_sheetfed == SANE_FALSE && - dev->parking == SANE_FALSE) - { - dev->model->cmd_set->slow_back_home (dev, dev->model->flags & GENESYS_FLAG_MUST_WAIT); + if (!dev->model->is_sheetfed && !dev->parking) { + dev->cmd_set->move_back_home(dev, dev->model->flags & GENESYS_FLAG_MUST_WAIT); dev->parking = !(s->dev->model->flags & GENESYS_FLAG_MUST_WAIT); } /* in case of dynamic lineart, we have buffered gray data which * must be converted to lineart first */ - if(s->dev->settings.dynamic_lineart==SANE_TRUE) - { + if (s->dev->settings.scan_mode == ScanColorMode::LINEART) { total/=8; std::vector<uint8_t> lineart(total); @@ -6128,34 +4812,32 @@ genesys_buffer_image(Genesys_Scanner *s) s->params.format==SANE_FRAME_RGB ? 3 : 1, s->params.pixels_per_line, s->params.lines); } - - return SANE_STATUS_GOOD; } /* -------------------------- SANE API functions ------------------------- */ -SANE_Status -sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize) +void sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize) { - SANE_Status status = SANE_STATUS_GOOD; - DBG_INIT (); - DBG(DBG_init, "SANE Genesys backend version %d.%d from %s\n", - SANE_CURRENT_MAJOR, V_MINOR, PACKAGE_STRING); + DBG_HELPER_ARGS(dbg, "authorize %s null", authorize ? "!=" : "=="); + DBG(DBG_init, "SANE Genesys backend from %s\n", PACKAGE_STRING); + + if (!is_testing_mode()) { #ifdef HAVE_LIBUSB - DBG(DBG_init, "SANE Genesys backend built with libusb-1.0\n"); + DBG(DBG_init, "SANE Genesys backend built with libusb-1.0\n"); #endif #ifdef HAVE_LIBUSB_LEGACY - DBG(DBG_init, "SANE Genesys backend built with libusb\n"); + DBG(DBG_init, "SANE Genesys backend built with libusb\n"); #endif + } - if (version_code) - *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, 0); - - DBG(DBG_proc, "%s: authorize %s null\n", __func__, authorize ? "!=" : "=="); + if (version_code) { + *version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0); + } - /* init usb use */ - sanei_usb_init (); + if (!is_testing_mode()) { + sanei_usb_init(); + } /* init sanei_magic */ sanei_magic_init(); @@ -6163,9 +4845,15 @@ sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize) s_scanners.init(); s_devices.init(); s_sane_devices.init(); + s_sane_devices_data.init(); s_sane_devices_ptrs.init(); genesys_init_sensor_tables(); genesys_init_frontend_tables(); + genesys_init_gpo_tables(); + genesys_init_motor_tables(); + genesys_init_motor_profile_tables(); + genesys_init_usb_device_tables(); + DBG(DBG_info, "%s: %s endian machine\n", __func__, #ifdef WORDS_BIGENDIAN @@ -6175,62 +4863,71 @@ sane_init_impl(SANE_Int * version_code, SANE_Auth_Callback authorize) #endif ); - /* cold-plug case :detection of allready connected scanners */ - status = probe_genesys_devices (); - - DBGCOMPLETED; - - return status; + // cold-plug case :detection of allready connected scanners + probe_genesys_devices(); } -extern "C" SANE_Status sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize) +SANE_GENESYS_API_LINKAGE +SANE_Status sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_init_impl(version_code, authorize); + sane_init_impl(version_code, authorize); }); } void sane_exit_impl(void) { - DBGSTART; + DBG_HELPER(dbg); - sanei_usb_exit(); + if (!is_testing_mode()) { + sanei_usb_exit(); + } run_functions_at_backend_exit(); - - DBGCOMPLETED; } +SANE_GENESYS_API_LINKAGE void sane_exit() { catch_all_exceptions(__func__, [](){ sane_exit_impl(); }); } -SANE_Status -sane_get_devices_impl(const SANE_Device *** device_list, SANE_Bool local_only) +void sane_get_devices_impl(const SANE_Device *** device_list, SANE_Bool local_only) { - DBG(DBG_proc, "%s: start: local_only = %s\n", __func__, - local_only == SANE_TRUE ? "true" : "false"); + DBG_HELPER_ARGS(dbg, "local_only = %s", local_only ? "true" : "false"); - /* hot-plug case : detection of newly connected scanners */ - sanei_usb_scan_devices (); - probe_genesys_devices (); + if (!is_testing_mode()) { + // hot-plug case : detection of newly connected scanners */ + sanei_usb_scan_devices(); + } + probe_genesys_devices(); s_sane_devices->clear(); + s_sane_devices_data->clear(); s_sane_devices_ptrs->clear(); s_sane_devices->reserve(s_devices->size()); + s_sane_devices_data->reserve(s_devices->size()); s_sane_devices_ptrs->reserve(s_devices->size() + 1); for (auto dev_it = s_devices->begin(); dev_it != s_devices->end();) { - present = SANE_FALSE; - sanei_usb_find_devices(dev_it->vendorId, dev_it->productId, check_present); + + if (is_testing_mode()) { + present = true; + } else { + present = false; + sanei_usb_find_devices(dev_it->vendorId, dev_it->productId, check_present); + } + if (present) { s_sane_devices->emplace_back(); + s_sane_devices_data->emplace_back(); auto& sane_device = s_sane_devices->back(); - sane_device.name = dev_it->file_name; + auto& sane_device_data = s_sane_devices_data->back(); + sane_device_data.name = dev_it->file_name; + sane_device.name = sane_device_data.name.c_str(); sane_device.vendor = dev_it->model->vendor; sane_device.model = dev_it->model->model; sane_device.type = "flatbed scanner"; @@ -6242,64 +4939,57 @@ sane_get_devices_impl(const SANE_Device *** device_list, SANE_Bool local_only) } s_sane_devices_ptrs->push_back(nullptr); - *((SANE_Device ***)device_list) = s_sane_devices_ptrs->data(); - - DBGCOMPLETED; - - return SANE_STATUS_GOOD; + *const_cast<SANE_Device***>(device_list) = s_sane_devices_ptrs->data(); } +SANE_GENESYS_API_LINKAGE SANE_Status sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_get_devices_impl(device_list, local_only); + sane_get_devices_impl(device_list, local_only); }); } -SANE_Status -sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle) +static void sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle) { - DBG_HELPER(dbg); - Genesys_Device *dev = nullptr; - SANE_Status status = SANE_STATUS_GOOD; - char *tmpstr; - - DBG(DBG_proc, "%s: devicename = `%s')\n", __func__, devicename); + DBG_HELPER_ARGS(dbg, "devicename = %s", devicename); + Genesys_Device* dev = nullptr; /* devicename="" or devicename="genesys" are default values that use * first available device */ - if (devicename[0] && strcmp ("genesys", devicename) != 0) - { + if (devicename[0] && strcmp ("genesys", devicename) != 0) { /* search for the given devicename in the device list */ for (auto& d : *s_devices) { - if (strcmp(d.file_name, devicename) == 0) { + if (d.file_name == devicename) { dev = &d; break; } } - if (!dev) - { - DBG(DBG_info, "%s: couldn't find `%s' in devlist, trying attach\n", __func__, devicename); - RIE (attach (devicename, &dev, SANE_TRUE)); - } - else - DBG(DBG_info, "%s: found `%s' in devlist\n", __func__, dev->model->name); - } - else - { + if (dev) { + DBG(DBG_info, "%s: found `%s' in devlist\n", __func__, dev->model->name); + } else if (is_testing_mode()) { + DBG(DBG_info, "%s: couldn't find `%s' in devlist, not attaching", __func__, devicename); + } else { + DBG(DBG_info, "%s: couldn't find `%s' in devlist, trying attach\n", __func__, + devicename); + dbg.status("attach_device_by_name"); + dev = attach_device_by_name(devicename, true); + dbg.clear(); + } + } else { // empty devicename or "genesys" -> use first device if (!s_devices->empty()) { dev = &s_devices->front(); - devicename = dev->file_name; - DBG(DBG_info, "%s: empty devicename, trying `%s'\n", __func__, devicename); - } + DBG(DBG_info, "%s: empty devicename, trying `%s'\n", __func__, dev->file_name.c_str()); + } } - if (!dev) - return SANE_STATUS_INVAL; + if (!dev) { + throw SaneException("could not find the device to open: %s", devicename); + } if (dev->model->flags & GENESYS_FLAG_UNTESTED) { @@ -6311,77 +5001,74 @@ sane_open_impl(SANE_String_Const devicename, SANE_Handle * handle) DBG(DBG_error0, " scanner and what does (not) work.\n"); } - dbg.vstatus("open device '%s'", dev->file_name); - dev->usb_dev.open(dev->file_name); - dbg.clear(); + dbg.vstatus("open device '%s'", dev->file_name.c_str()); + if (is_testing_mode()) { + auto interface = std::unique_ptr<TestScannerInterface>{new TestScannerInterface{dev}}; + interface->set_checkpoint_callback(get_testing_checkpoint_callback()); + dev->interface = std::move(interface); + } else { + dev->interface = std::unique_ptr<ScannerInterfaceUsb>{new ScannerInterfaceUsb{dev}}; + } + dev->interface->get_usb_device().open(dev->file_name.c_str()); + dbg.clear(); s_scanners->push_back(Genesys_Scanner()); auto* s = &s_scanners->back(); s->dev = dev; - s->scanning = SANE_FALSE; - s->dev->parking = SANE_FALSE; - s->dev->read_active = SANE_FALSE; + s->scanning = false; + s->dev->parking = false; + s->dev->read_active = false; s->dev->force_calibration = 0; - s->dev->line_interp = 0; s->dev->line_count = 0; - s->dev->segnb = 0; - s->dev->binary=NULL; *handle = s; - if (!dev->already_initialized) - sanei_genesys_init_structs (dev); + if (!dev->already_initialized) { + sanei_genesys_init_structs (dev); + } - RIE (init_options (s)); + init_options(s); - if (sanei_genesys_init_cmd_set (s->dev) != SANE_STATUS_GOOD) - { - DBG(DBG_error0, "This device doesn't have a valid command set!!\n"); - return SANE_STATUS_IO_ERROR; - } + sanei_genesys_init_cmd_set(s->dev); - // FIXME: we create sensor tables for the sensor, this should happen when we know which sensor - // we will select - RIE (dev->model->cmd_set->init(dev)); + // FIXME: we create sensor tables for the sensor, this should happen when we know which sensor + // we will select + dev->cmd_set->init(dev); - /* some hardware capabilities are detected through sensors */ - RIE (s->dev->model->cmd_set->update_hardware_sensors (s)); + // some hardware capabilities are detected through sensors + s->dev->cmd_set->update_hardware_sensors (s); /* here is the place to fetch a stored calibration cache */ if (s->dev->force_calibration == 0) { - tmpstr=calibration_filename(s->dev); - s->calibration_file = tmpstr; - s->dev->calib_file = tmpstr; + auto path = calibration_filename(s->dev); + s->calibration_file = path; + s->dev->calib_file = path; DBG(DBG_info, "%s: Calibration filename set to:\n", __func__); DBG(DBG_info, "%s: >%s<\n", __func__, s->dev->calib_file.c_str()); - free(tmpstr); catch_all_exceptions(__func__, [&]() { sanei_genesys_read_calibration(s->dev->calibration_cache, s->dev->calib_file); }); } - - return SANE_STATUS_GOOD; } +SANE_GENESYS_API_LINKAGE SANE_Status sane_open(SANE_String_Const devicename, SANE_Handle* handle) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_open_impl(devicename, handle); + sane_open_impl(devicename, handle); }); } void sane_close_impl(SANE_Handle handle) { - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; + DBG_HELPER(dbg); /* remove handle from list of open handles: */ auto it = s_scanners->end(); @@ -6401,64 +5088,46 @@ sane_close_impl(SANE_Handle handle) Genesys_Scanner* s = &*it; /* eject document for sheetfed scanners */ - if (s->dev->model->is_sheetfed == SANE_TRUE) - { - s->dev->model->cmd_set->eject_document (s->dev); + if (s->dev->model->is_sheetfed) { + catch_all_exceptions(__func__, [&](){ s->dev->cmd_set->eject_document(s->dev); }); } else { /* in case scanner is parking, wait for the head * to reach home position */ - if(s->dev->parking==SANE_TRUE) - { - status = sanei_genesys_wait_for_home (s->dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to wait for head to park: %s\n", __func__, - sane_strstatus(status)); - } + if (s->dev->parking) { + sanei_genesys_wait_for_home(s->dev); } } - /* enable power saving before leaving */ - status = s->dev->model->cmd_set->save_power (s->dev, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to enable power saving mode: %s\n", __func__, - sane_strstatus(status)); - } + // enable power saving before leaving + s->dev->cmd_set->save_power(s->dev, true); // here is the place to store calibration cache - if (s->dev->force_calibration == 0) { + if (s->dev->force_calibration == 0 && !is_testing_mode()) { catch_all_exceptions(__func__, [&](){ write_calibration(s->dev->calibration_cache, s->dev->calib_file); }); } - s->dev->already_initialized = SANE_FALSE; - - /* for an handful of bytes .. */ - free ((void *)(size_t)s->opt[OPT_RESOLUTION].constraint.word_list); - free ((void *)(size_t)s->opt[OPT_TL_X].constraint.range); - free ((void *)(size_t)s->opt[OPT_TL_Y].constraint.range); + s->dev->already_initialized = false; s->dev->clear(); - /* LAMP OFF : same register across all the ASICs */ - sanei_genesys_write_register (s->dev, 0x03, 0x00); + // LAMP OFF : same register across all the ASICs */ + s->dev->interface->write_register(0x03, 0x00); - catch_all_exceptions(__func__, [&](){ s->dev->usb_dev.clear_halt(); }); + catch_all_exceptions(__func__, [&](){ s->dev->interface->get_usb_device().clear_halt(); }); // we need this to avoid these ASIC getting stuck in bulk writes - catch_all_exceptions(__func__, [&](){ s->dev->usb_dev.reset(); }); + catch_all_exceptions(__func__, [&](){ s->dev->interface->get_usb_device().reset(); }); // not freeing s->dev because it's in the dev list - catch_all_exceptions(__func__, [&](){ s->dev->usb_dev.close(); }); + catch_all_exceptions(__func__, [&](){ s->dev->interface->get_usb_device().close(); }); s_scanners->erase(it); - - DBGCOMPLETED; } +SANE_GENESYS_API_LINKAGE void sane_close(SANE_Handle handle) { catch_all_exceptions(__func__, [=]() @@ -6470,19 +5139,22 @@ void sane_close(SANE_Handle handle) const SANE_Option_Descriptor * sane_get_option_descriptor_impl(SANE_Handle handle, SANE_Int option) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; + DBG_HELPER(dbg); + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); + + if (static_cast<unsigned>(option) >= NUM_OPTIONS) { + return nullptr; + } - if ((unsigned) option >= NUM_OPTIONS) - return 0; DBG(DBG_io2, "%s: option = %s (%d)\n", __func__, s->opt[option].name, option); return s->opt + option; } -const SANE_Option_Descriptor * -sane_get_option_descriptor(SANE_Handle handle, SANE_Int option) +SANE_GENESYS_API_LINKAGE +const SANE_Option_Descriptor* sane_get_option_descriptor(SANE_Handle handle, SANE_Int option) { - const SANE_Option_Descriptor* ret = NULL; + const SANE_Option_Descriptor* ret = nullptr; catch_all_exceptions(__func__, [&]() { ret = sane_get_option_descriptor_impl(handle, option); @@ -6490,18 +5162,46 @@ sane_get_option_descriptor(SANE_Handle handle, SANE_Int option) return ret; } -/* gets an option , called by sane_control_option */ -static SANE_Status -get_option_value (Genesys_Scanner * s, int option, void *val) +static void print_option(DebugMessageHelper& dbg, const Genesys_Scanner& s, int option, void* val) { + switch (s.opt[option].type) { + case SANE_TYPE_INT: { + dbg.vlog(DBG_proc, "value: %d", *reinterpret_cast<SANE_Word*>(val)); + return; + } + case SANE_TYPE_BOOL: { + dbg.vlog(DBG_proc, "value: %s", *reinterpret_cast<SANE_Bool*>(val) ? "true" : "false"); + return; + } + case SANE_TYPE_FIXED: { + dbg.vlog(DBG_proc, "value: %f", SANE_UNFIX(*reinterpret_cast<SANE_Word*>(val))); + return; + } + case SANE_TYPE_STRING: { + dbg.vlog(DBG_proc, "value: %s", reinterpret_cast<char*>(val)); + return; + } + default: break; + } + dbg.log(DBG_proc, "value: (non-printable)"); +} + +static void get_option_value(Genesys_Scanner* s, int option, void* val) +{ + DBG_HELPER_ARGS(dbg, "option: %s (%d)", s->opt[option].name, option); unsigned int i; - SANE_Word* table = nullptr; + SANE_Word* table = nullptr; std::vector<uint16_t> gamma_table; unsigned option_size = 0; - SANE_Status status = SANE_STATUS_GOOD; - // FIXME: we should pick correct sensor here - const Genesys_Sensor& sensor = sanei_genesys_find_sensor_any(s->dev); + const Genesys_Sensor* sensor = nullptr; + if (sanei_genesys_has_sensor(s->dev, s->dev->settings.xres, s->dev->settings.get_channels(), + s->dev->settings.scan_method)) + { + sensor = &sanei_genesys_find_sensor(s->dev, s->dev->settings.xres, + s->dev->settings.get_channels(), + s->dev->settings.scan_method); + } switch (option) { @@ -6537,9 +5237,6 @@ get_option_value (Genesys_Scanner * s, int option, void *val) case OPT_THRESHOLD_CURVE: *reinterpret_cast<SANE_Word*>(val) = s->threshold_curve; break; - case OPT_DISABLE_DYNAMIC_LINEART: - *reinterpret_cast<SANE_Word*>(val) = s->disable_dynamic_lineart; - break; case OPT_DISABLE_INTERPOLATION: *reinterpret_cast<SANE_Word*>(val) = s->disable_interpolation; break; @@ -6591,18 +5288,21 @@ get_option_value (Genesys_Scanner * s, int option, void *val) std::strcpy(reinterpret_cast<char*>(val), s->calibration_file.c_str()); break; case OPT_SOURCE: - std::strcpy(reinterpret_cast<char*>(val), s->source.c_str()); + std::strcpy(reinterpret_cast<char*>(val), scan_method_to_option_string(s->scan_method)); break; /* word array options */ case OPT_GAMMA_VECTOR: - table = (SANE_Word *) val; + if (!sensor) + throw SaneException("Unsupported scanner mode selected"); + + table = reinterpret_cast<SANE_Word*>(val); if (s->color_filter == "Red") { - gamma_table = get_gamma_table(s->dev, sensor, GENESYS_RED); + gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_RED); } else if (s->color_filter == "Blue") { - gamma_table = get_gamma_table(s->dev, sensor, GENESYS_BLUE); + gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_BLUE); } else { - gamma_table = get_gamma_table(s->dev, sensor, GENESYS_GREEN); + gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_GREEN); } option_size = s->opt[option].size / sizeof (SANE_Word); if (gamma_table.size() != option_size) { @@ -6613,8 +5313,11 @@ get_option_value (Genesys_Scanner * s, int option, void *val) } break; case OPT_GAMMA_VECTOR_R: - table = (SANE_Word *) val; - gamma_table = get_gamma_table(s->dev, sensor, GENESYS_RED); + if (!sensor) + throw SaneException("Unsupported scanner mode selected"); + + table = reinterpret_cast<SANE_Word*>(val); + gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_RED); option_size = s->opt[option].size / sizeof (SANE_Word); if (gamma_table.size() != option_size) { throw std::runtime_error("The size of the gamma tables does not match"); @@ -6624,8 +5327,11 @@ get_option_value (Genesys_Scanner * s, int option, void *val) } break; case OPT_GAMMA_VECTOR_G: - table = (SANE_Word *) val; - gamma_table = get_gamma_table(s->dev, sensor, GENESYS_GREEN); + if (!sensor) + throw SaneException("Unsupported scanner mode selected"); + + table = reinterpret_cast<SANE_Word*>(val); + gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_GREEN); option_size = s->opt[option].size / sizeof (SANE_Word); if (gamma_table.size() != option_size) { throw std::runtime_error("The size of the gamma tables does not match"); @@ -6635,8 +5341,11 @@ get_option_value (Genesys_Scanner * s, int option, void *val) } break; case OPT_GAMMA_VECTOR_B: - table = (SANE_Word *) val; - gamma_table = get_gamma_table(s->dev, sensor, GENESYS_BLUE); + if (!sensor) + throw SaneException("Unsupported scanner mode selected"); + + table = reinterpret_cast<SANE_Word*>(val); + gamma_table = get_gamma_table(s->dev, *sensor, GENESYS_BLUE); option_size = s->opt[option].size / sizeof (SANE_Word); if (gamma_table.size() != option_size) { throw std::runtime_error("The size of the gamma tables does not match"); @@ -6654,25 +5363,35 @@ get_option_value (Genesys_Scanner * s, int option, void *val) case OPT_OCR_SW: case OPT_POWER_SW: case OPT_EXTRA_SW: - RIE (s->dev->model->cmd_set->update_hardware_sensors (s)); - *(SANE_Bool *) val = s->buttons[genesys_option_to_button(option)].read(); - break; - case OPT_NEED_CALIBRATION_SW: - /* scanner needs calibration for current mode unless a matching - * calibration cache is found */ - *(SANE_Bool *) val = SANE_TRUE; - for (auto& cache : s->dev->calibration_cache) - { - if (s->dev->model->cmd_set->is_compatible_calibration(s->dev, sensor, &cache, SANE_FALSE)) - { - *(SANE_Bool *) val = SANE_FALSE; - } - } - break; + s->dev->cmd_set->update_hardware_sensors(s); + *reinterpret_cast<SANE_Bool*>(val) = s->buttons[genesys_option_to_button(option)].read(); + break; + + case OPT_NEED_CALIBRATION_SW: { + if (!sensor) { + throw SaneException("Unsupported scanner mode selected"); + } + + // scanner needs calibration for current mode unless a matching calibration cache is + // found + + bool result = true; + + auto session = s->dev->cmd_set->calculate_scan_session(s->dev, *sensor, + s->dev->settings); + + for (auto& cache : s->dev->calibration_cache) { + if (sanei_genesys_is_compatible_calibration(s->dev, session, &cache, false)) { + *reinterpret_cast<SANE_Bool*>(val) = SANE_FALSE; + } + } + *reinterpret_cast<SANE_Bool*>(val) = result; + break; + } default: DBG(DBG_warn, "%s: can't get unknown option %d\n", __func__, option); } - return status; + print_option(dbg, *s, option, val); } /** @brief set calibration file value @@ -6702,109 +5421,100 @@ static void set_calibration_value(Genesys_Scanner* s, const char* val) } /* sets an option , called by sane_control_option */ -static SANE_Status -set_option_value (Genesys_Scanner * s, int option, void *val, - SANE_Int * myinfo) +static void set_option_value(Genesys_Scanner* s, int option, void *val, SANE_Int* myinfo) { - SANE_Status status = SANE_STATUS_GOOD; + DBG_HELPER_ARGS(dbg, "option: %s (%d)", s->opt[option].name, option); + print_option(dbg, *s, option, val); + SANE_Word *table; unsigned int i; - SANE_Range *x_range, *y_range; unsigned option_size = 0; - // FIXME: we should modify device-specific sensor - auto& sensor = sanei_genesys_find_sensor_any_for_write(s->dev); - switch (option) { case OPT_TL_X: s->pos_top_left_x = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_TL_Y: s->pos_top_left_y = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_BR_X: s->pos_bottom_right_x = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_BR_Y: s->pos_bottom_right_y = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_RESOLUTION: s->resolution = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_THRESHOLD: s->threshold = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_THRESHOLD_CURVE: s->threshold_curve = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); - *myinfo |= SANE_INFO_RELOAD_PARAMS; - break; - case OPT_DISABLE_DYNAMIC_LINEART: - s->disable_dynamic_lineart = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_SWCROP: s->swcrop = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_SWDESKEW: s->swdeskew = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_DESPECK: s->despeck = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_SWDEROTATE: s->swderotate = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_SWSKIP: s->swskip = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_DISABLE_INTERPOLATION: s->disable_interpolation = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_LAMP_OFF: s->lamp_off = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_PREVIEW: s->preview = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_BRIGHTNESS: s->brightness = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_CONTRAST: s->contrast = *reinterpret_cast<SANE_Word*>(val); - RIE (calc_parameters(s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS; break; case OPT_SWDESPECK: @@ -6814,7 +5524,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val, } else { DISABLE(OPT_DESPECK); } - RIE (calc_parameters (s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; break; /* software enhancement functions only apply to 8 or 1 bits data */ @@ -6842,45 +5552,21 @@ set_option_value (Genesys_Scanner * s, int option, void *val, ENABLE(OPT_CONTRAST); ENABLE(OPT_BRIGHTNESS); } - RIE (calc_parameters (s)); + calc_parameters(s); *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; break; - case OPT_SOURCE: - if (s->source != reinterpret_cast<const char*>(val)) { - s->source = reinterpret_cast<const char*>(val); + case OPT_SOURCE: { + auto scan_method = option_string_to_scan_method(reinterpret_cast<const char*>(val)); + if (s->scan_method != scan_method) { + s->scan_method = scan_method; - // change geometry constraint to the new source value - if (s->source == STR_FLATBED) - { - x_range=create_range(s->dev->model->x_size); - y_range=create_range(s->dev->model->y_size); - } - else - { - x_range=create_range(s->dev->model->x_size_ta); - y_range=create_range(s->dev->model->y_size_ta); - } - if(x_range==NULL || y_range==NULL) - { - return SANE_STATUS_NO_MEM; - } + set_xy_range_option_values(*s); + set_resolution_option_values(*s, false); - /* assign new values */ - free((void *)(size_t)s->opt[OPT_TL_X].constraint.range); - free((void *)(size_t)s->opt[OPT_TL_Y].constraint.range); - s->opt[OPT_TL_X].constraint.range = x_range; - s->pos_top_left_x = 0; - s->opt[OPT_TL_Y].constraint.range = y_range; - s->pos_top_left_y = 0; - s->opt[OPT_BR_X].constraint.range = x_range; - s->pos_bottom_right_x = x_range->max; - s->opt[OPT_BR_Y].constraint.range = y_range; - s->pos_bottom_right_y = y_range->max; - - /* signals reload */ - *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; - } - break; + *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; + } + break; + } case OPT_MODE: s->mode = reinterpret_cast<const char*>(val); @@ -6889,36 +5575,30 @@ set_option_value (Genesys_Scanner * s, int option, void *val, ENABLE (OPT_THRESHOLD); ENABLE (OPT_THRESHOLD_CURVE); DISABLE (OPT_BIT_DEPTH); - if (s->dev->model->asic_type != GENESYS_GL646 || !s->dev->model->is_cis) - { - ENABLE (OPT_COLOR_FILTER); - } - ENABLE (OPT_DISABLE_DYNAMIC_LINEART); + if (s->dev->model->asic_type != AsicType::GL646 || !s->dev->model->is_cis) { + ENABLE(OPT_COLOR_FILTER); + } } else { DISABLE (OPT_THRESHOLD); DISABLE (OPT_THRESHOLD_CURVE); - DISABLE (OPT_DISABLE_DYNAMIC_LINEART); if (s->mode == SANE_VALUE_SCAN_MODE_GRAY) { - if (s->dev->model->asic_type != GENESYS_GL646 || !s->dev->model->is_cis) - { - ENABLE (OPT_COLOR_FILTER); - } + if (s->dev->model->asic_type != AsicType::GL646 || !s->dev->model->is_cis) { + ENABLE(OPT_COLOR_FILTER); + } create_bpp_list (s, s->dev->model->bpp_gray_values); + s->bit_depth = s->dev->model->bpp_gray_values[0]; } else { DISABLE (OPT_COLOR_FILTER); create_bpp_list (s, s->dev->model->bpp_color_values); + s->bit_depth = s->dev->model->bpp_color_values[0]; } - if (s->bpp_list[0] < 2) - DISABLE (OPT_BIT_DEPTH); - else - ENABLE (OPT_BIT_DEPTH); } - RIE (calc_parameters (s)); + calc_parameters(s); /* if custom gamma, toggle gamma table options according to the mode */ if (s->custom_gamma) @@ -6943,7 +5623,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val, break; case OPT_COLOR_FILTER: s->color_filter = reinterpret_cast<const char*>(val); - RIE (calc_parameters (s)); + calc_parameters(s); break; case OPT_CALIBRATION_FILE: if (s->dev->force_calibration == 0) { @@ -6953,14 +5633,14 @@ set_option_value (Genesys_Scanner * s, int option, void *val, case OPT_LAMP_OFF_TIME: if (*reinterpret_cast<SANE_Word*>(val) != s->lamp_off_time) { s->lamp_off_time = *reinterpret_cast<SANE_Word*>(val); - RIE(s->dev->model->cmd_set->set_powersaving(s->dev, s->lamp_off_time)); + s->dev->cmd_set->set_powersaving(s->dev, s->lamp_off_time); } break; case OPT_EXPIRATION_TIME: if (*reinterpret_cast<SANE_Word*>(val) != s->expiration_time) { s->expiration_time = *reinterpret_cast<SANE_Word*>(val); // BUG: this is most likely not intended behavior, found out during refactor - RIE(s->dev->model->cmd_set->set_powersaving(s->dev, s->expiration_time)); + s->dev->cmd_set->set_powersaving(s->dev, s->expiration_time); } break; @@ -6997,7 +5677,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val, break; case OPT_GAMMA_VECTOR: - table = (SANE_Word *) val; + table = reinterpret_cast<SANE_Word*>(val); option_size = s->opt[option].size / sizeof (SANE_Word); s->dev->gamma_override_tables[GENESYS_RED].resize(option_size); @@ -7010,7 +5690,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val, } break; case OPT_GAMMA_VECTOR_R: - table = (SANE_Word *) val; + table = reinterpret_cast<SANE_Word*>(val); option_size = s->opt[option].size / sizeof (SANE_Word); s->dev->gamma_override_tables[GENESYS_RED].resize(option_size); for (i = 0; i < option_size; i++) { @@ -7018,7 +5698,7 @@ set_option_value (Genesys_Scanner * s, int option, void *val, } break; case OPT_GAMMA_VECTOR_G: - table = (SANE_Word *) val; + table = reinterpret_cast<SANE_Word*>(val); option_size = s->opt[option].size / sizeof (SANE_Word); s->dev->gamma_override_tables[GENESYS_GREEN].resize(option_size); for (i = 0; i < option_size; i++) { @@ -7026,27 +5706,29 @@ set_option_value (Genesys_Scanner * s, int option, void *val, } break; case OPT_GAMMA_VECTOR_B: - table = (SANE_Word *) val; + table = reinterpret_cast<SANE_Word*>(val); option_size = s->opt[option].size / sizeof (SANE_Word); s->dev->gamma_override_tables[GENESYS_BLUE].resize(option_size); for (i = 0; i < option_size; i++) { s->dev->gamma_override_tables[GENESYS_BLUE][i] = table[i]; } break; - case OPT_CALIBRATE: - status = s->dev->model->cmd_set->save_power (s->dev, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to disable power saving mode: %s\n", __func__, - sane_strstatus(status)); - } - else - status = genesys_scanner_calibration(s->dev, sensor); - /* not critical if this fails*/ - s->dev->model->cmd_set->save_power (s->dev, SANE_TRUE); - /* signals that sensors will have to be read again */ - *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; - break; + case OPT_CALIBRATE: { + auto& sensor = sanei_genesys_find_sensor_for_write(s->dev, s->dev->settings.xres, + s->dev->settings.get_channels(), + s->dev->settings.scan_method); + catch_all_exceptions(__func__, [&]() + { + s->dev->cmd_set->save_power(s->dev, false); + genesys_scanner_calibration(s->dev, sensor); + }); + catch_all_exceptions(__func__, [&]() + { + s->dev->cmd_set->save_power(s->dev, true); + }); + *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; + break; + } case OPT_CLEAR_CALIBRATION: s->dev->calibration_cache.clear(); @@ -7064,116 +5746,93 @@ set_option_value (Genesys_Scanner * s, int option, void *val, *myinfo |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS; break; + case OPT_IGNORE_OFFSETS: { + s->dev->ignore_offsets = true; + break; + } default: DBG(DBG_warn, "%s: can't set unknown option %d\n", __func__, option); } - return status; } /* sets and gets scanner option values */ -SANE_Status -sane_control_option_impl(SANE_Handle handle, SANE_Int option, - SANE_Action action, void *val, SANE_Int * info) +void sane_control_option_impl(SANE_Handle handle, SANE_Int option, + SANE_Action action, void *val, SANE_Int * info) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; - SANE_Status status = SANE_STATUS_GOOD; + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); + auto action_str = (action == SANE_ACTION_GET_VALUE) ? "get" : + (action == SANE_ACTION_SET_VALUE) ? "set" : + (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown"; + DBG_HELPER_ARGS(dbg, "action = %s, option = %s (%d)", action_str, + s->opt[option].name, option); + SANE_Word cap; SANE_Int myinfo = 0; - DBG(DBG_io2, "%s: start: action = %s, option = %s (%d)\n", __func__, - (action == SANE_ACTION_GET_VALUE) ? "get" : (action == SANE_ACTION_SET_VALUE) ? - "set" : (action == SANE_ACTION_SET_AUTO) ? "set_auto" : "unknown", - s->opt[option].name, option); - - if (info) - *info = 0; - - if (s->scanning) - { - DBG(DBG_warn, "%s: don't call this function while scanning (option = %s (%d))\n", __func__, - s->opt[option].name, option); + if (info) { + *info = 0; + } - return SANE_STATUS_DEVICE_BUSY; + if (s->scanning) { + throw SaneException(SANE_STATUS_DEVICE_BUSY, + "don't call this function while scanning (option = %s (%d))", + s->opt[option].name, option); } - if (option >= NUM_OPTIONS || option < 0) - { - DBG(DBG_warn, "%s: option %d >= NUM_OPTIONS || option < 0\n", __func__, option); - return SANE_STATUS_INVAL; + if (option >= NUM_OPTIONS || option < 0) { + throw SaneException("option %d >= NUM_OPTIONS || option < 0", option); } cap = s->opt[option].cap; - if (!SANE_OPTION_IS_ACTIVE (cap)) - { - DBG(DBG_warn, "%s: option %d is inactive\n", __func__, option); - return SANE_STATUS_INVAL; + if (!SANE_OPTION_IS_ACTIVE (cap)) { + throw SaneException("option %d is inactive", option); } - switch (action) - { - case SANE_ACTION_GET_VALUE: - status = get_option_value (s, option, val); - break; - - case SANE_ACTION_SET_VALUE: - if (!SANE_OPTION_IS_SETTABLE (cap)) - { - DBG(DBG_warn, "%s: option %d is not settable\n", __func__, option); - return SANE_STATUS_INVAL; - } + switch (action) { + case SANE_ACTION_GET_VALUE: + get_option_value(s, option, val); + break; - status = sanei_constrain_value (s->opt + option, val, &myinfo); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_warn, "%s: sanei_constrain_value returned %s\n", __func__, - sane_strstatus(status)); - return status; - } + case SANE_ACTION_SET_VALUE: + if (!SANE_OPTION_IS_SETTABLE (cap)) { + throw SaneException("option %d is not settable", option); + } - status = set_option_value (s, option, val, &myinfo); - break; + TIE(sanei_constrain_value(s->opt + option, val, &myinfo)); - case SANE_ACTION_SET_AUTO: - DBG(DBG_error, - "%s: SANE_ACTION_SET_AUTO unsupported since no option has SANE_CAP_AUTOMATIC\n", - __func__); - status = SANE_STATUS_INVAL; - break; + set_option_value(s, option, val, &myinfo); + break; - default: - DBG(DBG_warn, "%s: unknown action %d for option %d\n", __func__, action, option); - status = SANE_STATUS_INVAL; - break; + case SANE_ACTION_SET_AUTO: + throw SaneException("SANE_ACTION_SET_AUTO unsupported since no option " + "has SANE_CAP_AUTOMATIC"); + default: + throw SaneException("unknown action %d for option %d", action, option); } if (info) *info = myinfo; - - DBG(DBG_io2, "%s: exit\n", __func__); - return status; } +SANE_GENESYS_API_LINKAGE SANE_Status sane_control_option(SANE_Handle handle, SANE_Int option, - SANE_Action action, void *val, SANE_Int * info) + SANE_Action action, void *val, SANE_Int * info) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_control_option_impl(handle, option, action, val, info); + sane_control_option_impl(handle, option, action, val, info); }); } -SANE_Status sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params) +void sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; + DBG_HELPER(dbg); + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); /* don't recompute parameters once data reading is active, ie during scan */ - if(s->dev->read_active == SANE_FALSE) - { - RIE (calc_parameters (s)); + if (!s->dev->read_active) { + calc_parameters(s); } if (params) { @@ -7184,56 +5843,46 @@ SANE_Status sane_get_parameters_impl(SANE_Handle handle, SANE_Parameters* params * don't know the real document height. * We don't do that doing buffering image for digital processing */ - if (s->dev->model->is_sheetfed == SANE_TRUE - && s->dev->buffer_image == SANE_FALSE - && s->pos_bottom_right_y == s->opt[OPT_BR_Y].constraint.range->max) - { + if (s->dev->model->is_sheetfed && !s->dev->buffer_image && + s->pos_bottom_right_y == s->opt[OPT_BR_Y].constraint.range->max) + { params->lines = -1; } } - - DBGCOMPLETED; - - return SANE_STATUS_GOOD; + debug_dump(DBG_proc, *params); } +SANE_GENESYS_API_LINKAGE SANE_Status sane_get_parameters(SANE_Handle handle, SANE_Parameters* params) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_get_parameters_impl(handle, params); + sane_get_parameters_impl(handle, params); }); } -SANE_Status sane_start_impl(SANE_Handle handle) +void sane_start_impl(SANE_Handle handle) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; - SANE_Status status=SANE_STATUS_GOOD; - - DBGSTART; + DBG_HELPER(dbg); + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); - if (s->pos_top_left_x >= s->pos_bottom_right_x) - { - DBG(DBG_error0, "%s: top left x >= bottom right x --- exiting\n", __func__); - return SANE_STATUS_INVAL; + if (s->pos_top_left_x >= s->pos_bottom_right_x) { + throw SaneException("top left x >= bottom right x"); } - if (s->pos_top_left_y >= s->pos_bottom_right_y) - { - DBG(DBG_error0, "%s: top left y >= bottom right y --- exiting\n", __func__); - return SANE_STATUS_INVAL; + if (s->pos_top_left_y >= s->pos_bottom_right_y) { + throw SaneException("top left y >= bottom right y"); } /* First make sure we have a current parameter set. Some of the parameters will be overwritten below, but that's OK. */ - RIE (calc_parameters (s)); - RIE(genesys_start_scan(s->dev, s->lamp_off)); + calc_parameters(s); + genesys_start_scan(s->dev, s->lamp_off); - s->scanning = SANE_TRUE; + s->scanning = true; /* allocate intermediate buffer when doing dynamic lineart */ - if(s->dev->settings.dynamic_lineart==SANE_TRUE) - { + if (s->dev->settings.scan_mode == ScanColorMode::LINEART) { s->dev->binarize_buffer.clear(); s->dev->binarize_buffer.alloc(s->dev->settings.pixels); s->dev->local_buffer.clear(); @@ -7246,101 +5895,90 @@ SANE_Status sane_start_impl(SANE_Handle handle) * at the end */ if (s->dev->buffer_image) { - RIE(genesys_buffer_image(s)); + genesys_buffer_image(s); /* check if we need to skip this page, sheetfed scanners * can go to next doc while flatbed ones can't */ if (s->swskip > 0 && IS_ACTIVE(OPT_SWSKIP)) { - status = sanei_magic_isBlank(&s->params, - s->dev->img_buffer.data(), - SANE_UNFIX(s->swskip)); - if(status == SANE_STATUS_NO_DOCS) - { - if (s->dev->model->is_sheetfed == SANE_TRUE) - { - DBG(DBG_info, "%s: blank page, recurse\n", __func__); - return sane_start(handle); - } - return status; + auto status = sanei_magic_isBlank(&s->params, + s->dev->img_buffer.data(), + SANE_UNFIX(s->swskip)); + + if (status == SANE_STATUS_NO_DOCS && s->dev->model->is_sheetfed) { + DBG(DBG_info, "%s: blank page, recurse\n", __func__); + sane_start(handle); + return; + } + + if (status != SANE_STATUS_GOOD) { + throw SaneException(status); } } if (s->swdeskew) { - const auto& sensor = sanei_genesys_find_sensor(s->dev, s->dev->settings.xres, - s->dev->settings.scan_method); - RIE(genesys_deskew(s, sensor)); + const auto& sensor = sanei_genesys_find_sensor(s->dev, s->dev->settings.xres, + s->dev->settings.get_channels(), + s->dev->settings.scan_method); + catch_all_exceptions(__func__, [&](){ genesys_deskew(s, sensor); }); } if (s->swdespeck) { - RIE(genesys_despeck(s)); + catch_all_exceptions(__func__, [&](){ genesys_despeck(s); }); } if(s->swcrop) { - RIE(genesys_crop(s)); + catch_all_exceptions(__func__, [&](){ genesys_crop(s); }); } if(s->swderotate) { - RIE(genesys_derotate(s)); + catch_all_exceptions(__func__, [&](){ genesys_derotate(s); }); } } - - DBGCOMPLETED; - return status; } +SANE_GENESYS_API_LINKAGE SANE_Status sane_start(SANE_Handle handle) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_start_impl(handle); + sane_start_impl(handle); }); } -SANE_Status -sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* len) +void sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* len) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; + DBG_HELPER(dbg); + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); Genesys_Device *dev; - SANE_Status status=SANE_STATUS_GOOD; size_t local_len; - if (!s) - { - DBG(DBG_error, "%s: handle is null!\n", __func__); - return SANE_STATUS_INVAL; + if (!s) { + throw SaneException("handle is nullptr"); } dev=s->dev; - if (!dev) - { - DBG(DBG_error, "%s: dev is null!\n", __func__); - return SANE_STATUS_INVAL; + if (!dev) { + throw SaneException("dev is nullptr"); } - if (!buf) - { - DBG(DBG_error, "%s: buf is null!\n", __func__); - return SANE_STATUS_INVAL; + if (!buf) { + throw SaneException("buf is nullptr"); } - if (!len) - { - DBG(DBG_error, "%s: len is null!\n", __func__); - return SANE_STATUS_INVAL; + if (!len) { + throw SaneException("len is nullptr"); } *len = 0; - if (!s->scanning) - { - DBG(DBG_warn, "%s: scan was cancelled, is over or has not been initiated yet\n", __func__); - return SANE_STATUS_CANCELLED; + if (!s->scanning) { + throw SaneException(SANE_STATUS_CANCELLED, + "scan was cancelled, is over or has not been initiated yet"); } DBG(DBG_proc, "%s: start, %d maximum bytes required\n", __func__, max_len); - DBG(DBG_io2, "%s: bytes_to_read=%lu, total_bytes_read=%lu\n", __func__, - (u_long) dev->total_bytes_to_read, (u_long) dev->total_bytes_read); - DBG(DBG_io2, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); + DBG(DBG_io2, "%s: bytes_to_read=%zu, total_bytes_read=%zu\n", __func__, + dev->total_bytes_to_read, dev->total_bytes_read); if(dev->total_bytes_read>=dev->total_bytes_to_read) { @@ -7348,14 +5986,13 @@ sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* /* issue park command immediatly in case scanner can handle it * so we save time */ - if (dev->model->is_sheetfed == SANE_FALSE - && !(dev->model->flags & GENESYS_FLAG_MUST_WAIT) - && dev->parking == SANE_FALSE) + if (!dev->model->is_sheetfed && !(dev->model->flags & GENESYS_FLAG_MUST_WAIT) && + !dev->parking) { - dev->model->cmd_set->slow_back_home (dev, SANE_FALSE); - dev->parking = SANE_TRUE; + dev->cmd_set->move_back_home(dev, false); + dev->parking = true; } - return SANE_STATUS_EOF; + throw SaneException(SANE_STATUS_EOF); } local_len = max_len; @@ -7366,36 +6003,31 @@ sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* { /* dynamic lineart is another kind of digital processing that needs * another layer of buffering on top of genesys_read_ordered_data */ - if(dev->settings.dynamic_lineart==SANE_TRUE) - { + if (dev->settings.scan_mode == ScanColorMode::LINEART) { /* if buffer is empty, fill it with genesys_read_ordered_data */ if(dev->binarize_buffer.avail() == 0) { /* store gray data */ local_len=dev->local_buffer.size(); dev->local_buffer.reset(); - status = genesys_read_ordered_data (dev, dev->local_buffer.get_write_pos(local_len), - &local_len); + genesys_read_ordered_data(dev, dev->local_buffer.get_write_pos(local_len), + &local_len); dev->local_buffer.produce(local_len); - /* binarize data is read successful */ - if(status==SANE_STATUS_GOOD) - { - dev->binarize_buffer.reset(); - genesys_gray_lineart (dev, - dev->local_buffer.get_read_pos(), - dev->binarize_buffer.get_write_pos(local_len / 8), - dev->settings.pixels, - local_len/dev->settings.pixels, - dev->settings.threshold); - dev->binarize_buffer.produce(local_len / 8); + dev->binarize_buffer.reset(); + if (!is_testing_mode()) { + genesys_gray_lineart(dev, dev->local_buffer.get_read_pos(), + dev->binarize_buffer.get_write_pos(local_len / 8), + dev->settings.pixels, + local_len / dev->settings.pixels, + dev->settings.threshold); } - + dev->binarize_buffer.produce(local_len / 8); } /* return data from lineart buffer if any, up to the available amount */ local_len = max_len; - if((size_t)max_len>dev->binarize_buffer.avail()) + if (static_cast<std::size_t>(max_len) > dev->binarize_buffer.avail()) { local_len=dev->binarize_buffer.avail(); } @@ -7407,8 +6039,8 @@ sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* } else { - /* most usual case, direct read of data from scanner */ - status = genesys_read_ordered_data (dev, buf, &local_len); + // most usual case, direct read of data from scanner */ + genesys_read_ordered_data(dev, buf, &local_len); } } else /* read data from buffer */ @@ -7422,145 +6054,103 @@ sane_read_impl(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* } *len = local_len; - if(local_len>(size_t)max_len) - { + if (local_len > static_cast<std::size_t>(max_len)) { fprintf (stderr, "[genesys] sane_read: returning incorrect length!!\n"); } DBG(DBG_proc, "%s: %d bytes returned\n", __func__, *len); - return status; } +SANE_GENESYS_API_LINKAGE SANE_Status sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int* len) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_read_impl(handle, buf, max_len, len); + sane_read_impl(handle, buf, max_len, len); }); } void sane_cancel_impl(SANE_Handle handle) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - - /* end binary logging if needed */ - if (s->dev->binary!=NULL) - { - fclose(s->dev->binary); - s->dev->binary=NULL; - } + DBG_HELPER(dbg); + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); - s->scanning = SANE_FALSE; - s->dev->read_active = SANE_FALSE; + s->scanning = false; + s->dev->read_active = false; s->dev->img_buffer.clear(); /* no need to end scan if we are parking the head */ - if(s->dev->parking==SANE_FALSE) - { - status = s->dev->model->cmd_set->end_scan(s->dev, &s->dev->reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return; - } + if (!s->dev->parking) { + s->dev->cmd_set->end_scan(s->dev, &s->dev->reg, true); } /* park head if flatbed scanner */ - if (s->dev->model->is_sheetfed == SANE_FALSE) - { - if(s->dev->parking==SANE_FALSE) - { - status = s->dev->model->cmd_set->slow_back_home (s->dev, s->dev->model->flags & GENESYS_FLAG_MUST_WAIT); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move scanhead to home position: %s\n", __func__, - sane_strstatus(status)); - return; - } + if (!s->dev->model->is_sheetfed) { + if (!s->dev->parking) { + s->dev->cmd_set->move_back_home (s->dev, s->dev->model->flags & + GENESYS_FLAG_MUST_WAIT); + s->dev->parking = !(s->dev->model->flags & GENESYS_FLAG_MUST_WAIT); } } else { /* in case of sheetfed scanners, we have to eject the document if still present */ - status = s->dev->model->cmd_set->eject_document (s->dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to eject document: %s\n", __func__, sane_strstatus(status)); - return; - } + s->dev->cmd_set->eject_document(s->dev); } /* enable power saving mode unless we are parking .... */ - if(s->dev->parking==SANE_FALSE) - { - status = s->dev->model->cmd_set->save_power (s->dev, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to enable power saving mode: %s\n", __func__, - sane_strstatus(status)); - return; - } + if (!s->dev->parking) { + s->dev->cmd_set->save_power(s->dev, true); } - DBGCOMPLETED; return; } +SANE_GENESYS_API_LINKAGE void sane_cancel(SANE_Handle handle) { catch_all_exceptions(__func__, [=]() { sane_cancel_impl(handle); }); } -SANE_Status -sane_set_io_mode_impl(SANE_Handle handle, SANE_Bool non_blocking) +void sane_set_io_mode_impl(SANE_Handle handle, SANE_Bool non_blocking) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; - - DBG(DBG_proc, "%s: handle = %p, non_blocking = %s\n", __func__, handle, - non_blocking == SANE_TRUE ? "true" : "false"); + DBG_HELPER_ARGS(dbg, "handle = %p, non_blocking = %s", handle, + non_blocking == SANE_TRUE ? "true" : "false"); + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); - if (!s->scanning) - { - DBG(DBG_error, "%s: not scanning\n", __func__); - return SANE_STATUS_INVAL; + if (!s->scanning) { + throw SaneException("not scanning"); + } + if (non_blocking) { + throw SaneException(SANE_STATUS_UNSUPPORTED); } - if (non_blocking) - return SANE_STATUS_UNSUPPORTED; - return SANE_STATUS_GOOD; } -SANE_Status -sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking) +SANE_GENESYS_API_LINKAGE +SANE_Status sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_set_io_mode_impl(handle, non_blocking); + sane_set_io_mode_impl(handle, non_blocking); }); } -SANE_Status -sane_get_select_fd_impl(SANE_Handle handle, SANE_Int * fd) +void sane_get_select_fd_impl(SANE_Handle handle, SANE_Int* fd) { - Genesys_Scanner *s = (Genesys_Scanner*) handle; - - DBG(DBG_proc, "%s: handle = %p, fd = %p\n", __func__, handle, (void *) fd); + DBG_HELPER_ARGS(dbg, "handle = %p, fd = %p", handle, reinterpret_cast<void*>(fd)); + Genesys_Scanner* s = reinterpret_cast<Genesys_Scanner*>(handle); - if (!s->scanning) - { - DBG(DBG_error, "%s: not scanning\n", __func__); - return SANE_STATUS_INVAL; + if (!s->scanning) { + throw SaneException("not scanning"); } - return SANE_STATUS_UNSUPPORTED; + throw SaneException(SANE_STATUS_UNSUPPORTED); } -SANE_Status -sane_get_select_fd(SANE_Handle handle, SANE_Int * fd) +SANE_GENESYS_API_LINKAGE +SANE_Status sane_get_select_fd(SANE_Handle handle, SANE_Int* fd) { return wrap_exceptions_to_status_code(__func__, [=]() { - return sane_get_select_fd_impl(handle, fd); + sane_get_select_fd_impl(handle, fd); }); } @@ -7578,3 +6168,5 @@ GenesysButtonName genesys_option_to_button(int option) default: throw std::runtime_error("Unknown option to convert to button index"); } } + +} // namespace genesys diff --git a/backend/genesys.h b/backend/genesys/genesys.h index 47a684c..255bf76 100644 --- a/backend/genesys.h +++ b/backend/genesys/genesys.h @@ -51,7 +51,7 @@ # define BACKEND_NAME genesys #endif -#include "genesys_low.h" +#include "low.h" #include <queue> #ifndef PATH_MAX @@ -71,17 +71,16 @@ #define GENESYS_CONFIG_FILE "genesys.conf" -/* Maximum time for lamp warm-up */ -#define WARMUP_TIME 65 - -#define STR_FLATBED "Flatbed" -#define STR_TRANSPARENCY_ADAPTER "Transparency Adapter" -#define STR_TRANSPARENCY_ADAPTER_INFRARED "Transparency Adapter Infrared" - #ifndef SANE_I18N #define SANE_I18N(text) text #endif +#define STR_FLATBED SANE_I18N("Flatbed") +#define STR_TRANSPARENCY_ADAPTER SANE_I18N("Transparency Adapter") +#define STR_TRANSPARENCY_ADAPTER_INFRARED SANE_I18N("Transparency Adapter Infrared") + +namespace genesys { + /** List of SANE options */ enum Genesys_Option @@ -122,7 +121,6 @@ enum Genesys_Option OPT_LAMP_OFF, OPT_THRESHOLD, OPT_THRESHOLD_CURVE, - OPT_DISABLE_DYNAMIC_LINEART, OPT_DISABLE_INTERPOLATION, OPT_COLOR_FILTER, OPT_CALIBRATION_FILE, @@ -142,6 +140,7 @@ enum Genesys_Option OPT_CALIBRATE, OPT_CLEAR_CALIBRATION, OPT_FORCE_CALIBRATION, + OPT_IGNORE_OFFSETS, /* must come last: */ NUM_OPTIONS @@ -202,17 +201,21 @@ struct Genesys_Scanner // SANE data // We are currently scanning - SANE_Bool scanning; + bool scanning; // Option descriptors SANE_Option_Descriptor opt[NUM_OPTIONS]; + std::vector<SANE_Word> opt_resolution_values; + SANE_Range opt_x_range = {}; + SANE_Range opt_y_range = {}; + std::vector<const char*> opt_source_values; + // Option values SANE_Word bit_depth = 0; SANE_Word resolution = 0; bool preview = false; SANE_Word threshold = 0; SANE_Word threshold_curve = 0; - bool disable_dynamic_lineart = false; bool disable_interpolation = false; bool lamp_off = false; SANE_Word lamp_off_time = 0; @@ -232,7 +235,10 @@ struct Genesys_Scanner SANE_Word pos_bottom_right_y = 0; SANE_Word pos_bottom_right_x = 0; - std::string mode, source, color_filter; + std::string mode, color_filter; + + // the value of the source option + ScanMethod scan_method = ScanMethod::FLATBED; std::string calibration_file; // Button states @@ -247,4 +253,6 @@ void write_calibration(std::ostream& str, Genesys_Device::Calibration& cache); bool read_calibration(std::istream& str, Genesys_Device::Calibration& cache, const std::string& path); +} // namespace genesys + #endif /* not GENESYS_H */ diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp new file mode 100644 index 0000000..054f1ef --- /dev/null +++ b/backend/genesys/gl124.cpp @@ -0,0 +1,2269 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2010-2016 Stéphane Voltz <stef.dev@free.fr> + + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "gl124.h" +#include "gl124_registers.h" +#include "test_settings.h" + +#include <vector> + +namespace genesys { +namespace gl124 { + +/** @brief set all registers to default values . + * This function is called only once at the beginning and + * fills register startup values for registers reused across scans. + * Those that are rarely modified or not modified are written + * individually. + * @param dev device structure holding register set to initialize + */ +static void +gl124_init_registers (Genesys_Device * dev) +{ + DBG_HELPER(dbg); + + dev->reg.clear(); + + // default to LiDE 110 + dev->reg.init_reg(0x01, 0xa2); // + REG_0x01_SHDAREA + dev->reg.init_reg(0x02, 0x90); + dev->reg.init_reg(0x03, 0x50); + dev->reg.init_reg(0x04, 0x03); + dev->reg.init_reg(0x05, 0x00); + + if(dev->model->sensor_id == SensorId::CIS_CANON_LIDE_120) { + dev->reg.init_reg(0x06, 0x50); + dev->reg.init_reg(0x07, 0x00); + } else { + dev->reg.init_reg(0x03, 0x50 & ~REG_0x03_AVEENB); + dev->reg.init_reg(0x06, 0x50 | REG_0x06_GAIN4); + } + dev->reg.init_reg(0x09, 0x00); + dev->reg.init_reg(0x0a, 0xc0); + dev->reg.init_reg(0x0b, 0x2a); + dev->reg.init_reg(0x0c, 0x12); + dev->reg.init_reg(0x11, 0x00); + dev->reg.init_reg(0x12, 0x00); + dev->reg.init_reg(0x13, 0x0f); + dev->reg.init_reg(0x14, 0x00); + dev->reg.init_reg(0x15, 0x80); + dev->reg.init_reg(0x16, 0x10); // SENSOR_DEF + dev->reg.init_reg(0x17, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x18, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x19, 0x01); // SENSOR_DEF + dev->reg.init_reg(0x1a, 0x30); // SENSOR_DEF + dev->reg.init_reg(0x1b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x1c, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x1d, 0x01); // SENSOR_DEF + dev->reg.init_reg(0x1e, 0x10); + dev->reg.init_reg(0x1f, 0x00); + dev->reg.init_reg(0x20, 0x15); // SENSOR_DEF + dev->reg.init_reg(0x21, 0x00); + if(dev->model->sensor_id != SensorId::CIS_CANON_LIDE_120) { + dev->reg.init_reg(0x22, 0x02); + } else { + dev->reg.init_reg(0x22, 0x14); + } + dev->reg.init_reg(0x23, 0x00); + dev->reg.init_reg(0x24, 0x00); + dev->reg.init_reg(0x25, 0x00); + dev->reg.init_reg(0x26, 0x0d); + dev->reg.init_reg(0x27, 0x48); + dev->reg.init_reg(0x28, 0x00); + dev->reg.init_reg(0x29, 0x56); + dev->reg.init_reg(0x2a, 0x5e); + dev->reg.init_reg(0x2b, 0x02); + dev->reg.init_reg(0x2c, 0x02); + dev->reg.init_reg(0x2d, 0x58); + dev->reg.init_reg(0x3b, 0x00); + dev->reg.init_reg(0x3c, 0x00); + dev->reg.init_reg(0x3d, 0x00); + dev->reg.init_reg(0x3e, 0x00); + dev->reg.init_reg(0x3f, 0x02); + dev->reg.init_reg(0x40, 0x00); + dev->reg.init_reg(0x41, 0x00); + dev->reg.init_reg(0x42, 0x00); + dev->reg.init_reg(0x43, 0x00); + dev->reg.init_reg(0x44, 0x00); + dev->reg.init_reg(0x45, 0x00); + dev->reg.init_reg(0x46, 0x00); + dev->reg.init_reg(0x47, 0x00); + dev->reg.init_reg(0x48, 0x00); + dev->reg.init_reg(0x49, 0x00); + dev->reg.init_reg(0x4f, 0x00); + dev->reg.init_reg(0x52, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x53, 0x02); // SENSOR_DEF + dev->reg.init_reg(0x54, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x55, 0x06); // SENSOR_DEF + dev->reg.init_reg(0x56, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x57, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x58, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x59, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x5a, 0x1a); // SENSOR_DEF + dev->reg.init_reg(0x5b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x5c, 0xc0); // SENSOR_DEF + dev->reg.init_reg(0x5f, 0x00); + dev->reg.init_reg(0x60, 0x02); + dev->reg.init_reg(0x61, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x62, 0x00); + dev->reg.init_reg(0x63, 0x00); + dev->reg.init_reg(0x64, 0x00); + dev->reg.init_reg(0x65, 0x00); + dev->reg.init_reg(0x66, 0x00); + dev->reg.init_reg(0x67, 0x00); + dev->reg.init_reg(0x68, 0x00); + dev->reg.init_reg(0x69, 0x00); + dev->reg.init_reg(0x6a, 0x00); + dev->reg.init_reg(0x6b, 0x00); + dev->reg.init_reg(0x6c, 0x00); + dev->reg.init_reg(0x6e, 0x00); + dev->reg.init_reg(0x6f, 0x00); + + if (dev->model->sensor_id != SensorId::CIS_CANON_LIDE_120) { + dev->reg.init_reg(0x6d, 0xd0); + dev->reg.init_reg(0x71, 0x08); + } else { + dev->reg.init_reg(0x6d, 0x00); + dev->reg.init_reg(0x71, 0x1f); + } + dev->reg.init_reg(0x70, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x71, 0x08); // SENSOR_DEF + dev->reg.init_reg(0x72, 0x08); // SENSOR_DEF + dev->reg.init_reg(0x73, 0x0a); // SENSOR_DEF + + // CKxMAP + dev->reg.init_reg(0x74, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x75, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x76, 0x3c); // SENSOR_DEF + dev->reg.init_reg(0x77, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x78, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x79, 0x9f); // SENSOR_DEF + dev->reg.init_reg(0x7a, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x7b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x7c, 0x55); // SENSOR_DEF + + dev->reg.init_reg(0x7d, 0x00); + dev->reg.init_reg(0x7e, 0x08); + dev->reg.init_reg(0x7f, 0x58); + + if (dev->model->sensor_id != SensorId::CIS_CANON_LIDE_120) { + dev->reg.init_reg(0x80, 0x00); + dev->reg.init_reg(0x81, 0x14); + } else { + dev->reg.init_reg(0x80, 0x00); + dev->reg.init_reg(0x81, 0x10); + } + + // STRPIXEL + dev->reg.init_reg(0x82, 0x00); + dev->reg.init_reg(0x83, 0x00); + dev->reg.init_reg(0x84, 0x00); + + // ENDPIXEL + dev->reg.init_reg(0x85, 0x00); + dev->reg.init_reg(0x86, 0x00); + dev->reg.init_reg(0x87, 0x00); + + dev->reg.init_reg(0x88, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x89, 0x65); // SENSOR_DEF + dev->reg.init_reg(0x8a, 0x00); + dev->reg.init_reg(0x8b, 0x00); + dev->reg.init_reg(0x8c, 0x00); + dev->reg.init_reg(0x8d, 0x00); + dev->reg.init_reg(0x8e, 0x00); + dev->reg.init_reg(0x8f, 0x00); + dev->reg.init_reg(0x90, 0x00); + dev->reg.init_reg(0x91, 0x00); + dev->reg.init_reg(0x92, 0x00); + dev->reg.init_reg(0x93, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x94, 0x14); // SENSOR_DEF + dev->reg.init_reg(0x95, 0x30); // SENSOR_DEF + dev->reg.init_reg(0x96, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x97, 0x90); // SENSOR_DEF + dev->reg.init_reg(0x98, 0x01); // SENSOR_DEF + dev->reg.init_reg(0x99, 0x1f); + dev->reg.init_reg(0x9a, 0x00); + dev->reg.init_reg(0x9b, 0x80); + dev->reg.init_reg(0x9c, 0x80); + dev->reg.init_reg(0x9d, 0x3f); + dev->reg.init_reg(0x9e, 0x00); + dev->reg.init_reg(0x9f, 0x00); + dev->reg.init_reg(0xa0, 0x20); + dev->reg.init_reg(0xa1, 0x30); + dev->reg.init_reg(0xa2, 0x00); + dev->reg.init_reg(0xa3, 0x20); + dev->reg.init_reg(0xa4, 0x01); + dev->reg.init_reg(0xa5, 0x00); + dev->reg.init_reg(0xa6, 0x00); + dev->reg.init_reg(0xa7, 0x08); + dev->reg.init_reg(0xa8, 0x00); + dev->reg.init_reg(0xa9, 0x08); + dev->reg.init_reg(0xaa, 0x01); + dev->reg.init_reg(0xab, 0x00); + dev->reg.init_reg(0xac, 0x00); + dev->reg.init_reg(0xad, 0x40); + dev->reg.init_reg(0xae, 0x01); + dev->reg.init_reg(0xaf, 0x00); + dev->reg.init_reg(0xb0, 0x00); + dev->reg.init_reg(0xb1, 0x40); + dev->reg.init_reg(0xb2, 0x00); + dev->reg.init_reg(0xb3, 0x09); + dev->reg.init_reg(0xb4, 0x5b); + dev->reg.init_reg(0xb5, 0x00); + dev->reg.init_reg(0xb6, 0x10); + dev->reg.init_reg(0xb7, 0x3f); + dev->reg.init_reg(0xb8, 0x00); + dev->reg.init_reg(0xbb, 0x00); + dev->reg.init_reg(0xbc, 0xff); + dev->reg.init_reg(0xbd, 0x00); + dev->reg.init_reg(0xbe, 0x07); + dev->reg.init_reg(0xc3, 0x00); + dev->reg.init_reg(0xc4, 0x00); + + /* gamma + dev->reg.init_reg(0xc5, 0x00); + dev->reg.init_reg(0xc6, 0x00); + dev->reg.init_reg(0xc7, 0x00); + dev->reg.init_reg(0xc8, 0x00); + dev->reg.init_reg(0xc9, 0x00); + dev->reg.init_reg(0xca, 0x00); + dev->reg.init_reg(0xcb, 0x00); + dev->reg.init_reg(0xcc, 0x00); + dev->reg.init_reg(0xcd, 0x00); + dev->reg.init_reg(0xce, 0x00); + */ + + if (dev->model->sensor_id == SensorId::CIS_CANON_LIDE_120) { + dev->reg.init_reg(0xc5, 0x20); + dev->reg.init_reg(0xc6, 0xeb); + dev->reg.init_reg(0xc7, 0x20); + dev->reg.init_reg(0xc8, 0xeb); + dev->reg.init_reg(0xc9, 0x20); + dev->reg.init_reg(0xca, 0xeb); + } + + // memory layout + /* + dev->reg.init_reg(0xd0, 0x0a); + dev->reg.init_reg(0xd1, 0x1f); + dev->reg.init_reg(0xd2, 0x34); + */ + dev->reg.init_reg(0xd3, 0x00); + dev->reg.init_reg(0xd4, 0x00); + dev->reg.init_reg(0xd5, 0x00); + dev->reg.init_reg(0xd6, 0x00); + dev->reg.init_reg(0xd7, 0x00); + dev->reg.init_reg(0xd8, 0x00); + dev->reg.init_reg(0xd9, 0x00); + + // memory layout + /* + dev->reg.init_reg(0xe0, 0x00); + dev->reg.init_reg(0xe1, 0x48); + dev->reg.init_reg(0xe2, 0x15); + dev->reg.init_reg(0xe3, 0x90); + dev->reg.init_reg(0xe4, 0x15); + dev->reg.init_reg(0xe5, 0x91); + dev->reg.init_reg(0xe6, 0x2a); + dev->reg.init_reg(0xe7, 0xd9); + dev->reg.init_reg(0xe8, 0x2a); + dev->reg.init_reg(0xe9, 0xad); + dev->reg.init_reg(0xea, 0x40); + dev->reg.init_reg(0xeb, 0x22); + dev->reg.init_reg(0xec, 0x40); + dev->reg.init_reg(0xed, 0x23); + dev->reg.init_reg(0xee, 0x55); + dev->reg.init_reg(0xef, 0x6b); + dev->reg.init_reg(0xf0, 0x55); + dev->reg.init_reg(0xf1, 0x6c); + dev->reg.init_reg(0xf2, 0x6a); + dev->reg.init_reg(0xf3, 0xb4); + dev->reg.init_reg(0xf4, 0x6a); + dev->reg.init_reg(0xf5, 0xb5); + dev->reg.init_reg(0xf6, 0x7f); + dev->reg.init_reg(0xf7, 0xfd); + */ + + dev->reg.init_reg(0xf8, 0x01); // other value is 0x05 + dev->reg.init_reg(0xf9, 0x00); + dev->reg.init_reg(0xfa, 0x00); + dev->reg.init_reg(0xfb, 0x00); + dev->reg.init_reg(0xfc, 0x00); + dev->reg.init_reg(0xff, 0x00); + + // fine tune upon device description + const auto& sensor = sanei_genesys_find_sensor_any(dev); + sanei_genesys_set_dpihw(dev->reg, sensor, sensor.optical_res); + + dev->calib_reg = dev->reg; +} + +/**@brief send slope table for motor movement + * Send slope_table in machine byte order + * @param dev device to send slope table + * @param table_nr index of the slope table in ASIC memory + * Must be in the [0-4] range. + * @param slope_table pointer to 16 bit values array of the slope table + * @param steps number of elemnts in the slope table + */ +static void gl124_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, + int steps) +{ + DBG_HELPER_ARGS(dbg, "table_nr = %d, steps = %d", table_nr, steps); + int i; + char msg[10000]; + + /* sanity check */ + if(table_nr<0 || table_nr>4) + { + throw SaneException("invalid table number"); + } + + std::vector<uint8_t> table(steps * 2); + for (i = 0; i < steps; i++) + { + table[i * 2] = slope_table[i] & 0xff; + table[i * 2 + 1] = slope_table[i] >> 8; + } + + if (DBG_LEVEL >= DBG_io) + { + std::sprintf(msg, "write slope %d (%d)=", table_nr, steps); + for (i = 0; i < steps; i++) { + std::sprintf(msg + std::strlen(msg), ",%d", slope_table[i]); + } + DBG (DBG_io, "%s: %s\n", __func__, msg); + } + + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } + // slope table addresses are fixed + dev->interface->write_ahb(0x10000000 + 0x4000 * table_nr, steps * 2, table.data()); +} + +/** @brief * Set register values of 'special' ti type frontend + * Registers value are taken from the frontend register data + * set. + * @param dev device owning the AFE + * @param set flag AFE_INIT to specify the AFE must be reset before writing data + * */ +static void gl124_set_ti_fe(Genesys_Device* dev, uint8_t set) +{ + DBG_HELPER(dbg); + int i; + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s: setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + + dev->frontend = dev->frontend_initial; + } + + // start writing to DAC + dev->interface->write_fe_register(0x00, 0x80); + + /* write values to analog frontend */ + for (uint16_t addr = 0x01; addr < 0x04; addr++) + { + dev->interface->write_fe_register(addr, dev->frontend.regs.get_value(addr)); + } + + dev->interface->write_fe_register(0x04, 0x00); + + /* these are not really sign for this AFE */ + for (i = 0; i < 3; i++) + { + dev->interface->write_fe_register(0x05 + i, dev->frontend.regs.get_value(0x24 + i)); + } + + if (dev->model->adc_id == AdcId::CANON_LIDE_120) { + dev->interface->write_fe_register(0x00, 0x01); + } + else + { + dev->interface->write_fe_register(0x00, 0x11); + } +} + + +// Set values of analog frontend +void CommandSetGl124::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const +{ + DBG_HELPER_ARGS(dbg, "%s", set == AFE_INIT ? "init" : + set == AFE_SET ? "set" : + set == AFE_POWER_SAVE ? "powersave" : "huh?"); + (void) sensor; + uint8_t val; + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + dev->frontend = dev->frontend_initial; + } + + val = dev->interface->read_register(REG_0x0A); + + /* route to correct analog FE */ + switch ((val & REG_0x0A_SIFSEL) >> REG_0x0AS_SIFSEL) { + case 3: + gl124_set_ti_fe(dev, set); + break; + case 0: + case 1: + case 2: + default: + throw SaneException("unsupported analog FE 0x%02x", val); + } +} + +static void gl124_init_motor_regs_scan(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const Motor_Profile& motor_profile, + unsigned int scan_exposure_time, + unsigned scan_yres, + unsigned int scan_lines, + unsigned int scan_dummy, + unsigned int feed_steps, + ScanColorMode scan_mode, + MotorFlag flags) +{ + DBG_HELPER(dbg); + int use_fast_fed; + unsigned int lincnt, fast_dpi; + unsigned int feedl,dist; + uint32_t z1, z2; + unsigned yres; + unsigned min_speed; + unsigned int linesel; + + DBG(DBG_info, "%s : scan_exposure_time=%d, scan_yres=%d, step_type=%d, scan_lines=%d, " + "scan_dummy=%d, feed_steps=%d, scan_mode=%d, flags=%x\n", __func__, scan_exposure_time, + scan_yres, static_cast<unsigned>(motor_profile.step_type), scan_lines, scan_dummy, + feed_steps, static_cast<unsigned>(scan_mode), + static_cast<unsigned>(flags)); + + /* we never use fast fed since we do manual feed for the scans */ + use_fast_fed=0; + + /* enforce motor minimal scan speed + * @TODO extend motor struct for this value */ + if (scan_mode == ScanColorMode::COLOR_SINGLE_PASS) + { + min_speed = 900; + } + else + { + switch(dev->model->motor_id) + { + case MotorId::CANON_LIDE_110: + min_speed = 600; + break; + case MotorId::CANON_LIDE_120: + min_speed = 900; + break; + default: + min_speed = 900; + break; + } + } + + /* compute min_speed and linesel */ + if(scan_yres<min_speed) + { + yres=min_speed; + linesel = yres / scan_yres - 1; + /* limit case, we need a linesel > 0 */ + if(linesel==0) + { + linesel=1; + yres=scan_yres*2; + } + } + else + { + yres=scan_yres; + linesel=0; + } + + DBG(DBG_io2, "%s: final yres=%d, linesel=%d\n", __func__, yres, linesel); + + lincnt=scan_lines*(linesel+1); + reg->set24(REG_LINCNT, lincnt); + DBG (DBG_io, "%s: lincnt=%d\n", __func__, lincnt); + + /* compute register 02 value */ + uint8_t r02 = REG_0x02_NOTHOME; + + if (use_fast_fed) { + r02 |= REG_0x02_FASTFED; + } else { + r02 &= ~REG_0x02_FASTFED; + } + + if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) { + r02 |= REG_0x02_AGOHOME; + } + + if (has_flag(flags, MotorFlag::DISABLE_BUFFER_FULL_MOVE) || (yres >= sensor.optical_res)) + { + r02 |= REG_0x02_ACDCDIS; + } + if (has_flag(flags, MotorFlag::REVERSE)) { + r02 |= REG_0x02_MTRREV; + } + + reg->set8(REG_0x02, r02); + sanei_genesys_set_motor_power(*reg, true); + + reg->set16(REG_SCANFED, 4); + + /* scan and backtracking slope table */ + auto scan_table = sanei_genesys_slope_table(dev->model->asic_type, yres, scan_exposure_time, + dev->motor.base_ydpi, 1, + motor_profile); + gl124_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.steps_count); + gl124_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.steps_count); + + reg->set16(REG_STEPNO, scan_table.steps_count); + + /* fast table */ + fast_dpi=yres; + + /* + if (scan_mode != ScanColorMode::COLOR_SINGLE_PASS) + { + fast_dpi*=3; + } + */ + auto fast_table = sanei_genesys_slope_table(dev->model->asic_type, fast_dpi, + scan_exposure_time, dev->motor.base_ydpi, + 1, motor_profile); + gl124_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.steps_count); + gl124_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.steps_count); + + reg->set16(REG_FASTNO, fast_table.steps_count); + reg->set16(REG_FSHDEC, fast_table.steps_count); + reg->set16(REG_FMOVNO, fast_table.steps_count); + + /* substract acceleration distance from feedl */ + feedl=feed_steps; + feedl <<= static_cast<unsigned>(motor_profile.step_type); + + dist = scan_table.steps_count; + if (has_flag(flags, MotorFlag::FEED)) { + dist *= 2; + } + if (use_fast_fed) { + dist += fast_table.steps_count * 2; + } + DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); + + /* get sure we don't use insane value */ + if (dist < feedl) { + feedl -= dist; + } else { + feedl = 0; + } + + reg->set24(REG_FEEDL, feedl); + DBG (DBG_io, "%s: feedl=%d\n", __func__, feedl); + + /* doesn't seem to matter that much */ + sanei_genesys_calculate_zmod(use_fast_fed, + scan_exposure_time, + scan_table.table, + scan_table.steps_count, + feedl, + scan_table.steps_count, + &z1, + &z2); + + reg->set24(REG_Z1MOD, z1); + DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); + + reg->set24(REG_Z2MOD, z2); + DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); + + /* LINESEL */ + reg->set8_mask(REG_0x1D, linesel, REG_0x1D_LINESEL); + reg->set8(REG_0xA0, (static_cast<unsigned>(motor_profile.step_type) << REG_0xA0S_STEPSEL) | + (static_cast<unsigned>(motor_profile.step_type) << REG_0xA0S_FSTPSEL)); + + reg->set16(REG_FMOVDEC, fast_table.steps_count); +} + + +/** @brief copy sensor specific settings + * Set up register set for the given sensor resolution. Values are from the device table + * in genesys_devices.c for registers: + * [0x16 ... 0x1d] + * [0x52 ... 0x5e] + * Other come from the specific device sensor table in genesys_gl124.h: + * 0x18, 0x20, 0x61, 0x98 and + * @param dev device to set up + * @param regs register set to modify + * @param dpi resolution of the sensor during scan + * @param ccd_size_divisor flag for half ccd mode + * */ +static void gl124_setup_sensor(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs) +{ + DBG_HELPER(dbg); + + for (const auto& reg : sensor.custom_regs) { + regs->set8(reg.address, reg.value); + } + + regs->set24(REG_EXPR, sensor.exposure.red); + regs->set24(REG_EXPG, sensor.exposure.green); + regs->set24(REG_EXPB, sensor.exposure.blue); + + dev->segment_order = sensor.segment_order; +} + +/** @brief setup optical related registers + * start and pixels are expressed in optical sensor resolution coordinate + * space. + * @param dev scanner device to use + * @param reg registers to set up + * @param exposure_time exposure time to use + * @param used_res scanning resolution used, may differ from + * scan's one + * @param start logical start pixel coordinate + * @param pixels logical number of pixels to use + * @param channels number of color channels (currently 1 or 3) + * @param depth bit depth of the scan (1, 8 or 16) + * @param ccd_size_divisor whether sensor's timings are such that x coordinates must be halved + * @param color_filter color channel to use as gray data + * @param flags optical flags (@see ) + */ +static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, unsigned int exposure_time, + const ScanSession& session) +{ + DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time); + unsigned int dpihw; + GenesysRegister *r; + uint32_t expmax; + + // resolution is divided according to ccd_pixels_per_system_pixel + unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); + DBG(DBG_io2, "%s: ccd_pixels_per_system_pixel=%d\n", __func__, ccd_pixels_per_system_pixel); + + // to manage high resolution device while keeping good low resolution scanning speed, we + // make hardware dpi vary + dpihw = sensor.get_register_hwdpi(session.output_resolution * ccd_pixels_per_system_pixel); + DBG(DBG_io2, "%s: dpihw=%d\n", __func__, dpihw); + + gl124_setup_sensor(dev, sensor, reg); + + dev->cmd_set->set_fe(dev, sensor, AFE_SET); + + /* enable shading */ + regs_set_optical_off(dev->model->asic_type, *reg); + r = sanei_genesys_get_address (reg, REG_0x01); + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || + (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) + { + r->value &= ~REG_0x01_DVDSET; + } else { + r->value |= REG_0x01_DVDSET; + } + + r = sanei_genesys_get_address(reg, REG_0x03); + if ((dev->model->sensor_id != SensorId::CIS_CANON_LIDE_120) && (session.params.xres>=600)) { + r->value &= ~REG_0x03_AVEENB; + DBG (DBG_io, "%s: disabling AVEENB\n", __func__); + } + else + { + r->value |= ~REG_0x03_AVEENB; + DBG (DBG_io, "%s: enabling AVEENB\n", __func__); + } + + sanei_genesys_set_lamp_power(dev, sensor, *reg, + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); + + // BW threshold + dev->interface->write_register(REG_0x114, dev->settings.threshold); + dev->interface->write_register(REG_0x115, dev->settings.threshold); + + /* monochrome / color scan */ + r = sanei_genesys_get_address (reg, REG_0x04); + switch (session.params.depth) { + case 8: + r->value &= ~(REG_0x04_LINEART | REG_0x04_BITSET); + break; + case 16: + r->value &= ~REG_0x04_LINEART; + r->value |= REG_0x04_BITSET; + break; + } + + r->value &= ~REG_0x04_FILTER; + if (session.params.channels == 1) + { + switch (session.params.color_filter) + { + case ColorFilter::RED: + r->value |= 0x10; + break; + case ColorFilter::BLUE: + r->value |= 0x30; + break; + case ColorFilter::GREEN: + r->value |= 0x20; + break; + default: + break; // should not happen + } + } + + sanei_genesys_set_dpihw(*reg, sensor, dpihw); + + if (should_enable_gamma(session, sensor)) { + reg->find_reg(REG_0x05).value |= REG_0x05_GMMENB; + } else { + reg->find_reg(REG_0x05).value &= ~REG_0x05_GMMENB; + } + + unsigned dpiset_reg = session.output_resolution * ccd_pixels_per_system_pixel * + session.ccd_size_divisor; + if (sensor.dpiset_override != 0) { + dpiset_reg = sensor.dpiset_override; + } + + reg->set16(REG_DPISET, dpiset_reg); + DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset_reg); + + r = sanei_genesys_get_address(reg, REG_0x06); + r->value |= REG_0x06_GAIN4; + + /* CIS scanners can do true gray by setting LEDADD */ + /* we set up LEDADD only when asked */ + if (dev->model->is_cis) { + r = sanei_genesys_get_address (reg, REG_0x60); + r->value &= ~REG_0x60_LEDADD; + if (session.enable_ledadd) { + r->value |= REG_0x60_LEDADD; + expmax = reg->get24(REG_EXPR); + expmax = std::max(expmax, reg->get24(REG_EXPG)); + expmax = std::max(expmax, reg->get24(REG_EXPB)); + + dev->reg.set24(REG_EXPR, expmax); + dev->reg.set24(REG_EXPG, expmax); + dev->reg.set24(REG_EXPB, expmax); + } + /* RGB weighting, REG_TRUER,G and B are to be set */ + r = sanei_genesys_get_address (reg, 0x01); + r->value &= ~REG_0x01_TRUEGRAY; + if (session.enable_ledadd) { + r->value |= REG_0x01_TRUEGRAY; + dev->interface->write_register(REG_TRUER, 0x80); + dev->interface->write_register(REG_TRUEG, 0x80); + dev->interface->write_register(REG_TRUEB, 0x80); + } + } + + reg->set24(REG_STRPIXEL, session.pixel_startx); + reg->set24(REG_ENDPIXEL, session.pixel_endx); + + dev->line_count = 0; + + build_image_pipeline(dev, session); + + // MAXWD is expressed in 2 words unit + + // BUG: we shouldn't multiply by channels here + reg->set24(REG_MAXWD, session.output_line_bytes_raw / session.ccd_size_divisor * session.params.channels); + + reg->set24(REG_LPERIOD, exposure_time); + DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time); + + reg->set16(REG_DUMMY, sensor.dummy_pixel); +} + +void CommandSetGl124::init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const +{ + DBG_HELPER(dbg); + session.assert_computed(); + + int move; + int exposure_time; + + int dummy = 0; + int slope_dpi = 0; + + /* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */ + if (dev->model->is_cis) { + slope_dpi = session.params.yres * session.params.channels; + } else { + slope_dpi = session.params.yres; + } + + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { + exposure_time = 2304; + } else { + exposure_time = sensor.exposure_lperiod; + } + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl124_motor_profiles, + dev->model->motor_id, + exposure_time); + + DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); + DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, static_cast<unsigned>(motor_profile.step_type)); + + /* we enable true gray for cis scanners only, and just when doing + * scan since color calibration is OK for this mode + */ + + // now _LOGICAL_ optical values used are known, setup registers + gl124_init_optical_regs_scan(dev, sensor, reg, exposure_time, session); + + /* add tl_y to base movement */ + move = session.params.starty; + DBG(DBG_info, "%s: move=%d steps\n", __func__, move); + + MotorFlag mflags = MotorFlag::NONE; + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { + mflags |= MotorFlag::DISABLE_BUFFER_FULL_MOVE; + } + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { + mflags |= MotorFlag::FEED; + } + if (has_flag(session.params.flags, ScanFlag::REVERSE)) { + mflags |= MotorFlag::REVERSE; + } + gl124_init_motor_regs_scan(dev, sensor, reg, motor_profile, exposure_time, slope_dpi, + dev->model->is_cis ? session.output_line_count * session.params.channels : + session.output_line_count, + dummy, move, session.params.scan_mode, mflags); + + /*** prepares data reordering ***/ + + dev->read_buffer.clear(); + dev->read_buffer.alloc(session.buffer_size_read); + + dev->read_active = true; + + dev->session = session; + + dev->total_bytes_read = 0; + dev->total_bytes_to_read = session.output_line_bytes_requested * session.params.lines; + + DBG(DBG_info, "%s: total bytes to send to frontend = %zu\n", __func__, + dev->total_bytes_to_read); +} + +ScanSession CommandSetGl124::calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const +{ + int start; + + DBG(DBG_info, "%s ", __func__); + debug_dump(DBG_info, settings); + + /* start */ + start = static_cast<int>(dev->model->x_offset); + start += static_cast<int>(settings.tl_x); + start = static_cast<int>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = settings.xres; + session.params.yres = settings.yres; + session.params.startx = start; + session.params.starty = 0; // not used + session.params.pixels = settings.pixels; + session.params.requested_pixels = settings.requested_pixels; + session.params.lines = settings.lines; + session.params.depth = settings.depth; + session.params.channels = settings.get_channels(); + session.params.scan_method = settings.scan_method; + session.params.scan_mode = settings.scan_mode; + session.params.color_filter = settings.color_filter; + session.params.flags = ScanFlag::NONE; + + compute_session(dev, session, sensor); + + return session; +} + +/** + * for fast power saving methods only, like disabling certain amplifiers + * @param dev device to use + * @param enable true to set inot powersaving + * */ +void CommandSetGl124::save_power(Genesys_Device* dev, bool enable) const +{ + (void) dev; + DBG_HELPER_ARGS(dbg, "enable = %d", enable); +} + +void CommandSetGl124::set_powersaving(Genesys_Device* dev, int delay /* in minutes */) const +{ + DBG_HELPER_ARGS(dbg, "delay = %d", delay); + GenesysRegister *r; + + r = sanei_genesys_get_address(&dev->reg, REG_0x03); + r->value &= ~0xf0; + if(delay<15) + { + r->value |= delay; + } + else + { + r->value |= 0x0f; + } +} + +/** @brief setup GPIOs for scan + * Setup GPIO values to drive motor (or light) needed for the + * target resolution + * @param *dev device to set up + * @param resolution dpi of the target scan + */ +void gl124_setup_scan_gpio(Genesys_Device* dev, int resolution) +{ + DBG_HELPER(dbg); + + uint8_t val = dev->interface->read_register(REG_0x32); + + /* LiDE 110, 210 and 220 cases */ + if(dev->model->gpio_id != GpioId::CANON_LIDE_120) { + if(resolution>=dev->motor.base_ydpi/2) + { + val &= 0xf7; + } + else if(resolution>=dev->motor.base_ydpi/4) + { + val &= 0xef; + } + else + { + val |= 0x10; + } + } + /* 120 : <=300 => 0x53 */ + else + { /* base_ydpi is 4800 */ + if(resolution<=300) + { + val &= 0xf7; + } + else if(resolution<=600) + { + val |= 0x08; + } + else if(resolution<=1200) + { + val &= 0xef; + val |= 0x08; + } + else + { + val &= 0xf7; + } + } + val |= 0x02; + dev->interface->write_register(REG_0x32, val); +} + +// Send the low-level scan command +// todo: is this that useful ? +void CommandSetGl124::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, bool start_motor) const +{ + DBG_HELPER(dbg); + (void) sensor; + (void) reg; + + // set up GPIO for scan + gl124_setup_scan_gpio(dev,dev->settings.yres); + + // clear scan and feed count + dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT); + + // enable scan and motor + uint8_t val = dev->interface->read_register(REG_0x01); + val |= REG_0x01_SCAN; + dev->interface->write_register(REG_0x01, val); + + scanner_start_action(*dev, start_motor); + + dev->advance_head_pos_by_session(ScanHeadId::PRIMARY); +} + + +// Send the stop scan command +void CommandSetGl124::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg, + bool check_stop) const +{ + (void) reg; + DBG_HELPER_ARGS(dbg, "check_stop = %d", check_stop); + + if (!dev->model->is_sheetfed) { + scanner_stop_action(*dev); + } +} + + +/** Park head + * Moves the slider to the home (top) position slowly + * @param dev device to park + * @param wait_until_home true to make the function waiting for head + * to be home before returning, if fals returne immediately + */ +void CommandSetGl124::move_back_home(Genesys_Device* dev, bool wait_until_home) const +{ + scanner_move_back_home(*dev, wait_until_home); +} + +// Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi +// from very top of scanner +void CommandSetGl124::search_start_position(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + int size; + Genesys_Register_Set local_reg = dev->reg; + + int pixels = 600; + int dpi = 300; + + /* sets for a 200 lines * 600 pixels */ + /* normal scan with no shading */ + + // FIXME: the current approach of doing search only for one resolution does not work on scanners + // whith employ different sensors with potentially different settings. + const auto& sensor = sanei_genesys_find_sensor(dev, dpi, 1, ScanMethod::FLATBED); + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; /*we should give a small offset here~60 steps */ + session.params.pixels = 600; + session.params.lines = dev->model->search_lines; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::GREEN; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_BUFFER_FULL_MOVE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + // send to scanner + dev->interface->write_registers(local_reg); + + size = pixels * dev->model->search_lines; + + std::vector<uint8_t> data(size); + + begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_start_position"); + end_scan(dev, &local_reg, true); + dev->reg = local_reg; + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl124_search_position.pnm", data.data(), 8, 1, pixels, + dev->model->search_lines); + } + + end_scan(dev, &local_reg, true); + + /* update regs to copy ASIC internal state */ + dev->reg = local_reg; + + for (auto& sensor_update : + sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method)) + { + sanei_genesys_search_reference_point(dev, sensor_update, data.data(), 0, dpi, pixels, + dev->model->search_lines); + } +} + +// sets up register for coarse gain calibration +// todo: check it for scanners using it +void CommandSetGl124::init_regs_for_coarse_calibration(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = sensor.optical_res / sensor.ccd_pixels_per_system_pixel(); + session.params.lines = 20; + session.params.depth = 16; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::FEEDING | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + sanei_genesys_set_motor_power(regs, false); + + DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, + sensor.optical_res / sensor.ccd_pixels_per_system_pixel(), dev->settings.xres); + + dev->interface->write_registers(regs); +} + + +// init registers for shading calibration shading calibration is done at dpihw +void CommandSetGl124::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int move, resolution, dpihw, factor; + + /* initial calibration reg values */ + regs = dev->reg; + + dev->calib_channels = 3; + dev->calib_lines = dev->model->shading_lines; + dpihw = sensor.get_register_hwdpi(dev->settings.xres); + if(dpihw>=2400) + { + dev->calib_lines *= 2; + } + resolution=dpihw; + + unsigned ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres); + + resolution /= ccd_size_divisor; + dev->calib_lines /= ccd_size_divisor; // reducing just because we reduced the resolution + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, + dev->calib_channels, + dev->settings.scan_method); + dev->calib_resolution = resolution; + dev->calib_total_bytes_to_read = 0; + factor = calib_sensor.optical_res / resolution; + dev->calib_pixels = calib_sensor.sensor_pixels / factor; + + /* distance to move to reach white target at high resolution */ + move=0; + if (dev->settings.yres >= 1200) { + move = static_cast<int>(dev->model->y_offset_calib_white); + move = static_cast<int>((move * (dev->motor.base_ydpi/4)) / MM_PER_INCH); + } + DBG (DBG_io, "%s: move=%d steps\n", __func__, move); + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 0; + session.params.starty = move; + session.params.pixels = dev->calib_pixels; + session.params.lines = dev->calib_lines; + session.params.depth = 16; + session.params.channels = dev->calib_channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + try { + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + } catch (...) { + catch_all_exceptions(__func__, [&](){ sanei_genesys_set_motor_power(regs, false); }); + throw; + } + sanei_genesys_set_motor_power(regs, false); + + dev->interface->write_registers(regs); +} + +void CommandSetGl124::wait_for_motor_stop(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + + auto status = scanner_read_status(*dev); + uint8_t val40 = dev->interface->read_register(REG_0x100); + + if (!status.is_motor_enabled && (val40 & REG_0x100_MOTMFLG) == 0) { + return; + } + + do { + dev->interface->sleep_ms(10); + status = scanner_read_status(*dev); + val40 = dev->interface->read_register(REG_0x100); + } while (status.is_motor_enabled ||(val40 & REG_0x100_MOTMFLG)); + dev->interface->sleep_ms(50); +} + +/** @brief set up registers for the actual scan + */ +void CommandSetGl124::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + float move; + int move_dpi; + float start; + + debug_dump(DBG_info, dev->settings); + + /* y (motor) distance to move to reach scanned area */ + move_dpi = dev->motor.base_ydpi/4; + move = static_cast<float>(dev->model->y_offset); + move += static_cast<float>(dev->settings.tl_y); + move = static_cast<float>((move * move_dpi) / MM_PER_INCH); + DBG (DBG_info, "%s: move=%f steps\n", __func__, move); + + if (dev->settings.get_channels() * dev->settings.yres >= 600 && move > 700) { + scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move - 500), + Direction::FORWARD); + move=500; + } + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + /* start */ + start = static_cast<float>(dev->model->x_offset); + start += static_cast<float>(dev->settings.tl_x); + start /= sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres); + start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = static_cast<unsigned>(start); + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = dev->settings.pixels; + session.params.requested_pixels = dev->settings.requested_pixels; + session.params.lines = dev->settings.lines; + session.params.depth = dev->settings.depth; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::NONE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &dev->reg, session); +} + +/** + * Send shading calibration data. The buffer is considered to always hold values + * for all the channels. + */ +void CommandSetGl124::send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + std::uint8_t* data, int size) const +{ + DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size); + uint32_t addr, length, x, factor, segcnt, pixels, i; + uint16_t dpiset,dpihw; + uint8_t *ptr, *src; + + /* logical size of a color as seen by generic code of the frontend */ + length = size / 3; + std::uint32_t strpixel = dev->session.pixel_startx; + std::uint32_t endpixel = dev->session.pixel_endx; + segcnt = dev->reg.get24(REG_SEGCNT); + if(endpixel==0) + { + endpixel=segcnt; + } + + /* compute deletion factor */ + dpiset = dev->reg.get16(REG_DPISET); + dpihw = sensor.get_register_hwdpi(dpiset); + factor=dpihw/dpiset; + DBG( DBG_io2, "%s: factor=%d\n",__func__,factor); + + /* turn pixel value into bytes 2x16 bits words */ + strpixel*=2*2; /* 2 words of 2 bytes */ + endpixel*=2*2; + segcnt*=2*2; + pixels=endpixel-strpixel; + + dev->interface->record_key_value("shading_start_pixel", std::to_string(strpixel)); + dev->interface->record_key_value("shading_pixels", std::to_string(pixels)); + dev->interface->record_key_value("shading_length", std::to_string(length)); + dev->interface->record_key_value("shading_factor", std::to_string(factor)); + dev->interface->record_key_value("shading_segcnt", std::to_string(segcnt)); + dev->interface->record_key_value("shading_segment_count", + std::to_string(dev->session.segment_count)); + + DBG( DBG_io2, "%s: using chunks of %d bytes (%d shading data pixels)\n",__func__,length, length/4); + std::vector<uint8_t> buffer(pixels * dev->session.segment_count, 0); + + /* write actual red data */ + for(i=0;i<3;i++) + { + /* copy data to work buffer and process it */ + /* coefficent destination */ + ptr = buffer.data(); + + /* iterate on both sensor segment */ + for(x=0;x<pixels;x+=4*factor) + { + /* coefficient source */ + src=data+x+strpixel+i*length; + + /* iterate over all the segments */ + switch (dev->session.segment_count) { + case 1: + ptr[0+pixels*0]=src[0+segcnt*0]; + ptr[1+pixels*0]=src[1+segcnt*0]; + ptr[2+pixels*0]=src[2+segcnt*0]; + ptr[3+pixels*0]=src[3+segcnt*0]; + break; + case 2: + ptr[0+pixels*0]=src[0+segcnt*0]; + ptr[1+pixels*0]=src[1+segcnt*0]; + ptr[2+pixels*0]=src[2+segcnt*0]; + ptr[3+pixels*0]=src[3+segcnt*0]; + ptr[0+pixels*1]=src[0+segcnt*1]; + ptr[1+pixels*1]=src[1+segcnt*1]; + ptr[2+pixels*1]=src[2+segcnt*1]; + ptr[3+pixels*1]=src[3+segcnt*1]; + break; + case 4: + ptr[0+pixels*0]=src[0+segcnt*0]; + ptr[1+pixels*0]=src[1+segcnt*0]; + ptr[2+pixels*0]=src[2+segcnt*0]; + ptr[3+pixels*0]=src[3+segcnt*0]; + ptr[0+pixels*1]=src[0+segcnt*2]; + ptr[1+pixels*1]=src[1+segcnt*2]; + ptr[2+pixels*1]=src[2+segcnt*2]; + ptr[3+pixels*1]=src[3+segcnt*2]; + ptr[0+pixels*2]=src[0+segcnt*1]; + ptr[1+pixels*2]=src[1+segcnt*1]; + ptr[2+pixels*2]=src[2+segcnt*1]; + ptr[3+pixels*2]=src[3+segcnt*1]; + ptr[0+pixels*3]=src[0+segcnt*3]; + ptr[1+pixels*3]=src[1+segcnt*3]; + ptr[2+pixels*3]=src[2+segcnt*3]; + ptr[3+pixels*3]=src[3+segcnt*3]; + break; + } + + /* next shading coefficient */ + ptr+=4; + } + uint8_t val = dev->interface->read_register(0xd0+i); + addr = val * 8192 + 0x10000000; + dev->interface->write_ahb(addr, pixels * dev->session.segment_count, buffer.data()); + } +} + + +/** @brief move to calibration area + * This functions moves scanning head to calibration area + * by doing a 600 dpi scan + * @param dev scanner device + */ +static void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) +{ + (void) sensor; + + DBG_HELPER(dbg); + int pixels; + int size; + + unsigned resolution = 600; + unsigned channels = 3; + const auto& move_sensor = sanei_genesys_find_sensor(dev, resolution, channels, + dev->settings.scan_method); + pixels = (move_sensor.sensor_pixels * 600) / move_sensor.optical_res; + + /* initial calibration reg values */ + regs = dev->reg; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = 1; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, move_sensor); + + dev->cmd_set->init_regs_for_scan_session(dev, move_sensor, ®s, session); + + size = pixels * 3; + std::vector<uint8_t> line(size); + + // write registers and scan data + dev->interface->write_registers(regs); + + DBG (DBG_info, "%s: starting line reading\n", __func__); + dev->cmd_set->begin_scan(dev, move_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("move_to_calibration_area"); + scanner_stop_action(*dev); + return; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), size); + + // stop scanning + scanner_stop_action(*dev); + + if (DBG_LEVEL >= DBG_data) + { + sanei_genesys_write_pnm_file("gl124_movetocalarea.pnm", line.data(), 8, 3, pixels, 1); + } +} + +/* this function does the led calibration by scanning one line of the calibration + area below scanner's top on white strip. + +-needs working coarse/gain +*/ +SensorExposure CommandSetGl124::led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int num_pixels; + int total_size; + int resolution; + int dpihw; + int i, j; + int val; + int channels; + int avg[3]; + int turn; + uint16_t exp[3],target; + + /* move to calibration area */ + move_to_calibration_area(dev, sensor, regs); + + /* offset calibration is always done in 16 bit depth color mode */ + channels = 3; + dpihw = sensor.get_register_hwdpi(dev->settings.xres); + resolution = dpihw; + unsigned ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres); + resolution /= ccd_size_divisor; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels, + dev->settings.scan_method); + num_pixels = (calib_sensor.sensor_pixels * resolution) / calib_sensor.optical_res; + + /* initial calibration reg values */ + regs = dev->reg; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + total_size = num_pixels * channels * (session.params.depth / 8) * 1; + std::vector<uint8_t> line(total_size); + + // initial loop values and boundaries + exp[0] = calib_sensor.exposure.red; + exp[1] = calib_sensor.exposure.green; + exp[2] = calib_sensor.exposure.blue; + target=sensor.gain_white_ref*256; + + turn = 0; + + /* no move during led calibration */ + sanei_genesys_set_motor_power(regs, false); + bool acceptable = false; + do + { + // set up exposure + regs.set24(REG_EXPR, exp[0]); + regs.set24(REG_EXPG, exp[1]); + regs.set24(REG_EXPB, exp[2]); + + // write registers and scan data + dev->interface->write_registers(regs); + + DBG(DBG_info, "%s: starting line reading\n", __func__); + begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("led_calibration"); + scanner_stop_action(*dev); + return calib_sensor.exposure; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + // stop scanning + scanner_stop_action(*dev); + + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl124_led_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, line.data(), session.params.depth, channels, num_pixels, + 1); + } + + /* compute average */ + for (j = 0; j < channels; j++) + { + avg[j] = 0; + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + line[i * 2 + j * 2 * num_pixels + 1] * 256 + + line[i * 2 + j * 2 * num_pixels]; + else + val = + line[i * 2 * channels + 2 * j + 1] * 256 + + line[i * 2 * channels + 2 * j]; + avg[j] += val; + } + + avg[j] /= num_pixels; + } + + DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); + + /* check if exposure gives average within the boundaries */ + acceptable = true; + for(i=0;i<3;i++) + { + /* we accept +- 2% delta from target */ + if(abs(avg[i]-target)>target/50) + { + float prev_weight = 0.5; + exp[i] = exp[i] * prev_weight + ((exp[i] * target) / avg[i]) * (1 - prev_weight); + acceptable = false; + } + } + + turn++; + } + while (!acceptable && turn < 100); + + DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); + + // set these values as final ones for scan + dev->reg.set24(REG_EXPR, exp[0]); + dev->reg.set24(REG_EXPG, exp[1]); + dev->reg.set24(REG_EXPB, exp[2]); + + return { exp[0], exp[1], exp[2] }; +} + +/** + * average dark pixels of a 8 bits scan + */ +static int +dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, + unsigned int channels, unsigned int black) +{ + unsigned int i, j, k, average, count; + unsigned int avg[3]; + uint8_t val; + + /* computes average value on black margin */ + for (k = 0; k < channels; k++) + { + avg[k] = 0; + count = 0; + for (i = 0; i < lines; i++) + { + for (j = 0; j < black; j++) + { + val = data[i * channels * pixels + j + k]; + avg[k] += val; + count++; + } + } + if (count) + avg[k] /= count; + DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); + } + average = 0; + for (i = 0; i < channels; i++) + average += avg[i]; + average /= channels; + DBG(DBG_info, "%s: average = %d\n", __func__, average); + return average; +} + + +void CommandSetGl124::offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + unsigned channels; + int pass = 0, avg, total_size; + int topavg, bottomavg, lines; + int top, bottom, black_pixels, pixels; + + // no gain nor offset for TI AFE + uint8_t reg0a = dev->interface->read_register(REG_0x0A); + if (((reg0a & REG_0x0A_SIFSEL) >> REG_0x0AS_SIFSEL) == 3) { + return; + } + + /* offset calibration is always done in color mode */ + channels = 3; + dev->calib_pixels = sensor.sensor_pixels; + lines=1; + pixels = (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res; + black_pixels = (sensor.black_pixels * sensor.optical_res) / sensor.optical_res; + DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = sensor.optical_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + sanei_genesys_set_motor_power(regs, false); + + /* allocate memory for scans */ + total_size = pixels * channels * lines * (session.params.depth / 8); + + std::vector<uint8_t> first_line(total_size); + std::vector<uint8_t> second_line(total_size); + + /* init gain */ + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + + /* scan with no move */ + bottom = 10; + dev->frontend.set_offset(0, bottom); + dev->frontend.set_offset(1, bottom); + dev->frontend.set_offset(2, bottom); + + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting first line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("offset_calibration"); + return; + } + + sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size); + if (DBG_LEVEL >= DBG_data) + { + char title[30]; + std::snprintf(title, 30, "gl124_offset%03d.pnm", bottom); + sanei_genesys_write_pnm_file(title, first_line.data(), session.params.depth, + channels, pixels, lines); + } + + bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); + + /* now top value */ + top = 255; + dev->frontend.set_offset(0, top); + dev->frontend.set_offset(1, top); + dev->frontend.set_offset(2, top); + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + + topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); + + /* loop until acceptable level */ + while ((pass < 32) && (top - bottom > 1)) + { + pass++; + + /* settings for new scan */ + dev->frontend.set_offset(0, (top + bottom) / 2); + dev->frontend.set_offset(1, (top + bottom) / 2); + dev->frontend.set_offset(2, (top + bottom) / 2); + + // scan with no move + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) + { + char title[30]; + std::snprintf(title, 30, "gl124_offset%03d.pnm", dev->frontend.get_offset(1)); + sanei_genesys_write_pnm_file(title, second_line.data(), session.params.depth, + channels, pixels, lines); + } + + avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); + + /* compute new boundaries */ + if (topavg == avg) + { + topavg = avg; + top = dev->frontend.get_offset(1); + } + else + { + bottomavg = avg; + bottom = dev->frontend.get_offset(1); + } + } + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); +} + + +/* alternative coarse gain calibration + this on uses the settings from offset_calibration and + uses only one scanline + */ +/* + with offset and coarse calibration we only want to get our input range into + a reasonable shape. the fine calibration of the upper and lower bounds will + be done with shading. + */ +void CommandSetGl124::coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const +{ + DBG_HELPER_ARGS(dbg, "dpi = %d", dpi); + int pixels; + int total_size; + int i, j, channels; + int max[3]; + float gain[3],coeff; + int val, code, lines; + + // no gain nor offset for TI AFE + uint8_t reg0a = dev->interface->read_register(REG_0x0A); + if (((reg0a & REG_0x0A_SIFSEL) >> REG_0x0AS_SIFSEL) == 3) { + return; + } + + /* coarse gain calibration is always done in color mode */ + channels = 3; + + if(dev->settings.xres<sensor.optical_res) + { + coeff = 0.9f; + } else { + coeff = 1.0f; + } + lines=10; + pixels = (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res; + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = sensor.optical_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + try { + init_regs_for_scan_session(dev, sensor, ®s, session); + } catch (...) { + catch_all_exceptions(__func__, [&](){ sanei_genesys_set_motor_power(regs, false); }); + throw; + } + + sanei_genesys_set_motor_power(regs, false); + + dev->interface->write_registers(regs); + + total_size = pixels * channels * (16 / session.params.depth) * lines; + + std::vector<uint8_t> line(total_size); + + set_fe(dev, sensor, AFE_SET); + begin_scan(dev, sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("coarse_gain_calibration"); + scanner_stop_action(*dev); + move_back_home(dev, true); + return; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl124_gain.pnm", line.data(), session.params.depth, + channels, pixels, lines); + } + + /* average value on each channel */ + for (j = 0; j < channels; j++) + { + max[j] = 0; + for (i = pixels/4; i < (pixels*3/4); i++) + { + if (dev->model->is_cis) { + val = line[i + j * pixels]; + } else { + val = line[i * channels + j]; + } + + max[j] += val; + } + max[j] = max[j] / (pixels/2); + + gain[j] = (static_cast<float>(sensor.gain_white_ref) * coeff) / max[j]; + + /* turn logical gain value into gain code, checking for overflow */ + code = static_cast<int>(283 - 208 / gain[j]); + if (code > 255) + code = 255; + else if (code < 0) + code = 0; + dev->frontend.set_gain(j, code); + + DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], + gain[j], dev->frontend.get_gain(j)); + } + + if (dev->model->is_cis) { + uint8_t gain0 = dev->frontend.get_gain(0); + if (gain0 > dev->frontend.get_gain(1)) { + gain0 = dev->frontend.get_gain(1); + } + if (gain0 > dev->frontend.get_gain(2)) { + gain0 = dev->frontend.get_gain(2); + } + dev->frontend.set_gain(0, gain0); + dev->frontend.set_gain(1, gain0); + dev->frontend.set_gain(2, gain0); + } + + if (channels == 1) { + dev->frontend.set_gain(0, dev->frontend.get_gain(1)); + dev->frontend.set_gain(2, dev->frontend.get_gain(1)); + } + + scanner_stop_action(*dev); + + move_back_home(dev, true); +} + +// wait for lamp warmup by scanning the same line until difference +// between 2 scans is below a threshold +void CommandSetGl124::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, int* channels, + int* total_size) const +{ + DBG_HELPER(dbg); + int num_pixels; + + *channels=3; + + *reg = dev->reg; + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = dev->motor.base_ydpi; + session.params.startx = sensor.sensor_pixels / 4; + session.params.starty = 0; + session.params.pixels = sensor.sensor_pixels / 2; + session.params.lines = 1; + session.params.depth = 8; + session.params.channels = *channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, reg, session); + + num_pixels = session.output_pixels; + + *total_size = num_pixels * 3 * 1; /* colors * bytes_per_color * scan lines */ + + sanei_genesys_set_motor_power(*reg, false); + dev->interface->write_registers(*reg); +} + +/** @brief default GPIO values + * set up GPIO/GPOE for idle state + * @param dev device to set up + */ +static void gl124_init_gpio(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + int idx; + + /* per model GPIO layout */ + if (dev->model->model_id == ModelId::CANON_LIDE_110) { + idx = 0; + } else if (dev->model->model_id == ModelId::CANON_LIDE_120) { + idx = 2; + } + else + { /* canon LiDE 210 and 220 case */ + idx = 1; + } + + dev->interface->write_register(REG_0x31, gpios[idx].r31); + dev->interface->write_register(REG_0x32, gpios[idx].r32); + dev->interface->write_register(REG_0x33, gpios[idx].r33); + dev->interface->write_register(REG_0x34, gpios[idx].r34); + dev->interface->write_register(REG_0x35, gpios[idx].r35); + dev->interface->write_register(REG_0x36, gpios[idx].r36); + dev->interface->write_register(REG_0x38, gpios[idx].r38); +} + +/** + * set memory layout by filling values in dedicated registers + */ +static void gl124_init_memory_layout(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + int idx = 0; + + /* point to per model memory layout */ + if (dev->model->model_id == ModelId::CANON_LIDE_110 || + dev->model->model_id == ModelId::CANON_LIDE_120) + { + idx = 0; + } + else + { /* canon LiDE 210 and 220 case */ + idx = 1; + } + + /* setup base address for shading data. */ + /* values must be multiplied by 8192=0x4000 to give address on AHB */ + /* R-Channel shading bank0 address setting for CIS */ + dev->interface->write_register(0xd0, layouts[idx].rd0); + /* G-Channel shading bank0 address setting for CIS */ + dev->interface->write_register(0xd1, layouts[idx].rd1); + /* B-Channel shading bank0 address setting for CIS */ + dev->interface->write_register(0xd2, layouts[idx].rd2); + + /* setup base address for scanned data. */ + /* values must be multiplied by 1024*2=0x0800 to give address on AHB */ + /* R-Channel ODD image buffer 0x0124->0x92000 */ + /* size for each buffer is 0x16d*1k word */ + dev->interface->write_register(0xe0, layouts[idx].re0); + dev->interface->write_register(0xe1, layouts[idx].re1); + /* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/ + dev->interface->write_register(0xe2, layouts[idx].re2); + dev->interface->write_register(0xe3, layouts[idx].re3); + + /* R-Channel EVEN image buffer 0x0292 */ + dev->interface->write_register(0xe4, layouts[idx].re4); + dev->interface->write_register(0xe5, layouts[idx].re5); + /* R-Channel EVEN image buffer end-address 0x03ff*/ + dev->interface->write_register(0xe6, layouts[idx].re6); + dev->interface->write_register(0xe7, layouts[idx].re7); + + /* same for green, since CIS, same addresses */ + dev->interface->write_register(0xe8, layouts[idx].re0); + dev->interface->write_register(0xe9, layouts[idx].re1); + dev->interface->write_register(0xea, layouts[idx].re2); + dev->interface->write_register(0xeb, layouts[idx].re3); + dev->interface->write_register(0xec, layouts[idx].re4); + dev->interface->write_register(0xed, layouts[idx].re5); + dev->interface->write_register(0xee, layouts[idx].re6); + dev->interface->write_register(0xef, layouts[idx].re7); + +/* same for blue, since CIS, same addresses */ + dev->interface->write_register(0xf0, layouts[idx].re0); + dev->interface->write_register(0xf1, layouts[idx].re1); + dev->interface->write_register(0xf2, layouts[idx].re2); + dev->interface->write_register(0xf3, layouts[idx].re3); + dev->interface->write_register(0xf4, layouts[idx].re4); + dev->interface->write_register(0xf5, layouts[idx].re5); + dev->interface->write_register(0xf6, layouts[idx].re6); + dev->interface->write_register(0xf7, layouts[idx].re7); +} + +/** + * initialize backend and ASIC : registers, motor tables, and gamma tables + * then ensure scanner's head is at home + */ +void CommandSetGl124::init(Genesys_Device* dev) const +{ + DBG_INIT (); + DBG_HELPER(dbg); + + sanei_genesys_asic_init(dev, 0); +} + + +/* * + * initialize ASIC from power on condition + */ +void CommandSetGl124::asic_boot(Genesys_Device* dev, bool cold) const +{ + DBG_HELPER(dbg); + + // reset ASIC in case of cold boot + if (cold) { + dev->interface->write_register(0x0e, 0x01); + dev->interface->write_register(0x0e, 0x00); + } + + // enable GPOE 17 + dev->interface->write_register(0x36, 0x01); + + // set GPIO 17 + uint8_t val = dev->interface->read_register(0x33); + val |= 0x01; + dev->interface->write_register(0x33, val); + + // test CHKVER + val = dev->interface->read_register(REG_0x100); + if (val & REG_0x100_CHKVER) { + val = dev->interface->read_register(0x00); + DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); + } + + /* Set default values for registers */ + gl124_init_registers (dev); + + // Write initial registers + dev->interface->write_registers(dev->reg); + + // tune reg 0B + dev->interface->write_register(REG_0x0B, REG_0x0B_30MHZ | REG_0x0B_ENBDRAM | REG_0x0B_64M); + dev->reg.remove_reg(0x0b); + + //set up end access + dev->interface->write_0x8c(0x10, 0x0b); + dev->interface->write_0x8c(0x13, 0x0e); + + /* CIS_LINE */ + dev->reg.init_reg(0x08, REG_0x08_CIS_LINE); + dev->interface->write_register(0x08, dev->reg.find_reg(0x08).value); + + // setup gpio + gl124_init_gpio(dev); + + // setup internal memory layout + gl124_init_memory_layout(dev); +} + + +void CommandSetGl124::update_hardware_sensors(Genesys_Scanner* s) const +{ + /* do what is needed to get a new set of events, but try to not loose + any of them. + */ + DBG_HELPER(dbg); + uint8_t val = s->dev->interface->read_register(REG_0x31); + + /* TODO : for the next scanner special case, + * add another per scanner button profile struct to avoid growing + * hard-coded button mapping here. + */ + if ((s->dev->model->gpio_id == GpioId::CANON_LIDE_110) || + (s->dev->model->gpio_id == GpioId::CANON_LIDE_120)) + { + s->buttons[BUTTON_SCAN_SW].write((val & 0x01) == 0); + s->buttons[BUTTON_FILE_SW].write((val & 0x08) == 0); + s->buttons[BUTTON_EMAIL_SW].write((val & 0x04) == 0); + s->buttons[BUTTON_COPY_SW].write((val & 0x02) == 0); + } + else + { /* LiDE 210 case */ + s->buttons[BUTTON_EXTRA_SW].write((val & 0x01) == 0); + s->buttons[BUTTON_SCAN_SW].write((val & 0x02) == 0); + s->buttons[BUTTON_COPY_SW].write((val & 0x04) == 0); + s->buttons[BUTTON_EMAIL_SW].write((val & 0x08) == 0); + s->buttons[BUTTON_FILE_SW].write((val & 0x10) == 0); + } +} + +void CommandSetGl124::update_home_sensor_gpio(Genesys_Device& dev) const +{ + DBG_HELPER(dbg); + + std::uint8_t val = dev.interface->read_register(REG_0x32); + val &= ~REG_0x32_GPIO10; + dev.interface->write_register(REG_0x32, val); +} + +bool CommandSetGl124::needs_home_before_init_regs_for_scan(Genesys_Device* dev) const +{ + (void) dev; + return true; +} + +void CommandSetGl124::send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + sanei_genesys_send_gamma_table(dev, sensor); +} + +void CommandSetGl124::load_document(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl124::detect_document_end(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl124::eject_document(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl124::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const +{ + (void) dev; + (void) sensor; + (void) forward; + (void) black; + throw SaneException("not implemented"); +} + +void CommandSetGl124::move_to_ta(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +std::unique_ptr<CommandSet> create_gl124_cmd_set() +{ + return std::unique_ptr<CommandSet>(new CommandSetGl124{}); +} + +} // namespace gl124 +} // namespace genesys diff --git a/backend/genesys/gl124.h b/backend/genesys/gl124.h new file mode 100644 index 0000000..cdf8faf --- /dev/null +++ b/backend/genesys/gl124.h @@ -0,0 +1,205 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2010-2016 Stéphane Voltz <stef.dev@free.fr> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL124_H +#define BACKEND_GENESYS_GL124_H + +#include "genesys.h" +#include "command_set.h" + +namespace genesys { +namespace gl124 { + +typedef struct +{ + uint8_t r31; + uint8_t r32; + uint8_t r33; + uint8_t r34; + uint8_t r35; + uint8_t r36; + uint8_t r38; +} Gpio_layout; + +/** @brief gpio layout + * describes initial gpio settings for a given model + * registers 0x31 to 0x38 + */ +static Gpio_layout gpios[]={ + /* LiDE 110 */ + { /* 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38 */ + 0x9f, 0x59, 0x01, 0x80, 0x5f, 0x01, 0x00 + }, + /* LiDE 210 */ + { + 0x9f, 0x59, 0x01, 0x80, 0x5f, 0x01, 0x00 + }, + /* LiDE 120 */ + { + 0x9f, 0x53, 0x01, 0x80, 0x5f, 0x01, 0x00 + }, +}; + +typedef struct +{ + uint8_t rd0; + uint8_t rd1; + uint8_t rd2; + uint8_t re0; + uint8_t re1; + uint8_t re2; + uint8_t re3; + uint8_t re4; + uint8_t re5; + uint8_t re6; + uint8_t re7; +} Memory_layout; + +static Memory_layout layouts[]={ + /* LIDE 110, 120 */ + { /* 0xd0 0xd1 0xd2 */ + 0x0a, 0x15, 0x20, + /* 0xe0 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 */ + 0x00, 0xac, 0x08, 0x55, 0x08, 0x56, 0x0f, 0xff + }, + /* LIDE 210, 220 */ + { + 0x0a, 0x1f, 0x34, + 0x01, 0x24, 0x08, 0x91, 0x08, 0x92, 0x0f, 0xff + } +}; + +static void gl124_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, int steps); + +class CommandSetGl124 : public CommandSet +{ +public: + ~CommandSetGl124() override = default; + + bool needs_home_before_init_regs_for_scan(Genesys_Device* dev) const override; + + void init(Genesys_Device* dev) const override; + + void init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const override; + + void init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const override; + + void set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const override; + void set_powersaving(Genesys_Device* dev, int delay) const override; + void save_power(Genesys_Device* dev, bool enable) const override; + + void begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, bool start_motor) const override; + + void end_scan(Genesys_Device* dev, Genesys_Register_Set* regs, bool check_stop) const override; + + void send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void search_start_position(Genesys_Device* dev) const override; + + void offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const override; + + SensorExposure led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void wait_for_motor_stop(Genesys_Device* dev) const override; + + void move_back_home(Genesys_Device* dev, bool wait_until_home) const override; + + void update_hardware_sensors(struct Genesys_Scanner* s) const override; + + bool needs_update_home_sensor_gpio() const override { return true; } + + void update_home_sensor_gpio(Genesys_Device& dev) const override; + + void load_document(Genesys_Device* dev) const override; + + void detect_document_end(Genesys_Device* dev) const override; + + void eject_document(Genesys_Device* dev) const override; + + void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const override; + + void move_to_ta(Genesys_Device* dev) const override; + + void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data, + int size) const override; + + ScanSession calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const override; + + void asic_boot(Genesys_Device* dev, bool cold) const override; +}; + +enum SlopeTable +{ + SCAN_TABLE = 0, // table 1 at 0x4000 + BACKTRACK_TABLE = 1, // table 2 at 0x4800 + STOP_TABLE = 2, // table 3 at 0x5000 + FAST_TABLE = 3, // table 4 at 0x5800 + HOME_TABLE = 4, // table 5 at 0x6000 +}; + +} // namespace gl124 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL124_H diff --git a/backend/genesys/gl124_registers.h b/backend/genesys/gl124_registers.h new file mode 100644 index 0000000..9b42084 --- /dev/null +++ b/backend/genesys/gl124_registers.h @@ -0,0 +1,316 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL124_REGISTERS_H +#define BACKEND_GENESYS_GL124_REGISTERS_H + +#include <cstdint> + +namespace genesys { +namespace gl124 { + +using RegAddr = std::uint16_t; +using RegMask = std::uint8_t; +using RegShift = unsigned; + +static constexpr RegAddr REG_0x01 = 0x01; +static constexpr RegMask REG_0x01_CISSET = 0x80; +static constexpr RegMask REG_0x01_DOGENB = 0x40; +static constexpr RegMask REG_0x01_DVDSET = 0x20; +static constexpr RegMask REG_0x01_STAGGER = 0x10; +static constexpr RegMask REG_0x01_COMPENB = 0x08; +static constexpr RegMask REG_0x01_TRUEGRAY = 0x04; +static constexpr RegMask REG_0x01_SHDAREA = 0x02; +static constexpr RegMask REG_0x01_SCAN = 0x01; + +static constexpr RegAddr REG_0x02 = 0x02; +static constexpr RegMask REG_0x02_NOTHOME = 0x80; +static constexpr RegMask REG_0x02_ACDCDIS = 0x40; +static constexpr RegMask REG_0x02_AGOHOME = 0x20; +static constexpr RegMask REG_0x02_MTRPWR = 0x10; +static constexpr RegMask REG_0x02_FASTFED = 0x08; +static constexpr RegMask REG_0x02_MTRREV = 0x04; +static constexpr RegMask REG_0x02_HOMENEG = 0x02; +static constexpr RegMask REG_0x02_LONGCURV = 0x01; + +static constexpr RegAddr REG_0x03 = 0x03; +static constexpr RegMask REG_0x03_LAMPDOG = 0x80; +static constexpr RegMask REG_0x03_AVEENB = 0x40; +static constexpr RegMask REG_0x03_XPASEL = 0x20; +static constexpr RegMask REG_0x03_LAMPPWR = 0x10; +static constexpr RegMask REG_0x03_LAMPTIM = 0x0f; + +static constexpr RegAddr REG_0x04 = 0x04; +static constexpr RegMask REG_0x04_LINEART = 0x80; +static constexpr RegMask REG_0x04_BITSET = 0x40; +static constexpr RegMask REG_0x04_FILTER = 0x30; +static constexpr RegMask REG_0x04_AFEMOD = 0x07; + +static constexpr RegAddr REG_0x05 = 0x05; +static constexpr RegMask REG_0x05_DPIHW = 0xc0; +static constexpr RegMask REG_0x05_DPIHW_600 = 0x00; +static constexpr RegMask REG_0x05_DPIHW_1200 = 0x40; +static constexpr RegMask REG_0x05_DPIHW_2400 = 0x80; +static constexpr RegMask REG_0x05_DPIHW_4800 = 0xc0; +static constexpr RegMask REG_0x05_MTLLAMP = 0x30; +static constexpr RegMask REG_0x05_GMMENB = 0x08; +static constexpr RegMask REG_0x05_ENB20M = 0x04; +static constexpr RegMask REG_0x05_MTLBASE = 0x03; + +static constexpr RegAddr REG_0x06 = 0x06; +static constexpr RegMask REG_0x06_SCANMOD = 0xe0; +static constexpr RegMask REG_0x06S_SCANMOD = 5; +static constexpr RegMask REG_0x06_PWRBIT = 0x10; +static constexpr RegMask REG_0x06_GAIN4 = 0x08; +static constexpr RegMask REG_0x06_OPTEST = 0x07; + +static constexpr RegMask REG_0x07_LAMPSIM = 0x80; + +static constexpr RegMask REG_0x08_DRAM2X = 0x80; +static constexpr RegMask REG_0x08_MPENB = 0x20; +static constexpr RegMask REG_0x08_CIS_LINE = 0x10; +static constexpr RegMask REG_0x08_IR2_ENB = 0x08; +static constexpr RegMask REG_0x08_IR1_ENB = 0x04; +static constexpr RegMask REG_0x08_ENB24M = 0x01; + +static constexpr RegMask REG_0x09_MCNTSET = 0xc0; +static constexpr RegMask REG_0x09_EVEN1ST = 0x20; +static constexpr RegMask REG_0x09_BLINE1ST = 0x10; +static constexpr RegMask REG_0x09_BACKSCAN = 0x08; +static constexpr RegMask REG_0x09_OUTINV = 0x04; +static constexpr RegMask REG_0x09_SHORTTG = 0x02; + +static constexpr RegShift REG_0x09S_MCNTSET = 6; +static constexpr RegShift REG_0x09S_CLKSET = 4; + +static constexpr RegAddr REG_0x0A = 0x0a; +static constexpr RegMask REG_0x0A_SIFSEL = 0xc0; +static constexpr RegShift REG_0x0AS_SIFSEL = 6; +static constexpr RegMask REG_0x0A_SHEETFED = 0x20; +static constexpr RegMask REG_0x0A_LPWMEN = 0x10; + +static constexpr RegAddr REG_0x0B = 0x0b; +static constexpr RegMask REG_0x0B_DRAMSEL = 0x07; +static constexpr RegMask REG_0x0B_16M = 0x01; +static constexpr RegMask REG_0x0B_64M = 0x02; +static constexpr RegMask REG_0x0B_128M = 0x03; +static constexpr RegMask REG_0x0B_256M = 0x04; +static constexpr RegMask REG_0x0B_512M = 0x05; +static constexpr RegMask REG_0x0B_1G = 0x06; +static constexpr RegMask REG_0x0B_ENBDRAM = 0x08; +static constexpr RegMask REG_0x0B_RFHDIS = 0x10; +static constexpr RegMask REG_0x0B_CLKSET = 0xe0; +static constexpr RegMask REG_0x0B_24MHZ = 0x00; +static constexpr RegMask REG_0x0B_30MHZ = 0x20; +static constexpr RegMask REG_0x0B_40MHZ = 0x40; +static constexpr RegMask REG_0x0B_48MHZ = 0x60; +static constexpr RegMask REG_0x0B_60MHZ = 0x80; + +static constexpr RegAddr REG_0x0D = 0x0d; +static constexpr RegMask REG_0x0D_MTRP_RDY = 0x80; +static constexpr RegMask REG_0x0D_FULLSTP = 0x10; +static constexpr RegMask REG_0x0D_CLRMCNT = 0x04; +static constexpr RegMask REG_0x0D_CLRDOCJM = 0x02; +static constexpr RegMask REG_0x0D_CLRLNCNT = 0x01; + +static constexpr RegAddr REG_0x0F = 0x0f; + +static constexpr RegMask REG_0x16_CTRLHI = 0x80; +static constexpr RegMask REG_0x16_TOSHIBA = 0x40; +static constexpr RegMask REG_0x16_TGINV = 0x20; +static constexpr RegMask REG_0x16_CK1INV = 0x10; +static constexpr RegMask REG_0x16_CK2INV = 0x08; +static constexpr RegMask REG_0x16_CTRLINV = 0x04; +static constexpr RegMask REG_0x16_CKDIS = 0x02; +static constexpr RegMask REG_0x16_CTRLDIS = 0x01; + +static constexpr RegMask REG_0x17_TGMODE = 0xc0; +static constexpr RegMask REG_0x17_SNRSYN = 0x0f; + +static constexpr RegAddr REG_0x18 = 0x18; +static constexpr RegMask REG_0x18_CNSET = 0x80; +static constexpr RegMask REG_0x18_DCKSEL = 0x60; +static constexpr RegMask REG_0x18_CKTOGGLE = 0x10; +static constexpr RegMask REG_0x18_CKDELAY = 0x0c; +static constexpr RegMask REG_0x18_CKSEL = 0x03; + +static constexpr RegMask REG_0x1A_SW2SET = 0x80; +static constexpr RegMask REG_0x1A_SW1SET = 0x40; +static constexpr RegMask REG_0x1A_MANUAL3 = 0x02; +static constexpr RegMask REG_0x1A_MANUAL1 = 0x01; +static constexpr RegMask REG_0x1A_CK4INV = 0x08; +static constexpr RegMask REG_0x1A_CK3INV = 0x04; +static constexpr RegMask REG_0x1A_LINECLP = 0x02; + +static constexpr RegMask REG_0x1C_TBTIME = 0x07; + +static constexpr RegAddr REG_0x1D = 0x1d; +static constexpr RegMask REG_0x1D_CK4LOW = 0x80; +static constexpr RegMask REG_0x1D_CK3LOW = 0x40; +static constexpr RegMask REG_0x1D_CK1LOW = 0x20; +static constexpr RegMask REG_0x1D_LINESEL = 0x1f; +static constexpr RegShift REG_0x1DS_LINESEL = 0; + +static constexpr RegAddr REG_0x1E = 0x1e; +static constexpr RegMask REG_0x1E_WDTIME = 0xf0; +static constexpr RegShift REG_0x1ES_WDTIME = 4; + +static constexpr RegAddr REG_0x30 = 0x30; +static constexpr RegAddr REG_0x31 = 0x31; +static constexpr RegAddr REG_0x32 = 0x32; +static constexpr RegMask REG_0x32_GPIO16 = 0x80; +static constexpr RegMask REG_0x32_GPIO15 = 0x40; +static constexpr RegMask REG_0x32_GPIO14 = 0x20; +static constexpr RegMask REG_0x32_GPIO13 = 0x10; +static constexpr RegMask REG_0x32_GPIO12 = 0x08; +static constexpr RegMask REG_0x32_GPIO11 = 0x04; +static constexpr RegMask REG_0x32_GPIO10 = 0x02; +static constexpr RegMask REG_0x32_GPIO9 = 0x01; +static constexpr RegAddr REG_0x33 = 0x33; +static constexpr RegAddr REG_0x34 = 0x34; +static constexpr RegAddr REG_0x35 = 0x35; +static constexpr RegAddr REG_0x36 = 0x36; +static constexpr RegAddr REG_0x37 = 0x37; +static constexpr RegAddr REG_0x38 = 0x38; +static constexpr RegAddr REG_0x39 = 0x39; + +static constexpr RegAddr REG_0x60 = 0x60; +static constexpr RegMask REG_0x60_LED4TG = 0x80; +static constexpr RegMask REG_0x60_YENB = 0x40; +static constexpr RegMask REG_0x60_YBIT = 0x20; +static constexpr RegMask REG_0x60_ACYNCNRLC = 0x10; +static constexpr RegMask REG_0x60_ENOFFSET = 0x08; +static constexpr RegMask REG_0x60_LEDADD = 0x04; +static constexpr RegMask REG_0x60_CK4ADC = 0x02; +static constexpr RegMask REG_0x60_AUTOCONF = 0x01; + +static constexpr RegAddr REG_0x80 = 0x80; +static constexpr RegAddr REG_0x81 = 0x81; + +static constexpr RegAddr REG_0xA0 = 0xa0; +static constexpr RegMask REG_0xA0_FSTPSEL = 0x38; +static constexpr RegShift REG_0xA0S_FSTPSEL = 3; +static constexpr RegMask REG_0xA0_STEPSEL = 0x07; +static constexpr RegShift REG_0xA0S_STEPSEL = 0; + +static constexpr RegAddr REG_0xA1 = 0xa1; +static constexpr RegAddr REG_0xA2 = 0xa2; +static constexpr RegAddr REG_0xA3 = 0xa3; +static constexpr RegAddr REG_0xA4 = 0xa4; +static constexpr RegAddr REG_0xA5 = 0xa5; +static constexpr RegAddr REG_0xA6 = 0xa6; +static constexpr RegAddr REG_0xA7 = 0xa7; +static constexpr RegAddr REG_0xA8 = 0xa8; +static constexpr RegAddr REG_0xA9 = 0xa9; +static constexpr RegAddr REG_0xAA = 0xaa; +static constexpr RegAddr REG_0xAB = 0xab; +static constexpr RegAddr REG_0xAC = 0xac; +static constexpr RegAddr REG_0xAD = 0xad; +static constexpr RegAddr REG_0xAE = 0xae; +static constexpr RegAddr REG_0xAF = 0xaf; +static constexpr RegAddr REG_0xB0 = 0xb0; +static constexpr RegAddr REG_0xB1 = 0xb1; + +static constexpr RegAddr REG_0xB2 = 0xb2; +static constexpr RegMask REG_0xB2_Z1MOD = 0x1f; +static constexpr RegAddr REG_0xB3 = 0xb3; +static constexpr RegMask REG_0xB3_Z1MOD = 0xff; +static constexpr RegAddr REG_0xB4 = 0xb4; +static constexpr RegMask REG_0xB4_Z1MOD = 0xff; + +static constexpr RegAddr REG_0xB5 = 0xb5; +static constexpr RegMask REG_0xB5_Z2MOD = 0x1f; +static constexpr RegAddr REG_0xB6 = 0xb6; +static constexpr RegMask REG_0xB6_Z2MOD = 0xff; +static constexpr RegAddr REG_0xB7 = 0xb7; +static constexpr RegMask REG_0xB7_Z2MOD = 0xff; + +static constexpr RegAddr REG_0x100 = 0x100; +static constexpr RegMask REG_0x100_DOCSNR = 0x80; +static constexpr RegMask REG_0x100_ADFSNR = 0x40; +static constexpr RegMask REG_0x100_COVERSNR = 0x20; +static constexpr RegMask REG_0x100_CHKVER = 0x10; +static constexpr RegMask REG_0x100_DOCJAM = 0x08; +static constexpr RegMask REG_0x100_HISPDFLG = 0x04; +static constexpr RegMask REG_0x100_MOTMFLG = 0x02; +static constexpr RegMask REG_0x100_DATAENB = 0x01; + +static constexpr RegAddr REG_0x114 = 0x114; +static constexpr RegAddr REG_0x115 = 0x115; + +static constexpr RegAddr REG_LINCNT = 0x25; +static constexpr RegAddr REG_MAXWD = 0x28; +static constexpr RegAddr REG_DPISET = 0x2c; +static constexpr RegAddr REG_FEEDL = 0x3d; +static constexpr RegAddr REG_CK1MAP = 0x74; +static constexpr RegAddr REG_CK3MAP = 0x77; +static constexpr RegAddr REG_CK4MAP = 0x7a; +static constexpr RegAddr REG_LPERIOD = 0x7d; +static constexpr RegAddr REG_DUMMY = 0x80; +static constexpr RegAddr REG_STRPIXEL = 0x82; +static constexpr RegAddr REG_ENDPIXEL = 0x85; +static constexpr RegAddr REG_EXPDMY = 0x88; +static constexpr RegAddr REG_EXPR = 0x8a; +static constexpr RegAddr REG_EXPG = 0x8d; +static constexpr RegAddr REG_EXPB = 0x90; +static constexpr RegAddr REG_SEGCNT = 0x93; +static constexpr RegAddr REG_TG0CNT = 0x96; +static constexpr RegAddr REG_SCANFED = 0xa2; +static constexpr RegAddr REG_STEPNO = 0xa4; +static constexpr RegAddr REG_FWDSTEP = 0xa6; +static constexpr RegAddr REG_BWDSTEP = 0xa8; +static constexpr RegAddr REG_FASTNO = 0xaa; +static constexpr RegAddr REG_FSHDEC = 0xac; +static constexpr RegAddr REG_FMOVNO = 0xae; +static constexpr RegAddr REG_FMOVDEC = 0xb0; +static constexpr RegAddr REG_Z1MOD = 0xb2; +static constexpr RegAddr REG_Z2MOD = 0xb5; + +static constexpr RegAddr REG_TRUER = 0x110; +static constexpr RegAddr REG_TRUEG = 0x111; +static constexpr RegAddr REG_TRUEB = 0x112; + +} // namespace gl124 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL843_REGISTERS_H diff --git a/backend/genesys/gl646.cpp b/backend/genesys/gl646.cpp new file mode 100644 index 0000000..04ee85e --- /dev/null +++ b/backend/genesys/gl646.cpp @@ -0,0 +1,3436 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2003 Oliver Rauch + Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de> + Copyright (C) 2004 Gerhard Jaeger <gerhard@gjaeger.de> + Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> + Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> + Copyright (C) 2007 Luke <iceyfor@gmail.com> + Copyright (C) 2011 Alexey Osipov <simba@lerlan.ru> for HP2400 description + and tuning + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "gl646.h" +#include "gl646_registers.h" +#include "test_settings.h" + +#include <vector> + +namespace genesys { +namespace gl646 { + +namespace { +constexpr unsigned CALIBRATION_LINES = 10; +} // namespace + +static void gl646_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, + int steps); + +/** + * reads value from gpio endpoint + */ +static void gl646_gpio_read(IUsbDevice& usb_dev, uint8_t* value) +{ + DBG_HELPER(dbg); + usb_dev.control_msg(REQUEST_TYPE_IN, REQUEST_REGISTER, GPIO_READ, INDEX, 1, value); +} + +/** + * writes the given value to gpio endpoint + */ +static void gl646_gpio_write(IUsbDevice& usb_dev, uint8_t value) +{ + DBG_HELPER_ARGS(dbg, "(0x%02x)", value); + usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, GPIO_WRITE, INDEX, 1, &value); +} + +/** + * writes the given value to gpio output enable endpoint + */ +static void gl646_gpio_output_enable(IUsbDevice& usb_dev, uint8_t value) +{ + DBG_HELPER_ARGS(dbg, "(0x%02x)", value); + usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, GPIO_OUTPUT_ENABLE, INDEX, 1, &value); +} + +/** + * stop scanner's motor + * @param dev scanner's device + */ +static void gl646_stop_motor(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + dev->interface->write_register(0x0f, 0x00); +} + +/** + * find the closest match in mode tables for the given resolution and scan mode. + * @param sensor id of the sensor + * @param required required resolution + * @param color true is color mode + * @return the closest resolution for the sensor and mode + */ +static unsigned get_closest_resolution(SensorId sensor_id, int required, unsigned channels) +{ + unsigned best_res = 0; + unsigned best_diff = 9600; + + for (const auto& sensor : *s_sensors) { + if (sensor_id != sensor.sensor_id) + continue; + + // exit on perfect match + if (sensor.resolutions.matches(required) && sensor.matches_channel_count(channels)) { + DBG(DBG_info, "%s: match found for %d\n", __func__, required); + return required; + } + + // computes distance and keep mode if it is closer than previous + if (sensor.matches_channel_count(channels)) { + for (auto res : sensor.resolutions.resolutions()) { + unsigned curr_diff = std::abs(static_cast<int>(res) - static_cast<int>(required)); + if (curr_diff < best_diff) { + best_res = res; + best_diff = curr_diff; + } + } + } + } + + DBG(DBG_info, "%s: closest match for %d is %d\n", __func__, required, best_res); + return best_res; +} + +/** + * Returns the cksel values used by the required scan mode. + * @param sensor id of the sensor + * @param required required resolution + * @param color true is color mode + * @return cksel value for mode + */ +static int get_cksel(SensorId sensor_id, int required, unsigned channels) +{ + for (const auto& sensor : *s_sensors) { + // exit on perfect match + if (sensor.sensor_id == sensor_id && sensor.resolutions.matches(required) && + sensor.matches_channel_count(channels)) + { + unsigned cksel = sensor.ccd_pixels_per_system_pixel(); + DBG(DBG_io, "%s: match found for %d (cksel=%d)\n", __func__, required, cksel); + return cksel; + } + } + DBG(DBG_error, "%s: failed to find match for %d dpi\n", __func__, required); + /* fail safe fallback */ + return 1; +} + +void CommandSetGl646::init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, + const ScanSession& session) const +{ + DBG_HELPER(dbg); + session.assert_computed(); + + debug_dump(DBG_info, sensor); + + uint32_t move = session.params.starty; + + int i, nb; + Motor_Master *motor = nullptr; + uint32_t z1, z2; + int feedl; + + + /* for the given resolution, search for master + * motor mode setting */ + i = 0; + nb = sizeof (motor_master) / sizeof (Motor_Master); + while (i < nb) + { + if (dev->model->motor_id == motor_master[i].motor_id + && motor_master[i].dpi == session.params.yres + && motor_master[i].channels == session.params.channels) + { + motor = &motor_master[i]; + } + i++; + } + if (motor == nullptr) + { + throw SaneException("unable to find settings for motor %d at %d dpi, color=%d", + static_cast<unsigned>(dev->model->motor_id), + session.params.yres, session.params.channels); + } + + /* now we can search for the specific sensor settings */ + i = 0; + + // now apply values from settings to registers + regs->set16(REG_EXPR, sensor.exposure.red); + regs->set16(REG_EXPG, sensor.exposure.green); + regs->set16(REG_EXPB, sensor.exposure.blue); + + for (const auto& reg : sensor.custom_regs) { + regs->set8(reg.address, reg.value); + } + + /* now generate slope tables : we are not using generate_slope_table3 yet */ + auto slope_table1 = create_slope_table(motor->slope1, motor->slope1.max_speed_w, StepType::FULL, + 1, 4, get_slope_table_max_size(AsicType::GL646)); + auto slope_table2 = create_slope_table(motor->slope2, motor->slope2.max_speed_w, StepType::FULL, + 1, 4, get_slope_table_max_size(AsicType::GL646)); + + /* R01 */ + /* now setup other registers for final scan (ie with shading enabled) */ + /* watch dog + shading + scan enable */ + regs->find_reg(0x01).value |= REG_0x01_DOGENB | REG_0x01_DVDSET | REG_0x01_SCAN; + if (dev->model->is_cis) { + regs->find_reg(0x01).value |= REG_0x01_CISSET; + } else { + regs->find_reg(0x01).value &= ~REG_0x01_CISSET; + } + + /* if device has no calibration, don't enable shading correction */ + if (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION) + { + regs->find_reg(0x01).value &= ~REG_0x01_DVDSET; + } + + regs->find_reg(0x01).value &= ~REG_0x01_FASTMOD; + if (motor->fastmod) { + regs->find_reg(0x01).value |= REG_0x01_FASTMOD; + } + + /* R02 */ + /* allow moving when buffer full by default */ + if (!dev->model->is_sheetfed) { + dev->reg.find_reg(0x02).value &= ~REG_0x02_ACDCDIS; + } else { + dev->reg.find_reg(0x02).value |= REG_0x02_ACDCDIS; + } + + /* setup motor power and direction */ + sanei_genesys_set_motor_power(*regs, true); + + if (has_flag(session.params.flags, ScanFlag::REVERSE)) { + regs->find_reg(0x02).value |= REG_0x02_MTRREV; + } else { + regs->find_reg(0x02).value &= ~REG_0x02_MTRREV; + } + + /* fastfed enabled (2 motor slope tables) */ + if (motor->fastfed) { + regs->find_reg(0x02).value |= REG_0x02_FASTFED; + } else { + regs->find_reg(0x02).value &= ~REG_0x02_FASTFED; + } + + /* step type */ + regs->find_reg(0x02).value &= ~REG_0x02_STEPSEL; + switch (motor->steptype) + { + case StepType::FULL: + break; + case StepType::HALF: + regs->find_reg(0x02).value |= 1; + break; + case StepType::QUARTER: + regs->find_reg(0x02).value |= 2; + break; + default: + regs->find_reg(0x02).value |= 3; + break; + } + + if (dev->model->is_sheetfed) { + regs->find_reg(0x02).value &= ~REG_0x02_AGOHOME; + } else { + regs->find_reg(0x02).value |= REG_0x02_AGOHOME; + } + + /* R03 */ + regs->find_reg(0x03).value &= ~REG_0x03_AVEENB; + // regs->find_reg(0x03).value |= REG_0x03_AVEENB; + regs->find_reg(0x03).value &= ~REG_0x03_LAMPDOG; + + /* select XPA */ + regs->find_reg(0x03).value &= ~REG_0x03_XPASEL; + if ((session.params.flags & ScanFlag::USE_XPA) != ScanFlag::NONE) { + regs->find_reg(0x03).value |= REG_0x03_XPASEL; + } + regs->state.is_xpa_on = (session.params.flags & ScanFlag::USE_XPA) != ScanFlag::NONE; + + /* R04 */ + /* monochrome / color scan */ + switch (session.params.depth) { + case 8: + regs->find_reg(0x04).value &= ~(REG_0x04_LINEART | REG_0x04_BITSET); + break; + case 16: + regs->find_reg(0x04).value &= ~REG_0x04_LINEART; + regs->find_reg(0x04).value |= REG_0x04_BITSET; + break; + } + + sanei_genesys_set_dpihw(*regs, sensor, sensor.optical_res); + + /* gamma enable for scans */ + if (dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) { + regs->find_reg(0x05).value |= REG_0x05_GMM14BIT; + } + + regs->find_reg(0x05).value &= ~REG_0x05_GMMENB; + + /* true CIS gray if needed */ + if (dev->model->is_cis && session.params.channels == 1 && dev->settings.true_gray) { + regs->find_reg(0x05).value |= REG_0x05_LEDADD; + } else { + regs->find_reg(0x05).value &= ~REG_0x05_LEDADD; + } + + /* HP2400 1200dpi mode tuning */ + + if (dev->model->sensor_id == SensorId::CCD_HP2400) { + /* reset count of dummy lines to zero */ + regs->find_reg(0x1e).value &= ~REG_0x1E_LINESEL; + if (session.params.xres >= 1200) { + /* there must be one dummy line */ + regs->find_reg(0x1e).value |= 1 & REG_0x1E_LINESEL; + + /* GPO12 need to be set to zero */ + regs->find_reg(0x66).value &= ~0x20; + } + else + { + /* set GPO12 back to one */ + regs->find_reg(0x66).value |= 0x20; + } + } + + /* motor steps used */ + unsigned forward_steps = motor->fwdbwd; + unsigned backward_steps = motor->fwdbwd; + + // the steps count must be different by at most 128, otherwise it's impossible to construct + // a proper backtracking curve. We're using slightly lower limit to allow at least a minimum + // distance between accelerations (forward_steps, backward_steps) + if (slope_table1.steps_count > slope_table2.steps_count + 100) { + slope_table2.steps_count += slope_table1.steps_count - 100; + } + if (slope_table2.steps_count > slope_table1.steps_count + 100) { + slope_table1.steps_count += slope_table2.steps_count - 100; + } + + if (slope_table1.steps_count >= slope_table2.steps_count) { + backward_steps += (slope_table1.steps_count - slope_table2.steps_count) * 2; + } else { + forward_steps += (slope_table2.steps_count - slope_table1.steps_count) * 2; + } + + if (forward_steps > 255) { + if (backward_steps < (forward_steps - 255)) { + throw SaneException("Can't set backtracking parameters without skipping image"); + } + backward_steps -= forward_steps - 255; + } + if (backward_steps > 255) { + if (forward_steps < (backward_steps - 255)) { + throw SaneException("Can't set backtracking parameters without skipping image"); + } + forward_steps -= backward_steps - 255; + } + + regs->find_reg(0x21).value = slope_table1.steps_count; + regs->find_reg(0x24).value = slope_table2.steps_count; + regs->find_reg(0x22).value = forward_steps; + regs->find_reg(0x23).value = backward_steps; + + /* CIS scanners read one line per color channel + * since gray mode use 'add' we also read 3 channels even not in + * color mode */ + if (dev->model->is_cis) { + regs->set24(REG_LINCNT, session.output_line_count * 3); + } else { + regs->set24(REG_LINCNT, session.output_line_count); + } + + regs->set16(REG_STRPIXEL, session.pixel_startx); + regs->set16(REG_ENDPIXEL, session.pixel_endx); + + regs->set24(REG_MAXWD, session.output_line_bytes); + + regs->set16(REG_DPISET, session.output_resolution * session.ccd_size_divisor * + sensor.ccd_pixels_per_system_pixel()); + regs->set16(REG_LPERIOD, sensor.exposure_lperiod); + + /* move distance must be adjusted to take into account the extra lines + * read to reorder data */ + feedl = move; + + if (session.num_staggered_lines + session.max_color_shift_lines > 0 && feedl != 0) { + int feed_offset = ((session.max_color_shift_lines + session.num_staggered_lines) * dev->motor.optical_ydpi) / + motor->dpi; + if (feedl > feed_offset) { + feedl = feedl - feed_offset; + } + } + + /* we assume all scans are done with 2 tables */ + /* + feedl = feed_steps - fast_slope_steps*2 - + (slow_slope_steps >> scan_step_type); */ + /* but head has moved due to shading calibration => dev->scanhead_position_primary */ + if (feedl > 0) + { + DBG(DBG_info, "%s: initial move=%d\n", __func__, feedl); + + /* TODO clean up this when I'll fully understand. + * for now, special casing each motor */ + switch (dev->model->motor_id) { + case MotorId::MD_5345: + switch (motor->dpi) { + case 200: + feedl -= 70; + break; + case 300: + feedl -= 70; + break; + case 400: + feedl += 130; + break; + case 600: + feedl += 160; + break; + case 1200: + feedl += 160; + break; + case 2400: + feedl += 180; + break; + default: + break; + } + break; + case MotorId::HP2300: + switch (motor->dpi) { + case 75: + feedl -= 180; + break; + case 150: + feedl += 0; + break; + case 300: + feedl += 30; + break; + case 600: + feedl += 35; + break; + case 1200: + feedl += 45; + break; + default: + break; + } + break; + case MotorId::HP2400: + switch (motor->dpi) { + case 150: + feedl += 150; + break; + case 300: + feedl += 220; + break; + case 600: + feedl += 260; + break; + case 1200: + feedl += 280; /* 300 */ + break; + case 50: + feedl += 0; + break; + case 100: + feedl += 100; + break; + default: + break; + } + break; + + /* theorical value */ + default: { + unsigned step_shift = static_cast<unsigned>(motor->steptype); + + if (motor->fastfed) + { + feedl = feedl - 2 * slope_table2.steps_count - + (slope_table1.steps_count >> step_shift); + } + else + { + feedl = feedl - (slope_table1.steps_count >> step_shift); + } + break; + } + } + /* security */ + if (feedl < 0) + feedl = 0; + } + + DBG(DBG_info, "%s: final move=%d\n", __func__, feedl); + regs->set24(REG_FEEDL, feedl); + + regs->find_reg(0x65).value = motor->mtrpwm; + + sanei_genesys_calculate_zmod(regs->find_reg(0x02).value & REG_0x02_FASTFED, + sensor.exposure_lperiod, + slope_table1.table, + slope_table1.steps_count, + move, motor->fwdbwd, &z1, &z2); + + /* no z1/z2 for sheetfed scanners */ + if (dev->model->is_sheetfed) { + z1 = 0; + z2 = 0; + } + regs->set16(REG_Z1MOD, z1); + regs->set16(REG_Z2MOD, z2); + regs->find_reg(0x6b).value = slope_table2.steps_count; + regs->find_reg(0x6c).value = + (regs->find_reg(0x6c).value & REG_0x6C_TGTIME) | ((z1 >> 13) & 0x38) | ((z2 >> 16) + & 0x07); + + write_control(dev, sensor, session.output_resolution); + + // setup analog frontend + gl646_set_fe(dev, sensor, AFE_SET, session.output_resolution); + + dev->read_buffer.clear(); + dev->read_buffer.alloc(session.buffer_size_read); + + build_image_pipeline(dev, session); + + dev->read_active = true; + + dev->session = session; + + dev->total_bytes_read = 0; + dev->total_bytes_to_read = session.output_line_bytes_requested * session.params.lines; + + /* select color filter based on settings */ + regs->find_reg(0x04).value &= ~REG_0x04_FILTER; + if (session.params.channels == 1) { + switch (session.params.color_filter) { + case ColorFilter::RED: + regs->find_reg(0x04).value |= 0x04; + break; + case ColorFilter::GREEN: + regs->find_reg(0x04).value |= 0x08; + break; + case ColorFilter::BLUE: + regs->find_reg(0x04).value |= 0x0c; + break; + default: + break; + } + } + + gl646_send_slope_table(dev, 0, slope_table1.table, regs->get8(0x21)); + gl646_send_slope_table(dev, 1, slope_table2.table, regs->get8(0x6b)); +} + + +/** copy sensor specific settings */ +/* *dev : device infos + *regs : regiters to be set + extended : do extended set up + ccd_size_divisor: set up for half ccd resolution + all registers 08-0B, 10-1D, 52-5E are set up. They shouldn't + appear anywhere else but in register init +*/ +static void +gl646_setup_sensor (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * regs) +{ + (void) dev; + DBG(DBG_proc, "%s: start\n", __func__); + + for (const auto& reg_setting : sensor.custom_base_regs) { + regs->set8(reg_setting.address, reg_setting.value); + } + // FIXME: all other drivers don't set exposure here + regs_set_exposure(AsicType::GL646, *regs, sensor.exposure); + + DBG(DBG_proc, "%s: end\n", __func__); +} + +/** + * Set all registers to default values after init + * @param dev scannerr's device to set + */ +static void +gl646_init_regs (Genesys_Device * dev) +{ + int addr; + + DBG(DBG_proc, "%s\n", __func__); + + dev->reg.clear(); + + for (addr = 1; addr <= 0x0b; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x10; addr <= 0x29; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x2c; addr <= 0x39; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x3d; addr <= 0x3f; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x52; addr <= 0x5e; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x60; addr <= 0x6d; addr++) + dev->reg.init_reg(addr, 0); + + dev->reg.find_reg(0x01).value = 0x20 /*0x22 */ ; /* enable shading, CCD, color, 1M */ + dev->reg.find_reg(0x02).value = 0x30 /*0x38 */ ; /* auto home, one-table-move, full step */ + if (dev->model->motor_id == MotorId::MD_5345) { + dev->reg.find_reg(0x02).value |= 0x01; // half-step + } + switch (dev->model->motor_id) { + case MotorId::MD_5345: + dev->reg.find_reg(0x02).value |= 0x01; /* half-step */ + break; + case MotorId::XP200: + /* for this sheetfed scanner, no AGOHOME, nor backtracking */ + dev->reg.find_reg(0x02).value = 0x50; + break; + default: + break; + } + dev->reg.find_reg(0x03).value = 0x1f /*0x17 */ ; /* lamp on */ + dev->reg.find_reg(0x04).value = 0x13 /*0x03 */ ; /* 8 bits data, 16 bits A/D, color, Wolfson fe *//* todo: according to spec, 0x0 is reserved? */ + switch (dev->model->adc_id) + { + case AdcId::AD_XP200: + dev->reg.find_reg(0x04).value = 0x12; + break; + default: + /* Wolfson frontend */ + dev->reg.find_reg(0x04).value = 0x13; + break; + } + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + dev->reg.find_reg(0x05).value = 0x00; /* 12 bits gamma, disable gamma, 24 clocks/pixel */ + sanei_genesys_set_dpihw(dev->reg, sensor, sensor.optical_res); + + if (dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) { + dev->reg.find_reg(0x05).value |= REG_0x05_GMM14BIT; + } + if (dev->model->adc_id == AdcId::AD_XP200) { + dev->reg.find_reg(0x05).value |= 0x01; /* 12 clocks/pixel */ + } + + if (dev->model->sensor_id == SensorId::CCD_HP2300) { + dev->reg.find_reg(0x06).value = 0x00; // PWRBIT off, shading gain=4, normal AFE image capture + } else { + dev->reg.find_reg(0x06).value = 0x18; // PWRBIT on, shading gain=8, normal AFE image capture + } + + + gl646_setup_sensor(dev, sensor, &dev->reg); + + dev->reg.find_reg(0x1e).value = 0xf0; /* watch-dog time */ + + switch (dev->model->sensor_id) + { + case SensorId::CCD_HP2300: + dev->reg.find_reg(0x1e).value = 0xf0; + dev->reg.find_reg(0x1f).value = 0x10; + dev->reg.find_reg(0x20).value = 0x20; + break; + case SensorId::CCD_HP2400: + dev->reg.find_reg(0x1e).value = 0x80; + dev->reg.find_reg(0x1f).value = 0x10; + dev->reg.find_reg(0x20).value = 0x20; + break; + case SensorId::CCD_HP3670: + dev->reg.find_reg(0x19).value = 0x2a; + dev->reg.find_reg(0x1e).value = 0x80; + dev->reg.find_reg(0x1f).value = 0x10; + dev->reg.find_reg(0x20).value = 0x20; + break; + case SensorId::CIS_XP200: + dev->reg.find_reg(0x1e).value = 0x10; + dev->reg.find_reg(0x1f).value = 0x01; + dev->reg.find_reg(0x20).value = 0x50; + break; + default: + dev->reg.find_reg(0x1f).value = 0x01; + dev->reg.find_reg(0x20).value = 0x50; + break; + } + + dev->reg.find_reg(0x21).value = 0x08 /*0x20 */ ; /* table one steps number for forward slope curve of the acc/dec */ + dev->reg.find_reg(0x22).value = 0x10 /*0x08 */ ; /* steps number of the forward steps for start/stop */ + dev->reg.find_reg(0x23).value = 0x10 /*0x08 */ ; /* steps number of the backward steps for start/stop */ + dev->reg.find_reg(0x24).value = 0x08 /*0x20 */ ; /* table one steps number backward slope curve of the acc/dec */ + dev->reg.find_reg(0x25).value = 0x00; /* scan line numbers (7000) */ + dev->reg.find_reg(0x26).value = 0x00 /*0x1b */ ; + dev->reg.find_reg(0x27).value = 0xd4 /*0x58 */ ; + dev->reg.find_reg(0x28).value = 0x01; /* PWM duty for lamp control */ + dev->reg.find_reg(0x29).value = 0xff; + + dev->reg.find_reg(0x2c).value = 0x02; /* set resolution (600 DPI) */ + dev->reg.find_reg(0x2d).value = 0x58; + dev->reg.find_reg(0x2e).value = 0x78; /* set black&white threshold high level */ + dev->reg.find_reg(0x2f).value = 0x7f; /* set black&white threshold low level */ + + dev->reg.find_reg(0x30).value = 0x00; /* begin pixel position (16) */ + dev->reg.find_reg(0x31).value = sensor.dummy_pixel /*0x10 */ ; /* TGW + 2*TG_SHLD + x */ + dev->reg.find_reg(0x32).value = 0x2a /*0x15 */ ; /* end pixel position (5390) */ + dev->reg.find_reg(0x33).value = 0xf8 /*0x0e */ ; /* TGW + 2*TG_SHLD + y */ + dev->reg.find_reg(0x34).value = sensor.dummy_pixel; + dev->reg.find_reg(0x35).value = 0x01 /*0x00 */ ; /* set maximum word size per line, for buffer full control (10800) */ + dev->reg.find_reg(0x36).value = 0x00 /*0x2a */ ; + dev->reg.find_reg(0x37).value = 0x00 /*0x30 */ ; + dev->reg.find_reg(0x38).value = 0x2a; // line period (exposure time = 11000 pixels) */ + dev->reg.find_reg(0x39).value = 0xf8; + dev->reg.find_reg(0x3d).value = 0x00; /* set feed steps number of motor move */ + dev->reg.find_reg(0x3e).value = 0x00; + dev->reg.find_reg(0x3f).value = 0x01 /*0x00 */ ; + + dev->reg.find_reg(0x60).value = 0x00; /* Z1MOD, 60h:61h:(6D b5:b3), remainder for start/stop */ + dev->reg.find_reg(0x61).value = 0x00; /* (21h+22h)/LPeriod */ + dev->reg.find_reg(0x62).value = 0x00; /* Z2MODE, 62h:63h:(6D b2:b0), remainder for start scan */ + dev->reg.find_reg(0x63).value = 0x00; /* (3Dh+3Eh+3Fh)/LPeriod for one-table mode,(21h+1Fh)/LPeriod */ + dev->reg.find_reg(0x64).value = 0x00; /* motor PWM frequency */ + dev->reg.find_reg(0x65).value = 0x00; /* PWM duty cycle for table one motor phase (63 = max) */ + if (dev->model->motor_id == MotorId::MD_5345) { + // PWM duty cycle for table one motor phase (63 = max) + dev->reg.find_reg(0x65).value = 0x02; + } + + for (const auto& reg : dev->gpo.regs) { + dev->reg.set8(reg.address, reg.value); + } + + switch (dev->model->motor_id) { + case MotorId::HP2300: + case MotorId::HP2400: + dev->reg.find_reg(0x6a).value = 0x7f; /* table two steps number for acc/dec */ + dev->reg.find_reg(0x6b).value = 0x78; /* table two steps number for acc/dec */ + dev->reg.find_reg(0x6d).value = 0x7f; + break; + case MotorId::MD_5345: + dev->reg.find_reg(0x6a).value = 0x42; /* table two fast moving step type, PWM duty for table two */ + dev->reg.find_reg(0x6b).value = 0xff; /* table two steps number for acc/dec */ + dev->reg.find_reg(0x6d).value = 0x41; /* select deceleration steps whenever go home (0), accel/decel stop time (31 * LPeriod) */ + break; + case MotorId::XP200: + dev->reg.find_reg(0x6a).value = 0x7f; /* table two fast moving step type, PWM duty for table two */ + dev->reg.find_reg(0x6b).value = 0x08; /* table two steps number for acc/dec */ + dev->reg.find_reg(0x6d).value = 0x01; /* select deceleration steps whenever go home (0), accel/decel stop time (31 * LPeriod) */ + break; + case MotorId::HP3670: + dev->reg.find_reg(0x6a).value = 0x41; /* table two steps number for acc/dec */ + dev->reg.find_reg(0x6b).value = 0xc8; /* table two steps number for acc/dec */ + dev->reg.find_reg(0x6d).value = 0x7f; + break; + default: + dev->reg.find_reg(0x6a).value = 0x40; /* table two fast moving step type, PWM duty for table two */ + dev->reg.find_reg(0x6b).value = 0xff; /* table two steps number for acc/dec */ + dev->reg.find_reg(0x6d).value = 0x01; /* select deceleration steps whenever go home (0), accel/decel stop time (31 * LPeriod) */ + break; + } + dev->reg.find_reg(0x6c).value = 0x00; /* peroid times for LPeriod, expR,expG,expB, Z1MODE, Z2MODE (one period time) */ +} + + +// Send slope table for motor movement slope_table in machine byte order +static void gl646_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, + int steps) +{ + DBG_HELPER_ARGS(dbg, "table_nr = %d, steps = %d)=%d .. %d", table_nr, steps, slope_table[0], + slope_table[steps - 1]); + int dpihw; + int start_address; + + dpihw = dev->reg.find_reg(0x05).value >> 6; + + if (dpihw == 0) /* 600 dpi */ + start_address = 0x08000; + else if (dpihw == 1) /* 1200 dpi */ + start_address = 0x10000; + else if (dpihw == 2) /* 2400 dpi */ + start_address = 0x1f800; + else { + throw SaneException("Unexpected dpihw"); + } + + std::vector<uint8_t> table(steps * 2); + for (int i = 0; i < steps; i++) + { + table[i * 2] = slope_table[i] & 0xff; + table[i * 2 + 1] = slope_table[i] >> 8; + } + + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } + dev->interface->write_buffer(0x3c, start_address + table_nr * 0x100, table.data(), steps * 2); +} + +// Set values of Analog Device type frontend +static void gl646_set_ad_fe(Genesys_Device* dev, uint8_t set) +{ + DBG_HELPER(dbg); + int i; + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + + dev->frontend = dev->frontend_initial; + + // write them to analog frontend + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); + } + if (set == AFE_SET) + { + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x02 + i, dev->frontend.get_gain(i)); + } + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x05 + i, dev->frontend.get_offset(i)); + } + } + /* + if (set == AFE_POWER_SAVE) + { + dev->interface->write_fe_register(0x00, dev->frontend.reg[0] | 0x04); + } */ +} + +/** set up analog frontend + * set up analog frontend + * @param dev device to set up + * @param set action from AFE_SET, AFE_INIT and AFE_POWERSAVE + * @param dpi resolution of the scan since it affects settings + */ +static void gl646_wm_hp3670(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set, + unsigned dpi) +{ + DBG_HELPER(dbg); + int i; + + switch (set) + { + case AFE_INIT: + dev->interface->write_fe_register(0x04, 0x80); + dev->interface->sleep_ms(200); + dev->interface->write_register(0x50, 0x00); + dev->frontend = dev->frontend_initial; + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); + dev->interface->write_fe_register(0x02, dev->frontend.regs.get_value(0x02)); + gl646_gpio_output_enable(dev->interface->get_usb_device(), 0x07); + break; + case AFE_POWER_SAVE: + dev->interface->write_fe_register(0x01, 0x06); + dev->interface->write_fe_register(0x06, 0x0f); + return; + break; + default: /* AFE_SET */ + /* mode setup */ + i = dev->frontend.regs.get_value(0x03); + if (dpi > sensor.optical_res / 2) + { + /* fe_reg_0x03 must be 0x12 for 1200 dpi in WOLFSON_HP3670. + * WOLFSON_HP2400 in 1200 dpi mode works well with + * fe_reg_0x03 set to 0x32 or 0x12 but not to 0x02 */ + i = 0x12; + } + dev->interface->write_fe_register(0x03, i); + /* offset and sign (or msb/lsb ?) */ + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x20 + i, dev->frontend.get_offset(i)); + dev->interface->write_fe_register(0x24 + i, dev->frontend.regs.get_value(0x24 + i)); + } + + // gain + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x28 + i, dev->frontend.get_gain(i)); + } + } +} + +/** Set values of analog frontend + * @param dev device to set + * @param set action to execute + * @param dpi dpi to setup the AFE + */ +static void gl646_set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set, int dpi) +{ + DBG_HELPER_ARGS(dbg, "%s,%d", set == AFE_INIT ? "init" : + set == AFE_SET ? "set" : + set == AFE_POWER_SAVE ? "powersave" : "huh?", dpi); + int i; + uint8_t val; + + /* Analog Device type frontend */ + uint8_t frontend_type = dev->reg.find_reg(0x04).value & REG_0x04_FESET; + if (frontend_type == 0x02) { + gl646_set_ad_fe(dev, set); + return; + } + + /* Wolfson type frontend */ + if (frontend_type != 0x03) { + throw SaneException("unsupported frontend type %d", frontend_type); + } + + /* per frontend function to keep code clean */ + switch (dev->model->adc_id) + { + case AdcId::WOLFSON_HP3670: + case AdcId::WOLFSON_HP2400: + gl646_wm_hp3670(dev, sensor, set, dpi); + return; + default: + DBG(DBG_proc, "%s(): using old method\n", __func__); + break; + } + + /* initialize analog frontend */ + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + dev->frontend = dev->frontend_initial; + + // reset only done on init + dev->interface->write_fe_register(0x04, 0x80); + + /* enable GPIO for some models */ + if (dev->model->sensor_id == SensorId::CCD_HP2300) { + val = 0x07; + gl646_gpio_output_enable(dev->interface->get_usb_device(), val); + } + return; + } + + // set fontend to power saving mode + if (set == AFE_POWER_SAVE) { + dev->interface->write_fe_register(0x01, 0x02); + return; + } + + /* here starts AFE_SET */ + /* TODO : base this test on cfg reg3 or a CCD family flag to be created */ + /* if (dev->model->ccd_type != SensorId::CCD_HP2300 + && dev->model->ccd_type != SensorId::CCD_HP3670 + && dev->model->ccd_type != SensorId::CCD_HP2400) */ + { + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + dev->interface->write_fe_register(0x02, dev->frontend.regs.get_value(0x02)); + } + + // start with reg3 + dev->interface->write_fe_register(0x03, dev->frontend.regs.get_value(0x03)); + + switch (dev->model->sensor_id) + { + default: + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x24 + i, dev->frontend.regs.get_value(0x24 + i)); + dev->interface->write_fe_register(0x28 + i, dev->frontend.get_gain(i)); + dev->interface->write_fe_register(0x20 + i, dev->frontend.get_offset(i)); + } + break; + /* just can't have it to work .... + case SensorId::CCD_HP2300: + case SensorId::CCD_HP2400: + case SensorId::CCD_HP3670: + + dev->interface->write_fe_register(0x23, dev->frontend.get_offset(1)); + dev->interface->write_fe_register(0x28, dev->frontend.get_gain(1)); + break; */ + } + + // end with reg1 + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); +} + +/** Set values of analog frontend + * this this the public interface, the gl646 as to use one more + * parameter to work effectively, hence the redirection + * @param dev device to set + * @param set action to execute + */ +void CommandSetGl646::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const +{ + gl646_set_fe(dev, sensor, set, dev->settings.yres); +} + +/** + * enters or leaves power saving mode + * limited to AFE for now. + * @param dev scanner's device + * @param enable true to enable power saving, false to leave it + */ +void CommandSetGl646::save_power(Genesys_Device* dev, bool enable) const +{ + DBG_HELPER_ARGS(dbg, "enable = %d", enable); + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + if (enable) + { + // gl646_set_fe(dev, sensor, AFE_POWER_SAVE); + } + else + { + gl646_set_fe(dev, sensor, AFE_INIT, 0); + } +} + +void CommandSetGl646::set_powersaving(Genesys_Device* dev, int delay /* in minutes */) const +{ + DBG_HELPER_ARGS(dbg, "delay = %d", delay); + Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); + int rate, exposure_time, tgtime, time; + + local_reg.init_reg(0x01, dev->reg.get8(0x01)); // disable fastmode + local_reg.init_reg(0x03, dev->reg.get8(0x03)); // Lamp power control + local_reg.init_reg(0x05, dev->reg.get8(0x05) & ~REG_0x05_BASESEL); // 24 clocks/pixel + local_reg.init_reg(0x38, 0x00); // line period low + local_reg.init_reg(0x39, 0x00); //line period high + local_reg.init_reg(0x6c, 0x00); // period times for LPeriod, expR,expG,expB, Z1MODE, Z2MODE + + if (!delay) + local_reg.find_reg(0x03).value &= 0xf0; /* disable lampdog and set lamptime = 0 */ + else if (delay < 20) + local_reg.find_reg(0x03).value = (local_reg.get8(0x03) & 0xf0) | 0x09; /* enable lampdog and set lamptime = 1 */ + else + local_reg.find_reg(0x03).value = (local_reg.get8(0x03) & 0xf0) | 0x0f; /* enable lampdog and set lamptime = 7 */ + + time = delay * 1000 * 60; /* -> msec */ + exposure_time = static_cast<std::uint32_t>((time * 32000.0 / + (24.0 * 64.0 * (local_reg.get8(0x03) & REG_0x03_LAMPTIM) * + 1024.0) + 0.5)); + /* 32000 = system clock, 24 = clocks per pixel */ + rate = (exposure_time + 65536) / 65536; + if (rate > 4) + { + rate = 8; + tgtime = 3; + } + else if (rate > 2) + { + rate = 4; + tgtime = 2; + } + else if (rate > 1) + { + rate = 2; + tgtime = 1; + } + else + { + rate = 1; + tgtime = 0; + } + + local_reg.find_reg(0x6c).value |= tgtime << 6; + exposure_time /= rate; + + if (exposure_time > 65535) + exposure_time = 65535; + + local_reg.find_reg(0x38).value = exposure_time / 256; + local_reg.find_reg(0x39).value = exposure_time & 255; + + dev->interface->write_registers(local_reg); +} + + +/** + * loads document into scanner + * currently only used by XP200 + * bit2 (0x04) of gpio is paper event (document in/out) on XP200 + * HOMESNR is set if no document in front of sensor, the sequence of events is + * paper event -> document is in the sheet feeder + * HOMESNR becomes 0 -> document reach sensor + * HOMESNR becomes 1 ->document left sensor + * paper event -> document is out + */ +void CommandSetGl646::load_document(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + + // FIXME: sequential not really needed in this case + Genesys_Register_Set regs(Genesys_Register_Set::SEQUENTIAL); + unsigned count; + + /* no need to load document is flatbed scanner */ + if (!dev->model->is_sheetfed) { + DBG(DBG_proc, "%s: nothing to load\n", __func__); + DBG(DBG_proc, "%s: end\n", __func__); + return; + } + + auto status = scanner_read_status(*dev); + + // home sensor is set if a document is inserted + if (status.is_at_home) { + /* if no document, waits for a paper event to start loading */ + /* with a 60 seconde minutes timeout */ + count = 0; + std::uint8_t val = 0; + do { + gl646_gpio_read(dev->interface->get_usb_device(), &val); + + DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, val); + if ((val & 0x04) != 0x04) + { + DBG(DBG_warn, "%s: no paper detected\n", __func__); + } + dev->interface->sleep_ms(200); + count++; + } + while (((val & 0x04) != 0x04) && (count < 300)); /* 1 min time out */ + if (count == 300) + { + throw SaneException(SANE_STATUS_NO_DOCS, "timeout waiting for document"); + } + } + + /* set up to fast move before scan then move until document is detected */ + regs.init_reg(0x01, 0x90); + + /* AGOME, 2 slopes motor moving */ + regs.init_reg(0x02, 0x79); + + /* motor feeding steps to 0 */ + regs.init_reg(0x3d, 0); + regs.init_reg(0x3e, 0); + regs.init_reg(0x3f, 0); + + /* 50 fast moving steps */ + regs.init_reg(0x6b, 50); + + /* set GPO */ + regs.init_reg(0x66, 0x30); + + /* stesp NO */ + regs.init_reg(0x21, 4); + regs.init_reg(0x22, 1); + regs.init_reg(0x23, 1); + regs.init_reg(0x24, 4); + + /* generate slope table 2 */ + auto slope_table = create_slope_table(MotorSlope::create_from_steps(6000, 2400, 50), 2400, + StepType::FULL, 1, 4, + get_slope_table_max_size(AsicType::GL646)); + // document loading: + // send regs + // start motor + // wait e1 status to become e0 + gl646_send_slope_table(dev, 1, slope_table.table, slope_table.steps_count); + + dev->interface->write_registers(regs); + + scanner_start_action(*dev, true); + + count = 0; + do + { + status = scanner_read_status(*dev); + dev->interface->sleep_ms(200); + count++; + } while (status.is_motor_enabled && (count < 300)); + + if (count == 300) + { + throw SaneException(SANE_STATUS_JAMMED, "can't load document"); + } + + /* when loading OK, document is here */ + dev->document = true; + + /* set up to idle */ + regs.set8(0x02, 0x71); + regs.set8(0x3f, 1); + regs.set8(0x6b, 8); + dev->interface->write_registers(regs); +} + +/** + * detects end of document and adjust current scan + * to take it into account + * used by sheetfed scanners + */ +void CommandSetGl646::detect_document_end(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + std::uint8_t gpio; + unsigned int bytes_left; + + // test for document presence + scanner_read_print_status(*dev); + + gl646_gpio_read(dev->interface->get_usb_device(), &gpio); + DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, gpio); + + /* detect document event. There one event when the document go in, + * then another when it leaves */ + if (dev->document && (gpio & 0x04) && (dev->total_bytes_read > 0)) { + DBG(DBG_info, "%s: no more document\n", __func__); + dev->document = false; + + /* adjust number of bytes to read: + * total_bytes_to_read is the number of byte to send to frontend + * total_bytes_read is the number of bytes sent to frontend + * read_bytes_left is the number of bytes to read from the scanner + */ + DBG(DBG_io, "%s: total_bytes_to_read=%zu\n", __func__, dev->total_bytes_to_read); + DBG(DBG_io, "%s: total_bytes_read =%zu\n", __func__, dev->total_bytes_read); + + // amount of data available from scanner is what to scan + sanei_genesys_read_valid_words(dev, &bytes_left); + + unsigned lines_in_buffer = bytes_left / dev->session.output_line_bytes_raw; + + // we add the number of lines needed to read the last part of the document in + unsigned lines_offset = static_cast<unsigned>( + (dev->model->y_offset * dev->session.params.yres) / MM_PER_INCH); + + unsigned remaining_lines = lines_in_buffer + lines_offset; + + bytes_left = remaining_lines * dev->session.output_line_bytes_raw; + + if (bytes_left < dev->get_pipeline_source().remaining_bytes()) { + dev->get_pipeline_source().set_remaining_bytes(bytes_left); + dev->total_bytes_to_read = dev->total_bytes_read + bytes_left; + } + DBG(DBG_io, "%s: total_bytes_to_read=%zu\n", __func__, dev->total_bytes_to_read); + DBG(DBG_io, "%s: total_bytes_read =%zu\n", __func__, dev->total_bytes_read); + } +} + +/** + * eject document from the feeder + * currently only used by XP200 + * TODO we currently rely on AGOHOME not being set for sheetfed scanners, + * maybe check this flag in eject to let the document being eject automaticaly + */ +void CommandSetGl646::eject_document(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + + // FIXME: SEQUENTIAL not really needed in this case + Genesys_Register_Set regs((Genesys_Register_Set::SEQUENTIAL)); + unsigned count; + std::uint8_t gpio; + + /* at the end there will be noe more document */ + dev->document = false; + + // first check for document event + gl646_gpio_read(dev->interface->get_usb_device(), &gpio); + + DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, gpio); + + // test status : paper event + HOMESNR -> no more doc ? + auto status = scanner_read_status(*dev); + + // home sensor is set when document is inserted + if (status.is_at_home) { + dev->document = false; + DBG(DBG_info, "%s: no more document to eject\n", __func__); + DBG(DBG_proc, "%s: end\n", __func__); + return; + } + + // there is a document inserted, eject it + dev->interface->write_register(0x01, 0xb0); + + /* wait for motor to stop */ + do { + dev->interface->sleep_ms(200); + status = scanner_read_status(*dev); + } + while (status.is_motor_enabled); + + /* set up to fast move before scan then move until document is detected */ + regs.init_reg(0x01, 0xb0); + + /* AGOME, 2 slopes motor moving , eject 'backward' */ + regs.init_reg(0x02, 0x5d); + + /* motor feeding steps to 119880 */ + regs.init_reg(0x3d, 1); + regs.init_reg(0x3e, 0xd4); + regs.init_reg(0x3f, 0x48); + + /* 60 fast moving steps */ + regs.init_reg(0x6b, 60); + + /* set GPO */ + regs.init_reg(0x66, 0x30); + + /* stesp NO */ + regs.init_reg(0x21, 4); + regs.init_reg(0x22, 1); + regs.init_reg(0x23, 1); + regs.init_reg(0x24, 4); + + /* generate slope table 2 */ + auto slope_table = create_slope_table(MotorSlope::create_from_steps(10000, 1600, 60), 1600, + StepType::FULL, 1, 4, + get_slope_table_max_size(AsicType::GL646)); + // document eject: + // send regs + // start motor + // wait c1 status to become c8 : HOMESNR and ~MOTFLAG + gl646_send_slope_table(dev, 1, slope_table.table, slope_table.steps_count); + + dev->interface->write_registers(regs); + + scanner_start_action(*dev, true); + + /* loop until paper sensor tells paper is out, and till motor is running */ + /* use a 30 timeout */ + count = 0; + do { + status = scanner_read_status(*dev); + + dev->interface->sleep_ms(200); + count++; + } while (!status.is_at_home && (count < 150)); + + // read GPIO on exit + gl646_gpio_read(dev->interface->get_usb_device(), &gpio); + + DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, gpio); +} + +// Send the low-level scan command +void CommandSetGl646::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, bool start_motor) const +{ + DBG_HELPER(dbg); + (void) sensor; + // FIXME: SEQUENTIAL not really needed in this case + Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); + + local_reg.init_reg(0x03, reg->get8(0x03)); + local_reg.init_reg(0x01, reg->get8(0x01) | REG_0x01_SCAN); + + if (start_motor) { + local_reg.init_reg(0x0f, 0x01); + } else { + local_reg.init_reg(0x0f, 0x00); // do not start motor yet + } + + dev->interface->write_registers(local_reg); + + dev->advance_head_pos_by_session(ScanHeadId::PRIMARY); +} + + +// Send the stop scan command +static void end_scan_impl(Genesys_Device* dev, Genesys_Register_Set* reg, bool check_stop, + bool eject) +{ + DBG_HELPER_ARGS(dbg, "check_stop = %d, eject = %d", check_stop, eject); + + scanner_stop_action_no_move(*dev, *reg); + + unsigned wait_limit_seconds = 30; + + /* for sheetfed scanners, we may have to eject document */ + if (dev->model->is_sheetfed) { + if (eject && dev->document) { + dev->cmd_set->eject_document(dev); + } + wait_limit_seconds = 3; + } + + if (is_testing_mode()) { + return; + } + + dev->interface->sleep_ms(100); + + if (check_stop) { + for (unsigned i = 0; i < wait_limit_seconds * 10; i++) { + if (scanner_is_motor_stopped(*dev)) { + return; + } + + dev->interface->sleep_ms(100); + } + throw SaneException(SANE_STATUS_IO_ERROR, "could not stop motor"); + } +} + +// Send the stop scan command +void CommandSetGl646::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg, + bool check_stop) const +{ + end_scan_impl(dev, reg, check_stop, false); +} + +/** + * parks head + * @param dev scanner's device + * @param wait_until_home true if the function waits until head parked + */ +void CommandSetGl646::move_back_home(Genesys_Device* dev, bool wait_until_home) const +{ + DBG_HELPER_ARGS(dbg, "wait_until_home = %d\n", wait_until_home); + int i; + int loop = 0; + + auto status = scanner_read_status(*dev); + + if (status.is_at_home) { + DBG(DBG_info, "%s: end since already at home\n", __func__); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + + /* stop motor if needed */ + if (status.is_motor_enabled) { + gl646_stop_motor(dev); + dev->interface->sleep_ms(200); + } + + /* when scanhead is moving then wait until scanhead stops or timeout */ + DBG(DBG_info, "%s: ensuring that motor is off\n", __func__); + for (i = 400; i > 0; i--) { + // do not wait longer than 40 seconds, count down to get i = 0 when busy + + status = scanner_read_status(*dev); + + if (!status.is_motor_enabled && status.is_at_home) { + DBG(DBG_info, "%s: already at home and not moving\n", __func__); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + if (!status.is_motor_enabled) { + break; + } + + dev->interface->sleep_ms(100); + } + + if (!i) /* the loop counted down to 0, scanner still is busy */ + { + dev->set_head_pos_unknown(); + throw SaneException(SANE_STATUS_DEVICE_BUSY, "motor is still on: device busy"); + } + + // setup for a backward scan of 65535 steps, with no actual data reading + auto resolution = sanei_genesys_get_lowest_dpi(dev); + + const auto& sensor = sanei_genesys_find_sensor(dev, resolution, 3, + dev->model->default_method); + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 0; + session.params.starty = 65535; + session.params.pixels = 600; + session.params.requested_pixels = 600; + session.params.lines = 1; + session.params.depth = 8; + session.params.channels = 3; + session.params.scan_method = dev->model->default_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::USE_XCORRECTION | + ScanFlag::REVERSE; + if (dev->model->default_method == ScanMethod::TRANSPARENCY) { + session.params.flags |= ScanFlag::USE_XPA; + } + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &dev->reg, session); + + /* backward , no actual data scanned TODO more setup flags to avoid this register manipulations ? */ + regs_set_optical_off(dev->model->asic_type, dev->reg); + + // sets frontend + gl646_set_fe(dev, sensor, AFE_SET, resolution); + + /* write scan registers */ + try { + dev->interface->write_registers(dev->reg); + } catch (...) { + DBG(DBG_error, "%s: failed to bulk write registers\n", __func__); + } + + /* registers are restored to an iddl state, give up if no head to park */ + if (dev->model->is_sheetfed) { + DBG(DBG_proc, "%s: end \n", __func__); + return; + } + + // starts scan + { + // this is effectively the same as dev->cmd_set->begin_scan(dev, sensor, &dev->reg, true); + // except that we don't modify the head position calculations + + // FIXME: SEQUENTIAL not really needed in this case + Genesys_Register_Set scan_local_reg(Genesys_Register_Set::SEQUENTIAL); + + scan_local_reg.init_reg(0x03, dev->reg.get8(0x03)); + scan_local_reg.init_reg(0x01, dev->reg.get8(0x01) | REG_0x01_SCAN); + scan_local_reg.init_reg(0x0f, 0x01); + + dev->interface->write_registers(scan_local_reg); + } + + if (is_testing_mode()) { + dev->interface->test_checkpoint("move_back_home"); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + + /* loop until head parked */ + if (wait_until_home) + { + while (loop < 300) /* do not wait longer then 30 seconds */ + { + auto status = scanner_read_status(*dev); + + if (status.is_at_home) { + DBG(DBG_info, "%s: reached home position\n", __func__); + DBG(DBG_proc, "%s: end\n", __func__); + dev->interface->sleep_ms(500); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + dev->interface->sleep_ms(100); + ++loop; + } + + // when we come here then the scanner needed too much time for this, so we better + // stop the motor + catch_all_exceptions(__func__, [&](){ gl646_stop_motor (dev); }); + catch_all_exceptions(__func__, [&](){ end_scan_impl(dev, &dev->reg, true, false); }); + dev->set_head_pos_unknown(); + throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); + } + + + DBG(DBG_info, "%s: scanhead is still moving\n", __func__); +} + +/** + * Automatically set top-left edge of the scan area by scanning an + * area at 300 dpi from very top of scanner + * @param dev device stucture describing the scanner + */ +void CommandSetGl646::search_start_position(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + Genesys_Settings settings; + unsigned int resolution, x, y; + + /* we scan at 300 dpi */ + resolution = get_closest_resolution(dev->model->sensor_id, 300, 1); + + // FIXME: the current approach of doing search only for one resolution does not work on scanners + // whith employ different sensors with potentially different settings. + const auto& sensor = sanei_genesys_find_sensor(dev, resolution, 1, + dev->model->default_method); + + /* fill settings for a gray level scan */ + settings.scan_method = dev->model->default_method; + settings.scan_mode = ScanColorMode::GRAY; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = 600; + settings.requested_pixels = settings.pixels; + settings.lines = dev->model->search_lines; + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + // scan the desired area + std::vector<uint8_t> data; + simple_scan(dev, sensor, settings, true, true, false, data, "search_start_position"); + + // handle stagger case : reorder gray data and thus loose some lines + auto staggered_lines = dev->session.num_staggered_lines; + if (staggered_lines > 0) { + DBG(DBG_proc, "%s: 'un-staggering'\n", __func__); + for (y = 0; y < settings.lines - staggered_lines; y++) { + /* one point out of 2 is 'unaligned' */ + for (x = 0; x < settings.pixels; x += 2) + { + data[y * settings.pixels + x] = data[(y + staggered_lines) * settings.pixels + x]; + } + } + /* correct line number */ + settings.lines -= staggered_lines; + } + + if (DBG_LEVEL >= DBG_data) + { + sanei_genesys_write_pnm_file("gl646_search_position.pnm", data.data(), settings.depth, 1, + settings.pixels, settings.lines); + } + + // now search reference points on the data + for (auto& sensor_update : + sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method)) + { + sanei_genesys_search_reference_point(dev, sensor_update, data.data(), 0, + resolution, settings.pixels, settings.lines); + } +} + +/** + * internally overriden during effective calibration + * sets up register for coarse gain calibration + */ +void CommandSetGl646::init_regs_for_coarse_calibration(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + (void) dev; + (void) sensor; + (void) regs; +} + + +/** + * init registers for shading calibration + * we assume that scanner's head is on an area suiting shading calibration. + * We scan a full scan width area by the shading line number for the device + * at either at full sensor's resolution or half depending upon ccd_size_divisor + * @param dev scanner's device + */ +void CommandSetGl646::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + (void) regs; + Genesys_Settings settings; + int cksel = 1; + + /* fill settings for scan : always a color scan */ + int channels = 3; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, dev->settings.xres, channels, + dev->settings.scan_method); + + unsigned ccd_size_divisor = calib_sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres); + + settings.scan_method = dev->settings.scan_method; + settings.scan_mode = dev->settings.scan_mode; + if (!dev->model->is_cis) { + // FIXME: always a color scan, but why don't we set scan_mode to COLOR_SINGLE_PASS always? + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + } + settings.xres = sensor.optical_res / ccd_size_divisor; + cksel = get_cksel(dev->model->sensor_id, dev->settings.xres, channels); + settings.xres = settings.xres / cksel; + settings.yres = settings.xres; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = (calib_sensor.sensor_pixels * settings.xres) / calib_sensor.optical_res; + settings.requested_pixels = settings.pixels; + dev->calib_lines = dev->model->shading_lines; + settings.lines = dev->calib_lines * (3 - ccd_size_divisor); + settings.depth = 16; + settings.color_filter = dev->settings.color_filter; + + settings.disable_interpolation = dev->settings.disable_interpolation; + settings.threshold = dev->settings.threshold; + + // we don't want top offset, but we need right margin to be the same than the one for the final + // scan + setup_for_scan(dev, calib_sensor, &dev->reg, settings, true, false, false, false); + + /* used when sending shading calibration data */ + dev->calib_pixels = settings.pixels; + dev->calib_channels = dev->session.params.channels; + if (!dev->model->is_cis) { + dev->calib_channels = 3; + } + + /* no shading */ + dev->reg.find_reg(0x01).value &= ~REG_0x01_DVDSET; + dev->reg.find_reg(0x02).value |= REG_0x02_ACDCDIS; /* ease backtracking */ + dev->reg.find_reg(0x02).value &= ~(REG_0x02_FASTFED | REG_0x02_AGOHOME); + dev->reg.find_reg(0x05).value &= ~REG_0x05_GMMENB; + sanei_genesys_set_motor_power(dev->reg, false); + + /* TODO another flag to setup regs ? */ + /* enforce needed LINCNT, getting rid of extra lines for color reordering */ + if (!dev->model->is_cis) { + dev->reg.set24(REG_LINCNT, dev->calib_lines); + } else { + dev->reg.set24(REG_LINCNT, dev->calib_lines * 3); + } + + /* copy reg to calib_reg */ + dev->calib_reg = dev->reg; + + DBG(DBG_info, "%s:\n\tdev->settings.xres=%d\n\tdev->settings.yres=%d\n", __func__, + dev->settings.xres, dev->settings.yres); +} + +bool CommandSetGl646::needs_home_before_init_regs_for_scan(Genesys_Device* dev) const +{ + return dev->is_head_pos_known(ScanHeadId::PRIMARY) && + dev->head_pos(ScanHeadId::PRIMARY) && + dev->settings.scan_method == ScanMethod::FLATBED; +} + +/** + * set up registers for the actual scan. The scan's parameters are given + * through the device settings. It allocates the scan buffers. + */ +void CommandSetGl646::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + + debug_dump(DBG_info, dev->settings); + + ScanSession session = calculate_scan_session(dev, sensor, dev->settings); + + init_regs_for_scan_session(dev, sensor, &dev->reg, session); + + /* gamma is only enabled at final scan time */ + if (dev->settings.depth < 16) { + dev->reg.find_reg(0x05).value |= REG_0x05_GMMENB; + } +} + +/** + * set up registers for the actual scan. The scan's parameters are given + * through the device settings. It allocates the scan buffers. + * @param dev scanner's device + * @param regs registers to set up + * @param settings settings of scan + * @param split true if move to scan area is split from scan, false is + * scan first moves to area + * @param xcorrection take x geometry correction into account (fixed and detected offsets) + * @param ycorrection take y geometry correction into account + */ +static void setup_for_scan(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set*regs, + Genesys_Settings settings, + bool split, + bool xcorrection, + bool ycorrection, + bool reverse) +{ + DBG_HELPER(dbg); + + debug_dump(DBG_info, dev->settings); + + // compute distance to move + float move = 0; + // XXX STEF XXX MD5345 -> optical_ydpi, other base_ydpi => half/full step ? */ + if (!split) { + if (!dev->model->is_sheetfed) { + if (ycorrection) { + move = static_cast<float>(dev->model->y_offset); + } + + // add tl_y to base movement + } + move += static_cast<float>(settings.tl_y); + + if (move < 0) { + DBG(DBG_error, "%s: overriding negative move value %f\n", __func__, move); + move = 0; + } + } + move = static_cast<float>((move * dev->motor.optical_ydpi) / MM_PER_INCH); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + float start = static_cast<float>(settings.tl_x); + if (xcorrection) { + if (settings.scan_method == ScanMethod::FLATBED) { + start += static_cast<float>(dev->model->x_offset); + } else { + start += static_cast<float>(dev->model->x_offset_ta); + } + } + start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = settings.xres; + session.params.yres = settings.yres; + session.params.startx = static_cast<unsigned>(start); + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = settings.pixels; + session.params.requested_pixels = settings.requested_pixels; + session.params.lines = settings.lines; + session.params.depth = settings.depth; + session.params.channels = settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = settings.scan_mode; + session.params.color_filter = settings.color_filter; + session.params.flags = ScanFlag::NONE; + if (settings.scan_method == ScanMethod::TRANSPARENCY) { + session.params.flags |= ScanFlag::USE_XPA; + } + if (xcorrection) { + session.params.flags |= ScanFlag::USE_XCORRECTION; + } + if (reverse) { + session.params.flags |= ScanFlag::REVERSE; + } + compute_session(dev, session, sensor); + + dev->cmd_set->init_regs_for_scan_session(dev, sensor, regs, session); +} + +/** + * this function send gamma table to ASIC + */ +void CommandSetGl646::send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + int size; + int address; + int bits; + + /* gamma table size */ + if (dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) + { + size = 16384; + bits = 14; + } + else + { + size = 4096; + bits = 12; + } + + /* allocate temporary gamma tables: 16 bits words, 3 channels */ + std::vector<uint8_t> gamma(size * 2 * 3); + + sanei_genesys_generate_gamma_buffer(dev, sensor, bits, size-1, size, gamma.data()); + + /* table address */ + switch (dev->reg.find_reg(0x05).value >> 6) + { + case 0: /* 600 dpi */ + address = 0x09000; + break; + case 1: /* 1200 dpi */ + address = 0x11000; + break; + case 2: /* 2400 dpi */ + address = 0x20000; + break; + default: + throw SaneException("invalid dpi"); + } + + dev->interface->write_buffer(0x3c, address, gamma.data(), size * 2 * 3); +} + +/** @brief this function does the led calibration. + * this function does the led calibration by scanning one line of the calibration + * area below scanner's top on white strip. The scope of this function is + * currently limited to the XP200 + */ +SensorExposure CommandSetGl646::led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + (void) regs; + int total_size; + unsigned int i, j; + int val; + int avg[3], avga, avge; + int turn; + uint16_t expr, expg, expb; + Genesys_Settings settings; + SANE_Int resolution; + + unsigned channels = dev->settings.get_channels(); + + /* get led calibration resolution */ + if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) + { + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + } + else + { + settings.scan_mode = ScanColorMode::GRAY; + } + resolution = get_closest_resolution(dev->model->sensor_id, sensor.optical_res, channels); + + /* offset calibration is always done in color mode */ + settings.scan_method = dev->model->default_method; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = (sensor.sensor_pixels * resolution) / sensor.optical_res; + settings.requested_pixels = settings.pixels; + settings.lines = 1; + settings.depth = 16; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + /* colors * bytes_per_color * scan lines */ + total_size = settings.pixels * channels * 2 * 1; + + std::vector<uint8_t> line(total_size); + +/* + we try to get equal bright leds here: + + loop: + average per color + adjust exposure times + */ + expr = sensor.exposure.red; + expg = sensor.exposure.green; + expb = sensor.exposure.blue; + + turn = 0; + + auto calib_sensor = sensor; + + bool acceptable = false; + do { + calib_sensor.exposure.red = expr; + calib_sensor.exposure.green = expg; + calib_sensor.exposure.blue = expb; + + DBG(DBG_info, "%s: starting first line reading\n", __func__); + + simple_scan(dev, calib_sensor, settings, false, true, false, line, "led_calibration"); + + if (is_testing_mode()) { + return calib_sensor.exposure; + } + + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl646_led_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, line.data(), 16, channels, settings.pixels, 1); + } + + acceptable = true; + + for (j = 0; j < channels; j++) + { + avg[j] = 0; + for (i = 0; i < settings.pixels; i++) + { + if (dev->model->is_cis) + val = + line[i * 2 + j * 2 * settings.pixels + 1] * 256 + + line[i * 2 + j * 2 * settings.pixels]; + else + val = + line[i * 2 * channels + 2 * j + 1] * 256 + + line[i * 2 * channels + 2 * j]; + avg[j] += val; + } + + avg[j] /= settings.pixels; + } + + DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); + + acceptable = true; + + if (!acceptable) + { + avga = (avg[0] + avg[1] + avg[2]) / 3; + expr = (expr * avga) / avg[0]; + expg = (expg * avga) / avg[1]; + expb = (expb * avga) / avg[2]; + + /* keep exposure time in a working window */ + avge = (expr + expg + expb) / 3; + if (avge > 0x2000) + { + expr = (expr * 0x2000) / avge; + expg = (expg * 0x2000) / avge; + expb = (expb * 0x2000) / avge; + } + if (avge < 0x400) + { + expr = (expr * 0x400) / avge; + expg = (expg * 0x400) / avge; + expb = (expb * 0x400) / avge; + } + } + + turn++; + + } + while (!acceptable && turn < 100); + + DBG(DBG_info,"%s: acceptable exposure: 0x%04x,0x%04x,0x%04x\n", __func__, expr, expg, expb); + // BUG: we don't store the result of the last iteration to the sensor + return calib_sensor.exposure; +} + +/** + * average dark pixels of a scan + */ +static int +dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, + unsigned int channels, unsigned int black) +{ + unsigned int i, j, k, average, count; + unsigned int avg[3]; + uint8_t val; + + /* computes average value on black margin */ + for (k = 0; k < channels; k++) + { + avg[k] = 0; + count = 0; + for (i = 0; i < lines; i++) + { + for (j = 0; j < black; j++) + { + val = data[i * channels * pixels + j + k]; + avg[k] += val; + count++; + } + } + if (count) + avg[k] /= count; + DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); + } + average = 0; + for (i = 0; i < channels; i++) + average += avg[i]; + average /= channels; + DBG(DBG_info, "%s: average = %d\n", __func__, average); + return average; +} + + +/** @brief calibration for AD frontend devices + * we do simple scan until all black_pixels are higher than 0, + * raising offset at each turn. + */ +static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor) +{ + DBG_HELPER(dbg); + (void) sensor; + + unsigned int channels; + int pass = 0; + SANE_Int resolution; + Genesys_Settings settings; + unsigned int x, y, adr, min; + unsigned int bottom, black_pixels; + + channels = 3; + resolution = get_closest_resolution(dev->model->sensor_id, sensor.optical_res, channels); + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, 3, ScanMethod::FLATBED); + black_pixels = (calib_sensor.black_pixels * resolution) / calib_sensor.optical_res; + DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); + + settings.scan_method = dev->model->default_method; + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = (calib_sensor.sensor_pixels * resolution) / calib_sensor.optical_res; + settings.requested_pixels = settings.pixels; + settings.lines = CALIBRATION_LINES; + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + /* scan first line of data with no gain */ + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + + std::vector<uint8_t> line; + + /* scan with no move */ + bottom = 1; + do + { + pass++; + dev->frontend.set_offset(0, bottom); + dev->frontend.set_offset(1, bottom); + dev->frontend.set_offset(2, bottom); + simple_scan(dev, calib_sensor, settings, false, true, false, line, + "ad_fe_offset_calibration"); + + if (is_testing_mode()) { + return; + } + + if (DBG_LEVEL >= DBG_data) + { + char title[30]; + std::snprintf(title, 30, "gl646_offset%03d.pnm", static_cast<int>(bottom)); + sanei_genesys_write_pnm_file (title, line.data(), 8, channels, + settings.pixels, settings.lines); + } + + min = 0; + for (y = 0; y < settings.lines; y++) + { + for (x = 0; x < black_pixels; x++) + { + adr = (x + y * settings.pixels) * channels; + if (line[adr] > min) + min = line[adr]; + if (line[adr + 1] > min) + min = line[adr + 1]; + if (line[adr + 2] > min) + min = line[adr + 2]; + } + } + + DBG(DBG_io2, "%s: pass=%d, min=%d\n", __func__, pass, min); + bottom++; + } + while (pass < 128 && min == 0); + if (pass == 128) + { + throw SaneException(SANE_STATUS_INVAL, "failed to find correct offset"); + } + + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); +} + +/** + * This function does the offset calibration by scanning one line of the calibration + * area below scanner's top. There is a black margin and the remaining is white. + * genesys_search_start() must have been called so that the offsets and margins + * are already known. + * @param dev scanner's device +*/ +void CommandSetGl646::offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + (void) regs; + + unsigned int channels; + int pass = 0, avg; + Genesys_Settings settings; + int topavg, bottomavg; + int top, bottom, black_pixels; + + if (dev->model->adc_id == AdcId::AD_XP200) { + ad_fe_offset_calibration(dev, sensor); + return; + } + + DBG(DBG_proc, "%s: start\n", __func__); // TODO + + /* setup for a RGB scan, one full sensor's width line */ + /* resolution is the one from the final scan */ + channels = 3; + int resolution = get_closest_resolution(dev->model->sensor_id, dev->settings.xres, channels); + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, 3, ScanMethod::FLATBED); + black_pixels = (calib_sensor.black_pixels * resolution) / calib_sensor.optical_res; + + DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); + + settings.scan_method = dev->model->default_method; + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = (calib_sensor.sensor_pixels * resolution) / calib_sensor.optical_res; + settings.requested_pixels = settings.pixels; + settings.lines = CALIBRATION_LINES; + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + /* scan first line of data with no gain, but with offset from + * last calibration */ + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + + /* scan with no move */ + bottom = 90; + dev->frontend.set_offset(0, bottom); + dev->frontend.set_offset(1, bottom); + dev->frontend.set_offset(2, bottom); + + std::vector<uint8_t> first_line, second_line; + + simple_scan(dev, calib_sensor, settings, false, true, false, first_line, + "offset_first_line"); + + if (DBG_LEVEL >= DBG_data) + { + char title[30]; + std::snprintf(title, 30, "gl646_offset%03d.pnm", bottom); + sanei_genesys_write_pnm_file(title, first_line.data(), 8, channels, + settings.pixels, settings.lines); + } + bottomavg = dark_average(first_line.data(), settings.pixels, settings.lines, channels, + black_pixels); + DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); + + /* now top value */ + top = 231; + dev->frontend.set_offset(0, top); + dev->frontend.set_offset(1, top); + dev->frontend.set_offset(2, top); + simple_scan(dev, calib_sensor, settings, false, true, false, second_line, + "offset_second_line"); + + if (DBG_LEVEL >= DBG_data) + { + char title[30]; + std::snprintf(title, 30, "gl646_offset%03d.pnm", top); + sanei_genesys_write_pnm_file (title, second_line.data(), 8, channels, + settings.pixels, settings.lines); + } + topavg = dark_average(second_line.data(), settings.pixels, settings.lines, channels, + black_pixels); + DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); + + if (is_testing_mode()) { + return; + } + + /* loop until acceptable level */ + while ((pass < 32) && (top - bottom > 1)) + { + pass++; + + /* settings for new scan */ + dev->frontend.set_offset(0, (top + bottom) / 2); + dev->frontend.set_offset(1, (top + bottom) / 2); + dev->frontend.set_offset(2, (top + bottom) / 2); + + // scan with no move + simple_scan(dev, calib_sensor, settings, false, true, false, second_line, + "offset_calibration_i"); + + if (DBG_LEVEL >= DBG_data) + { + char title[30]; + std::snprintf(title, 30, "gl646_offset%03d.pnm", dev->frontend.get_offset(1)); + sanei_genesys_write_pnm_file (title, second_line.data(), 8, channels, + settings.pixels, settings.lines); + } + + avg = + dark_average (second_line.data(), settings.pixels, settings.lines, channels, + black_pixels); + DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); + + /* compute new boundaries */ + if (topavg == avg) + { + topavg = avg; + top = dev->frontend.get_offset(1); + } + else + { + bottomavg = avg; + bottom = dev->frontend.get_offset(1); + } + } + + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); +} + +/** @brief gain calibration for Analog Device frontends + * Alternative coarse gain calibration + */ +static void ad_fe_coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) +{ + DBG_HELPER(dbg); + (void) sensor; + (void) regs; + + unsigned int i, channels, val; + unsigned int size, count, resolution, pass; + float average; + Genesys_Settings settings; + char title[32]; + + /* setup for a RGB scan, one full sensor's width line */ + /* resolution is the one from the final scan */ + channels = 3; + resolution = get_closest_resolution(dev->model->sensor_id, dpi, channels); + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, 3, ScanMethod::FLATBED); + + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + + settings.scan_method = dev->model->default_method; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = (calib_sensor.sensor_pixels * resolution) / calib_sensor.optical_res; + settings.requested_pixels = settings.pixels; + settings.lines = CALIBRATION_LINES; + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + size = channels * settings.pixels * settings.lines; + + /* start gain value */ + dev->frontend.set_gain(0, 1); + dev->frontend.set_gain(1, 1); + dev->frontend.set_gain(2, 1); + + average = 0; + pass = 0; + + std::vector<uint8_t> line; + + // loop until each channel raises to acceptable level + while ((average < calib_sensor.gain_white_ref) && (pass < 30)) { + // scan with no move + simple_scan(dev, calib_sensor, settings, false, true, false, line, + "ad_fe_coarse_gain_calibration"); + + /* log scanning data */ + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl646_alternative_gain%02d.pnm", pass); + sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels, + settings.lines); + } + pass++; + + /* computes white average */ + average = 0; + count = 0; + for (i = 0; i < size; i++) + { + val = line[i]; + average += val; + count++; + } + average = average / count; + + uint8_t gain0 = dev->frontend.get_gain(0); + // adjusts gain for the channel + if (average < calib_sensor.gain_white_ref) { + gain0 += 1; + } + + dev->frontend.set_gain(0, gain0); + dev->frontend.set_gain(1, gain0); + dev->frontend.set_gain(2, gain0); + + DBG(DBG_proc, "%s: average = %.2f, gain = %d\n", __func__, average, gain0); + } + + DBG(DBG_info, "%s: gains=(%d,%d,%d)\n", __func__, + dev->frontend.get_gain(0), + dev->frontend.get_gain(1), + dev->frontend.get_gain(2)); +} + +/** + * Alternative coarse gain calibration + * this on uses the settings from offset_calibration. First scan moves so + * we can go to calibration area for XPA. + * @param dev device for scan + * @param dpi resolutnio to calibrate at + */ +void CommandSetGl646::coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const +{ + DBG_HELPER(dbg); + (void) dpi; + + unsigned int i, j, k, channels, val, maximum, idx; + unsigned int count, resolution, pass; + float average[3]; + Genesys_Settings settings; + char title[32]; + + if (dev->model->sensor_id == SensorId::CIS_XP200) { + return ad_fe_coarse_gain_calibration(dev, sensor, regs, sensor.optical_res); + } + + /* setup for a RGB scan, one full sensor's width line */ + /* resolution is the one from the final scan */ + channels = 3; + + /* we are searching a sensor resolution */ + resolution = get_closest_resolution(dev->model->sensor_id, dev->settings.xres, channels); + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels, + ScanMethod::FLATBED); + + settings.scan_method = dev->settings.scan_method; + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_y = 0; + if (settings.scan_method == ScanMethod::FLATBED) + { + settings.tl_x = 0; + settings.pixels = (calib_sensor.sensor_pixels * resolution) / calib_sensor.optical_res; + } + else + { + settings.tl_x = dev->model->x_offset_ta; + settings.pixels = static_cast<unsigned>((dev->model->x_size_ta * resolution) / MM_PER_INCH); + } + settings.requested_pixels = settings.pixels; + settings.lines = CALIBRATION_LINES; + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + /* start gain value */ + dev->frontend.set_gain(0, 1); + dev->frontend.set_gain(1, 1); + dev->frontend.set_gain(2, 1); + + if (channels > 1) + { + average[0] = 0; + average[1] = 0; + average[2] = 0; + idx = 0; + } + else + { + average[0] = 255; + average[1] = 255; + average[2] = 255; + switch (dev->settings.color_filter) { + case ColorFilter::RED: idx = 0; break; + case ColorFilter::GREEN: idx = 1; break; + case ColorFilter::BLUE: idx = 2; break; + default: idx = 0; break; // should not happen + } + average[idx] = 0; + } + pass = 0; + + std::vector<uint8_t> line; + + /* loop until each channel raises to acceptable level */ + while (((average[0] < calib_sensor.gain_white_ref) || + (average[1] < calib_sensor.gain_white_ref) || + (average[2] < calib_sensor.gain_white_ref)) && (pass < 30)) + { + // scan with no move + simple_scan(dev, calib_sensor, settings, false, true, false, line, + "coarse_gain_calibration"); + + /* log scanning data */ + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl646_gain%02d.pnm", pass); + sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels, + settings.lines); + } + pass++; + + /* average high level for each channel and compute gain + to reach the target code + we only use the central half of the CCD data */ + for (k = idx; k < idx + channels; k++) + { + /* we find the maximum white value, so we can deduce a threshold + to average white values */ + maximum = 0; + for (i = 0; i < settings.lines; i++) + { + for (j = 0; j < settings.pixels; j++) + { + val = line[i * channels * settings.pixels + j + k]; + if (val > maximum) + maximum = val; + } + } + + /* threshold */ + maximum = static_cast<int>(maximum * 0.9); + + /* computes white average */ + average[k] = 0; + count = 0; + for (i = 0; i < settings.lines; i++) + { + for (j = 0; j < settings.pixels; j++) + { + /* averaging only white points allow us not to care about dark margins */ + val = line[i * channels * settings.pixels + j + k]; + if (val > maximum) + { + average[k] += val; + count++; + } + } + } + average[k] = average[k] / count; + + /* adjusts gain for the channel */ + if (average[k] < calib_sensor.gain_white_ref) + dev->frontend.set_gain(k, dev->frontend.get_gain(k) + 1); + + DBG(DBG_proc, "%s: channel %d, average = %.2f, gain = %d\n", __func__, k, average[k], + dev->frontend.get_gain(k)); + } + } + + if (channels < 3) { + dev->frontend.set_gain(1, dev->frontend.get_gain(0)); + dev->frontend.set_gain(2, dev->frontend.get_gain(0)); + } + + DBG(DBG_info, "%s: gains=(%d,%d,%d)\n", __func__, + dev->frontend.get_gain(0), + dev->frontend.get_gain(1), + dev->frontend.get_gain(2)); +} + +/** + * sets up the scanner's register for warming up. We scan 2 lines without moving. + * + */ +void CommandSetGl646::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* local_reg, int* channels, + int* total_size) const +{ + DBG_HELPER(dbg); + (void) sensor; + + Genesys_Settings settings; + int resolution, lines; + + dev->frontend = dev->frontend_initial; + + resolution = get_closest_resolution(dev->model->sensor_id, 300, 1); + + const auto& local_sensor = sanei_genesys_find_sensor(dev, resolution, 1, + dev->settings.scan_method); + + /* set up for a half width 2 lines gray scan without moving */ + settings.scan_method = dev->model->default_method; + settings.scan_mode = ScanColorMode::GRAY; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = (local_sensor.sensor_pixels * resolution) / local_sensor.optical_res; + settings.requested_pixels = settings.pixels; + settings.lines = 2; + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + // setup for scan + setup_for_scan(dev, local_sensor, &dev->reg, settings, true, false, false, false); + + /* we are not going to move, so clear these bits */ + dev->reg.find_reg(0x02).value &= ~(REG_0x02_FASTFED | REG_0x02_AGOHOME); + + /* don't enable any correction for this scan */ + dev->reg.find_reg(0x01).value &= ~REG_0x01_DVDSET; + + /* copy to local_reg */ + *local_reg = dev->reg; + + /* turn off motor during this scan */ + sanei_genesys_set_motor_power(*local_reg, false); + + /* returned value to higher level warmup function */ + *channels = 1; + lines = local_reg->get24(REG_LINCNT) + 1; + *total_size = lines * settings.pixels; + + // now registers are ok, write them to scanner + gl646_set_fe(dev, local_sensor, AFE_SET, settings.xres); + dev->interface->write_registers(*local_reg); +} + + +/* + * this function moves head without scanning, forward, then backward + * so that the head goes to park position. + * as a by-product, also check for lock + */ +static void gl646_repark_head(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + Genesys_Settings settings; + unsigned int expected, steps; + + settings.scan_method = dev->model->default_method; + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + settings.xres = get_closest_resolution(dev->model->sensor_id, 75, 1); + settings.yres = settings.xres; + settings.tl_x = 0; + settings.tl_y = 5; + settings.pixels = 600; + settings.requested_pixels = settings.pixels; + settings.lines = 4; + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + const auto& sensor = sanei_genesys_find_sensor(dev, settings.xres, 3, + dev->model->default_method); + + setup_for_scan(dev, sensor, &dev->reg, settings, false, false, false, false); + + /* TODO seems wrong ... no effective scan */ + regs_set_optical_off(dev->model->asic_type, dev->reg); + + dev->interface->write_registers(dev->reg); + + // start scan + dev->cmd_set->begin_scan(dev, sensor, &dev->reg, true); + + expected = dev->reg.get24(REG_FEEDL); + do + { + dev->interface->sleep_ms(100); + sanei_genesys_read_feed_steps (dev, &steps); + } + while (steps < expected); + + // toggle motor flag, put an huge step number and redo move backward + dev->cmd_set->move_back_home(dev, 1); +} + +/* * + * initialize ASIC : registers, motor tables, and gamma tables + * then ensure scanner's head is at home + * @param dev device description of the scanner to initailize + */ +void CommandSetGl646::init(Genesys_Device* dev) const +{ + DBG_INIT(); + DBG_HELPER(dbg); + + uint8_t val = 0; + uint32_t addr = 0xdead; + size_t len; + + // to detect real power up condition, we write to REG_0x41 with pwrbit set, then read it back. + // When scanner is cold (just replugged) PWRBIT will be set in the returned value + auto status = scanner_read_status(*dev); + if (status.is_replugged) { + DBG(DBG_info, "%s: device is cold\n", __func__); + } else { + DBG(DBG_info, "%s: device is hot\n", __func__); + } + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + /* if scanning session hasn't been initialized, set it up */ + if (!dev->already_initialized) + { + dev->dark_average_data.clear(); + dev->white_average_data.clear(); + + dev->settings.color_filter = ColorFilter::GREEN; + + /* Set default values for registers */ + gl646_init_regs (dev); + + // Init shading data + sanei_genesys_init_shading_data(dev, sensor, sensor.sensor_pixels); + + /* initial calibration reg values */ + dev->calib_reg = dev->reg; + } + + // execute physical unit init only if cold + if (status.is_replugged) + { + DBG(DBG_info, "%s: device is cold\n", __func__); + + val = 0x04; + dev->interface->get_usb_device().control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, + VALUE_INIT, INDEX, 1, &val); + + // ASIC reset + dev->interface->write_register(0x0e, 0x00); + dev->interface->sleep_ms(100); + + // Write initial registers + dev->interface->write_registers(dev->reg); + + // send gamma tables if needed + dev->cmd_set->send_gamma_table(dev, sensor); + + // Set powersaving(default = 15 minutes) + dev->cmd_set->set_powersaving(dev, 15); + } + + // Set analog frontend + gl646_set_fe(dev, sensor, AFE_INIT, 0); + + /* GPO enabling for XP200 */ + if (dev->model->sensor_id == SensorId::CIS_XP200) { + dev->interface->write_register(0x68, dev->gpo.regs.get_value(0x68)); + dev->interface->write_register(0x69, dev->gpo.regs.get_value(0x69)); + + // enable GPIO + gl646_gpio_output_enable(dev->interface->get_usb_device(), 6); + + // writes 0 to GPIO + gl646_gpio_write(dev->interface->get_usb_device(), 0); + + // clear GPIO enable + gl646_gpio_output_enable(dev->interface->get_usb_device(), 0); + + dev->interface->write_register(0x66, 0x10); + dev->interface->write_register(0x66, 0x00); + dev->interface->write_register(0x66, 0x10); + } + + /* MD6471/G2410 and XP200 read/write data from an undocumented memory area which + * is after the second slope table */ + if (dev->model->gpio_id != GpioId::HP3670 && + dev->model->gpio_id != GpioId::HP2400) + { + switch (sensor.optical_res) + { + case 600: + addr = 0x08200; + break; + case 1200: + addr = 0x10200; + break; + case 2400: + addr = 0x1fa00; + break; + } + sanei_genesys_set_buffer_address(dev, addr); + + sanei_usb_set_timeout (2 * 1000); + len = 6; + // for some reason, read fails here for MD6471, HP2300 and XP200 one time out of + // 2 scanimage launches + try { + dev->interface->bulk_read_data(0x45, dev->control, len); + } catch (...) { + dev->interface->bulk_read_data(0x45, dev->control, len); + } + DBG(DBG_info, "%s: control read=0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__, + dev->control[0], dev->control[1], dev->control[2], dev->control[3], dev->control[4], + dev->control[5]); + sanei_usb_set_timeout (30 * 1000); + } + else + /* HP2400 and HP3670 case */ + { + dev->control[0] = 0x00; + dev->control[1] = 0x00; + dev->control[2] = 0x01; + dev->control[3] = 0x00; + dev->control[4] = 0x00; + dev->control[5] = 0x00; + } + + /* ensure head is correctly parked, and check lock */ + if (!dev->model->is_sheetfed) { + if (dev->model->flags & GENESYS_FLAG_REPARK) + { + // FIXME: if repark fails, we should print an error message that the scanner is locked and + // the user should unlock the lock. We should also rethrow with SANE_STATUS_JAMMED + gl646_repark_head(dev); + } + else + { + move_back_home(dev, true); + } + } + + /* here session and device are initialized */ + dev->already_initialized = true; +} + +void CommandSetGl646::move_to_ta(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + + simple_move(dev, static_cast<int>(dev->model->y_offset_sensor_to_ta)); +} + + +/** + * Does a simple scan: ie no line reordering and avanced data buffering and + * shading correction. Memory for data is allocated in this function + * and must be freed by caller. + * @param dev device of the scanner + * @param settings parameters of the scan + * @param move true if moving during scan + * @param forward true if moving forward during scan + * @param shading true to enable shading correction + * @param data pointer for the data + */ +static void simple_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Settings settings, bool move, bool forward, + bool shading, std::vector<uint8_t>& data, + const char* scan_identifier) +{ + DBG_HELPER_ARGS(dbg, "move=%d, forward=%d, shading=%d", move, forward, shading); + unsigned int size, lines, x, y, bpp; + bool split; + + /* round up to multiple of 3 in case of CIS scanner */ + if (dev->model->is_cis) { + settings.lines = ((settings.lines + 2) / 3) * 3; + } + + /* setup for move then scan */ + split = !(move && settings.tl_y > 0); + setup_for_scan(dev, sensor, &dev->reg, settings, split, false, false, !forward); + + /* allocate memory fo scan : LINCNT may have been adjusted for CCD reordering */ + if (dev->model->is_cis) { + lines = dev->reg.get24(REG_LINCNT) / 3; + } else { + lines = dev->reg.get24(REG_LINCNT) + 1; + } + size = lines * settings.pixels; + if (settings.depth == 16) { + bpp = 2; + } else { + bpp = 1; + } + size *= bpp * settings.get_channels(); + data.clear(); + data.resize(size); + + DBG(DBG_io, "%s: allocated %d bytes of memory for %d lines\n", __func__, size, lines); + + /* put back real line number in settings */ + settings.lines = lines; + + // initialize frontend + gl646_set_fe(dev, sensor, AFE_SET, settings.xres); + + /* no shading correction and not watch dog for simple scan */ + dev->reg.find_reg(0x01).value &= ~(REG_0x01_DVDSET | REG_0x01_DOGENB); + if (shading) { + dev->reg.find_reg(0x01).value |= REG_0x01_DVDSET; + } + + /* enable gamma table for the scan */ + dev->reg.find_reg(0x05).value |= REG_0x05_GMMENB; + + /* one table movement for simple scan */ + dev->reg.find_reg(0x02).value &= ~REG_0x02_FASTFED; + + if (!move) { + sanei_genesys_set_motor_power(dev->reg, false); + + /* no automatic go home if no movement */ + dev->reg.find_reg(0x02).value &= ~REG_0x02_AGOHOME; + } + + /* no automatic go home when using XPA */ + if (settings.scan_method == ScanMethod::TRANSPARENCY) { + dev->reg.find_reg(0x02).value &= ~REG_0x02_AGOHOME; + } + + // write scan registers + dev->interface->write_registers(dev->reg); + + // starts scan + dev->cmd_set->begin_scan(dev, sensor, &dev->reg, move); + + if (is_testing_mode()) { + dev->interface->test_checkpoint(scan_identifier); + return; + } + + wait_until_buffer_non_empty(dev, true); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + /* in case of CIS scanner, we must reorder data */ + if (dev->model->is_cis && settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) { + /* alloc one line sized working buffer */ + std::vector<uint8_t> buffer(settings.pixels * 3 * bpp); + + /* reorder one line of data and put it back to buffer */ + if (bpp == 1) + { + for (y = 0; y < lines; y++) + { + /* reorder line */ + for (x = 0; x < settings.pixels; x++) + { + buffer[x * 3] = data[y * settings.pixels * 3 + x]; + buffer[x * 3 + 1] = data[y * settings.pixels * 3 + settings.pixels + x]; + buffer[x * 3 + 2] = data[y * settings.pixels * 3 + 2 * settings.pixels + x]; + } + /* copy line back */ + memcpy (data.data() + settings.pixels * 3 * y, buffer.data(), + settings.pixels * 3); + } + } + else + { + for (y = 0; y < lines; y++) + { + /* reorder line */ + for (x = 0; x < settings.pixels; x++) + { + buffer[x * 6] = data[y * settings.pixels * 6 + x * 2]; + buffer[x * 6 + 1] = data[y * settings.pixels * 6 + x * 2 + 1]; + buffer[x * 6 + 2] = data[y * settings.pixels * 6 + 2 * settings.pixels + x * 2]; + buffer[x * 6 + 3] = data[y * settings.pixels * 6 + 2 * settings.pixels + x * 2 + 1]; + buffer[x * 6 + 4] = data[y * settings.pixels * 6 + 4 * settings.pixels + x * 2]; + buffer[x * 6 + 5] = data[y * settings.pixels * 6 + 4 * settings.pixels + x * 2 + 1]; + } + /* copy line back */ + memcpy (data.data() + settings.pixels * 6 * y, buffer.data(), + settings.pixels * 6); + } + } + } + + // end scan , waiting the motor to stop if needed (if moving), but without ejecting doc + end_scan_impl(dev, &dev->reg, true, false); +} + +/** + * Does a simple move of the given distance by doing a scan at lowest resolution + * shading correction. Memory for data is allocated in this function + * and must be freed by caller. + * @param dev device of the scanner + * @param distance distance to move in MM + */ +static void simple_move(Genesys_Device* dev, SANE_Int distance) +{ + DBG_HELPER_ARGS(dbg, "%d mm", distance); + Genesys_Settings settings; + + unsigned resolution = sanei_genesys_get_lowest_dpi(dev); + + const auto& sensor = sanei_genesys_find_sensor(dev, resolution, 3, dev->model->default_method); + + /* TODO give a no AGOHOME flag */ + settings.scan_method = dev->model->default_method; + settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + settings.xres = resolution; + settings.yres = resolution; + settings.tl_y = 0; + settings.tl_x = 0; + settings.pixels = (sensor.sensor_pixels * settings.xres) / sensor.optical_res; + settings.requested_pixels = settings.pixels; + settings.lines = static_cast<unsigned>((distance * settings.xres) / MM_PER_INCH); + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + std::vector<uint8_t> data; + simple_scan(dev, sensor, settings, true, true, false, data, "simple_move"); +} + +/** + * update the status of the required sensor in the scanner session + * the button fileds are used to make events 'sticky' + */ +void CommandSetGl646::update_hardware_sensors(Genesys_Scanner* session) const +{ + DBG_HELPER(dbg); + Genesys_Device *dev = session->dev; + uint8_t value; + + // do what is needed to get a new set of events, but try to not loose any of them. + gl646_gpio_read(dev->interface->get_usb_device(), &value); + DBG(DBG_io, "%s: GPIO=0x%02x\n", __func__, value); + + // scan button + if (dev->model->buttons & GENESYS_HAS_SCAN_SW) { + switch (dev->model->gpio_id) { + case GpioId::XP200: + session->buttons[BUTTON_SCAN_SW].write((value & 0x02) != 0); + break; + case GpioId::MD_5345: + session->buttons[BUTTON_SCAN_SW].write(value == 0x16); + break; + case GpioId::HP2300: + session->buttons[BUTTON_SCAN_SW].write(value == 0x6c); + break; + case GpioId::HP3670: + case GpioId::HP2400: + session->buttons[BUTTON_SCAN_SW].write((value & 0x20) == 0); + break; + default: + throw SaneException(SANE_STATUS_UNSUPPORTED, "unknown gpo type"); + } + } + + // email button + if (dev->model->buttons & GENESYS_HAS_EMAIL_SW) { + switch (dev->model->gpio_id) { + case GpioId::MD_5345: + session->buttons[BUTTON_EMAIL_SW].write(value == 0x12); + break; + case GpioId::HP3670: + case GpioId::HP2400: + session->buttons[BUTTON_EMAIL_SW].write((value & 0x08) == 0); + break; + default: + throw SaneException(SANE_STATUS_UNSUPPORTED, "unknown gpo type"); + } + } + + // copy button + if (dev->model->buttons & GENESYS_HAS_COPY_SW) { + switch (dev->model->gpio_id) { + case GpioId::MD_5345: + session->buttons[BUTTON_COPY_SW].write(value == 0x11); + break; + case GpioId::HP2300: + session->buttons[BUTTON_COPY_SW].write(value == 0x5c); + break; + case GpioId::HP3670: + case GpioId::HP2400: + session->buttons[BUTTON_COPY_SW].write((value & 0x10) == 0); + break; + default: + throw SaneException(SANE_STATUS_UNSUPPORTED, "unknown gpo type"); + } + } + + // power button + if (dev->model->buttons & GENESYS_HAS_POWER_SW) { + switch (dev->model->gpio_id) { + case GpioId::MD_5345: + session->buttons[BUTTON_POWER_SW].write(value == 0x14); + break; + default: + throw SaneException(SANE_STATUS_UNSUPPORTED, "unknown gpo type"); + } + } + + // ocr button + if (dev->model->buttons & GENESYS_HAS_OCR_SW) { + switch (dev->model->gpio_id) { + case GpioId::MD_5345: + session->buttons[BUTTON_OCR_SW].write(value == 0x13); + break; + default: + throw SaneException(SANE_STATUS_UNSUPPORTED, "unknown gpo type"); + } + } + + // document detection + if (dev->model->buttons & GENESYS_HAS_PAGE_LOADED_SW) { + switch (dev->model->gpio_id) { + case GpioId::XP200: + session->buttons[BUTTON_PAGE_LOADED_SW].write((value & 0x04) != 0); + break; + default: + throw SaneException(SANE_STATUS_UNSUPPORTED, "unknown gpo type"); + } + } + + /* XPA detection */ + if (dev->model->flags & GENESYS_FLAG_XPA) + { + switch (dev->model->gpio_id) { + case GpioId::HP3670: + case GpioId::HP2400: + /* test if XPA is plugged-in */ + if ((value & 0x40) == 0) + { + DBG(DBG_io, "%s: enabling XPA\n", __func__); + session->opt[OPT_SOURCE].cap &= ~SANE_CAP_INACTIVE; + } + else + { + DBG(DBG_io, "%s: disabling XPA\n", __func__); + session->opt[OPT_SOURCE].cap |= SANE_CAP_INACTIVE; + } + break; + default: + throw SaneException(SANE_STATUS_UNSUPPORTED, "unknown gpo type"); + } + } +} + + +static void write_control(Genesys_Device* dev, const Genesys_Sensor& sensor, int resolution) +{ + DBG_HELPER(dbg); + uint8_t control[4]; + uint32_t addr = 0xdead; + + /* 2300 does not write to 'control' */ + if (dev->model->motor_id == MotorId::HP2300) { + return; + } + + /* MD6471/G2410/HP2300 and XP200 read/write data from an undocumented memory area which + * is after the second slope table */ + switch (sensor.optical_res) + { + case 600: + addr = 0x08200; + break; + case 1200: + addr = 0x10200; + break; + case 2400: + addr = 0x1fa00; + break; + default: + throw SaneException("failed to compute control address"); + } + + /* XP200 sets dpi, what other scanner put is unknown yet */ + switch (dev->model->motor_id) + { + case MotorId::XP200: + /* we put scan's dpi, not motor one */ + control[0] = resolution & 0xff; + control[1] = (resolution >> 8) & 0xff; + control[2] = dev->control[4]; + control[3] = dev->control[5]; + break; + case MotorId::HP3670: + case MotorId::HP2400: + case MotorId::MD_5345: + default: + control[0] = dev->control[2]; + control[1] = dev->control[3]; + control[2] = dev->control[4]; + control[3] = dev->control[5]; + break; + } + + DBG(DBG_info, "%s: control write=0x%02x 0x%02x 0x%02x 0x%02x\n", __func__, control[0], control[1], + control[2], control[3]); + dev->interface->write_buffer(0x3c, addr, control, 4); +} + +/** + * search for a full width black or white strip. + * @param dev scanner device + * @param forward true if searching forward, false if searching backward + * @param black true if searching for a black strip, false for a white strip + */ +void CommandSetGl646::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward, + bool black) const +{ + DBG_HELPER(dbg); + (void) sensor; + + Genesys_Settings settings; + int res = get_closest_resolution(dev->model->sensor_id, 75, 1); + unsigned int pass, count, found, x, y; + char title[80]; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, res, 1, ScanMethod::FLATBED); + + /* we set up for a lowest available resolution color grey scan, full width */ + settings.scan_method = dev->model->default_method; + settings.scan_mode = ScanColorMode::GRAY; + settings.xres = res; + settings.yres = res; + settings.tl_x = 0; + settings.tl_y = 0; + settings.pixels = static_cast<unsigned>((dev->model->x_size * res) / MM_PER_INCH); + settings.pixels /= calib_sensor.get_ccd_size_divisor_for_dpi(res); + settings.requested_pixels = settings.pixels; + + /* 15 mm at at time */ + settings.lines = static_cast<unsigned>((15 * settings.yres) / MM_PER_INCH); + settings.depth = 8; + settings.color_filter = ColorFilter::RED; + + settings.disable_interpolation = 0; + settings.threshold = 0; + + /* signals if a strip of the given color has been found */ + found = 0; + + /* detection pass done */ + pass = 0; + + std::vector<uint8_t> data; + + /* loop until strip is found or maximum pass number done */ + while (pass < 20 && !found) + { + // scan a full width strip + simple_scan(dev, calib_sensor, settings, true, forward, false, data, "search_strip"); + + if (is_testing_mode()) { + return; + } + + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl646_search_strip_%s%02d.pnm", forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file (title, data.data(), settings.depth, 1, + settings.pixels, settings.lines); + } + + /* search data to find black strip */ + /* when searching forward, we only need one line of the searched color since we + * will scan forward. But when doing backward search, we need all the area of the + * same color */ + if (forward) + { + for (y = 0; y < settings.lines && !found; y++) + { + count = 0; + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < settings.pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * settings.pixels + x] > 90) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * settings.pixels + x] < 60) + { + count++; + } + } + + /* at end of line, if count >= 3%, line is not fully of the desired color + * so we must go to next line of the buffer */ + /* count*100/pixels < 3 */ + if ((count * 100) / settings.pixels < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, + pass, y); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d\n", __func__, settings.pixels, count); + } + } + } + else /* since calibration scans are done forward, we need the whole area + to be of the required color when searching backward */ + { + count = 0; + for (y = 0; y < settings.lines; y++) + { + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < settings.pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * settings.pixels + x] > 60) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * settings.pixels + x] < 60) + { + count++; + } + } + } + + /* at end of area, if count >= 3%, area is not fully of the desired color + * so we must go to next buffer */ + if ((count * 100) / (settings.pixels * settings.lines) < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d\n", __func__, settings.pixels, count); + } + } + pass++; + } + if (found) + { + DBG(DBG_info, "%s: strip found\n", __func__); + } + else + { + throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white"); + } +} + +void CommandSetGl646::wait_for_motor_stop(Genesys_Device* dev) const +{ + (void) dev; +} + +void CommandSetGl646::send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + std::uint8_t* data, int size) const +{ + (void) dev; + (void) sensor; + (void) data; + (void) size; + throw SaneException("not implemented"); +} + +ScanSession CommandSetGl646::calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const +{ + // compute distance to move + float move = 0; + // XXX STEF XXX MD5345 -> optical_ydpi, other base_ydpi => half/full step ? */ + if (!dev->model->is_sheetfed) { + move = static_cast<float>(dev->model->y_offset); + // add tl_y to base movement + } + move += static_cast<float>(settings.tl_y); + + if (move < 0) { + DBG(DBG_error, "%s: overriding negative move value %f\n", __func__, move); + move = 0; + } + + move = static_cast<float>((move * dev->motor.optical_ydpi) / MM_PER_INCH); + float start = static_cast<float>(settings.tl_x); + if (settings.scan_method == ScanMethod::FLATBED) { + start += static_cast<float>(dev->model->x_offset); + } else { + start += static_cast<float>(dev->model->x_offset_ta); + } + start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = settings.xres; + session.params.yres = settings.yres; + session.params.startx = static_cast<unsigned>(start); + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = settings.pixels; + session.params.requested_pixels = settings.requested_pixels; + session.params.lines = settings.lines; + session.params.depth = settings.depth; + session.params.channels = settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = settings.scan_mode; + session.params.color_filter = settings.color_filter; + session.params.flags = ScanFlag::USE_XCORRECTION; + if (settings.scan_method == ScanMethod::TRANSPARENCY) { + session.params.flags |= ScanFlag::USE_XPA; + } + compute_session(dev, session, sensor); + + return session; +} + +void CommandSetGl646::asic_boot(Genesys_Device *dev, bool cold) const +{ + (void) dev; + (void) cold; + throw SaneException("not implemented"); +} + +std::unique_ptr<CommandSet> create_gl646_cmd_set() +{ + return std::unique_ptr<CommandSet>(new CommandSetGl646{}); +} + +} // namespace gl646 +} // namespace genesys diff --git a/backend/genesys/gl646.h b/backend/genesys/gl646.h new file mode 100644 index 0000000..afcfa05 --- /dev/null +++ b/backend/genesys/gl646.h @@ -0,0 +1,521 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2003-2004 Henning Meier-Geinitz <henning@meier-geinitz.de> + Copyright (C) 2004-2005 Gerhard Jaeger <gerhard@gjaeger.de> + Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> + Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL646_H +#define BACKEND_GENESYS_GL646_H + +#include "genesys.h" +#include "command_set.h" +#include "motor.h" + +namespace genesys { +namespace gl646 { + +static void gl646_set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set, int dpi); + +/** + * sets up the scanner for a scan, registers, gamma tables, shading tables + * and slope tables, based on the parameter struct. + * @param dev device to set up + * @param regs registers to set up + * @param settings settings of the scan + * @param split true if move before scan has to be done + * @param xcorrection true if scanner's X geometry must be taken into account to + * compute X, ie add left margins + * @param ycorrection true if scanner's Y geometry must be taken into account to + * compute Y, ie add top margins + */ +static void setup_for_scan(Genesys_Device* device, + const Genesys_Sensor& sensor, + Genesys_Register_Set*regs, + Genesys_Settings settings, + bool split, + bool xcorrection, + bool ycorrection, + bool reverse); + +/** + * Does a simple move of the given distance by doing a scan at lowest resolution + * shading correction. Memory for data is allocated in this function + * and must be freed by caller. + * @param dev device of the scanner + * @param distance distance to move in MM + */ +static void simple_move(Genesys_Device* dev, SANE_Int distance); + +/** + * Does a simple scan of the area given by the settings. Scanned data + * it put in an allocated area which must be freed by the caller. + * and slope tables, based on the parameter struct. There is no shading + * correction while gamma correction is active. + * @param dev device to set up + * @param settings settings of the scan + * @param move flag to enable scanhead to move + * @param forward flag to tell movement direction + * @param shading flag to tell if shading correction should be done + * @param data pointer that will point to the scanned data + */ +static void simple_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Settings settings, bool move, bool forward, + bool shading, std::vector<uint8_t>& data, const char* test_identifier); + +/** + * Send the stop scan command + * */ +static void end_scan_impl(Genesys_Device* dev, Genesys_Register_Set* reg, bool check_stop, + bool eject); +/** + * writes control data to an area behind the last motor table. + */ +static void write_control(Genesys_Device* dev, const Genesys_Sensor& sensor, int resolution); + + +/** + * initialize scanner's registers at SANE init time + */ +static void gl646_init_regs (Genesys_Device * dev); + +/** + * master motor settings table entry + */ +typedef struct +{ + /* key */ + MotorId motor_id; + unsigned dpi; + unsigned channels; + + /* settings */ + StepType steptype; + bool fastmod; // fast scanning + bool fastfed; // fast fed slope tables + SANE_Int mtrpwm; + MotorSlope slope1; + MotorSlope slope2; + SANE_Int fwdbwd; /* forward/backward steps */ +} Motor_Master; + +/** + * master motor settings, for a given motor and dpi, + * it gives steps and speed informations + */ +static Motor_Master motor_master[] = { + /* HP3670 motor settings */ + {MotorId::HP3670, 50, 3, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(2329, 120, 229), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 75, 3, StepType::FULL, false, true, 1, + MotorSlope::create_from_steps(3429, 305, 200), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 100, 3, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(2905, 187, 143), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 150, 3, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(3429, 305, 73), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 300, 3, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(1055, 563, 11), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 600, 3, StepType::FULL, false, true, 0, + MotorSlope::create_from_steps(10687, 5126, 3), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670,1200, 3, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(15937, 6375, 3), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 50, 1, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(2329, 120, 229), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 75, 1, StepType::FULL, false, true, 1, + MotorSlope::create_from_steps(3429, 305, 200), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 100, 1, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(2905, 187, 143), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 150, 1, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(3429, 305, 73), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 300, 1, StepType::HALF, false, true, 1, + MotorSlope::create_from_steps(1055, 563, 11), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670, 600, 1, StepType::FULL, false, true, 0, + MotorSlope::create_from_steps(10687, 5126, 3), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + {MotorId::HP3670,1200, 1, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(15937, 6375, 3), + MotorSlope::create_from_steps(3399, 337, 192), 192}, + + /* HP2400/G2410 motor settings base motor dpi = 600 */ + {MotorId::HP2400, 50, 3, StepType::FULL, false, true, 63, + MotorSlope::create_from_steps(8736, 601, 120), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 100, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(8736, 601, 120), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 150, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(15902, 902, 67), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 300, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(16703, 2188, 32), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 600, 3, StepType::FULL, false, true, 63, + MotorSlope::create_from_steps(18761, 18761, 3), + MotorSlope::create_from_steps(4905, 627, 192), 192}, + + {MotorId::HP2400,1200, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(43501, 43501, 3), + MotorSlope::create_from_steps(4905, 627, 192), 192}, + + {MotorId::HP2400, 50, 1, StepType::FULL, false, true, 63, + MotorSlope::create_from_steps(8736, 601, 120), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 100, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(8736, 601, 120), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 150, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(15902, 902, 67), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 300, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(16703, 2188, 32), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400, 600, 1, StepType::FULL, false, true, 63, + MotorSlope::create_from_steps(18761, 18761, 3), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + {MotorId::HP2400,1200, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(43501, 43501, 3), + MotorSlope::create_from_steps(4905, 337, 192), 192}, + + /* XP 200 motor settings */ + {MotorId::XP200, 75, 3, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(6000, 2136, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 100, 3, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(6000, 2850, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 200, 3, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(6999, 5700, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 250, 3, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(6999, 6999, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 300, 3, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(13500, 13500, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 600, 3, StepType::HALF, true, true, 0, + MotorSlope::create_from_steps(31998, 31998, 4), + MotorSlope::create_from_steps(12000, 1200, 2), 1}, + + {MotorId::XP200, 75, 1, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(6000, 2000, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 100, 1, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(6000, 1300, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 200, 1, StepType::HALF, true, true, 0, + MotorSlope::create_from_steps(6000, 3666, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 300, 1, StepType::HALF, true, false, 0, + MotorSlope::create_from_steps(6500, 6500, 4), + MotorSlope::create_from_steps(12000, 1200, 8), 1}, + + {MotorId::XP200, 600, 1, StepType::HALF, true, true, 0, + MotorSlope::create_from_steps(24000, 24000, 4), + MotorSlope::create_from_steps(12000, 1200, 2), 1}, + + /* HP scanjet 2300c */ + {MotorId::HP2300, 75, 3, StepType::FULL, false, true, 63, + MotorSlope::create_from_steps(8139, 560, 120), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 150, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(7903, 543, 67), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 300, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(2175, 1087, 3), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 600, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(8700, 4350, 3), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300,1200, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(17400, 8700, 3), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 75, 1, StepType::FULL, false, true, 63, + MotorSlope::create_from_steps(8139, 560, 120), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 150, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(7903, 543, 67), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 300, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(2175, 1087, 3), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 600, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(8700, 4350, 3), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300,1200, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(17400, 8700, 3), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + /* non half ccd settings for 300 dpi + {MotorId::HP2300, 300, 3, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(5386, 2175, 44), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + + {MotorId::HP2300, 300, 1, StepType::HALF, false, true, 63, + MotorSlope::create_from_steps(5386, 2175, 44), + MotorSlope::create_from_steps(4905, 337, 120), 16}, + */ + + /* MD5345/6471 motor settings */ + /* vfinal=(exposure/(1200/dpi))/step_type */ + {MotorId::MD_5345, 50, 3, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 250, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 75, 3, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 343, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 100, 3, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 458, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 150, 3, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 687, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 200, 3, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 916, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 300, 3, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 1375, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 400, 3, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(2000, 1833, 32), + MotorSlope::create_from_steps(2000, 300, 255), 32}, + + {MotorId::MD_5345, 500, 3, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(2291, 2291, 32), + MotorSlope::create_from_steps(2000, 300, 255), 32}, + + {MotorId::MD_5345, 600, 3, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(2750, 2750, 32), + MotorSlope::create_from_steps(2000, 300, 255), 32}, + + {MotorId::MD_5345, 1200, 3, StepType::QUARTER, false, true, 0, + MotorSlope::create_from_steps(2750, 2750, 16), + MotorSlope::create_from_steps(2000, 300, 255), 146}, + + {MotorId::MD_5345, 2400, 3, StepType::QUARTER, false, true, 0, + MotorSlope::create_from_steps(5500, 5500, 16), + MotorSlope::create_from_steps(2000, 300, 255), 146}, + + {MotorId::MD_5345, 50, 1, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 250, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 75, 1, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 343, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 100, 1, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 458, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 150, 1, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 687, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 200, 1, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 916, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 300, 1, StepType::HALF, false, true, 2, + MotorSlope::create_from_steps(2500, 1375, 255), + MotorSlope::create_from_steps(2000, 300, 255), 64}, + + {MotorId::MD_5345, 400, 1, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(2000, 1833, 32), + MotorSlope::create_from_steps(2000, 300, 255), 32}, + + {MotorId::MD_5345, 500, 1, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(2291, 2291, 32), + MotorSlope::create_from_steps(2000, 300, 255), 32}, + + {MotorId::MD_5345, 600, 1, StepType::HALF, false, true, 0, + MotorSlope::create_from_steps(2750, 2750, 32), + MotorSlope::create_from_steps(2000, 300, 255), 32}, + + {MotorId::MD_5345, 1200, 1, StepType::QUARTER, false, true, 0, + MotorSlope::create_from_steps(2750, 2750, 16), + MotorSlope::create_from_steps(2000, 300, 255), 146}, + + {MotorId::MD_5345, 2400, 1, StepType::QUARTER, false, true, 0, + MotorSlope::create_from_steps(5500, 5500, 16), + MotorSlope::create_from_steps(2000, 300, 255), 146}, /* 5500 guessed */ +}; + +class CommandSetGl646 : public CommandSet +{ +public: + ~CommandSetGl646() override = default; + + bool needs_home_before_init_regs_for_scan(Genesys_Device* dev) const override; + + void init(Genesys_Device* dev) const override; + + void init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const override; + + void init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const override; + + void set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const override; + void set_powersaving(Genesys_Device* dev, int delay) const override; + void save_power(Genesys_Device* dev, bool enable) const override; + + void begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, bool start_motor) const override; + + void end_scan(Genesys_Device* dev, Genesys_Register_Set* regs, bool check_stop) const override; + + void send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void search_start_position(Genesys_Device* dev) const override; + + void offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const override; + + SensorExposure led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void wait_for_motor_stop(Genesys_Device* dev) const override; + + void move_back_home(Genesys_Device* dev, bool wait_until_home) const override; + + void update_hardware_sensors(struct Genesys_Scanner* s) const override; + + void load_document(Genesys_Device* dev) const override; + + void detect_document_end(Genesys_Device* dev) const override; + + void eject_document(Genesys_Device* dev) const override; + + void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const override; + + void move_to_ta(Genesys_Device* dev) const override; + + void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data, + int size) const override; + + bool has_send_shading_data() const override + { + return false; + } + + ScanSession calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const override; + + void asic_boot(Genesys_Device* dev, bool cold) const override; +}; + +} // namespace gl646 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL646_H diff --git a/backend/genesys/gl646_registers.h b/backend/genesys/gl646_registers.h new file mode 100644 index 0000000..2fe8f19 --- /dev/null +++ b/backend/genesys/gl646_registers.h @@ -0,0 +1,176 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL646_REGISTERS_H +#define BACKEND_GENESYS_GL646_REGISTERS_H + +#include <cstdint> + +namespace genesys { +namespace gl646 { + +using RegAddr = std::uint16_t; +using RegMask = std::uint8_t; +using RegShift = unsigned; + +static constexpr RegAddr REG_0x01 = 0x01; +static constexpr RegMask REG_0x01_CISSET = 0x80; +static constexpr RegMask REG_0x01_DOGENB = 0x40; +static constexpr RegMask REG_0x01_DVDSET = 0x20; +static constexpr RegMask REG_0x01_FASTMOD = 0x10; +static constexpr RegMask REG_0x01_COMPENB = 0x08; +static constexpr RegMask REG_0x01_DRAMSEL = 0x04; +static constexpr RegMask REG_0x01_SHDAREA = 0x02; +static constexpr RegMask REG_0x01_SCAN = 0x01; + +static constexpr RegMask REG_0x02_NOTHOME = 0x80; +static constexpr RegMask REG_0x02_ACDCDIS = 0x40; +static constexpr RegMask REG_0x02_AGOHOME = 0x20; +static constexpr RegMask REG_0x02_MTRPWR = 0x10; +static constexpr RegMask REG_0x02_FASTFED = 0x08; +static constexpr RegMask REG_0x02_MTRREV = 0x04; +static constexpr RegMask REG_0x02_STEPSEL = 0x03; + +static constexpr RegMask REG_0x02_FULLSTEP = 0x00; +static constexpr RegMask REG_0x02_HALFSTEP = 0x01; +static constexpr RegMask REG_0x02_QUATERSTEP = 0x02; + +static constexpr RegMask REG_0x03_TG3 = 0x80; +static constexpr RegMask REG_0x03_AVEENB = 0x40; +static constexpr RegMask REG_0x03_XPASEL = 0x20; +static constexpr RegMask REG_0x03_LAMPPWR = 0x10; +static constexpr RegMask REG_0x03_LAMPDOG = 0x08; +static constexpr RegMask REG_0x03_LAMPTIM = 0x07; + +static constexpr RegMask REG_0x04_LINEART = 0x80; +static constexpr RegMask REG_0x04_BITSET = 0x40; +static constexpr RegMask REG_0x04_ADTYPE = 0x30; +static constexpr RegMask REG_0x04_FILTER = 0x0c; +static constexpr RegMask REG_0x04_FESET = 0x03; + +static constexpr RegMask REG_0x05_DPIHW = 0xc0; +static constexpr RegMask REG_0x05_DPIHW_600 = 0x00; +static constexpr RegMask REG_0x05_DPIHW_1200 = 0x40; +static constexpr RegMask REG_0x05_DPIHW_2400 = 0x80; +static constexpr RegMask REG_0x05_DPIHW_4800 = 0xc0; +static constexpr RegMask REG_0x05_GMMTYPE = 0x30; +static constexpr RegMask REG_0x05_GMM14BIT = 0x10; +static constexpr RegMask REG_0x05_GMMENB = 0x08; +static constexpr RegMask REG_0x05_LEDADD = 0x04; +static constexpr RegMask REG_0x05_BASESEL = 0x03; + +static constexpr RegAddr REG_0x06 = 0x06; +static constexpr RegMask REG_0x06_PWRBIT = 0x10; +static constexpr RegMask REG_0x06_GAIN4 = 0x08; +static constexpr RegMask REG_0x06_OPTEST = 0x07; + +static constexpr RegMask REG_0x07_DMASEL = 0x02; +static constexpr RegMask REG_0x07_DMARDWR = 0x01; + +static constexpr RegMask REG_0x16_CTRLHI = 0x80; +static constexpr RegMask REG_0x16_SELINV = 0x40; +static constexpr RegMask REG_0x16_TGINV = 0x20; +static constexpr RegMask REG_0x16_CK1INV = 0x10; +static constexpr RegMask REG_0x16_CK2INV = 0x08; +static constexpr RegMask REG_0x16_CTRLINV = 0x04; +static constexpr RegMask REG_0x16_CKDIS = 0x02; +static constexpr RegMask REG_0x16_CTRLDIS = 0x01; + +static constexpr RegMask REG_0x17_TGMODE = 0xc0; +static constexpr RegMask REG_0x17_TGMODE_NO_DUMMY = 0x00; +static constexpr RegMask REG_0x17_TGMODE_REF = 0x40; +static constexpr RegMask REG_0x17_TGMODE_XPA = 0x80; +static constexpr RegMask REG_0x17_TGW = 0x3f; + +static constexpr RegMask REG_0x18_CNSET = 0x80; +static constexpr RegMask REG_0x18_DCKSEL = 0x60; +static constexpr RegMask REG_0x18_CKTOGGLE = 0x10; +static constexpr RegMask REG_0x18_CKDELAY = 0x0c; +static constexpr RegMask REG_0x18_CKSEL = 0x03; + +static constexpr RegMask REG_0x1D_CKMANUAL = 0x80; + +static constexpr RegMask REG_0x1E_WDTIME = 0xf0; +static constexpr RegMask REG_0x1E_LINESEL = 0x0f; + +static constexpr RegMask REG_0x41_PWRBIT = 0x80; +static constexpr RegMask REG_0x41_BUFEMPTY = 0x40; +static constexpr RegMask REG_0x41_FEEDFSH = 0x20; +static constexpr RegMask REG_0x41_SCANFSH = 0x10; +static constexpr RegMask REG_0x41_HOMESNR = 0x08; +static constexpr RegMask REG_0x41_LAMPSTS = 0x04; +static constexpr RegMask REG_0x41_FEBUSY = 0x02; +static constexpr RegMask REG_0x41_MOTMFLG = 0x01; + +static constexpr RegMask REG_0x66_LOW_CURRENT = 0x10; + +static constexpr RegMask REG_0x6A_FSTPSEL = 0xc0; +static constexpr RegMask REG_0x6A_FASTPWM = 0x3f; + +static constexpr RegMask REG_0x6C_TGTIME = 0xc0; +static constexpr RegMask REG_0x6C_Z1MOD = 0x38; +static constexpr RegMask REG_0x6C_Z2MOD = 0x07; + +static constexpr RegAddr REG_EXPR = 0x10; +static constexpr RegAddr REG_EXPG = 0x12; +static constexpr RegAddr REG_EXPB = 0x14; +static constexpr RegAddr REG_SCANFED = 0x1f; +static constexpr RegAddr REG_BUFSEL = 0x20; +static constexpr RegAddr REG_LINCNT = 0x25; +static constexpr RegAddr REG_DPISET = 0x2c; +static constexpr RegAddr REG_STRPIXEL = 0x30; +static constexpr RegAddr REG_ENDPIXEL = 0x32; +static constexpr RegAddr REG_DUMMY = 0x34; +static constexpr RegAddr REG_MAXWD = 0x35; +static constexpr RegAddr REG_LPERIOD = 0x38; +static constexpr RegAddr REG_FEEDL = 0x3d; +static constexpr RegAddr REG_VALIDWORD = 0x42; +static constexpr RegAddr REG_FEDCNT = 0x48; +static constexpr RegAddr REG_SCANCNT = 0x4b; +static constexpr RegAddr REG_Z1MOD = 0x60; +static constexpr RegAddr REG_Z2MOD = 0x62; + +} // namespace gl646 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL646_REGISTERS_H diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp new file mode 100644 index 0000000..470f9ba --- /dev/null +++ b/backend/genesys/gl841.cpp @@ -0,0 +1,4010 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2003 Oliver Rauch + Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de> + Copyright (C) 2004 Gerhard Jaeger <gerhard@gjaeger.de> + Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> + Copyright (C) 2005 Philipp Schmid <philipp8288@web.de> + Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> + Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com> + Copyright (C) 2010 Chris Berry <s0457957@sms.ed.ac.uk> and Michael Rickmann <mrickma@gwdg.de> + for Plustek Opticbook 3600 support + + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "gl841.h" +#include "gl841_registers.h" +#include "test_settings.h" + +#include <vector> + +namespace genesys { +namespace gl841 { + + +static int gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor, + float slope_dpi, + StepType scan_step_type, + int start, + int used_pixels); + +/** copy sensor specific settings */ +/* *dev : device infos + *regs : registers to be set + extended : do extended set up + ccd_size_divisor: set up for half ccd resolution + all registers 08-0B, 10-1D, 52-59 are set up. They shouldn't + appear anywhere else but in register_ini + +Responsible for signals to CCD/CIS: + CCD_CK1X (CK1INV(0x16),CKDIS(0x16),CKTOGGLE(0x18),CKDELAY(0x18),MANUAL1(0x1A),CK1MTGL(0x1C),CK1LOW(0x1D),CK1MAP(0x74,0x75,0x76),CK1NEG(0x7D)) + CCD_CK2X (CK2INV(0x16),CKDIS(0x16),CKTOGGLE(0x18),CKDELAY(0x18),MANUAL1(0x1A),CK1LOW(0x1D),CK1NEG(0x7D)) + CCD_CK3X (MANUAL3(0x1A),CK3INV(0x1A),CK3MTGL(0x1C),CK3LOW(0x1D),CK3MAP(0x77,0x78,0x79),CK3NEG(0x7D)) + CCD_CK4X (MANUAL3(0x1A),CK4INV(0x1A),CK4MTGL(0x1C),CK4LOW(0x1D),CK4MAP(0x7A,0x7B,0x7C),CK4NEG(0x7D)) + CCD_CPX (CTRLHI(0x16),CTRLINV(0x16),CTRLDIS(0x16),CPH(0x72),CPL(0x73),CPNEG(0x7D)) + CCD_RSX (CTRLHI(0x16),CTRLINV(0x16),CTRLDIS(0x16),RSH(0x70),RSL(0x71),RSNEG(0x7D)) + CCD_TGX (TGINV(0x16),TGMODE(0x17),TGW(0x17),EXPR(0x10,0x11),TGSHLD(0x1D)) + CCD_TGG (TGINV(0x16),TGMODE(0x17),TGW(0x17),EXPG(0x12,0x13),TGSHLD(0x1D)) + CCD_TGB (TGINV(0x16),TGMODE(0x17),TGW(0x17),EXPB(0x14,0x15),TGSHLD(0x1D)) + LAMP_SW (EXPR(0x10,0x11),XPA_SEL(0x03),LAMP_PWR(0x03),LAMPTIM(0x03),MTLLAMP(0x04),LAMPPWM(0x29)) + XPA_SW (EXPG(0x12,0x13),XPA_SEL(0x03),LAMP_PWR(0x03),LAMPTIM(0x03),MTLLAMP(0x04),LAMPPWM(0x29)) + LAMP_B (EXPB(0x14,0x15),LAMP_PWR(0x03)) + +other registers: + CISSET(0x01),CNSET(0x18),DCKSEL(0x18),SCANMOD(0x18),EXPDMY(0x19),LINECLP(0x1A),CKAREA(0x1C),TGTIME(0x1C),LINESEL(0x1E),DUMMY(0x34) + +Responsible for signals to AFE: + VSMP (VSMP(0x58),VSMPW(0x58)) + BSMP (BSMP(0x59),BSMPW(0x59)) + +other register settings depending on this: + RHI(0x52),RLOW(0x53),GHI(0x54),GLOW(0x55),BHI(0x56),BLOW(0x57), + +*/ +static void sanei_gl841_setup_sensor(Genesys_Device * dev, const Genesys_Sensor& sensor, + Genesys_Register_Set * regs, + bool extended, unsigned ccd_size_divisor) +{ + DBG(DBG_proc, "%s\n", __func__); + + // that one is tricky at least + for (uint16_t addr = 0x08; addr <= 0x0b; ++addr) { + regs->set8(0x70 + addr - 0x08, sensor.custom_regs.get_value(addr)); + } + + // ignore registers in range [0x10..0x16) + for (uint16_t addr = 0x16; addr < 0x1e; ++addr) { + regs->set8(addr, sensor.custom_regs.get_value(addr)); + } + + // ignore registers in range [0x5b..0x5e] + for (uint16_t addr = 0x52; addr < 0x52 + 9; ++addr) { + regs->set8(addr, sensor.custom_regs.get_value(addr)); + } + + /* don't go any further if no extended setup */ + if (!extended) + return; + + /* todo : add more CCD types if needed */ + /* we might want to expand the Sensor struct to have these + 2 kind of settings */ + if (dev->model->sensor_id == SensorId::CCD_5345) { + if (ccd_size_divisor > 1) { + GenesysRegister* r; + /* settings for CCD used at half is max resolution */ + r = sanei_genesys_get_address (regs, 0x70); + r->value = 0x00; + r = sanei_genesys_get_address (regs, 0x71); + r->value = 0x05; + r = sanei_genesys_get_address (regs, 0x72); + r->value = 0x06; + r = sanei_genesys_get_address (regs, 0x73); + r->value = 0x08; + r = sanei_genesys_get_address (regs, 0x18); + r->value = 0x28; + r = sanei_genesys_get_address (regs, 0x58); + r->value = 0x80 | (r->value & 0x03); /* VSMP=16 */ + } + else + { + GenesysRegister* r; + /* swap latch times */ + r = sanei_genesys_get_address (regs, 0x18); + r->value = 0x30; + regs->set8(0x52, sensor.custom_regs.get_value(0x55)); + regs->set8(0x53, sensor.custom_regs.get_value(0x56)); + regs->set8(0x54, sensor.custom_regs.get_value(0x57)); + regs->set8(0x55, sensor.custom_regs.get_value(0x52)); + regs->set8(0x56, sensor.custom_regs.get_value(0x53)); + regs->set8(0x57, sensor.custom_regs.get_value(0x54)); + r = sanei_genesys_get_address (regs, 0x58); + r->value = 0x20 | (r->value & 0x03); /* VSMP=4 */ + } + return; + } + + if (dev->model->sensor_id == SensorId::CCD_HP2300) { + /* settings for CCD used at half is max resolution */ + GenesysRegister* r; + if (ccd_size_divisor > 1) { + r = sanei_genesys_get_address (regs, 0x70); + r->value = 0x16; + r = sanei_genesys_get_address (regs, 0x71); + r->value = 0x00; + r = sanei_genesys_get_address (regs, 0x72); + r->value = 0x01; + r = sanei_genesys_get_address (regs, 0x73); + r->value = 0x03; + /* manual clock programming */ + r = sanei_genesys_get_address (regs, 0x1d); + r->value |= 0x80; + } + else + { + r = sanei_genesys_get_address (regs, 0x70); + r->value = 1; + r = sanei_genesys_get_address (regs, 0x71); + r->value = 3; + r = sanei_genesys_get_address (regs, 0x72); + r->value = 4; + r = sanei_genesys_get_address (regs, 0x73); + r->value = 6; + } + r = sanei_genesys_get_address (regs, 0x58); + r->value = 0x80 | (r->value & 0x03); /* VSMP=16 */ + return; + } +} + +/* + * Set all registers LiDE 80 to default values + * (function called only once at the beginning) + * we are doing a special case to ease development + */ +static void +gl841_init_lide80 (Genesys_Device * dev) +{ + dev->reg.init_reg(0x01, 0x82); // 0x02 = SHDAREA and no CISSET ! + dev->reg.init_reg(0x02, 0x10); + dev->reg.init_reg(0x03, 0x50); + dev->reg.init_reg(0x04, 0x02); + dev->reg.init_reg(0x05, 0x4c); // 1200 DPI + dev->reg.init_reg(0x06, 0x38); // 0x38 scanmod=1, pwrbit, GAIN4 + dev->reg.init_reg(0x07, 0x00); + dev->reg.init_reg(0x08, 0x00); + dev->reg.init_reg(0x09, 0x11); + dev->reg.init_reg(0x0a, 0x00); + + dev->reg.init_reg(0x10, 0x40); + dev->reg.init_reg(0x11, 0x00); + dev->reg.init_reg(0x12, 0x40); + dev->reg.init_reg(0x13, 0x00); + dev->reg.init_reg(0x14, 0x40); + dev->reg.init_reg(0x15, 0x00); + dev->reg.init_reg(0x16, 0x00); + dev->reg.init_reg(0x17, 0x01); + dev->reg.init_reg(0x18, 0x00); + dev->reg.init_reg(0x19, 0x06); + dev->reg.init_reg(0x1a, 0x00); + dev->reg.init_reg(0x1b, 0x00); + dev->reg.init_reg(0x1c, 0x00); + dev->reg.init_reg(0x1d, 0x04); + dev->reg.init_reg(0x1e, 0x10); + dev->reg.init_reg(0x1f, 0x04); + dev->reg.init_reg(0x20, 0x02); + dev->reg.init_reg(0x21, 0x10); + dev->reg.init_reg(0x22, 0x20); + dev->reg.init_reg(0x23, 0x20); + dev->reg.init_reg(0x24, 0x10); + dev->reg.init_reg(0x25, 0x00); + dev->reg.init_reg(0x26, 0x00); + dev->reg.init_reg(0x27, 0x00); + + dev->reg.init_reg(0x29, 0xff); + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + dev->reg.init_reg(0x2c, sensor.optical_res>>8); + dev->reg.init_reg(0x2d, sensor.optical_res & 0xff); + dev->reg.init_reg(0x2e, 0x80); + dev->reg.init_reg(0x2f, 0x80); + dev->reg.init_reg(0x30, 0x00); + dev->reg.init_reg(0x31, 0x10); + dev->reg.init_reg(0x32, 0x15); + dev->reg.init_reg(0x33, 0x0e); + dev->reg.init_reg(0x34, 0x40); + dev->reg.init_reg(0x35, 0x00); + dev->reg.init_reg(0x36, 0x2a); + dev->reg.init_reg(0x37, 0x30); + dev->reg.init_reg(0x38, 0x2a); + dev->reg.init_reg(0x39, 0xf8); + + dev->reg.init_reg(0x3d, 0x00); + dev->reg.init_reg(0x3e, 0x00); + dev->reg.init_reg(0x3f, 0x00); + + dev->reg.init_reg(0x52, 0x03); + dev->reg.init_reg(0x53, 0x07); + dev->reg.init_reg(0x54, 0x00); + dev->reg.init_reg(0x55, 0x00); + dev->reg.init_reg(0x56, 0x00); + dev->reg.init_reg(0x57, 0x00); + dev->reg.init_reg(0x58, 0x29); + dev->reg.init_reg(0x59, 0x69); + dev->reg.init_reg(0x5a, 0x55); + + dev->reg.init_reg(0x5d, 0x20); + dev->reg.init_reg(0x5e, 0x41); + dev->reg.init_reg(0x5f, 0x40); + dev->reg.init_reg(0x60, 0x00); + dev->reg.init_reg(0x61, 0x00); + dev->reg.init_reg(0x62, 0x00); + dev->reg.init_reg(0x63, 0x00); + dev->reg.init_reg(0x64, 0x00); + dev->reg.init_reg(0x65, 0x00); + dev->reg.init_reg(0x66, 0x00); + dev->reg.init_reg(0x67, 0x40); + dev->reg.init_reg(0x68, 0x40); + dev->reg.init_reg(0x69, 0x20); + dev->reg.init_reg(0x6a, 0x20); + dev->reg.init_reg(0x6c, 0x00); + dev->reg.init_reg(0x6d, 0x00); + dev->reg.init_reg(0x6e, 0x00); + dev->reg.init_reg(0x6f, 0x00); + dev->reg.init_reg(0x70, 0x00); + dev->reg.init_reg(0x71, 0x05); + dev->reg.init_reg(0x72, 0x07); + dev->reg.init_reg(0x73, 0x09); + dev->reg.init_reg(0x74, 0x00); + dev->reg.init_reg(0x75, 0x01); + dev->reg.init_reg(0x76, 0xff); + dev->reg.init_reg(0x77, 0x00); + dev->reg.init_reg(0x78, 0x0f); + dev->reg.init_reg(0x79, 0xf0); + dev->reg.init_reg(0x7a, 0xf0); + dev->reg.init_reg(0x7b, 0x00); + dev->reg.init_reg(0x7c, 0x1e); + dev->reg.init_reg(0x7d, 0x11); + dev->reg.init_reg(0x7e, 0x00); + dev->reg.init_reg(0x7f, 0x50); + dev->reg.init_reg(0x80, 0x00); + dev->reg.init_reg(0x81, 0x00); + dev->reg.init_reg(0x82, 0x0f); + dev->reg.init_reg(0x83, 0x00); + dev->reg.init_reg(0x84, 0x0e); + dev->reg.init_reg(0x85, 0x00); + dev->reg.init_reg(0x86, 0x0d); + dev->reg.init_reg(0x87, 0x02); + dev->reg.init_reg(0x88, 0x00); + dev->reg.init_reg(0x89, 0x00); + + for (const auto& reg : dev->gpo.regs) { + dev->reg.set8(reg.address, reg.value); + } + + // specific scanner settings, clock and gpio first + // FIXME: remove the dummy reads as we don't use the values + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6B); + } + dev->interface->write_register(REG_0x6B, 0x0c); + dev->interface->write_register(0x06, 0x10); + dev->interface->write_register(REG_0x6E, 0x6d); + dev->interface->write_register(REG_0x6F, 0x80); + dev->interface->write_register(REG_0x6B, 0x0e); + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6C); + } + dev->interface->write_register(REG_0x6C, 0x00); + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6D); + } + dev->interface->write_register(REG_0x6D, 0x8f); + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6B); + } + dev->interface->write_register(REG_0x6B, 0x0e); + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6B); + } + dev->interface->write_register(REG_0x6B, 0x0e); + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6B); + } + dev->interface->write_register(REG_0x6B, 0x0a); + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6B); + } + dev->interface->write_register(REG_0x6B, 0x02); + if (!is_testing_mode()) { + dev->interface->read_register(REG_0x6B); + } + dev->interface->write_register(REG_0x6B, 0x06); + + dev->interface->write_0x8c(0x10, 0x94); + dev->interface->write_register(0x09, 0x10); + + // FIXME: the following code originally changed 0x6b, but due to bug the 0x6c register was + // effectively changed. The current behavior matches the old code, but should probably be fixed. + dev->reg.find_reg(0x6c).value |= REG_0x6B_GPO18; + dev->reg.find_reg(0x6c).value &= ~REG_0x6B_GPO17; + + sanei_gl841_setup_sensor(dev, sensor, &dev->reg, 0, 1); +} + +/* + * Set all registers to default values + * (function called only once at the beginning) + */ +static void +gl841_init_registers (Genesys_Device * dev) +{ + int addr; + + DBG(DBG_proc, "%s\n", __func__); + + dev->reg.clear(); + if (dev->model->model_id == ModelId::CANON_LIDE_80) { + gl841_init_lide80(dev); + return ; + } + + for (addr = 1; addr <= 0x0a; addr++) { + dev->reg.init_reg(addr, 0); + } + for (addr = 0x10; addr <= 0x27; addr++) { + dev->reg.init_reg(addr, 0); + } + dev->reg.init_reg(0x29, 0); + for (addr = 0x2c; addr <= 0x39; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x3d; addr <= 0x3f; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x52; addr <= 0x5a; addr++) + dev->reg.init_reg(addr, 0); + for (addr = 0x5d; addr <= 0x87; addr++) + dev->reg.init_reg(addr, 0); + + + dev->reg.find_reg(0x01).value = 0x20; /* (enable shading), CCD, color, 1M */ + if (dev->model->is_cis) { + dev->reg.find_reg(0x01).value |= REG_0x01_CISSET; + } else { + dev->reg.find_reg(0x01).value &= ~REG_0x01_CISSET; + } + + dev->reg.find_reg(0x02).value = 0x30 /*0x38 */ ; /* auto home, one-table-move, full step */ + dev->reg.find_reg(0x02).value |= REG_0x02_AGOHOME; + sanei_genesys_set_motor_power(dev->reg, true); + dev->reg.find_reg(0x02).value |= REG_0x02_FASTFED; + + dev->reg.find_reg(0x03).value = 0x1f /*0x17 */ ; /* lamp on */ + dev->reg.find_reg(0x03).value |= REG_0x03_AVEENB; + + if (dev->model->sensor_id == SensorId::CCD_PLUSTEK_OPTICPRO_3600) { + // AD front end + dev->reg.find_reg(0x04).value = (2 << REG_0x04S_AFEMOD) | 0x02; + } + else /* Wolfson front end */ + { + dev->reg.find_reg(0x04).value |= 1 << REG_0x04S_AFEMOD; + } + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + dev->reg.find_reg(0x05).value = 0x00; /* disable gamma, 24 clocks/pixel */ + + unsigned dpihw = 0; + if (sensor.sensor_pixels < 0x1500) { + dpihw = 600; + } else if (sensor.sensor_pixels < 0x2a80) { + dpihw = 1200; + } else if (sensor.sensor_pixels < 0x5400) { + dpihw = 2400; + } else { + throw SaneException("Cannot handle sensor pixel count %d", sensor.sensor_pixels); + } + sanei_genesys_set_dpihw(dev->reg, sensor, dpihw); + + dev->reg.find_reg(0x06).value |= REG_0x06_PWRBIT; + dev->reg.find_reg(0x06).value |= REG_0x06_GAIN4; + + /* XP300 CCD needs different clock and clock/pixels values */ + if (dev->model->sensor_id != SensorId::CCD_XP300 && + dev->model->sensor_id != SensorId::CCD_DP685 && + dev->model->sensor_id != SensorId::CCD_PLUSTEK_OPTICPRO_3600) + { + dev->reg.find_reg(0x06).value |= 0 << REG_0x06S_SCANMOD; + dev->reg.find_reg(0x09).value |= 1 << REG_0x09S_CLKSET; + } + else + { + dev->reg.find_reg(0x06).value |= 0x05 << REG_0x06S_SCANMOD; /* 15 clocks/pixel */ + dev->reg.find_reg(0x09).value = 0; /* 24 MHz CLKSET */ + } + + dev->reg.find_reg(0x1e).value = 0xf0; /* watch-dog time */ + + dev->reg.find_reg(0x17).value |= 1 << REG_0x17S_TGW; + + dev->reg.find_reg(0x19).value = 0x50; + + dev->reg.find_reg(0x1d).value |= 1 << REG_0x1DS_TGSHLD; + + dev->reg.find_reg(0x1e).value |= 1 << REG_0x1ES_WDTIME; + +/*SCANFED*/ + dev->reg.find_reg(0x1f).value = 0x01; + +/*BUFSEL*/ + dev->reg.find_reg(0x20).value = 0x20; + +/*LAMPPWM*/ + dev->reg.find_reg(0x29).value = 0xff; + +/*BWHI*/ + dev->reg.find_reg(0x2e).value = 0x80; + +/*BWLOW*/ + dev->reg.find_reg(0x2f).value = 0x80; + +/*LPERIOD*/ + dev->reg.find_reg(0x38).value = 0x4f; + dev->reg.find_reg(0x39).value = 0xc1; + +/*VSMPW*/ + dev->reg.find_reg(0x58).value |= 3 << REG_0x58S_VSMPW; + +/*BSMPW*/ + dev->reg.find_reg(0x59).value |= 3 << REG_0x59S_BSMPW; + +/*RLCSEL*/ + dev->reg.find_reg(0x5a).value |= REG_0x5A_RLCSEL; + +/*STOPTIM*/ + dev->reg.find_reg(0x5e).value |= 0x2 << REG_0x5ES_STOPTIM; + + sanei_gl841_setup_sensor(dev, sensor, &dev->reg, 0, 1); + + // set up GPIO + for (const auto& reg : dev->gpo.regs) { + dev->reg.set8(reg.address, reg.value); + } + + /* TODO there is a switch calling to be written here */ + if (dev->model->gpio_id == GpioId::CANON_LIDE_35) { + dev->reg.find_reg(0x6b).value |= REG_0x6B_GPO18; + dev->reg.find_reg(0x6b).value &= ~REG_0x6B_GPO17; + } + + if (dev->model->gpio_id == GpioId::XP300) { + dev->reg.find_reg(0x6b).value |= REG_0x6B_GPO17; + } + + if (dev->model->gpio_id == GpioId::DP685) { + /* REG_0x6B_GPO18 lights on green led */ + dev->reg.find_reg(0x6b).value |= REG_0x6B_GPO17|REG_0x6B_GPO18; + } + + DBG(DBG_proc, "%s complete\n", __func__); +} + +// Send slope table for motor movement slope_table in machine byte order +static void gl841_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, + int steps) +{ + DBG_HELPER_ARGS(dbg, "table_nr = %d, steps = %d", table_nr, steps); + int dpihw; + int start_address; + char msg[4000]; +/*#ifdef WORDS_BIGENDIAN*/ + int i; +/*#endif*/ + + dpihw = dev->reg.find_reg(0x05).value >> 6; + + if (dpihw == 0) /* 600 dpi */ + start_address = 0x08000; + else if (dpihw == 1) /* 1200 dpi */ + start_address = 0x10000; + else if (dpihw == 2) /* 2400 dpi */ + start_address = 0x20000; + else { + throw SaneException("Unexpected dpihw"); + } + + std::vector<uint8_t> table(steps * 2); + for(i = 0; i < steps; i++) { + table[i * 2] = slope_table[i] & 0xff; + table[i * 2 + 1] = slope_table[i] >> 8; + } + + if (DBG_LEVEL >= DBG_io) + { + std::sprintf(msg, "write slope %d (%d)=", table_nr, steps); + for (i = 0; i < steps; i++) { + std::sprintf (msg+strlen(msg), ",%d", slope_table[i]); + } + DBG(DBG_io, "%s: %s\n", __func__, msg); + } + + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } + dev->interface->write_buffer(0x3c, start_address + table_nr * 0x200, table.data(), steps * 2); +} + +static void gl841_set_lide80_fe(Genesys_Device* dev, uint8_t set) +{ + DBG_HELPER(dbg); + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + + dev->frontend = dev->frontend_initial; + + // write them to analog frontend + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + dev->interface->write_fe_register(0x03, dev->frontend.regs.get_value(0x01)); + dev->interface->write_fe_register(0x06, dev->frontend.regs.get_value(0x02)); + } + + if (set == AFE_SET) + { + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + dev->interface->write_fe_register(0x06, dev->frontend.regs.get_value(0x20)); + dev->interface->write_fe_register(0x03, dev->frontend.regs.get_value(0x28)); + } +} + +// Set values of Analog Device type frontend +static void gl841_set_ad_fe(Genesys_Device* dev, uint8_t set) +{ + DBG_HELPER(dbg); + int i; + + if (dev->model->adc_id==AdcId::CANON_LIDE_80) { + gl841_set_lide80_fe(dev, set); + return; + } + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + + dev->frontend = dev->frontend_initial; + + // write them to analog frontend + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); + + for (i = 0; i < 6; i++) { + dev->interface->write_fe_register(0x02 + i, 0x00); + } + } + if (set == AFE_SET) + { + // write them to analog frontend + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); + + // Write fe 0x02 (red gain) + dev->interface->write_fe_register(0x02, dev->frontend.get_gain(0)); + + // Write fe 0x03 (green gain) + dev->interface->write_fe_register(0x03, dev->frontend.get_gain(1)); + + // Write fe 0x04 (blue gain) + dev->interface->write_fe_register(0x04, dev->frontend.get_gain(2)); + + // Write fe 0x05 (red offset) + dev->interface->write_fe_register(0x05, dev->frontend.get_offset(0)); + + // Write fe 0x06 (green offset) + dev->interface->write_fe_register(0x06, dev->frontend.get_offset(1)); + + // Write fe 0x07 (blue offset) + dev->interface->write_fe_register(0x07, dev->frontend.get_offset(2)); + } +} + +// Set values of analog frontend +void CommandSetGl841::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const +{ + DBG_HELPER_ARGS(dbg, "%s", set == AFE_INIT ? "init" : + set == AFE_SET ? "set" : + set == AFE_POWER_SAVE ? "powersave" : "huh?"); + (void) sensor; + + /* Analog Device type frontend */ + uint8_t frontend_type = dev->reg.find_reg(0x04).value & REG_0x04_FESET; + + if (frontend_type == 0x02) { + gl841_set_ad_fe(dev, set); + return; + } + + if (frontend_type != 0x00) { + throw SaneException("unsupported frontend type %d", frontend_type); + } + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + dev->frontend = dev->frontend_initial; + + // reset only done on init + dev->interface->write_fe_register(0x04, 0x80); + DBG(DBG_proc, "%s(): frontend reset complete\n", __func__); + } + + + if (set == AFE_POWER_SAVE) + { + dev->interface->write_fe_register(0x01, 0x02); + return; + } + + /* todo : base this test on cfg reg3 or a CCD family flag to be created */ + /*if (dev->model->ccd_type!=SensorId::CCD_HP2300 && dev->model->ccd_type!=SensorId::CCD_HP2400) */ + { + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + dev->interface->write_fe_register(0x02, dev->frontend.regs.get_value(0x02)); + } + + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); + dev->interface->write_fe_register(0x03, dev->frontend.regs.get_value(0x03)); + dev->interface->write_fe_register(0x06, dev->frontend.reg2[0]); + dev->interface->write_fe_register(0x08, dev->frontend.reg2[1]); + dev->interface->write_fe_register(0x09, dev->frontend.reg2[2]); + + for (unsigned i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x24 + i, dev->frontend.regs.get_value(0x24 + i)); + dev->interface->write_fe_register(0x28 + i, dev->frontend.get_gain(i)); + dev->interface->write_fe_register(0x20 + i, dev->frontend.get_offset(i)); + } +} + +enum MotorAction { + MOTOR_ACTION_FEED = 1, + MOTOR_ACTION_GO_HOME = 2, + MOTOR_ACTION_HOME_FREE = 3 +}; + +// @brief turn off motor +static void gl841_init_motor_regs_off(Genesys_Register_Set* reg, unsigned int scan_lines) +{ + DBG_HELPER_ARGS(dbg, "scan_lines=%d", scan_lines); + unsigned int feedl; + GenesysRegister* r; + + feedl = 2; + + r = sanei_genesys_get_address (reg, 0x3d); + r->value = (feedl >> 16) & 0xf; + r = sanei_genesys_get_address (reg, 0x3e); + r->value = (feedl >> 8) & 0xff; + r = sanei_genesys_get_address (reg, 0x3f); + r->value = feedl & 0xff; + r = sanei_genesys_get_address (reg, 0x5e); + r->value &= ~0xe0; + + r = sanei_genesys_get_address (reg, 0x25); + r->value = (scan_lines >> 16) & 0xf; + r = sanei_genesys_get_address (reg, 0x26); + r->value = (scan_lines >> 8) & 0xff; + r = sanei_genesys_get_address (reg, 0x27); + r->value = scan_lines & 0xff; + + r = sanei_genesys_get_address (reg, 0x02); + r->value &= ~0x01; /*LONGCURV OFF*/ + r->value &= ~0x80; /*NOT_HOME OFF*/ + + r->value &= ~0x10; + + r->value &= ~0x06; + + r->value &= ~0x08; + + r->value &= ~0x20; + + r->value &= ~0x40; + + r = sanei_genesys_get_address (reg, 0x67); + r->value = 0x3f; + + r = sanei_genesys_get_address (reg, 0x68); + r->value = 0x3f; + + r = sanei_genesys_get_address(reg, REG_STEPNO); + r->value = 0; + + r = sanei_genesys_get_address(reg, REG_FASTNO); + r->value = 0; + + r = sanei_genesys_get_address (reg, 0x69); + r->value = 0; + + r = sanei_genesys_get_address (reg, 0x6a); + r->value = 0; + + r = sanei_genesys_get_address (reg, 0x5f); + r->value = 0; +} + +/** @brief write motor table frequency + * Write motor frequency data table. + * @param dev device to set up motor + * @param ydpi motor target resolution + */ +static void gl841_write_freq(Genesys_Device* dev, unsigned int ydpi) +{ + DBG_HELPER(dbg); +/**< fast table */ +uint8_t tdefault[] = {0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76}; +uint8_t t1200[] = {0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20}; +uint8_t t300[] = {0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60}; +uint8_t t150[] = {0x0c,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0x40,0x14,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x0c,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0x11,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x0c,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0x40,0xd4,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x0c,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0x11,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60}; + +uint8_t *table; + + if(dev->model->motor_id == MotorId::CANON_LIDE_80) { + switch(ydpi) + { + case 3600: + case 1200: + table=t1200; + break; + case 900: + case 300: + table=t300; + break; + case 450: + case 150: + table=t150; + break; + default: + table=tdefault; + } + dev->interface->write_register(0x66, 0x00); + dev->interface->write_gamma(0x28, 0xc000, table, 128, + ScannerInterface::FLAG_SWAP_REGISTERS); + dev->interface->write_register(0x5b, 0x00); + dev->interface->write_register(0x5c, 0x00); + } +} + + +static void gl841_init_motor_regs(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, unsigned int feed_steps,/*1/base_ydpi*/ + /*maybe float for half/quarter step resolution?*/ + unsigned int action, MotorFlag flags) +{ + DBG_HELPER_ARGS(dbg, "feed_steps=%d, action=%d, flags=%x", feed_steps, action, + static_cast<unsigned>(flags)); + unsigned int fast_exposure = 0; + int use_fast_fed = 0; + unsigned int feedl; + GenesysRegister* r; +/*number of scan lines to add in a scan_lines line*/ + + { + std::vector<uint16_t> table; + table.resize(256, 0xffff); + + gl841_send_slope_table(dev, 0, table, 256); + gl841_send_slope_table(dev, 1, table, 256); + gl841_send_slope_table(dev, 2, table, 256); + gl841_send_slope_table(dev, 3, table, 256); + gl841_send_slope_table(dev, 4, table, 256); + } + + gl841_write_freq(dev, dev->motor.base_ydpi / 4); + + if (action == MOTOR_ACTION_FEED || action == MOTOR_ACTION_GO_HOME) { + /* FEED and GO_HOME can use fastest slopes available */ + fast_exposure = gl841_exposure_time(dev, sensor, + dev->motor.base_ydpi / 4, + StepType::FULL, + 0, + 0); + DBG(DBG_info, "%s : fast_exposure=%d pixels\n", __func__, fast_exposure); + } + + if (action == MOTOR_ACTION_HOME_FREE) { +/* HOME_FREE must be able to stop in one step, so do not try to get faster */ + fast_exposure = dev->motor.get_slope(StepType::FULL).max_speed_w; + } + + auto fast_table = sanei_genesys_create_slope_table3(dev->model->asic_type, dev->motor, + StepType::FULL, fast_exposure, + dev->motor.base_ydpi / 4); + + feedl = feed_steps - fast_table.steps_count * 2; + use_fast_fed = 1; + +/* all needed slopes available. we did even decide which mode to use. + what next? + - transfer slopes +SCAN: +flags \ use_fast_fed ! 0 1 +------------------------\-------------------- + 0 ! 0,1,2 0,1,2,3 +MotorFlag::AUTO_GO_HOME ! 0,1,2,4 0,1,2,3,4 +OFF: none +FEED: 3 +GO_HOME: 3 +HOME_FREE: 3 + - setup registers + * slope specific registers (already done) + * DECSEL for HOME_FREE/GO_HOME/SCAN + * FEEDL + * MTRREV + * MTRPWR + * FASTFED + * STEPSEL + * MTRPWM + * FSTPSEL + * FASTPWM + * HOMENEG + * BWDSTEP + * FWDSTEP + * Z1 + * Z2 + */ + + r = sanei_genesys_get_address(reg, 0x3d); + r->value = (feedl >> 16) & 0xf; + r = sanei_genesys_get_address(reg, 0x3e); + r->value = (feedl >> 8) & 0xff; + r = sanei_genesys_get_address(reg, 0x3f); + r->value = feedl & 0xff; + r = sanei_genesys_get_address(reg, 0x5e); + r->value &= ~0xe0; + + r = sanei_genesys_get_address(reg, 0x25); + r->value = 0; + r = sanei_genesys_get_address(reg, 0x26); + r->value = 0; + r = sanei_genesys_get_address(reg, 0x27); + r->value = 0; + + r = sanei_genesys_get_address(reg, 0x02); + r->value &= ~0x01; /*LONGCURV OFF*/ + r->value &= ~0x80; /*NOT_HOME OFF*/ + + r->value |= 0x10; + + if (action == MOTOR_ACTION_GO_HOME) + r->value |= 0x06; + else + r->value &= ~0x06; + + if (use_fast_fed) + r->value |= 0x08; + else + r->value &= ~0x08; + + if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) { + r->value |= 0x20; + } else { + r->value &= ~0x20; + } + + r->value &= ~0x40; + + if (has_flag(flags, MotorFlag::REVERSE)) { + r->value |= REG_0x02_MTRREV; + } + + gl841_send_slope_table(dev, 3, fast_table.table, 256); + + r = sanei_genesys_get_address(reg, 0x67); + r->value = 0x3f; + + r = sanei_genesys_get_address(reg, 0x68); + r->value = 0x3f; + + r = sanei_genesys_get_address(reg, REG_STEPNO); + r->value = 0; + + r = sanei_genesys_get_address(reg, REG_FASTNO); + r->value = 0; + + r = sanei_genesys_get_address(reg, 0x69); + r->value = 0; + + r = sanei_genesys_get_address(reg, 0x6a); + r->value = (fast_table.steps_count >> 1) + (fast_table.steps_count & 1); + + r = sanei_genesys_get_address(reg, 0x5f); + r->value = (fast_table.steps_count >> 1) + (fast_table.steps_count & 1); +} + +static void gl841_init_motor_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + unsigned int scan_exposure_time,/*pixel*/ + unsigned scan_yres, // dpi, motor resolution + StepType scan_step_type, + unsigned int scan_lines,/*lines, scan resolution*/ + unsigned int scan_dummy, + // number of scan lines to add in a scan_lines line + unsigned int feed_steps,/*1/base_ydpi*/ + // maybe float for half/quarter step resolution? + MotorFlag flags) +{ + DBG_HELPER_ARGS(dbg, "scan_exposure_time=%d, scan_yres=%d, scan_step_type=%d, scan_lines=%d," + " scan_dummy=%d, feed_steps=%d, flags=%x", + scan_exposure_time, scan_yres, static_cast<unsigned>(scan_step_type), + scan_lines, scan_dummy, feed_steps, static_cast<unsigned>(flags)); + unsigned int fast_exposure; + int use_fast_fed = 0; + unsigned int fast_time; + unsigned int slow_time; + unsigned int feedl; + GenesysRegister* r; + unsigned int min_restep = 0x20; + uint32_t z1, z2; + + fast_exposure = gl841_exposure_time(dev, sensor, + dev->motor.base_ydpi / 4, + StepType::FULL, + 0, + 0); + + DBG(DBG_info, "%s : fast_exposure=%d pixels\n", __func__, fast_exposure); + + { + std::vector<uint16_t> table; + table.resize(256, 0xffff); + + gl841_send_slope_table(dev, 0, table, 256); + gl841_send_slope_table(dev, 1, table, 256); + gl841_send_slope_table(dev, 2, table, 256); + gl841_send_slope_table(dev, 3, table, 256); + gl841_send_slope_table(dev, 4, table, 256); + } + + + /* motor frequency table */ + gl841_write_freq(dev, scan_yres); + +/* + we calculate both tables for SCAN. the fast slope step count depends on + how many steps we need for slow acceleration and how much steps we are + allowed to use. + */ + + auto slow_table = sanei_genesys_create_slope_table3(dev->model->asic_type, dev->motor, + scan_step_type, scan_exposure_time, + scan_yres); + + auto back_table = sanei_genesys_create_slope_table3(dev->model->asic_type, dev->motor, + scan_step_type, 0, scan_yres); + + if (feed_steps < (slow_table.steps_count >> static_cast<unsigned>(scan_step_type))) { + /*TODO: what should we do here?? go back to exposure calculation?*/ + feed_steps = slow_table.steps_count >> static_cast<unsigned>(scan_step_type); + } + + auto fast_table = sanei_genesys_create_slope_table3(dev->model->asic_type, dev->motor, + StepType::FULL, fast_exposure, + dev->motor.base_ydpi / 4); + + unsigned max_fast_slope_steps_count = 1; + if (feed_steps > (slow_table.steps_count >> static_cast<unsigned>(scan_step_type)) + 2) { + max_fast_slope_steps_count = (feed_steps - + (slow_table.steps_count >> static_cast<unsigned>(scan_step_type))) / 2; + } + + if (fast_table.steps_count > max_fast_slope_steps_count) { + fast_table.slice_steps(max_fast_slope_steps_count); + } + + /* fast fed special cases handling */ + if (dev->model->gpio_id == GpioId::XP300 + || dev->model->gpio_id == GpioId::DP685) + { + /* quirk: looks like at least this scanner is unable to use + 2-feed mode */ + use_fast_fed = 0; + } + else if (feed_steps < fast_table.steps_count * 2 + + (slow_table.steps_count >> static_cast<unsigned>(scan_step_type))) + { + use_fast_fed = 0; + DBG(DBG_info, "%s: feed too short, slow move forced.\n", __func__); + } else { +/* for deciding whether we should use fast mode we need to check how long we + need for (fast)accelerating, moving, decelerating, (TODO: stopping?) + (slow)accelerating again versus (slow)accelerating and moving. we need + fast and slow tables here. +*/ +/*NOTE: scan_exposure_time is per scan_yres*/ +/*NOTE: fast_exposure is per base_ydpi/4*/ +/*we use full steps as base unit here*/ + fast_time = + fast_exposure / 4 * + (feed_steps - fast_table.steps_count*2 - + (slow_table.steps_count >> static_cast<unsigned>(scan_step_type))) + + fast_table.pixeltime_sum*2 + slow_table.pixeltime_sum; + slow_time = + (scan_exposure_time * scan_yres) / dev->motor.base_ydpi * + (feed_steps - (slow_table.steps_count >> static_cast<unsigned>(scan_step_type))) + + slow_table.pixeltime_sum; + + DBG(DBG_info, "%s: Time for slow move: %d\n", __func__, slow_time); + DBG(DBG_info, "%s: Time for fast move: %d\n", __func__, fast_time); + + use_fast_fed = fast_time < slow_time; + } + + if (use_fast_fed) { + feedl = feed_steps - fast_table.steps_count * 2 - + (slow_table.steps_count >> static_cast<unsigned>(scan_step_type)); + } else if ((feed_steps << static_cast<unsigned>(scan_step_type)) < slow_table.steps_count) { + feedl = 0; + } else { + feedl = (feed_steps << static_cast<unsigned>(scan_step_type)) - slow_table.steps_count; + } + DBG(DBG_info, "%s: Decided to use %s mode\n", __func__, use_fast_fed?"fast feed":"slow feed"); + +/* all needed slopes available. we did even decide which mode to use. + what next? + - transfer slopes +SCAN: +flags \ use_fast_fed ! 0 1 +------------------------\-------------------- + 0 ! 0,1,2 0,1,2,3 +MotorFlag::AUTO_GO_HOME ! 0,1,2,4 0,1,2,3,4 +OFF: none +FEED: 3 +GO_HOME: 3 +HOME_FREE: 3 + - setup registers + * slope specific registers (already done) + * DECSEL for HOME_FREE/GO_HOME/SCAN + * FEEDL + * MTRREV + * MTRPWR + * FASTFED + * STEPSEL + * MTRPWM + * FSTPSEL + * FASTPWM + * HOMENEG + * BWDSTEP + * FWDSTEP + * Z1 + * Z2 + */ + + r = sanei_genesys_get_address (reg, 0x3d); + r->value = (feedl >> 16) & 0xf; + r = sanei_genesys_get_address (reg, 0x3e); + r->value = (feedl >> 8) & 0xff; + r = sanei_genesys_get_address (reg, 0x3f); + r->value = feedl & 0xff; + r = sanei_genesys_get_address (reg, 0x5e); + r->value &= ~0xe0; + + r = sanei_genesys_get_address (reg, 0x25); + r->value = (scan_lines >> 16) & 0xf; + r = sanei_genesys_get_address (reg, 0x26); + r->value = (scan_lines >> 8) & 0xff; + r = sanei_genesys_get_address (reg, 0x27); + r->value = scan_lines & 0xff; + + r = sanei_genesys_get_address (reg, 0x02); + r->value &= ~0x01; /*LONGCURV OFF*/ + r->value &= ~0x80; /*NOT_HOME OFF*/ + r->value |= 0x10; + + r->value &= ~0x06; + + if (use_fast_fed) + r->value |= 0x08; + else + r->value &= ~0x08; + + if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) + r->value |= 0x20; + else + r->value &= ~0x20; + + if (has_flag(flags, MotorFlag::DISABLE_BUFFER_FULL_MOVE)) { + r->value |= 0x40; + } else { + r->value &= ~0x40; + } + + gl841_send_slope_table(dev, 0, slow_table.table, 256); + + gl841_send_slope_table(dev, 1, back_table.table, 256); + + gl841_send_slope_table(dev, 2, slow_table.table, 256); + + if (use_fast_fed) { + gl841_send_slope_table(dev, 3, fast_table.table, 256); + } + + if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) { + gl841_send_slope_table(dev, 4, fast_table.table, 256); + } + +/* now reg 0x21 and 0x24 are available, we can calculate reg 0x22 and 0x23, + reg 0x60-0x62 and reg 0x63-0x65 + rule: + 2*STEPNO+FWDSTEP=2*FASTNO+BWDSTEP +*/ +/* steps of table 0*/ + if (min_restep < slow_table.steps_count * 2 + 2) { + min_restep = slow_table.steps_count * 2 + 2; + } +/* steps of table 1*/ + if (min_restep < back_table.steps_count * 2 + 2) { + min_restep = back_table.steps_count * 2 + 2; + } +/* steps of table 0*/ + r = sanei_genesys_get_address(reg, REG_FWDSTEP); + r->value = min_restep - slow_table.steps_count*2; +/* steps of table 1*/ + r = sanei_genesys_get_address(reg, REG_BWDSTEP); + r->value = min_restep - back_table.steps_count*2; + +/* + for z1/z2: + in dokumentation mentioned variables a-d: + a = time needed for acceleration, table 1 + b = time needed for reg 0x1f... wouldn't that be reg0x1f*exposure_time? + c = time needed for acceleration, table 1 + d = time needed for reg 0x22... wouldn't that be reg0x22*exposure_time? + z1 = (c+d-1) % exposure_time + z2 = (a+b-1) % exposure_time +*/ +/* i don't see any effect of this. i can only guess that this will enhance + sub-pixel accuracy + z1 = (slope_0_time-1) % exposure_time; + z2 = (slope_0_time-1) % exposure_time; +*/ + z1 = z2 = 0; + + DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); + DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); + r = sanei_genesys_get_address (reg, 0x60); + r->value = ((z1 >> 16) & 0xff); + r = sanei_genesys_get_address (reg, 0x61); + r->value = ((z1 >> 8) & 0xff); + r = sanei_genesys_get_address (reg, 0x62); + r->value = (z1 & 0xff); + r = sanei_genesys_get_address (reg, 0x63); + r->value = ((z2 >> 16) & 0xff); + r = sanei_genesys_get_address (reg, 0x64); + r->value = ((z2 >> 8) & 0xff); + r = sanei_genesys_get_address (reg, 0x65); + r->value = (z2 & 0xff); + + r = sanei_genesys_get_address(reg, REG_0x1E); + r->value &= REG_0x1E_WDTIME; + r->value |= scan_dummy; + + r = sanei_genesys_get_address (reg, 0x67); + r->value = 0x3f | (static_cast<unsigned>(scan_step_type) << 6); + + r = sanei_genesys_get_address (reg, 0x68); + r->value = 0x3f; + + r = sanei_genesys_get_address(reg, REG_STEPNO); + r->value = (slow_table.steps_count >> 1) + (slow_table.steps_count & 1); + + r = sanei_genesys_get_address(reg, REG_FASTNO); + r->value = (back_table.steps_count >> 1) + (back_table.steps_count & 1); + + r = sanei_genesys_get_address (reg, 0x69); + r->value = (slow_table.steps_count >> 1) + (slow_table.steps_count & 1); + + r = sanei_genesys_get_address (reg, 0x6a); + r->value = (fast_table.steps_count >> 1) + (fast_table.steps_count & 1); + + r = sanei_genesys_get_address (reg, 0x5f); + r->value = (fast_table.steps_count >> 1) + (fast_table.steps_count & 1); +} + +static int +gl841_get_dpihw(Genesys_Device * dev) +{ + GenesysRegister* r; + r = sanei_genesys_get_address(&dev->reg, 0x05); + if ((r->value & REG_0x05_DPIHW) == REG_0x05_DPIHW_600) { + return 600; + } + if ((r->value & REG_0x05_DPIHW) == REG_0x05_DPIHW_1200) { + return 1200; + } + if ((r->value & REG_0x05_DPIHW) == REG_0x05_DPIHW_2400) { + return 2400; + } + return 0; +} + +static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, unsigned int exposure_time, + const ScanSession& session) +{ + DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time); + GenesysRegister* r; + uint16_t expavg, expr, expb, expg; + + dev->cmd_set->set_fe(dev, sensor, AFE_SET); + + /* gpio part.*/ + if (dev->model->gpio_id == GpioId::CANON_LIDE_35) { + r = sanei_genesys_get_address(reg, REG_0x6C); + if (session.ccd_size_divisor > 1) { + r->value &= ~0x80; + } else { + r->value |= 0x80; + } + } + if (dev->model->gpio_id == GpioId::CANON_LIDE_80) { + r = sanei_genesys_get_address(reg, REG_0x6C); + if (session.ccd_size_divisor > 1) { + r->value &= ~0x40; + r->value |= 0x20; + } else { + r->value &= ~0x20; + r->value |= 0x40; + } + } + + /* enable shading */ + r = sanei_genesys_get_address (reg, 0x01); + r->value |= REG_0x01_SCAN; + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || + (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) { + r->value &= ~REG_0x01_DVDSET; + } else { + r->value |= REG_0x01_DVDSET; + } + + /* average looks better than deletion, and we are already set up to + use one of the average enabled resolutions + */ + r = sanei_genesys_get_address (reg, 0x03); + r->value |= REG_0x03_AVEENB; + sanei_genesys_set_lamp_power(dev, sensor, *reg, + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); + + /* BW threshold */ + r = sanei_genesys_get_address (reg, 0x2e); + r->value = dev->settings.threshold; + r = sanei_genesys_get_address (reg, 0x2f); + r->value = dev->settings.threshold; + + + /* monochrome / color scan */ + r = sanei_genesys_get_address (reg, 0x04); + switch (session.params.depth) { + case 8: + r->value &= ~(REG_0x04_LINEART | REG_0x04_BITSET); + break; + case 16: + r->value &= ~REG_0x04_LINEART; + r->value |= REG_0x04_BITSET; + break; + } + + /* AFEMOD should depend on FESET, and we should set these + * bits separately */ + r->value &= ~(REG_0x04_FILTER | REG_0x04_AFEMOD); + if (has_flag(session.params.flags, ScanFlag::ENABLE_LEDADD)) { + r->value |= 0x10; /* no filter */ + } + else if (session.params.channels == 1) + { + switch (session.params.color_filter) + { + case ColorFilter::RED: + r->value |= 0x14; + break; + case ColorFilter::GREEN: + r->value |= 0x18; + break; + case ColorFilter::BLUE: + r->value |= 0x1c; + break; + default: + r->value |= 0x10; + break; + } + } + else + { + if (dev->model->sensor_id == SensorId::CCD_PLUSTEK_OPTICPRO_3600) { + r->value |= 0x22; /* slow color pixel by pixel */ + } + else + { + r->value |= 0x10; /* color pixel by pixel */ + } + } + + /* CIS scanners can do true gray by setting LEDADD */ + r = sanei_genesys_get_address (reg, 0x87); + r->value &= ~REG_0x87_LEDADD; + if (has_flag(session.params.flags, ScanFlag::ENABLE_LEDADD)) { + r->value |= REG_0x87_LEDADD; + expr = reg->get16(REG_EXPR); + expg = reg->get16(REG_EXPG); + expb = reg->get16(REG_EXPB); + + /* use minimal exposure for best image quality */ + expavg = expg; + if (expr < expg) + expavg = expr; + if (expb < expavg) + expavg = expb; + + dev->reg.set16(REG_EXPR, expavg); + dev->reg.set16(REG_EXPG, expavg); + dev->reg.set16(REG_EXPB, expavg); + } + + // enable gamma tables + if (should_enable_gamma(session, sensor)) { + reg->find_reg(REG_0x05).value |= REG_0x05_GMMENB; + } else { + reg->find_reg(REG_0x05).value &= ~REG_0x05_GMMENB; + } + + /* sensor parameters */ + sanei_gl841_setup_sensor(dev, sensor, &dev->reg, 1, session.ccd_size_divisor); + + r = sanei_genesys_get_address (reg, 0x29); + r->value = 255; /*<<<"magic" number, only suitable for cis*/ + + reg->set16(REG_DPISET, gl841_get_dpihw(dev) * session.output_resolution / session.optical_resolution); + reg->set16(REG_STRPIXEL, session.pixel_startx); + reg->set16(REG_ENDPIXEL, session.pixel_endx); + + reg->set24(REG_MAXWD, session.output_line_bytes); + + reg->set16(REG_LPERIOD, exposure_time); + + r = sanei_genesys_get_address (reg, 0x34); + r->value = sensor.dummy_pixel; +} + +static int +gl841_get_led_exposure(Genesys_Device * dev, const Genesys_Sensor& sensor) +{ + int d,r,g,b,m; + if (!dev->model->is_cis) + return 0; + d = dev->reg.find_reg(0x19).value; + + r = sensor.exposure.red; + g = sensor.exposure.green; + b = sensor.exposure.blue; + + m = r; + if (m < g) + m = g; + if (m < b) + m = b; + + return m + d; +} + +/** @brief compute exposure time + * Compute exposure time for the device and the given scan resolution + */ +static int +gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor, + float slope_dpi, + StepType scan_step_type, + int start, + int used_pixels) +{ +int exposure_time = 0; +int led_exposure; + + led_exposure=gl841_get_led_exposure(dev, sensor); + exposure_time = sanei_genesys_exposure_time2( + dev, + slope_dpi, + scan_step_type, + start+used_pixels,/*+tgtime? currently done in sanei_genesys_exposure_time2 with tgtime = 32 pixel*/ + led_exposure); + + return exposure_time; +} + +/**@brief compute scan_step_type + * Try to do at least 4 steps per line. if that is impossible we will have to + * live with that. + * @param dev device + * @param yres motor resolution + */ +static StepType gl841_scan_step_type(Genesys_Device *dev, int yres) +{ + StepType type = StepType::FULL; + + /* TODO : check if there is a bug around the use of max_step_type */ + /* should be <=1, need to chek all devices entry in genesys_devices */ + if (yres * 4 < dev->motor.base_ydpi || dev->motor.max_step_type() == StepType::FULL) { + type = StepType::FULL; + } else if (yres * 4 < dev->motor.base_ydpi * 2 || + dev->motor.max_step_type() <= StepType::HALF) + { + type = StepType::HALF; + } else { + type = StepType::QUARTER; + } + + /* this motor behaves differently */ + if (dev->model->motor_id==MotorId::CANON_LIDE_80) { + // driven by 'frequency' tables ? + type = StepType::FULL; + } + + return type; +} + +void CommandSetGl841::init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const +{ + DBG_HELPER(dbg); + session.assert_computed(); + + int move; + int exposure_time; + + int slope_dpi = 0; + int dummy = 0; + +/* +results: + +for scanner: +start +end +dpiset +exposure_time +dummy +z1 +z2 + +for ordered_read: + dev->words_per_line + dev->read_factor + dev->requested_buffer_size + dev->read_buffer_size + dev->read_pos + dev->read_bytes_in_buffer + dev->read_bytes_left + dev->max_shift + dev->stagger + +independent of our calculated values: + dev->total_bytes_read + dev->bytes_to_read + */ + +/* dummy */ + /* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1 + dummy line. Maybe the dummy line adds correctness since the motor runs + slower (higher dpi) + */ +/* for cis this creates better aligned color lines: +dummy \ scanned lines + 0: R G B R ... + 1: R G B - R ... + 2: R G B - - R ... + 3: R G B - - - R ... + 4: R G B - - - - R ... + 5: R G B - - - - - R ... + 6: R G B - - - - - - R ... + 7: R G B - - - - - - - R ... + 8: R G B - - - - - - - - R ... + 9: R G B - - - - - - - - - R ... + 10: R G B - - - - - - - - - - R ... + 11: R G B - - - - - - - - - - - R ... + 12: R G B - - - - - - - - - - - - R ... + 13: R G B - - - - - - - - - - - - - R ... + 14: R G B - - - - - - - - - - - - - - R ... + 15: R G B - - - - - - - - - - - - - - - R ... + -- pierre + */ + dummy = 0; + +/* slope_dpi */ +/* cis color scan is effectively a gray scan with 3 gray lines per color + line and a FILTER of 0 */ + if (dev->model->is_cis) { + slope_dpi = session.params.yres* session.params.channels; + } else { + slope_dpi = session.params.yres; + } + + slope_dpi = slope_dpi * (1 + dummy); + + StepType scan_step_type = gl841_scan_step_type(dev, session.params.yres); + exposure_time = gl841_exposure_time(dev, sensor, + slope_dpi, + scan_step_type, + session.pixel_startx, + session.optical_pixels); + DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); + + gl841_init_optical_regs_scan(dev, sensor, reg, exposure_time, session); + + move = session.params.starty; + DBG(DBG_info, "%s: move=%d steps\n", __func__, move); + + /* subtract current head position */ + move -= (dev->head_pos(ScanHeadId::PRIMARY) * session.params.yres) / dev->motor.base_ydpi; + DBG(DBG_info, "%s: move=%d steps\n", __func__, move); + + if (move < 0) + move = 0; + + /* round it */ +/* the move is not affected by dummy -- pierre */ +/* move = ((move + dummy) / (dummy + 1)) * (dummy + 1); + DBG(DBG_info, "%s: move=%d steps\n", __func__, move);*/ + + if (has_flag(session.params.flags, ScanFlag::SINGLE_LINE)) { + gl841_init_motor_regs_off(reg, dev->model->is_cis ? session.output_line_count * session.params.channels + : session.output_line_count); + } else { + auto motor_flag = has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE) ? + MotorFlag::DISABLE_BUFFER_FULL_MOVE : MotorFlag::NONE; + + gl841_init_motor_regs_scan(dev, sensor, reg, exposure_time, slope_dpi, scan_step_type, + dev->model->is_cis ? session.output_line_count * session.params.channels + : session.output_line_count, + dummy, move, motor_flag); + } + + dev->read_buffer.clear(); + dev->read_buffer.alloc(session.buffer_size_read); + + build_image_pipeline(dev, session); + + dev->read_active = true; + + dev->session = session; + + dev->total_bytes_read = 0; + dev->total_bytes_to_read = session.output_line_bytes_requested * session.params.lines; + + DBG(DBG_info, "%s: total bytes to send = %zu\n", __func__, dev->total_bytes_to_read); +} + +ScanSession CommandSetGl841::calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const +{ + int start; + + DBG(DBG_info, "%s ", __func__); + debug_dump(DBG_info, settings); + +/* start */ + start = static_cast<int>(dev->model->x_offset); + start += static_cast<int>(settings.tl_x); + + start = static_cast<int>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = settings.xres; + session.params.yres = settings.yres; + session.params.startx = start; + session.params.starty = 0; // not used + session.params.pixels = settings.pixels; + session.params.requested_pixels = settings.requested_pixels; + session.params.lines = settings.lines; + session.params.depth = settings.depth; + session.params.channels = settings.get_channels(); + session.params.scan_method = settings.scan_method; + session.params.scan_mode = settings.scan_mode; + session.params.color_filter = settings.color_filter; + session.params.flags = ScanFlag::NONE; + + compute_session(dev, session, sensor); + + return session; +} + +// for fast power saving methods only, like disabling certain amplifiers +void CommandSetGl841::save_power(Genesys_Device* dev, bool enable) const +{ + DBG_HELPER_ARGS(dbg, "enable = %d", enable); + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + if (enable) + { + if (dev->model->gpio_id == GpioId::CANON_LIDE_35) + { +/* expect GPIO17 to be enabled, and GPIO9 to be disabled, + while GPIO8 is disabled*/ +/* final state: GPIO8 disabled, GPIO9 enabled, GPIO17 disabled, + GPIO18 disabled*/ + + uint8_t val = dev->interface->read_register(REG_0x6D); + dev->interface->write_register(REG_0x6D, val | 0x80); + + dev->interface->sleep_ms(1); + + /*enable GPIO9*/ + val = dev->interface->read_register(REG_0x6C); + dev->interface->write_register(REG_0x6C, val | 0x01); + + /*disable GPO17*/ + val = dev->interface->read_register(REG_0x6B); + dev->interface->write_register(REG_0x6B, val & ~REG_0x6B_GPO17); + + /*disable GPO18*/ + val = dev->interface->read_register(REG_0x6B); + dev->interface->write_register(REG_0x6B, val & ~REG_0x6B_GPO18); + + dev->interface->sleep_ms(1); + + val = dev->interface->read_register(REG_0x6D); + dev->interface->write_register(REG_0x6D, val & ~0x80); + + } + if (dev->model->gpio_id == GpioId::DP685) + { + uint8_t val = dev->interface->read_register(REG_0x6B); + dev->interface->write_register(REG_0x6B, val & ~REG_0x6B_GPO17); + dev->reg.find_reg(0x6b).value &= ~REG_0x6B_GPO17; + dev->calib_reg.find_reg(0x6b).value &= ~REG_0x6B_GPO17; + } + + set_fe(dev, sensor, AFE_POWER_SAVE); + + } + else + { + if (dev->model->gpio_id == GpioId::CANON_LIDE_35) + { +/* expect GPIO17 to be enabled, and GPIO9 to be disabled, + while GPIO8 is disabled*/ +/* final state: GPIO8 enabled, GPIO9 disabled, GPIO17 enabled, + GPIO18 enabled*/ + + uint8_t val = dev->interface->read_register(REG_0x6D); + dev->interface->write_register(REG_0x6D, val | 0x80); + + dev->interface->sleep_ms(10); + + /*disable GPIO9*/ + val = dev->interface->read_register(REG_0x6C); + dev->interface->write_register(REG_0x6C, val & ~0x01); + + /*enable GPIO10*/ + val = dev->interface->read_register(REG_0x6C); + dev->interface->write_register(REG_0x6C, val | 0x02); + + /*enable GPO17*/ + val = dev->interface->read_register(REG_0x6B); + dev->interface->write_register(REG_0x6B, val | REG_0x6B_GPO17); + dev->reg.find_reg(0x6b).value |= REG_0x6B_GPO17; + dev->calib_reg.find_reg(0x6b).value |= REG_0x6B_GPO17; + + /*enable GPO18*/ + val = dev->interface->read_register(REG_0x6B); + dev->interface->write_register(REG_0x6B, val | REG_0x6B_GPO18); + dev->reg.find_reg(0x6b).value |= REG_0x6B_GPO18; + dev->calib_reg.find_reg(0x6b).value |= REG_0x6B_GPO18; + + } + if (dev->model->gpio_id == GpioId::DP665 + || dev->model->gpio_id == GpioId::DP685) + { + uint8_t val = dev->interface->read_register(REG_0x6B); + dev->interface->write_register(REG_0x6B, val | REG_0x6B_GPO17); + dev->reg.find_reg(0x6b).value |= REG_0x6B_GPO17; + dev->calib_reg.find_reg(0x6b).value |= REG_0x6B_GPO17; + } + + } +} + +void CommandSetGl841::set_powersaving(Genesys_Device* dev, int delay /* in minutes */) const +{ + DBG_HELPER_ARGS(dbg, "delay = %d", delay); + // FIXME: SEQUENTIAL not really needed in this case + Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); + int rate, exposure_time, tgtime, time; + + local_reg.init_reg(0x01, dev->reg.get8(0x01)); /* disable fastmode */ + local_reg.init_reg(0x03, dev->reg.get8(0x03)); /* Lamp power control */ + local_reg.init_reg(0x05, dev->reg.get8(0x05)); /*& ~REG_0x05_BASESEL*/; /* 24 clocks/pixel */ + local_reg.init_reg(0x18, 0x00); // Set CCD type + local_reg.init_reg(0x38, 0x00); + local_reg.init_reg(0x39, 0x00); + + // period times for LPeriod, expR,expG,expB, Z1MODE, Z2MODE + local_reg.init_reg(0x1c, dev->reg.get8(0x05) & ~REG_0x1C_TGTIME); + + if (!delay) { + local_reg.find_reg(0x03).value = local_reg.find_reg(0x03).value & 0xf0; /* disable lampdog and set lamptime = 0 */ + } else if (delay < 20) { + local_reg.find_reg(0x03).value = (local_reg.find_reg(0x03).value & 0xf0) | 0x09; /* enable lampdog and set lamptime = 1 */ + } else { + local_reg.find_reg(0x03).value = (local_reg.find_reg(0x03).value & 0xf0) | 0x0f; /* enable lampdog and set lamptime = 7 */ + } + + time = delay * 1000 * 60; /* -> msec */ + exposure_time = static_cast<std::uint32_t>(time * 32000.0 / + (24.0 * 64.0 * (local_reg.find_reg(0x03).value & REG_0x03_LAMPTIM) * + 1024.0) + 0.5); + /* 32000 = system clock, 24 = clocks per pixel */ + rate = (exposure_time + 65536) / 65536; + if (rate > 4) + { + rate = 8; + tgtime = 3; + } + else if (rate > 2) + { + rate = 4; + tgtime = 2; + } + else if (rate > 1) + { + rate = 2; + tgtime = 1; + } + else + { + rate = 1; + tgtime = 0; + } + + local_reg.find_reg(0x1c).value |= tgtime; + exposure_time /= rate; + + if (exposure_time > 65535) + exposure_time = 65535; + + local_reg.set8(0x38, exposure_time >> 8); + local_reg.set8(0x39, exposure_time & 255); /* lowbyte */ + + dev->interface->write_registers(local_reg); +} + +static void gl841_stop_action(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + Genesys_Register_Set local_reg; + unsigned int loop; + + scanner_read_print_status(*dev); + + if (scanner_is_motor_stopped(*dev)) { + DBG(DBG_info, "%s: already stopped\n", __func__); + return; + } + + local_reg = dev->reg; + + regs_set_optical_off(dev->model->asic_type, local_reg); + + gl841_init_motor_regs_off(&local_reg,0); + dev->interface->write_registers(local_reg); + + if (is_testing_mode()) { + return; + } + + /* looks like writing the right registers to zero is enough to get the chip + out of scan mode into command mode, actually triggering(writing to + register 0x0f) seems to be unnecessary */ + + loop = 10; + while (loop > 0) { + if (scanner_is_motor_stopped(*dev)) { + return; + } + + dev->interface->sleep_ms(100); + loop--; + } + + throw SaneException(SANE_STATUS_IO_ERROR, "could not stop motor"); +} + +static bool gl841_get_paper_sensor(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + + uint8_t val = dev->interface->read_register(REG_0x6D); + + return (val & 0x1) == 0; +} + +void CommandSetGl841::eject_document(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + Genesys_Register_Set local_reg; + unsigned int init_steps; + float feed_mm; + int loop; + + if (!dev->model->is_sheetfed) { + DBG(DBG_proc, "%s: there is no \"eject sheet\"-concept for non sheet fed\n", __func__); + DBG(DBG_proc, "%s: finished\n", __func__); + return; + } + + + local_reg.clear(); + + // FIXME: unused result + scanner_read_status(*dev); + + gl841_stop_action(dev); + + local_reg = dev->reg; + + regs_set_optical_off(dev->model->asic_type, local_reg); + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + gl841_init_motor_regs(dev, sensor, &local_reg, 65536, MOTOR_ACTION_FEED, MotorFlag::NONE); + + dev->interface->write_registers(local_reg); + + try { + scanner_start_action(*dev, true); + } catch (...) { + catch_all_exceptions(__func__, [&]() { gl841_stop_action(dev); }); + // restore original registers + catch_all_exceptions(__func__, [&]() + { + dev->interface->write_registers(dev->reg); + }); + throw; + } + + if (is_testing_mode()) { + dev->interface->test_checkpoint("eject_document"); + gl841_stop_action(dev); + return; + } + + if (gl841_get_paper_sensor(dev)) { + DBG(DBG_info, "%s: paper still loaded\n", __func__); + /* force document TRUE, because it is definitely present */ + dev->document = true; + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + + loop = 300; + while (loop > 0) /* do not wait longer then 30 seconds */ + { + + if (!gl841_get_paper_sensor(dev)) { + DBG(DBG_info, "%s: reached home position\n", __func__); + DBG(DBG_proc, "%s: finished\n", __func__); + break; + } + dev->interface->sleep_ms(100); + --loop; + } + + if (loop == 0) + { + // when we come here then the scanner needed too much time for this, so we better stop + // the motor + catch_all_exceptions(__func__, [&](){ gl841_stop_action(dev); }); + throw SaneException(SANE_STATUS_IO_ERROR, + "timeout while waiting for scanhead to go home"); + } + } + + feed_mm = static_cast<float>(dev->model->eject_feed); + if (dev->document) + { + feed_mm += static_cast<float>(dev->model->post_scan); + } + + sanei_genesys_read_feed_steps(dev, &init_steps); + + /* now feed for extra <number> steps */ + loop = 0; + while (loop < 300) /* do not wait longer then 30 seconds */ + { + unsigned int steps; + + sanei_genesys_read_feed_steps(dev, &steps); + + DBG(DBG_info, "%s: init_steps: %d, steps: %d\n", __func__, init_steps, steps); + + if (steps > init_steps + (feed_mm * dev->motor.base_ydpi) / MM_PER_INCH) + { + break; + } + + dev->interface->sleep_ms(100); + ++loop; + } + + gl841_stop_action(dev); + + dev->document = false; +} + + +void CommandSetGl841::load_document(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + int loop = 300; + while (loop > 0) /* do not wait longer then 30 seconds */ + { + if (gl841_get_paper_sensor(dev)) { + DBG(DBG_info, "%s: document inserted\n", __func__); + + /* when loading OK, document is here */ + dev->document = true; + + // give user some time to place document correctly + dev->interface->sleep_ms(1000); + break; + } + dev->interface->sleep_ms(100); + --loop; + } + + if (loop == 0) + { + // when we come here then the user needed to much time for this + throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for document"); + } +} + +/** + * detects end of document and adjust current scan + * to take it into account + * used by sheetfed scanners + */ +void CommandSetGl841::detect_document_end(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + bool paper_loaded = gl841_get_paper_sensor(dev); + + /* sheetfed scanner uses home sensor as paper present */ + if (dev->document && !paper_loaded) { + DBG(DBG_info, "%s: no more document\n", __func__); + dev->document = false; + + /* we can't rely on total_bytes_to_read since the frontend + * might have been slow to read data, so we re-evaluate the + * amount of data to scan form the hardware settings + */ + unsigned scanned_lines = 0; + try { + sanei_genesys_read_scancnt(dev, &scanned_lines); + } catch (...) { + dev->total_bytes_to_read = dev->total_bytes_read; + throw; + } + + if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS && dev->model->is_cis) { + scanned_lines /= 3; + } + + std::size_t output_lines = dev->session.output_line_count; + + std::size_t offset_lines = static_cast<std::size_t>( + (dev->model->post_scan / MM_PER_INCH) * dev->settings.yres); + + std::size_t scan_end_lines = scanned_lines + offset_lines; + + std::size_t remaining_lines = dev->get_pipeline_source().remaining_bytes() / + dev->session.output_line_bytes_raw; + + DBG(DBG_io, "%s: scanned_lines=%u\n", __func__, scanned_lines); + DBG(DBG_io, "%s: scan_end_lines=%zu\n", __func__, scan_end_lines); + DBG(DBG_io, "%s: output_lines=%zu\n", __func__, output_lines); + DBG(DBG_io, "%s: remaining_lines=%zu\n", __func__, remaining_lines); + + if (scan_end_lines > output_lines) { + auto skip_lines = scan_end_lines - output_lines; + + if (remaining_lines > skip_lines) { + DBG(DBG_io, "%s: skip_lines=%zu\n", __func__, skip_lines); + + remaining_lines -= skip_lines; + dev->get_pipeline_source().set_remaining_bytes(remaining_lines * + dev->session.output_line_bytes_raw); + dev->total_bytes_to_read -= skip_lines * dev->session.output_line_bytes_requested; + } + } + } +} + +// Send the low-level scan command +// todo : is this that useful ? +void CommandSetGl841::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, bool start_motor) const +{ + DBG_HELPER(dbg); + (void) sensor; + // FIXME: SEQUENTIAL not really needed in this case + Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); + uint8_t val; + + if (dev->model->gpio_id == GpioId::CANON_LIDE_80) { + val = dev->interface->read_register(REG_0x6B); + val = REG_0x6B_GPO18; + dev->interface->write_register(REG_0x6B, val); + } + + if (dev->model->sensor_id != SensorId::CCD_PLUSTEK_OPTICPRO_3600) { + local_reg.init_reg(0x03, reg->get8(0x03) | REG_0x03_LAMPPWR); + } else { + // TODO PLUSTEK_3600: why ?? + local_reg.init_reg(0x03, reg->get8(0x03)); + } + + local_reg.init_reg(0x01, reg->get8(0x01) | REG_0x01_SCAN); + local_reg.init_reg(0x0d, 0x01); + + // scanner_start_action(dev, start_motor) + if (start_motor) { + local_reg.init_reg(0x0f, 0x01); + } else { + // do not start motor yet + local_reg.init_reg(0x0f, 0x00); + } + + dev->interface->write_registers(local_reg); + + dev->advance_head_pos_by_session(ScanHeadId::PRIMARY); +} + + +// Send the stop scan command +void CommandSetGl841::end_scan(Genesys_Device* dev, Genesys_Register_Set __sane_unused__* reg, + bool check_stop) const +{ + DBG_HELPER_ARGS(dbg, "check_stop = %d", check_stop); + + if (!dev->model->is_sheetfed) { + gl841_stop_action(dev); + } +} + +// Moves the slider to steps +static void gl841_feed(Genesys_Device* dev, int steps) +{ + DBG_HELPER_ARGS(dbg, "steps = %d", steps); + Genesys_Register_Set local_reg; + int loop; + + gl841_stop_action(dev); + + // FIXME: we should pick sensor according to the resolution scanner is currently operating on + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + local_reg = dev->reg; + + regs_set_optical_off(dev->model->asic_type, local_reg); + + gl841_init_motor_regs(dev, sensor, &local_reg, steps, MOTOR_ACTION_FEED, MotorFlag::NONE); + + dev->interface->write_registers(local_reg); + + try { + scanner_start_action(*dev, true); + } catch (...) { + catch_all_exceptions(__func__, [&]() { gl841_stop_action (dev); }); + // restore original registers + catch_all_exceptions(__func__, [&]() + { + dev->interface->write_registers(dev->reg); + }); + throw; + } + + if (is_testing_mode()) { + dev->interface->test_checkpoint("feed"); + dev->advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::FORWARD, steps); + gl841_stop_action(dev); + return; + } + + loop = 0; + while (loop < 300) /* do not wait longer then 30 seconds */ + { + auto status = scanner_read_status(*dev); + + if (!status.is_motor_enabled) { + DBG(DBG_proc, "%s: finished\n", __func__); + dev->advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::FORWARD, steps); + return; + } + dev->interface->sleep_ms(100); + ++loop; + } + + /* when we come here then the scanner needed too much time for this, so we better stop the motor */ + gl841_stop_action (dev); + + dev->set_head_pos_unknown(); + + throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); +} + +// Moves the slider to the home (top) position slowly +void CommandSetGl841::move_back_home(Genesys_Device* dev, bool wait_until_home) const +{ + DBG_HELPER_ARGS(dbg, "wait_until_home = %d", wait_until_home); + Genesys_Register_Set local_reg; + int loop = 0; + + if (dev->model->is_sheetfed) { + DBG(DBG_proc, "%s: there is no \"home\"-concept for sheet fed\n", __func__); + DBG(DBG_proc, "%s: finished\n", __func__); + return; + } + + // reset gpio pin + uint8_t val; + if (dev->model->gpio_id == GpioId::CANON_LIDE_35) { + val = dev->interface->read_register(REG_0x6C); + val = dev->gpo.regs.get_value(0x6c); + dev->interface->write_register(REG_0x6C, val); + } + if (dev->model->gpio_id == GpioId::CANON_LIDE_80) { + val = dev->interface->read_register(REG_0x6B); + val = REG_0x6B_GPO18 | REG_0x6B_GPO17; + dev->interface->write_register(REG_0x6B, val); + } + dev->cmd_set->save_power(dev, false); + + // first read gives HOME_SENSOR true + auto status = scanner_read_reliable_status(*dev); + + + if (status.is_at_home) { + DBG(DBG_info, "%s: already at home, completed\n", __func__); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + + scanner_stop_action_no_move(*dev, dev->reg); + + /* if motor is on, stop current action */ + if (status.is_motor_enabled) { + gl841_stop_action(dev); + } + + local_reg = dev->reg; + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + gl841_init_motor_regs(dev, sensor, &local_reg, 65536, MOTOR_ACTION_GO_HOME, MotorFlag::REVERSE); + + // set up for no scan + regs_set_optical_off(dev->model->asic_type, local_reg); + + dev->interface->write_registers(local_reg); + + try { + scanner_start_action(*dev, true); + } catch (...) { + catch_all_exceptions(__func__, [&]() { gl841_stop_action(dev); }); + // restore original registers + catch_all_exceptions(__func__, [&]() + { + dev->interface->write_registers(dev->reg); + }); + throw; + } + + if (is_testing_mode()) { + dev->interface->test_checkpoint("move_back_home"); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + + if (wait_until_home) + { + while (loop < 300) /* do not wait longer then 30 seconds */ + { + auto status = scanner_read_status(*dev); + if (status.is_at_home) { + DBG(DBG_info, "%s: reached home position\n", __func__); + DBG(DBG_proc, "%s: finished\n", __func__); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + return; + } + dev->interface->sleep_ms(100); + ++loop; + } + + // when we come here then the scanner needed too much time for this, so we better stop + // the motor + catch_all_exceptions(__func__, [&](){ gl841_stop_action(dev); }); + dev->set_head_pos_unknown(); + throw SaneException(SANE_STATUS_IO_ERROR, "timeout while waiting for scanhead to go home"); + } + + DBG(DBG_info, "%s: scanhead is still moving\n", __func__); +} + +// Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi +// from very top of scanner +void CommandSetGl841::search_start_position(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + int size; + Genesys_Register_Set local_reg; + + int pixels = 600; + int dpi = 300; + + local_reg = dev->reg; + + /* sets for a 200 lines * 600 pixels */ + /* normal scan with no shading */ + + // FIXME: the current approach of doing search only for one resolution does not work on scanners + // whith employ different sensors with potentially different settings. + const auto& sensor = sanei_genesys_find_sensor(dev, dpi, 1, dev->model->default_method); + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; /*we should give a small offset here~60 steps*/ + session.params.pixels = 600; + session.params.lines = dev->model->search_lines; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::GREEN; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_BUFFER_FULL_MOVE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + // send to scanner + dev->interface->write_registers(local_reg); + + size = pixels * dev->model->search_lines; + + std::vector<uint8_t> data(size); + + dev->cmd_set->begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_start_position"); + dev->cmd_set->end_scan(dev, &local_reg, true); + dev->reg = local_reg; + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl841_search_position.pnm", data.data(), 8, 1, pixels, + dev->model->search_lines); + } + + dev->cmd_set->end_scan(dev, &local_reg, true); + + /* update regs to copy ASIC internal state */ + dev->reg = local_reg; + + for (auto& sensor_update : + sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method)) + { + sanei_genesys_search_reference_point(dev, sensor_update, data.data(), 0, dpi, pixels, + dev->model->search_lines); + } +} + +// sets up register for coarse gain calibration +// todo: check it for scanners using it +void CommandSetGl841::init_regs_for_coarse_calibration(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = sensor.optical_res / sensor.ccd_pixels_per_system_pixel(); + session.params.lines = 20; + session.params.depth = 16; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, + sensor.optical_res / sensor.ccd_pixels_per_system_pixel(), dev->settings.xres); + + dev->interface->write_registers(regs); + +/* if (DBG_LEVEL >= DBG_info) + sanei_gl841_print_registers (regs);*/ +} + + +// init registers for shading calibration +void CommandSetGl841::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER_ARGS(dbg, "lines = %zu", dev->calib_lines); + SANE_Int ydpi; + unsigned starty = 0; + + /* initial calibration reg values */ + regs = dev->reg; + + ydpi = dev->motor.base_ydpi; + if (dev->model->motor_id == MotorId::PLUSTEK_OPTICPRO_3600) /* TODO PLUSTEK_3600: 1200dpi not yet working, produces dark bar */ + { + ydpi = 600; + } + if (dev->model->motor_id == MotorId::CANON_LIDE_80) { + ydpi = gl841_get_dpihw(dev); + /* get over extra dark area for this model. + It looks like different devices have dark areas of different width + due to manufacturing variability. The initial value of starty was 140, + but it moves the sensor almost past the dark area completely in places + on certain devices. + + On a particular device the black area starts at roughly position + 160 to 230 depending on location (the dark area is not completely + parallel to the frame). + */ + starty = 70; + } + + dev->calib_channels = 3; + dev->calib_lines = dev->model->shading_lines; + + unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres); + unsigned factor = sensor.optical_res / resolution; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, dev->calib_channels, + dev->settings.scan_method); + + dev->calib_pixels = calib_sensor.sensor_pixels / factor; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = ydpi; + session.params.startx = 0; + session.params.starty = starty; + session.params.pixels = dev->calib_pixels; + session.params.lines = dev->calib_lines; + session.params.depth = 16; + session.params.channels = dev->calib_channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + /*ScanFlag::DISABLE_BUFFER_FULL_MOVE |*/ + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + dev->interface->write_registers(regs); +} + +// set up registers for the actual scan +void CommandSetGl841::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + float move; + int move_dpi; + float start; + + debug_dump(DBG_info, dev->settings); + + /* steps to move to reach scanning area: + - first we move to physical start of scanning + either by a fixed steps amount from the black strip + or by a fixed amount from parking position, + minus the steps done during shading calibration + - then we move by the needed offset whitin physical + scanning area + + assumption: steps are expressed at maximum motor resolution + + we need: + float y_offset; + float y_size; + float y_offset_calib; + mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */ + + /* if scanner uses GENESYS_FLAG_SEARCH_START y_offset is + relative from origin, else, it is from parking position */ + + move_dpi = dev->motor.base_ydpi; + + move = 0; + if (dev->model->flags & GENESYS_FLAG_SEARCH_START) { + move += static_cast<float>(dev->model->y_offset_calib_white); + } + + DBG(DBG_info, "%s move=%f steps\n", __func__, move); + + move += static_cast<float>(dev->model->y_offset); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + move += static_cast<float>(dev->settings.tl_y); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + move = static_cast<float>((move * move_dpi) / MM_PER_INCH); + +/* start */ + start = static_cast<float>(dev->model->x_offset); + + start += static_cast<float>(dev->settings.tl_x); + + start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH); + + /* we enable true gray for cis scanners only, and just when doing + * scan since color calibration is OK for this mode + */ + ScanFlag flags = ScanFlag::NONE; + + /* true gray (led add for cis scanners) */ + if(dev->model->is_cis && dev->settings.true_gray + && dev->settings.scan_mode != ScanColorMode::COLOR_SINGLE_PASS + && dev->model->sensor_id != SensorId::CIS_CANON_LIDE_80) + { + // on Lide 80 the LEDADD bit results in only red LED array being lit + DBG(DBG_io, "%s: activating LEDADD\n", __func__); + flags |= ScanFlag::ENABLE_LEDADD; + } + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = static_cast<unsigned>(start); + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = dev->settings.pixels; + session.params.requested_pixels = dev->settings.requested_pixels; + session.params.lines = dev->settings.lines; + session.params.depth = dev->settings.depth; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = flags; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &dev->reg, session); +} + + +// this function sends generic gamma table (ie linear ones) or the Sensor specific one if provided +void CommandSetGl841::send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + int size; + + size = 256; + + /* allocate temporary gamma tables: 16 bits words, 3 channels */ + std::vector<uint8_t> gamma(size * 2 * 3); + + sanei_genesys_generate_gamma_buffer(dev, sensor, 16, 65535, size, gamma.data()); + + dev->interface->write_gamma(0x28, 0x0000, gamma.data(), size * 2 * 3); +} + + +/* this function does the led calibration by scanning one line of the calibration + area below scanner's top on white strip. + +-needs working coarse/gain +*/ +SensorExposure CommandSetGl841::led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int num_pixels; + int total_size; + int i, j; + int val; + int channels; + int avg[3], avga, avge; + int turn; + uint16_t exp[3], target; + int move; + + /* these 2 boundaries should be per sensor */ + uint16_t min_exposure=500; + uint16_t max_exposure; + + /* feed to white strip if needed */ + if (dev->model->y_offset_calib_white > 0) { + move = static_cast<int>(dev->model->y_offset_calib_white); + move = static_cast<int>((move * (dev->motor.base_ydpi)) / MM_PER_INCH); + DBG(DBG_io, "%s: move=%d lines\n", __func__, move); + gl841_feed(dev, move); + } + + /* offset calibration is always done in color mode */ + channels = 3; + + unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres); + unsigned factor = sensor.optical_res / resolution; + + const auto& calib_sensor_base = sanei_genesys_find_sensor(dev, resolution, channels, + dev->settings.scan_method); + + num_pixels = calib_sensor_base.sensor_pixels / factor; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor_base); + + init_regs_for_scan_session(dev, calib_sensor_base, ®s, session); + + dev->interface->write_registers(regs); + + + total_size = num_pixels * channels * 2 * 1; /* colors * bytes_per_color * scan lines */ + + std::vector<uint8_t> line(total_size); + +/* + we try to get equal bright leds here: + + loop: + average per color + adjust exposure times + */ + + exp[0] = sensor.exposure.red; + exp[1] = sensor.exposure.green; + exp[2] = sensor.exposure.blue; + + turn = 0; + /* max exposure is set to ~2 time initial average + * exposure, or 2 time last calibration exposure */ + max_exposure=((exp[0]+exp[1]+exp[2])/3)*2; + target=sensor.gain_white_ref*256; + + auto calib_sensor = calib_sensor_base; + + bool acceptable = false; + do { + calib_sensor.exposure.red = exp[0]; + calib_sensor.exposure.green = exp[1]; + calib_sensor.exposure.blue = exp[2]; + + regs_set_exposure(dev->model->asic_type, regs, calib_sensor.exposure); + dev->interface->write_register(0x10, (calib_sensor.exposure.red >> 8) & 0xff); + dev->interface->write_register(0x11, calib_sensor.exposure.red & 0xff); + dev->interface->write_register(0x12, (calib_sensor.exposure.green >> 8) & 0xff); + dev->interface->write_register(0x13, calib_sensor.exposure.green & 0xff); + dev->interface->write_register(0x14, (calib_sensor.exposure.blue >> 8) & 0xff); + dev->interface->write_register(0x15, calib_sensor.exposure.blue & 0xff); + + dev->interface->write_registers(regs); + + DBG(DBG_info, "%s: starting line reading\n", __func__); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("led_calibration"); + move_back_home(dev, true); + return calib_sensor.exposure; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) { + char fn[30]; + std::snprintf(fn, 30, "gl841_led_%d.pnm", turn); + sanei_genesys_write_pnm_file(fn, line.data(), 16, channels, num_pixels, 1); + } + + /* compute average */ + for (j = 0; j < channels; j++) + { + avg[j] = 0; + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + line[i * 2 + j * 2 * num_pixels + 1] * 256 + + line[i * 2 + j * 2 * num_pixels]; + else + val = + line[i * 2 * channels + 2 * j + 1] * 256 + + line[i * 2 * channels + 2 * j]; + avg[j] += val; + } + + avg[j] /= num_pixels; + } + + DBG(DBG_info,"%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); + + acceptable = true; + + /* exposure is acceptable if each color is in the %5 range + * of other color channels */ + if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 || + avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 || + avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95) + { + acceptable = false; + } + + /* led exposure is not acceptable if white level is too low + * ~80 hardcoded value for white level */ + if(avg[0]<20000 || avg[1]<20000 || avg[2]<20000) + { + acceptable = false; + } + + /* for scanners using target value */ + if(target>0) + { + acceptable = true; + for(i=0;i<3;i++) + { + /* we accept +- 2% delta from target */ + if(abs(avg[i]-target)>target/50) + { + exp[i]=(exp[i]*target)/avg[i]; + acceptable = false; + } + } + } + else + { + if (!acceptable) + { + avga = (avg[0]+avg[1]+avg[2])/3; + exp[0] = (exp[0] * avga) / avg[0]; + exp[1] = (exp[1] * avga) / avg[1]; + exp[2] = (exp[2] * avga) / avg[2]; + /* + keep the resulting exposures below this value. + too long exposure drives the ccd into saturation. + we may fix this by relying on the fact that + we get a striped scan without shading, by means of + statistical calculation + */ + avge = (exp[0] + exp[1] + exp[2]) / 3; + + if (avge > max_exposure) { + exp[0] = (exp[0] * max_exposure) / avge; + exp[1] = (exp[1] * max_exposure) / avge; + exp[2] = (exp[2] * max_exposure) / avge; + } + if (avge < min_exposure) { + exp[0] = (exp[0] * min_exposure) / avge; + exp[1] = (exp[1] * min_exposure) / avge; + exp[2] = (exp[2] * min_exposure) / avge; + } + + } + } + + gl841_stop_action(dev); + + turn++; + + } while (!acceptable && turn < 100); + + DBG(DBG_info,"%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); + + dev->cmd_set->move_back_home(dev, true); + + return calib_sensor.exposure; +} + +/** @brief calibration for AD frontend devices + * offset calibration assumes that the scanning head is on a black area + * For LiDE80 analog frontend + * 0x0003 : is gain and belongs to [0..63] + * 0x0006 : is offset + * We scan a line with no gain until average offset reaches the target + */ +static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) +{ + DBG_HELPER(dbg); + int num_pixels; + int total_size; + int i; + int average; + int turn; + int top; + int bottom; + int target; + + /* don't impact 3600 behavior since we can't test it */ + if (dev->model->sensor_id == SensorId::CCD_PLUSTEK_OPTICPRO_3600) { + return; + } + + unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres); + unsigned factor = sensor.optical_res / resolution; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, 3, + dev->settings.scan_method); + + num_pixels = calib_sensor.sensor_pixels / factor; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 8; + session.params.channels = 3; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + dev->cmd_set->init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + total_size = num_pixels * 3 * 2 * 1; + + std::vector<uint8_t> line(total_size); + + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + + /* loop on scan until target offset is reached */ + turn=0; + target=24; + bottom=0; + top=255; + do { + /* set up offset mid range */ + dev->frontend.set_offset(0, (top + bottom) / 2); + dev->frontend.set_offset(1, (top + bottom) / 2); + dev->frontend.set_offset(2, (top + bottom) / 2); + + /* scan line */ + DBG(DBG_info, "%s: starting line reading\n", __func__); + dev->interface->write_registers(regs); + dev->cmd_set->set_fe(dev, calib_sensor, AFE_SET); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("ad_fe_offset_calibration"); + gl841_stop_action(dev); + return; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + gl841_stop_action (dev); + if (DBG_LEVEL >= DBG_data) { + char fn[30]; + std::snprintf(fn, 30, "gl841_offset_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, line.data(), 8, 3, num_pixels, 1); + } + + /* search for minimal value */ + average=0; + for(i=0;i<total_size;i++) + { + average+=line[i]; + } + average/=total_size; + DBG(DBG_data, "%s: average=%d\n", __func__, average); + + /* if min value is above target, the current value becomes the new top + * else it is the new bottom */ + if(average>target) + { + top=(top+bottom)/2; + } + else + { + bottom=(top+bottom)/2; + } + turn++; + } while ((top-bottom)>1 && turn < 100); + + // FIXME: don't overwrite the calibrated values + dev->frontend.set_offset(0, 0); + dev->frontend.set_offset(1, 0); + dev->frontend.set_offset(2, 0); + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); +} + +/* this function does the offset calibration by scanning one line of the calibration + area below scanner's top. There is a black margin and the remaining is white. + sanei_genesys_search_start() must have been called so that the offsets and margins + are allready known. + +this function expects the slider to be where? +*/ +void CommandSetGl841::offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int num_pixels; + int total_size; + int i, j; + int val; + int channels; + int off[3],offh[3],offl[3],off1[3],off2[3]; + int min1[3],min2[3]; + int cmin[3],cmax[3]; + int turn; + int mintgt = 0x400; + + /* Analog Device fronted have a different calibration */ + if ((dev->reg.find_reg(0x04).value & REG_0x04_FESET) == 0x02) { + return ad_fe_offset_calibration(dev, sensor, regs); + } + + /* offset calibration is always done in color mode */ + channels = 3; + + unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres); + unsigned factor = sensor.optical_res / resolution; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels, + dev->settings.scan_method); + + num_pixels = calib_sensor.sensor_pixels / factor; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_LAMP; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + total_size = num_pixels * channels * 2 * 1; /* colors * bytes_per_color * scan lines */ + + std::vector<uint8_t> first_line(total_size); + std::vector<uint8_t> second_line(total_size); + + /* scan first line of data with no offset nor gain */ +/*WM8199: gain=0.73; offset=-260mV*/ +/*okay. the sensor black level is now at -260mV. we only get 0 from AFE...*/ +/* we should probably do real calibration here: + * -detect acceptable offset with binary search + * -calculate offset from this last version + * + * acceptable offset means + * - few completely black pixels(<10%?) + * - few completely white pixels(<10%?) + * + * final offset should map the minimum not completely black + * pixel to 0(16 bits) + * + * this does account for dummy pixels at the end of ccd + * this assumes slider is at black strip(which is not quite as black as "no + * signal"). + * + */ + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + offh[0] = 0xff; + offh[1] = 0xff; + offh[2] = 0xff; + offl[0] = 0x00; + offl[1] = 0x00; + offl[2] = 0x00; + turn = 0; + + bool acceptable = false; + do { + + dev->interface->write_registers(regs); + + for (j=0; j < channels; j++) { + off[j] = (offh[j]+offl[j])/2; + dev->frontend.set_offset(j, off[j]); + } + + dev->cmd_set->set_fe(dev, calib_sensor, AFE_SET); + + DBG(DBG_info, "%s: starting first line reading\n", __func__); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("offset_calibration"); + return; + } + + sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) { + char fn[30]; + std::snprintf(fn, 30, "gl841_offset1_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, first_line.data(), 16, channels, num_pixels, 1); + } + + acceptable = true; + + for (j = 0; j < channels; j++) + { + cmin[j] = 0; + cmax[j] = 0; + + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + first_line[i * 2 + j * 2 * num_pixels + 1] * 256 + + first_line[i * 2 + j * 2 * num_pixels]; + else + val = + first_line[i * 2 * channels + 2 * j + 1] * 256 + + first_line[i * 2 * channels + 2 * j]; + if (val < 10) + cmin[j]++; + if (val > 65525) + cmax[j]++; + } + + /* TODO the DP685 has a black strip in the middle of the sensor + * should be handled in a more elegant way , could be a bug */ + if (dev->model->sensor_id == SensorId::CCD_DP685) + cmin[j] -= 20; + + if (cmin[j] > num_pixels/100) { + acceptable = false; + if (dev->model->is_cis) + offl[0] = off[0]; + else + offl[j] = off[j]; + } + if (cmax[j] > num_pixels/100) { + acceptable = false; + if (dev->model->is_cis) + offh[0] = off[0]; + else + offh[j] = off[j]; + } + } + + DBG(DBG_info,"%s: black/white pixels: %d/%d,%d/%d,%d/%d\n", __func__, cmin[0], cmax[0], + cmin[1], cmax[1], cmin[2], cmax[2]); + + if (dev->model->is_cis) { + offh[2] = offh[1] = offh[0]; + offl[2] = offl[1] = offl[0]; + } + + gl841_stop_action(dev); + + turn++; + } while (!acceptable && turn < 100); + + DBG(DBG_info,"%s: acceptable offsets: %d,%d,%d\n", __func__, off[0], off[1], off[2]); + + + for (j = 0; j < channels; j++) + { + off1[j] = off[j]; + + min1[j] = 65536; + + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + first_line[i * 2 + j * 2 * num_pixels + 1] * 256 + + first_line[i * 2 + j * 2 * num_pixels]; + else + val = + first_line[i * 2 * channels + 2 * j + 1] * 256 + + first_line[i * 2 * channels + 2 * j]; + if (min1[j] > val && val >= 10) + min1[j] = val; + } + } + + + offl[0] = off[0]; + offl[1] = off[0]; + offl[2] = off[0]; + turn = 0; + + do { + + for (j=0; j < channels; j++) { + off[j] = (offh[j]+offl[j])/2; + dev->frontend.set_offset(j, off[j]); + } + + dev->cmd_set->set_fe(dev, calib_sensor, AFE_SET); + + DBG(DBG_info, "%s: starting second line reading\n", __func__); + dev->interface->write_registers(regs); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) { + char fn[30]; + std::snprintf(fn, 30, "gl841_offset2_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, second_line.data(), 16, channels, num_pixels, 1); + } + + acceptable = true; + + for (j = 0; j < channels; j++) + { + cmin[j] = 0; + cmax[j] = 0; + + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + second_line[i * 2 + j * 2 * num_pixels + 1] * 256 + + second_line[i * 2 + j * 2 * num_pixels]; + else + val = + second_line[i * 2 * channels + 2 * j + 1] * 256 + + second_line[i * 2 * channels + 2 * j]; + if (val < 10) + cmin[j]++; + if (val > 65525) + cmax[j]++; + } + + if (cmin[j] > num_pixels/100) { + acceptable = false; + if (dev->model->is_cis) + offl[0] = off[0]; + else + offl[j] = off[j]; + } + if (cmax[j] > num_pixels/100) { + acceptable = false; + if (dev->model->is_cis) + offh[0] = off[0]; + else + offh[j] = off[j]; + } + } + + DBG(DBG_info, "%s: black/white pixels: %d/%d,%d/%d,%d/%d\n", __func__, cmin[0], cmax[0], + cmin[1], cmax[1], cmin[2], cmax[2]); + + if (dev->model->is_cis) { + offh[2] = offh[1] = offh[0]; + offl[2] = offl[1] = offl[0]; + } + + gl841_stop_action(dev); + + turn++; + + } while (!acceptable && turn < 100); + + DBG(DBG_info, "%s: acceptable offsets: %d,%d,%d\n", __func__, off[0], off[1], off[2]); + + + for (j = 0; j < channels; j++) + { + off2[j] = off[j]; + + min2[j] = 65536; + + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + second_line[i * 2 + j * 2 * num_pixels + 1] * 256 + + second_line[i * 2 + j * 2 * num_pixels]; + else + val = + second_line[i * 2 * channels + 2 * j + 1] * 256 + + second_line[i * 2 * channels + 2 * j]; + if (min2[j] > val && val != 0) + min2[j] = val; + } + } + + DBG(DBG_info, "%s: first set: %d/%d,%d/%d,%d/%d\n", __func__, off1[0], min1[0], off1[1], min1[1], + off1[2], min1[2]); + + DBG(DBG_info, "%s: second set: %d/%d,%d/%d,%d/%d\n", __func__, off2[0], min2[0], off2[1], min2[1], + off2[2], min2[2]); + +/* + calculate offset for each channel + based on minimal pixel value min1 at offset off1 and minimal pixel value min2 + at offset off2 + + to get min at off, values are linearly interpolated: + min=real+off*fact + min1=real+off1*fact + min2=real+off2*fact + + fact=(min1-min2)/(off1-off2) + real=min1-off1*(min1-min2)/(off1-off2) + + off=(min-min1+off1*(min1-min2)/(off1-off2))/((min1-min2)/(off1-off2)) + + off=(min*(off1-off2)+min1*off2-off1*min2)/(min1-min2) + + */ + for (j = 0; j < channels; j++) + { + if (min2[j]-min1[j] == 0) { +/*TODO: try to avoid this*/ + DBG(DBG_warn, "%s: difference too small\n", __func__); + if (mintgt * (off1[j] - off2[j]) + min1[j] * off2[j] - min2[j] * off1[j] >= 0) + off[j] = 0x0000; + else + off[j] = 0xffff; + } else + off[j] = (mintgt * (off1[j] - off2[j]) + min1[j] * off2[j] - min2[j] * off1[j])/(min1[j]-min2[j]); + if (off[j] > 255) + off[j] = 255; + if (off[j] < 0) + off[j] = 0; + dev->frontend.set_offset(j, off[j]); + } + + DBG(DBG_info, "%s: final offsets: %d,%d,%d\n", __func__, off[0], off[1], off[2]); + + if (dev->model->is_cis) { + if (off[0] < off[1]) + off[0] = off[1]; + if (off[0] < off[2]) + off[0] = off[2]; + dev->frontend.set_offset(0, off[0]); + dev->frontend.set_offset(1, off[0]); + dev->frontend.set_offset(2, off[0]); + } + + if (channels == 1) + { + dev->frontend.set_offset(1, dev->frontend.get_offset(0)); + dev->frontend.set_offset(2, dev->frontend.get_offset(0)); + } +} + + +/* alternative coarse gain calibration + this on uses the settings from offset_calibration and + uses only one scanline + */ +/* + with offset and coarse calibration we only want to get our input range into + a reasonable shape. the fine calibration of the upper and lower bounds will + be done with shading. + */ +void CommandSetGl841::coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const +{ + DBG_HELPER_ARGS(dbg, "dpi=%d", dpi); + int num_pixels; + int total_size; + int i, j, channels; + int max[3]; + float gain[3]; + int val; + int lines=1; + int move; + + // feed to white strip if needed + if (dev->model->y_offset_calib_white > 0) { + move = static_cast<int>(dev->model->y_offset_calib_white); + move = static_cast<int>((move * (dev->motor.base_ydpi)) / MM_PER_INCH); + DBG(DBG_io, "%s: move=%d lines\n", __func__, move); + gl841_feed(dev, move); + } + + /* coarse gain calibration is allways done in color mode */ + channels = 3; + + unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres); + unsigned factor = sensor.optical_res / resolution; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels, + dev->settings.scan_method); + + num_pixels = calib_sensor.sensor_pixels / factor; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = lines; + session.params.depth = 16; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + dev->interface->write_registers(regs); + + total_size = num_pixels * channels * 2 * lines; /* colors * bytes_per_color * scan lines */ + + std::vector<uint8_t> line(total_size); + + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("coarse_gain_calibration"); + gl841_stop_action(dev); + move_back_home(dev, true); + return; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) + sanei_genesys_write_pnm_file("gl841_gain.pnm", line.data(), 16, channels, num_pixels, lines); + + /* average high level for each channel and compute gain + to reach the target code + we only use the central half of the CCD data */ + for (j = 0; j < channels; j++) + { + max[j] = 0; + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + line[i * 2 + j * 2 * num_pixels + 1] * 256 + + line[i * 2 + j * 2 * num_pixels]; + else + val = + line[i * 2 * channels + 2 * j + 1] * 256 + + line[i * 2 * channels + 2 * j]; + + if (val > max[j]) + max[j] = val; + } + + gain[j] = 65535.0f / max[j]; + + uint8_t out_gain = 0; + + if (dev->model->adc_id == AdcId::CANON_LIDE_35 || + dev->model->adc_id == AdcId::WOLFSON_XP300 || + dev->model->adc_id == AdcId::WOLFSON_DSM600) + { + gain[j] *= 0.69f; // seems we don't get the real maximum. empirically derived + if (283 - 208/gain[j] > 255) + out_gain = 255; + else if (283 - 208/gain[j] < 0) + out_gain = 0; + else + out_gain = static_cast<std::uint8_t>(283 - 208 / gain[j]); + } else if (dev->model->adc_id == AdcId::CANON_LIDE_80) { + out_gain = static_cast<std::uint8_t>(gain[j] * 12); + } + dev->frontend.set_gain(j, out_gain); + + DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], + out_gain); + } + + for (j = 0; j < channels; j++) + { + if(gain[j] > 10) + { + DBG (DBG_error0, "**********************************************\n"); + DBG (DBG_error0, "**********************************************\n"); + DBG (DBG_error0, "**** ****\n"); + DBG (DBG_error0, "**** Extremely low Brightness detected. ****\n"); + DBG (DBG_error0, "**** Check the scanning head is ****\n"); + DBG (DBG_error0, "**** unlocked and moving. ****\n"); + DBG (DBG_error0, "**** ****\n"); + DBG (DBG_error0, "**********************************************\n"); + DBG (DBG_error0, "**********************************************\n"); + throw SaneException(SANE_STATUS_JAMMED, "scanning head is locked"); + } + + } + + if (dev->model->is_cis) { + uint8_t gain0 = dev->frontend.get_gain(0); + if (gain0 > dev->frontend.get_gain(1)) { + gain0 = dev->frontend.get_gain(1); + } + if (gain0 > dev->frontend.get_gain(2)) { + gain0 = dev->frontend.get_gain(2); + } + dev->frontend.set_gain(0, gain0); + dev->frontend.set_gain(1, gain0); + dev->frontend.set_gain(2, gain0); + } + + if (channels == 1) { + dev->frontend.set_gain(0, dev->frontend.get_gain(1)); + dev->frontend.set_gain(2, dev->frontend.get_gain(1)); + } + + DBG(DBG_info, "%s: gain=(%d,%d,%d)\n", __func__, + dev->frontend.get_gain(0), + dev->frontend.get_gain(1), + dev->frontend.get_gain(2)); + + gl841_stop_action(dev); + + dev->cmd_set->move_back_home(dev, true); +} + +// wait for lamp warmup by scanning the same line until difference +// between 2 scans is below a threshold +void CommandSetGl841::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* local_reg, int* channels, + int* total_size) const +{ + DBG_HELPER(dbg); + int num_pixels = 4 * 300; + *local_reg = dev->reg; + +/* okay.. these should be defaults stored somewhere */ + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + dev->frontend.set_offset(0, 0x80); + dev->frontend.set_offset(1, 0x80); + dev->frontend.set_offset(2, 0x80); + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = dev->settings.yres; + session.params.startx = sensor.dummy_pixel; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = *channels; + session.params.scan_method = dev->settings.scan_method; + if (*channels == 3) { + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + } else { + session.params.scan_mode = ScanColorMode::GRAY; + } + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, local_reg, session); + + num_pixels = session.output_pixels; + + *total_size = num_pixels * 3 * 2 * 1; /* colors * bytes_per_color * scan lines */ + + dev->interface->write_registers(*local_reg); +} + + +/* + * this function moves head without scanning, forward, then backward + * so that the head goes to park position. + * as a by-product, also check for lock + */ +static void sanei_gl841_repark_head(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + + gl841_feed(dev,232); + + // toggle motor flag, put an huge step number and redo move backward + dev->cmd_set->move_back_home(dev, true); +} + +/* + * initialize ASIC : registers, motor tables, and gamma tables + * then ensure scanner's head is at home + */ +void CommandSetGl841::init(Genesys_Device* dev) const +{ + size_t size; + + DBG_INIT (); + DBG_HELPER(dbg); + + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + + /* Check if the device has already been initialized and powered up */ + if (dev->already_initialized) + { + auto status = scanner_read_status(*dev); + if (!status.is_replugged) { + DBG(DBG_info, "%s: already initialized\n", __func__); + return; + } + } + + dev->dark_average_data.clear(); + dev->white_average_data.clear(); + + dev->settings.color_filter = ColorFilter::RED; + + // ASIC reset + dev->interface->write_register(0x0e, 0x01); + dev->interface->write_register(0x0e, 0x00); + + /* Set default values for registers */ + gl841_init_registers (dev); + + // Write initial registers + dev->interface->write_registers(dev->reg); + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + // Set analog frontend + dev->cmd_set->set_fe(dev, sensor, AFE_INIT); + + // FIXME: move_back_home modifies dev->calib_reg and requires it to be filled + dev->calib_reg = dev->reg; + + // Move home + dev->cmd_set->move_back_home(dev, true); + + // Init shading data + sanei_genesys_init_shading_data(dev, sensor, sensor.sensor_pixels); + + /* ensure head is correctly parked, and check lock */ + if (dev->model->flags & GENESYS_FLAG_REPARK) + { + // FIXME: if repark fails, we should print an error message that the scanner is locked and + // the user should unlock the lock. We should also rethrow with SANE_STATUS_JAMMED + sanei_gl841_repark_head(dev); + } + + // send gamma tables + dev->cmd_set->send_gamma_table(dev, sensor); + + /* initial calibration reg values */ + Genesys_Register_Set& regs = dev->calib_reg; + regs = dev->reg; + + unsigned resolution = sensor.get_logical_hwdpi(300); + unsigned factor = sensor.optical_res / resolution; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, 3, + dev->settings.scan_method); + + unsigned num_pixels = 16 / factor; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = 300; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = 3; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + dev->interface->write_registers(regs); + + size = num_pixels * 3 * 2 * 1; // colors * bytes_per_color * scan lines + + std::vector<uint8_t> line(size); + + DBG(DBG_info, "%s: starting dummy data reading\n", __func__); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + sanei_usb_set_timeout(1000);/* 1 second*/ + + if (is_testing_mode()) { + dev->interface->test_checkpoint("init"); + } else { + // ignore errors. next read will succeed + catch_all_exceptions(__func__, + [&](){ sanei_genesys_read_data_from_scanner(dev, line.data(), size); }); + } + + sanei_usb_set_timeout(30 * 1000);/* 30 seconds*/ + + end_scan(dev, ®s, true); + + regs = dev->reg; + + // Set powersaving(default = 15 minutes) + set_powersaving(dev, 15); + dev->already_initialized = true; +} + +void CommandSetGl841::update_hardware_sensors(Genesys_Scanner* s) const +{ + DBG_HELPER(dbg); + /* do what is needed to get a new set of events, but try to not lose + any of them. + */ + uint8_t val; + + if (s->dev->model->gpio_id == GpioId::CANON_LIDE_35 + || s->dev->model->gpio_id == GpioId::CANON_LIDE_80) + { + val = s->dev->interface->read_register(REG_0x6D); + s->buttons[BUTTON_SCAN_SW].write((val & 0x01) == 0); + s->buttons[BUTTON_FILE_SW].write((val & 0x02) == 0); + s->buttons[BUTTON_EMAIL_SW].write((val & 0x04) == 0); + s->buttons[BUTTON_COPY_SW].write((val & 0x08) == 0); + } + + if (s->dev->model->gpio_id == GpioId::XP300 || + s->dev->model->gpio_id == GpioId::DP665 || + s->dev->model->gpio_id == GpioId::DP685) + { + val = s->dev->interface->read_register(REG_0x6D); + + s->buttons[BUTTON_PAGE_LOADED_SW].write((val & 0x01) == 0); + s->buttons[BUTTON_SCAN_SW].write((val & 0x02) == 0); + } +} + +/** @brief search for a full width black or white strip. + * This function searches for a black or white stripe across the scanning area. + * When searching backward, the searched area must completely be of the desired + * color since this area will be used for calibration which scans forward. + * @param dev scanner device + * @param forward true if searching forward, false if searching backward + * @param black true if searching for a black strip, false for a white strip + */ +void CommandSetGl841::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward, + bool black) const +{ + DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse"); + unsigned int pixels, lines, channels; + Genesys_Register_Set local_reg; + size_t size; + unsigned int pass, count, found, x, y, length; + char title[80]; + GenesysRegister *r; + uint8_t white_level=90; /**< default white level to detect white dots */ + uint8_t black_level=60; /**< default black level to detect black dots */ + + /* use maximum gain when doing forward white strip detection + * since we don't have calibrated the sensor yet */ + if(!black && forward) + { + dev->frontend.set_gain(0, 0xff); + dev->frontend.set_gain(1, 0xff); + dev->frontend.set_gain(2, 0xff); + } + + dev->cmd_set->set_fe(dev, sensor, AFE_SET); + gl841_stop_action(dev); + + // set up for a gray scan at lowest dpi + const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method); + unsigned dpi = resolution_settings.get_min_resolution_x(); + channels = 1; + + /* shading calibation is done with dev->motor.base_ydpi */ + /* lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; */ + lines = static_cast<unsigned>((10 * dpi) / MM_PER_INCH); + + pixels = (sensor.sensor_pixels * dpi) / sensor.optical_res; + + /* 20 cm max length for calibration sheet */ + length = static_cast<unsigned>(((200 * dpi) / MM_PER_INCH) / lines); + + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + + local_reg = dev->reg; + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA; + compute_session(dev, session, sensor); + + size = pixels * channels * lines * (session.params.depth / 8); + std::vector<uint8_t> data(size); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + /* set up for reverse or forward */ + r = sanei_genesys_get_address(&local_reg, 0x02); + if (forward) { + r->value &= ~4; + } else { + r->value |= 4; + } + + dev->interface->write_registers(local_reg); + + dev->cmd_set->begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_strip"); + gl841_stop_action(dev); + return; + } + + // waits for valid data + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + gl841_stop_action(dev); + + pass = 0; + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl841_search_strip_%s_%s%02u.pnm", black ? "black" : "white", + forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, + channels, pixels, lines); + } + + /* loop until strip is found or maximum pass number done */ + found = 0; + while (pass < length && !found) + { + dev->interface->write_registers(local_reg); + + //now start scan + dev->cmd_set->begin_scan(dev, sensor, &local_reg, true); + + // waits for valid data + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + gl841_stop_action (dev); + + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl841_search_strip_%s_%s%02u.pnm", + black ? "black" : "white", forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, + channels, pixels, lines); + } + + /* search data to find black strip */ + /* when searching forward, we only need one line of the searched color since we + * will scan forward. But when doing backward search, we need all the area of the + * same color */ + if (forward) + { + for (y = 0; y < lines && !found; y++) + { + count = 0; + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * pixels + x] > white_level) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * pixels + x] < black_level) + { + count++; + } + } + + /* at end of line, if count >= 3%, line is not fully of the desired color + * so we must go to next line of the buffer */ + /* count*100/pixels < 3 */ + if ((count * 100) / pixels < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, + pass, y); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + } + else /* since calibration scans are done forward, we need the whole area + to be of the required color when searching backward */ + { + count = 0; + for (y = 0; y < lines; y++) + { + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * pixels + x] > white_level) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * pixels + x] < black_level) + { + count++; + } + } + } + + /* at end of area, if count >= 3%, area is not fully of the desired color + * so we must go to next buffer */ + if ((count * 100) / (pixels * lines) < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + pass++; + } + + if (found) + { + DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); + } + else + { + throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white"); + } +} + +/** + * Send shading calibration data. The buffer is considered to always hold values + * for all the channels. + */ +void CommandSetGl841::send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + uint8_t* data, int size) const +{ + DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size); + uint32_t length, x, factor, pixels, i; + uint16_t dpiset, dpihw, beginpixel; + uint8_t *ptr,*src; + + /* old method if no SHDAREA */ + if ((dev->reg.find_reg(0x01).value & REG_0x01_SHDAREA) == 0) { + dev->interface->write_buffer(0x3c, 0x0000, data, size); + return; + } + + /* data is whole line, we extract only the part for the scanned area */ + length = static_cast<std::uint32_t>(size / 3); + unsigned strpixel = dev->session.pixel_startx; + unsigned endpixel = dev->session.pixel_endx; + + /* compute deletion/average factor */ + dpiset = dev->reg.get16(REG_DPISET); + dpihw = gl841_get_dpihw(dev); + unsigned ccd_size_divisor = dev->session.ccd_size_divisor; + factor=dpihw/dpiset; + DBG(DBG_io2, "%s: dpihw=%d, dpiset=%d, ccd_size_divisor=%d, factor=%d\n", __func__, dpihw, dpiset, + ccd_size_divisor, factor); + + /* turn pixel value into bytes 2x16 bits words */ + strpixel*=2*2; /* 2 words of 2 bytes */ + endpixel*=2*2; + pixels=endpixel-strpixel; + + /* shading pixel begin is start pixel minus start pixel during shading + * calibration. Currently only cases handled are full and half ccd resolution. + */ + beginpixel = sensor.ccd_start_xoffset / ccd_size_divisor; + beginpixel += sensor.dummy_pixel + 1; + DBG(DBG_io2, "%s: ORIGIN PIXEL=%d\n", __func__, beginpixel); + beginpixel = (strpixel-beginpixel*2*2)/factor; + DBG(DBG_io2, "%s: BEGIN PIXEL=%d\n", __func__, beginpixel/4); + + dev->interface->record_key_value("shading_offset", std::to_string(beginpixel)); + dev->interface->record_key_value("shading_pixels", std::to_string(pixels)); + dev->interface->record_key_value("shading_length", std::to_string(length)); + + DBG(DBG_io2, "%s: using chunks of %d bytes (%d shading data pixels)\n", __func__, length, + length/4); + std::vector<uint8_t> buffer(pixels, 0); + + /* write actual shading data contigously + * channel by channel, starting at addr 0x0000 + * */ + for(i=0;i<3;i++) + { + /* copy data to work buffer and process it */ + /* coefficent destination */ + ptr=buffer.data(); + + /* iterate on both sensor segment, data has been averaged, + * so is in the right order and we only have to copy it */ + for(x=0;x<pixels;x+=4) + { + /* coefficient source */ + src=data+x+beginpixel+i*length; + ptr[0]=src[0]; + ptr[1]=src[1]; + ptr[2]=src[2]; + ptr[3]=src[3]; + + /* next shading coefficient */ + ptr+=4; + } + + // 0x5400 alignment for LIDE80 internal memory + dev->interface->write_buffer(0x3c, 0x5400 * i, buffer.data(), pixels); + } +} + +bool CommandSetGl841::needs_home_before_init_regs_for_scan(Genesys_Device* dev) const +{ + (void) dev; + return true; +} + +void CommandSetGl841::wait_for_motor_stop(Genesys_Device* dev) const +{ + (void) dev; +} + +void CommandSetGl841::move_to_ta(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl841::asic_boot(Genesys_Device *dev, bool cold) const +{ + (void) dev; + (void) cold; + throw SaneException("not implemented"); +} + +std::unique_ptr<CommandSet> create_gl841_cmd_set() +{ + return std::unique_ptr<CommandSet>(new CommandSetGl841{}); +} + +} // namespace gl841 +} // namespace genesys diff --git a/backend/genesys/gl841.h b/backend/genesys/gl841.h new file mode 100644 index 0000000..5e24249 --- /dev/null +++ b/backend/genesys/gl841.h @@ -0,0 +1,130 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2011-2013 Stéphane Voltz <stef.dev@free.fr> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#include "genesys.h" +#include "command_set.h" + +#ifndef BACKEND_GENESYS_GL841_H +#define BACKEND_GENESYS_GL841_H + +namespace genesys { +namespace gl841 { + +class CommandSetGl841 : public CommandSet +{ +public: + ~CommandSetGl841() override = default; + + bool needs_home_before_init_regs_for_scan(Genesys_Device* dev) const override; + + void init(Genesys_Device* dev) const override; + + void init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const override; + + void init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const override; + + void set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const override; + void set_powersaving(Genesys_Device* dev, int delay) const override; + void save_power(Genesys_Device* dev, bool enable) const override; + + void begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, bool start_motor) const override; + + void end_scan(Genesys_Device* dev, Genesys_Register_Set* regs, bool check_stop) const override; + + void send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void search_start_position(Genesys_Device* dev) const override; + + void offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const override; + + SensorExposure led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void wait_for_motor_stop(Genesys_Device* dev) const override; + + void move_back_home(Genesys_Device* dev, bool wait_until_home) const override; + + void update_hardware_sensors(struct Genesys_Scanner* s) const override; + + void load_document(Genesys_Device* dev) const override; + + void detect_document_end(Genesys_Device* dev) const override; + + void eject_document(Genesys_Device* dev) const override; + + void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const override; + + void move_to_ta(Genesys_Device* dev) const override; + + void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data, + int size) const override; + + ScanSession calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const override; + + void asic_boot(Genesys_Device* dev, bool cold) const override; +}; + +} // namespace gl841 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL841_H diff --git a/backend/genesys/gl841_registers.h b/backend/genesys/gl841_registers.h new file mode 100644 index 0000000..8e0c204 --- /dev/null +++ b/backend/genesys/gl841_registers.h @@ -0,0 +1,269 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL841_REGISTERS_H +#define BACKEND_GENESYS_GL841_REGISTERS_H + +#include <cstdint> + +namespace genesys { +namespace gl841 { + +using RegAddr = std::uint16_t; +using RegMask = std::uint8_t; +using RegShift = unsigned; + +static constexpr RegAddr REG_0x01 = 0x01; +static constexpr RegMask REG_0x01_CISSET = 0x80; +static constexpr RegMask REG_0x01_DOGENB = 0x40; +static constexpr RegMask REG_0x01_DVDSET = 0x20; +static constexpr RegMask REG_0x01_M16DRAM = 0x08; +static constexpr RegMask REG_0x01_DRAMSEL = 0x04; +static constexpr RegMask REG_0x01_SHDAREA = 0x02; +static constexpr RegMask REG_0x01_SCAN = 0x01; + +static constexpr RegAddr REG_0x02 = 0x02; +static constexpr RegMask REG_0x02_NOTHOME = 0x80; +static constexpr RegMask REG_0x02_ACDCDIS = 0x40; +static constexpr RegMask REG_0x02_AGOHOME = 0x20; +static constexpr RegMask REG_0x02_MTRPWR = 0x10; +static constexpr RegMask REG_0x02_FASTFED = 0x08; +static constexpr RegMask REG_0x02_MTRREV = 0x04; +static constexpr RegMask REG_0x02_HOMENEG = 0x02; +static constexpr RegMask REG_0x02_LONGCURV = 0x01; + +static constexpr RegMask REG_0x03_LAMPDOG = 0x80; +static constexpr RegMask REG_0x03_AVEENB = 0x40; +static constexpr RegMask REG_0x03_XPASEL = 0x20; +static constexpr RegMask REG_0x03_LAMPPWR = 0x10; +static constexpr RegMask REG_0x03_LAMPTIM = 0x0f; + +static constexpr RegMask REG_0x04_LINEART = 0x80; +static constexpr RegMask REG_0x04_BITSET = 0x40; +static constexpr RegMask REG_0x04_AFEMOD = 0x30; +static constexpr RegMask REG_0x04_FILTER = 0x0c; +static constexpr RegMask REG_0x04_FESET = 0x03; + +static constexpr RegShift REG_0x04S_AFEMOD = 4; + +static constexpr RegAddr REG_0x05 = 0x05; +static constexpr RegMask REG_0x05_DPIHW = 0xc0; +static constexpr RegMask REG_0x05_DPIHW_600 = 0x00; +static constexpr RegMask REG_0x05_DPIHW_1200 = 0x40; +static constexpr RegMask REG_0x05_DPIHW_2400 = 0x80; +static constexpr RegMask REG_0x05_MTLLAMP = 0x30; +static constexpr RegMask REG_0x05_GMMENB = 0x08; +static constexpr RegMask REG_0x05_MTLBASE = 0x03; + +static constexpr RegAddr REG_0x06 = 0x06; +static constexpr RegMask REG_0x06_SCANMOD = 0xe0; +static constexpr RegShift REG_0x06S_SCANMOD = 5; +static constexpr RegMask REG_0x06_PWRBIT = 0x10; +static constexpr RegMask REG_0x06_GAIN4 = 0x08; +static constexpr RegMask REG_0x06_OPTEST = 0x07; + +static constexpr RegMask REG_0x07_SRAMSEL = 0x08; +static constexpr RegMask REG_0x07_FASTDMA = 0x04; +static constexpr RegMask REG_0x07_DMASEL = 0x02; +static constexpr RegMask REG_0x07_DMARDWR = 0x01; + +static constexpr RegMask REG_0x08_DECFLAG = 0x40; +static constexpr RegMask REG_0x08_GMMFFR = 0x20; +static constexpr RegMask REG_0x08_GMMFFG = 0x10; +static constexpr RegMask REG_0x08_GMMFFB = 0x08; +static constexpr RegMask REG_0x08_GMMZR = 0x04; +static constexpr RegMask REG_0x08_GMMZG = 0x02; +static constexpr RegMask REG_0x08_GMMZB = 0x01; + +static constexpr RegMask REG_0x09_MCNTSET = 0xc0; +static constexpr RegMask REG_0x09_CLKSET = 0x30; +static constexpr RegMask REG_0x09_BACKSCAN = 0x08; +static constexpr RegMask REG_0x09_ENHANCE = 0x04; +static constexpr RegMask REG_0x09_SHORTTG = 0x02; +static constexpr RegMask REG_0x09_NWAIT = 0x01; + +static constexpr RegShift REG_0x09S_MCNTSET = 6; +static constexpr RegShift REG_0x09S_CLKSET = 4; + + +static constexpr RegMask REG_0x0A_SRAMBUF = 0x01; + +static constexpr RegAddr REG_0x0D = 0x0d; +static constexpr RegMask REG_0x0D_CLRLNCNT = 0x01; + +static constexpr RegMask REG_0x16_CTRLHI = 0x80; +static constexpr RegMask REG_0x16_TOSHIBA = 0x40; +static constexpr RegMask REG_0x16_TGINV = 0x20; +static constexpr RegMask REG_0x16_CK1INV = 0x10; +static constexpr RegMask REG_0x16_CK2INV = 0x08; +static constexpr RegMask REG_0x16_CTRLINV = 0x04; +static constexpr RegMask REG_0x16_CKDIS = 0x02; +static constexpr RegMask REG_0x16_CTRLDIS = 0x01; + +static constexpr RegMask REG_0x17_TGMODE = 0xc0; +static constexpr RegMask REG_0x17_TGMODE_NO_DUMMY = 0x00; +static constexpr RegMask REG_0x17_TGMODE_REF = 0x40; +static constexpr RegMask REG_0x17_TGMODE_XPA = 0x80; +static constexpr RegMask REG_0x17_TGW = 0x3f; +static constexpr RegShift REG_0x17S_TGW = 0; + +static constexpr RegMask REG_0x18_CNSET = 0x80; +static constexpr RegMask REG_0x18_DCKSEL = 0x60; +static constexpr RegMask REG_0x18_CKTOGGLE = 0x10; +static constexpr RegMask REG_0x18_CKDELAY = 0x0c; +static constexpr RegMask REG_0x18_CKSEL = 0x03; + +static constexpr RegMask REG_0x1A_MANUAL3 = 0x02; +static constexpr RegMask REG_0x1A_MANUAL1 = 0x01; +static constexpr RegMask REG_0x1A_CK4INV = 0x08; +static constexpr RegMask REG_0x1A_CK3INV = 0x04; +static constexpr RegMask REG_0x1A_LINECLP = 0x02; + +static constexpr RegMask REG_0x1C_TGTIME = 0x07; + +static constexpr RegMask REG_0x1D_CK4LOW = 0x80; +static constexpr RegMask REG_0x1D_CK3LOW = 0x40; +static constexpr RegMask REG_0x1D_CK1LOW = 0x20; +static constexpr RegMask REG_0x1D_TGSHLD = 0x1f; +static constexpr RegShift REG_0x1DS_TGSHLD = 0; + + +static constexpr RegAddr REG_0x1E = 0x1e; +static constexpr RegMask REG_0x1E_WDTIME = 0xf0; +static constexpr RegShift REG_0x1ES_WDTIME = 4; +static constexpr RegMask REG_0x1E_LINESEL = 0x0f; +static constexpr RegShift REG_0x1ES_LINESEL = 0; + +static constexpr RegAddr REG_EXPR = 0x10; +static constexpr RegAddr REG_EXPG = 0x12; +static constexpr RegAddr REG_EXPB = 0x14; +static constexpr RegAddr REG_STEPNO = 0x21; +static constexpr RegAddr REG_FWDSTEP = 0x22; +static constexpr RegAddr REG_BWDSTEP = 0x23; +static constexpr RegAddr REG_FASTNO = 0x24; +static constexpr RegAddr REG_LINCNT = 0x25; +static constexpr RegAddr REG_DPISET = 0x2c; +static constexpr RegAddr REG_STRPIXEL = 0x30; +static constexpr RegAddr REG_ENDPIXEL = 0x32; +static constexpr RegAddr REG_MAXWD = 0x35; +static constexpr RegAddr REG_LPERIOD = 0x38; + +static constexpr RegAddr REG_0x40 = 0x40; +static constexpr RegMask REG_0x40_HISPDFLG = 0x04; +static constexpr RegMask REG_0x40_MOTMFLG = 0x02; +static constexpr RegMask REG_0x40_DATAENB = 0x01; + +static constexpr RegMask REG_0x41_PWRBIT = 0x80; +static constexpr RegMask REG_0x41_BUFEMPTY = 0x40; +static constexpr RegMask REG_0x41_FEEDFSH = 0x20; +static constexpr RegMask REG_0x41_SCANFSH = 0x10; +static constexpr RegMask REG_0x41_HOMESNR = 0x08; +static constexpr RegMask REG_0x41_LAMPSTS = 0x04; +static constexpr RegMask REG_0x41_FEBUSY = 0x02; +static constexpr RegMask REG_0x41_MOTORENB = 0x01; + +static constexpr RegMask REG_0x58_VSMP = 0xf8; +static constexpr RegShift REG_0x58S_VSMP = 3; +static constexpr RegMask REG_0x58_VSMPW = 0x07; +static constexpr RegShift REG_0x58S_VSMPW = 0; + +static constexpr RegMask REG_0x59_BSMP = 0xf8; +static constexpr RegShift REG_0x59S_BSMP = 3; +static constexpr RegMask REG_0x59_BSMPW = 0x07; +static constexpr RegShift REG_0x59S_BSMPW = 0; + +static constexpr RegMask REG_0x5A_ADCLKINV = 0x80; +static constexpr RegMask REG_0x5A_RLCSEL = 0x40; +static constexpr RegMask REG_0x5A_CDSREF = 0x30; +static constexpr RegShift REG_0x5AS_CDSREF = 4; +static constexpr RegMask REG_0x5A_RLC = 0x0f; +static constexpr RegShift REG_0x5AS_RLC = 0; + +static constexpr RegMask REG_0x5E_DECSEL = 0xe0; +static constexpr RegShift REG_0x5ES_DECSEL = 5; +static constexpr RegMask REG_0x5E_STOPTIM = 0x1f; +static constexpr RegShift REG_0x5ES_STOPTIM = 0; + +static constexpr RegMask REG_0x60_ZIMOD = 0x1f; +static constexpr RegMask REG_0x61_Z1MOD = 0xff; +static constexpr RegMask REG_0x62_Z1MOD = 0xff; + +static constexpr RegMask REG_0x63_Z2MOD = 0x1f; +static constexpr RegMask REG_0x64_Z2MOD = 0xff; +static constexpr RegMask REG_0x65_Z2MOD = 0xff; + +static constexpr RegMask REG_0x67_STEPSEL = 0xc0; +static constexpr RegMask REG_0x67_FULLSTEP = 0x00; +static constexpr RegMask REG_0x67_HALFSTEP = 0x40; +static constexpr RegMask REG_0x67_QUATERSTEP = 0x80; +static constexpr RegMask REG_0x67_MTRPWM = 0x3f; + +static constexpr RegMask REG_0x68_FSTPSEL = 0xc0; +static constexpr RegMask REG_0x68_FULLSTEP = 0x00; +static constexpr RegMask REG_0x68_HALFSTEP = 0x40; +static constexpr RegMask REG_0x68_QUATERSTEP = 0x80; +static constexpr RegMask REG_0x68_FASTPWM = 0x3f; + +static constexpr RegMask REG_0x6B_MULTFILM = 0x80; +static constexpr RegMask REG_0x6B_GPOM13 = 0x40; +static constexpr RegMask REG_0x6B_GPOM12 = 0x20; +static constexpr RegMask REG_0x6B_GPOM11 = 0x10; +static constexpr RegMask REG_0x6B_GPO18 = 0x02; +static constexpr RegMask REG_0x6B_GPO17 = 0x01; + +static constexpr RegAddr REG_0x6B = 0x6b; + +static constexpr RegAddr REG_0x6C = 0x6c; +static constexpr RegMask REG_0x6C_GPIOH = 0xff; +static constexpr RegMask REG_0x6C_GPIOL = 0xff; + +static constexpr RegAddr REG_0x6D = 0x6d; +static constexpr RegAddr REG_0x6E = 0x6e; +static constexpr RegAddr REG_0x6F = 0x6f; + +static constexpr RegMask REG_0x87_LEDADD = 0x04; + +} // namespace gl841 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL841_REGISTERS_H diff --git a/backend/genesys/gl843.cpp b/backend/genesys/gl843.cpp new file mode 100644 index 0000000..f83ac8d --- /dev/null +++ b/backend/genesys/gl843.cpp @@ -0,0 +1,3060 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> + + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "gl843_registers.h" +#include "gl843.h" +#include "test_settings.h" + +#include <string> +#include <vector> + +namespace genesys { +namespace gl843 { + +// Set address for writing data +static void gl843_set_buffer_address(Genesys_Device* dev, uint32_t addr) +{ + DBG_HELPER_ARGS(dbg, "setting address to 0x%05x", addr & 0xffff); + + dev->interface->write_register(0x5b, ((addr >> 8) & 0xff)); + dev->interface->write_register(0x5c, (addr & 0xff)); +} + +/** + * compute the step multiplier used + */ +static int gl843_get_step_multiplier(Genesys_Register_Set* regs) +{ + GenesysRegister *r = sanei_genesys_get_address(regs, REG_0x9D); + int value = 1; + if (r != nullptr) + { + switch (r->value & 0x0c) + { + case 0x04: + value = 2; + break; + case 0x08: + value = 4; + break; + default: + value = 1; + } + } + DBG(DBG_io, "%s: step multiplier is %d\n", __func__, value); + return value; +} + +/** copy sensor specific settings */ +static void gl843_setup_sensor(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs) +{ + DBG_HELPER(dbg); + for (const auto& custom_reg : sensor.custom_regs) { + regs->set8(custom_reg.address, custom_reg.value); + } + if (!(dev->model->flags & GENESYS_FLAG_FULL_HWDPI_MODE) && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7200I && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7300 && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7500I) + { + regs->set8(0x7d, 0x90); + } + + dev->segment_order = sensor.segment_order; +} + + +/** @brief set all registers to default values . + * This function is called only once at the beginning and + * fills register startup values for registers reused across scans. + * Those that are rarely modified or not modified are written + * individually. + * @param dev device structure holding register set to initialize + */ +static void +gl843_init_registers (Genesys_Device * dev) +{ + // Within this function SENSOR_DEF marker documents that a register is part + // of the sensors definition and the actual value is set in + // gl843_setup_sensor(). + + // 0x6c, 0x6d, 0x6e, 0x6f, 0xa6, 0xa7, 0xa8, 0xa9 are defined in the Gpo sensor struct + + DBG_HELPER(dbg); + + dev->reg.clear(); + + dev->reg.init_reg(0x01, 0x00); + dev->reg.init_reg(0x02, 0x78); + dev->reg.init_reg(0x03, 0x1f); + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x03, 0x1d); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x03, 0x1c); + } + + dev->reg.init_reg(0x04, 0x10); + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x04, 0x22); + } + + // fine tune upon device description + dev->reg.init_reg(0x05, 0x80); + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x05, 0x08); + } + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + sanei_genesys_set_dpihw(dev->reg, sensor, sensor.optical_res); + + // TODO: on 8600F the windows driver turns off GAIN4 which is recommended + dev->reg.init_reg(0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */ + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */ + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I) { + dev->reg.init_reg(0x06, 0xd0); + } + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x06, 0xf0); /* SCANMOD=111, PWRBIT and no GAIN4 */ + } + + dev->reg.init_reg(0x08, 0x00); + dev->reg.init_reg(0x09, 0x00); + dev->reg.init_reg(0x0a, 0x00); + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x0a, 0x18); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x0a, 0x10); + } + + // This register controls clock and RAM settings and is further modified in + // gl843_boot + dev->reg.init_reg(0x0b, 0x6a); + + if (dev->model->model_id == ModelId::CANON_4400F) { + dev->reg.init_reg(0x0b, 0x69); // 16M only + } + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x0b, 0x89); + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I) { + dev->reg.init_reg(0x0b, 0x2a); + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) { + dev->reg.init_reg(0x0b, 0x4a); + } + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x0b, 0x69); + } + + if (dev->model->model_id != ModelId::CANON_8400F && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7200I && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7300) + { + dev->reg.init_reg(0x0c, 0x00); + } + + // EXPR[0:15], EXPG[0:15], EXPB[0:15]: Exposure time settings. + dev->reg.init_reg(0x10, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x11, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x12, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x13, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x14, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x15, 0x00); // SENSOR_DEF + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8600F) + { + dev->reg.set16(REG_EXPR, 0x9c40); + dev->reg.set16(REG_EXPG, 0x9c40); + dev->reg.set16(REG_EXPB, 0x9c40); + } + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.set16(REG_EXPR, 0x2c09); + dev->reg.set16(REG_EXPG, 0x22b8); + dev->reg.set16(REG_EXPB, 0x10f0); + } + + // CCD signal settings. + dev->reg.init_reg(0x16, 0x33); // SENSOR_DEF + dev->reg.init_reg(0x17, 0x1c); // SENSOR_DEF + dev->reg.init_reg(0x18, 0x10); // SENSOR_DEF + + // EXPDMY[0:7]: Exposure time of dummy lines. + dev->reg.init_reg(0x19, 0x2a); // SENSOR_DEF + + // Various CCD clock settings. + dev->reg.init_reg(0x1a, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x1b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x1c, 0x20); // SENSOR_DEF + dev->reg.init_reg(0x1d, 0x04); // SENSOR_DEF + + dev->reg.init_reg(0x1e, 0x10); + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8600F) + { + dev->reg.init_reg(0x1e, 0x20); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x1e, 0xa0); + } + + dev->reg.init_reg(0x1f, 0x01); + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x1f, 0xff); + } + + dev->reg.init_reg(0x20, 0x10); + dev->reg.init_reg(0x21, 0x04); + + dev->reg.init_reg(0x22, 0x10); + dev->reg.init_reg(0x23, 0x10); + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x22, 0xc8); + dev->reg.init_reg(0x23, 0xc8); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x22, 0x50); + dev->reg.init_reg(0x23, 0x50); + } + + dev->reg.init_reg(0x24, 0x04); + dev->reg.init_reg(0x25, 0x00); + dev->reg.init_reg(0x26, 0x00); + dev->reg.init_reg(0x27, 0x00); + dev->reg.init_reg(0x2c, 0x02); + dev->reg.init_reg(0x2d, 0x58); + // BWHI[0:7]: high level of black and white threshold + dev->reg.init_reg(0x2e, 0x80); + // BWLOW[0:7]: low level of black and white threshold + dev->reg.init_reg(0x2f, 0x80); + dev->reg.init_reg(0x30, 0x00); + dev->reg.init_reg(0x31, 0x14); + dev->reg.init_reg(0x32, 0x27); + dev->reg.init_reg(0x33, 0xec); + + // DUMMY: CCD dummy and optically black pixel count + dev->reg.init_reg(0x34, 0x24); + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x34, 0x14); + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x34, 0x3c); + } + + // MAXWD: If available buffer size is less than 2*MAXWD words, then + // "buffer full" state will be set. + dev->reg.init_reg(0x35, 0x00); + dev->reg.init_reg(0x36, 0xff); + dev->reg.init_reg(0x37, 0xff); + + // LPERIOD: Line period or exposure time for CCD or CIS. + dev->reg.init_reg(0x38, 0x55); // SENSOR_DEF + dev->reg.init_reg(0x39, 0xf0); // SENSOR_DEF + + // FEEDL[0:24]: The number of steps of motor movement. + dev->reg.init_reg(0x3d, 0x00); + dev->reg.init_reg(0x3e, 0x00); + dev->reg.init_reg(0x3f, 0x01); + + // Latch points for high and low bytes of R, G and B channels of AFE. If + // multiple clocks per pixel are consumed, then the setting defines during + // which clock the corresponding value will be read. + // RHI[0:4]: The latch point for high byte of R channel. + // RLOW[0:4]: The latch point for low byte of R channel. + // GHI[0:4]: The latch point for high byte of G channel. + // GLOW[0:4]: The latch point for low byte of G channel. + // BHI[0:4]: The latch point for high byte of B channel. + // BLOW[0:4]: The latch point for low byte of B channel. + dev->reg.init_reg(0x52, 0x01); // SENSOR_DEF + dev->reg.init_reg(0x53, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x54, 0x07); // SENSOR_DEF + dev->reg.init_reg(0x55, 0x0a); // SENSOR_DEF + dev->reg.init_reg(0x56, 0x0d); // SENSOR_DEF + dev->reg.init_reg(0x57, 0x10); // SENSOR_DEF + + // VSMP[0:4]: The position of the image sampling pulse for AFE in cycles. + // VSMPW[0:2]: The length of the image sampling pulse for AFE in cycles. + dev->reg.init_reg(0x58, 0x1b); // SENSOR_DEF + + dev->reg.init_reg(0x59, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x5a, 0x40); // SENSOR_DEF + + // 0x5b-0x5c: GMMADDR[0:15] address for gamma or motor tables download + // SENSOR_DEF + + // DECSEL[0:2]: The number of deceleration steps after touching home sensor + // STOPTIM[0:4]: The stop duration between change of directions in + // backtracking + dev->reg.init_reg(0x5e, 0x23); + if (dev->model->model_id == ModelId::CANON_4400F) { + dev->reg.init_reg(0x5e, 0x3f); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x5e, 0x85); + } + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x5e, 0x1f); + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x5e, 0x01); + } + + //FMOVDEC: The number of deceleration steps in table 5 for auto-go-home + dev->reg.init_reg(0x5f, 0x01); + if (dev->model->model_id == ModelId::CANON_4400F) { + dev->reg.init_reg(0x5f, 0xf0); + } + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x5f, 0xf0); + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x5f, 0x01); + } + + // Z1MOD[0:20] + dev->reg.init_reg(0x60, 0x00); + dev->reg.init_reg(0x61, 0x00); + dev->reg.init_reg(0x62, 0x00); + + // Z2MOD[0:20] + dev->reg.init_reg(0x63, 0x00); + dev->reg.init_reg(0x64, 0x00); + dev->reg.init_reg(0x65, 0x00); + + // STEPSEL[0:1]. Motor movement step mode selection for tables 1-3 in + // scanning mode. + // MTRPWM[0:5]. Motor phase PWM duty cycle setting for tables 1-3 + dev->reg.init_reg(0x67, 0x7f); + // FSTPSEL[0:1]: Motor movement step mode selection for tables 4-5 in + // command mode. + // FASTPWM[5:0]: Motor phase PWM duty cycle setting for tables 4-5 + dev->reg.init_reg(0x68, 0x7f); + + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300) { + dev->reg.init_reg(0x67, 0x80); + dev->reg.init_reg(0x68, 0x80); + } + + // FSHDEC[0:7]: The number of deceleration steps after scanning is finished + // (table 3) + dev->reg.init_reg(0x69, 0x01); + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x69, 64); + } + + // FMOVNO[0:7] The number of acceleration or deceleration steps for fast + // moving (table 4) + dev->reg.init_reg(0x6a, 0x04); + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x69, 64); + } + + // GPIO-related register bits + dev->reg.init_reg(0x6b, 0x30); + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8600F) + { + dev->reg.init_reg(0x6b, 0x72); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x6b, 0xb1); + } + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x6b, 0xf4); + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x6b, 0x31); + } + + // 0x6c, 0x6d, 0x6e, 0x6f are set according to gpio tables. See + // gl843_init_gpio. + + // RSH[0:4]: The position of rising edge of CCD RS signal in cycles + // RSL[0:4]: The position of falling edge of CCD RS signal in cycles + // CPH[0:4]: The position of rising edge of CCD CP signal in cycles. + // CPL[0:4]: The position of falling edge of CCD CP signal in cycles + dev->reg.init_reg(0x70, 0x01); // SENSOR_DEF + dev->reg.init_reg(0x71, 0x03); // SENSOR_DEF + dev->reg.init_reg(0x72, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x73, 0x05); // SENSOR_DEF + + if (dev->model->model_id == ModelId::CANON_4400F) { + dev->reg.init_reg(0x70, 0x01); + dev->reg.init_reg(0x71, 0x03); + dev->reg.init_reg(0x72, 0x01); + dev->reg.init_reg(0x73, 0x03); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x70, 0x01); + dev->reg.init_reg(0x71, 0x03); + dev->reg.init_reg(0x72, 0x03); + dev->reg.init_reg(0x73, 0x04); + } + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x70, 0x00); + dev->reg.init_reg(0x71, 0x02); + dev->reg.init_reg(0x72, 0x02); + dev->reg.init_reg(0x73, 0x04); + } + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x70, 0x00); + dev->reg.init_reg(0x71, 0x02); + dev->reg.init_reg(0x72, 0x00); + dev->reg.init_reg(0x73, 0x00); + } + + // CK1MAP[0:17], CK3MAP[0:17], CK4MAP[0:17]: CCD clock bit mapping setting. + dev->reg.init_reg(0x74, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x75, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x76, 0x3c); // SENSOR_DEF + dev->reg.init_reg(0x77, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x78, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x79, 0x9f); // SENSOR_DEF + dev->reg.init_reg(0x7a, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x7b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x7c, 0x55); // SENSOR_DEF + + // various AFE settings + dev->reg.init_reg(0x7d, 0x00); + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x7d, 0x20); + } + + // GPOLED[x]: LED vs GPIO settings + dev->reg.init_reg(0x7e, 0x00); + + // BSMPDLY, VSMPDLY + // LEDCNT[0:1]: Controls led blinking and its period + dev->reg.init_reg(0x7f, 0x00); + + // VRHOME, VRMOVE, VRBACK, VRSCAN: Vref settings of the motor driver IC for + // moving in various situations. + dev->reg.init_reg(0x80, 0x00); + if (dev->model->model_id == ModelId::CANON_4400F) { + dev->reg.init_reg(0x80, 0x0c); + } + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->reg.init_reg(0x80, 0x28); + } + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x80, 0x50); + } + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x80, 0x0f); + } + + if (dev->model->model_id != ModelId::CANON_4400F) { + dev->reg.init_reg(0x81, 0x00); + dev->reg.init_reg(0x82, 0x00); + dev->reg.init_reg(0x83, 0x00); + dev->reg.init_reg(0x84, 0x00); + dev->reg.init_reg(0x85, 0x00); + dev->reg.init_reg(0x86, 0x00); + } + + dev->reg.init_reg(0x87, 0x00); + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8400F || + dev->model->model_id == ModelId::CANON_8600F) + { + dev->reg.init_reg(0x87, 0x02); + } + + // MTRPLS[0:7]: The width of the ADF motor trigger signal pulse. + if (dev->model->model_id != ModelId::CANON_8400F && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7200I && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7300) + { + dev->reg.init_reg(0x94, 0xff); + } + + // 0x95-0x97: SCANLEN[0:19]: Controls when paper jam bit is set in sheetfed + // scanners. + + // ONDUR[0:15]: The duration of PWM ON phase for LAMP control + // OFFDUR[0:15]: The duration of PWM OFF phase for LAMP control + // both of the above are in system clocks + if (dev->model->model_id == ModelId::CANON_8600F) { + dev->reg.init_reg(0x98, 0x00); + dev->reg.init_reg(0x99, 0x00); + dev->reg.init_reg(0x9a, 0x00); + dev->reg.init_reg(0x9b, 0x00); + } + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + // TODO: move to set for scan + dev->reg.init_reg(0x98, 0x03); + dev->reg.init_reg(0x99, 0x30); + dev->reg.init_reg(0x9a, 0x01); + dev->reg.init_reg(0x9b, 0x80); + } + + // RMADLY[0:1], MOTLAG, CMODE, STEPTIM, MULDMYLN, IFRS + dev->reg.init_reg(0x9d, 0x04); + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->reg.init_reg(0x9d, 0x00); + } + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8400F || + dev->model->model_id == ModelId::CANON_8600F || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I || + dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0x9d, 0x08); // sets the multiplier for slope tables + } + + + // SEL3INV, TGSTIME[0:2], TGWTIME[0:2] + if (dev->model->model_id != ModelId::CANON_8400F && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7200I && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7300) + { + dev->reg.init_reg(0x9e, 0x00); // SENSOR_DEF + } + + if (dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7300) { + dev->reg.init_reg(0xa2, 0x0f); + } + + // RFHSET[0:4]: Refresh time of SDRAM in units of 2us + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8600F) + { + dev->reg.init_reg(0xa2, 0x1f); + } + + // 0xa6-0xa9: controls gpio, see gl843_gpio_init + + // not documented + if (dev->model->model_id != ModelId::CANON_4400F && + dev->model->model_id != ModelId::CANON_8400F && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7200I && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7300) + { + dev->reg.init_reg(0xaa, 0x00); + } + + // GPOM9, MULSTOP[0-2], NODECEL, TB3TB1, TB5TB2, FIX16CLK. Not documented + if (dev->model->model_id != ModelId::CANON_8400F && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7200I && + dev->model->model_id != ModelId::PLUSTEK_OPTICFILM_7300) { + dev->reg.init_reg(0xab, 0x50); + } + if (dev->model->model_id == ModelId::CANON_4400F) { + dev->reg.init_reg(0xab, 0x00); + } + if (dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + // BUG: this should apply to ModelId::CANON_CANOSCAN_8600F too, but due to previous bug + // the 8400F case overwrote it + dev->reg.init_reg(0xab, 0x40); + } + + // VRHOME[3:2], VRMOVE[3:2], VRBACK[3:2]: Vref setting of the motor driver IC + // for various situations. + if (dev->model->model_id == ModelId::CANON_8600F || + dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050 || + dev->model->model_id == ModelId::HP_SCANJET_4850C) + { + dev->reg.init_reg(0xac, 0x00); + } + + dev->calib_reg = dev->reg; + + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I) { + uint8_t data[32] = { + 0x8c, 0x8f, 0xc9, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6a, 0x73, 0x63, 0x68, 0x69, 0x65, 0x6e, 0x00, + }; + + dev->interface->write_buffer(0x3c, 0x3ff000, data, 32, + ScannerInterface::FLAG_SWAP_REGISTERS); + } +} + +// Send slope table for motor movement slope_table in machine byte order +static void gl843_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, + int steps) +{ + DBG_HELPER_ARGS(dbg, "table_nr = %d, steps = %d", table_nr, steps); + + int i; + char msg[10000]; + + std::vector<uint8_t> table(steps * 2); + for (i = 0; i < steps; i++) + { + table[i * 2] = slope_table[i] & 0xff; + table[i * 2 + 1] = slope_table[i] >> 8; + } + + if (DBG_LEVEL >= DBG_io) + { + std::sprintf(msg, "write slope %d (%d)=", table_nr, steps); + for (i = 0; i < steps; i++) { + std::sprintf (msg+strlen(msg), "%d", slope_table[i]); + } + DBG(DBG_io, "%s: %s\n", __func__, msg); + } + + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } + + // slope table addresses are fixed : 0x40000, 0x48000, 0x50000, 0x58000, 0x60000 + // XXX STEF XXX USB 1.1 ? sanei_genesys_write_0x8c (dev, 0x0f, 0x14); + dev->interface->write_gamma(0x28, 0x40000 + 0x8000 * table_nr, table.data(), steps * 2, + ScannerInterface::FLAG_SWAP_REGISTERS); + + // FIXME: remove this when updating tests + gl843_set_buffer_address(dev, 0); +} + +static void gl843_set_ad_fe(Genesys_Device* dev) +{ + for (const auto& reg : dev->frontend.regs) { + dev->interface->write_fe_register(reg.address, reg.value); + } +} + +// Set values of analog frontend +void CommandSetGl843::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const +{ + DBG_HELPER_ARGS(dbg, "%s", set == AFE_INIT ? "init" : + set == AFE_SET ? "set" : + set == AFE_POWER_SAVE ? "powersave" : "huh?"); + (void) sensor; + int i; + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + dev->frontend = dev->frontend_initial; + dev->frontend_is_init = true; + } + + // check analog frontend type + // FIXME: looks like we write to that register with initial data + uint8_t fe_type = dev->interface->read_register(REG_0x04) & REG_0x04_FESET; + if (fe_type == 2) { + gl843_set_ad_fe(dev); + return; + } + if (fe_type != 0) { + throw SaneException(SANE_STATUS_UNSUPPORTED, "unsupported frontend type %d", fe_type); + } + + DBG(DBG_proc, "%s(): frontend reset complete\n", __func__); + + for (i = 1; i <= 3; i++) + { + // FIXME: the check below is just historical artifact, we can remove it when convenient + if (!dev->frontend_is_init) { + dev->interface->write_fe_register(i, 0x00); + } else { + dev->interface->write_fe_register(i, dev->frontend.regs.get_value(0x00 + i)); + } + } + for (const auto& reg : sensor.custom_fe_regs) { + dev->interface->write_fe_register(reg.address, reg.value); + } + + for (i = 0; i < 3; i++) + { + // FIXME: the check below is just historical artifact, we can remove it when convenient + if (!dev->frontend_is_init) { + dev->interface->write_fe_register(0x20 + i, 0x00); + } else { + dev->interface->write_fe_register(0x20 + i, dev->frontend.get_offset(i)); + } + } + + if (dev->model->sensor_id == SensorId::CCD_KVSS080) { + for (i = 0; i < 3; i++) + { + // FIXME: the check below is just historical artifact, we can remove it when convenient + if (!dev->frontend_is_init) { + dev->interface->write_fe_register(0x24 + i, 0x00); + } else { + dev->interface->write_fe_register(0x24 + i, dev->frontend.regs.get_value(0x24 + i)); + } + } + } + + for (i = 0; i < 3; i++) + { + // FIXME: the check below is just historical artifact, we can remove it when convenient + if (!dev->frontend_is_init) { + dev->interface->write_fe_register(0x28 + i, 0x00); + } else { + dev->interface->write_fe_register(0x28 + i, dev->frontend.get_gain(i)); + } + } +} + + +static void gl843_init_motor_regs_scan(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const Motor_Profile& motor_profile, + unsigned int exposure, + unsigned scan_yres, + unsigned int scan_lines, + unsigned int scan_dummy, + unsigned int feed_steps, + MotorFlag flags) +{ + DBG_HELPER_ARGS(dbg, "exposure=%d, scan_yres=%d, step_type=%d, scan_lines=%d, scan_dummy=%d, " + "feed_steps=%d, flags=%x", + exposure, scan_yres, static_cast<unsigned>(motor_profile.step_type), + scan_lines, scan_dummy, feed_steps, static_cast<unsigned>(flags)); + + int use_fast_fed, coeff; + unsigned int lincnt; + unsigned feedl, dist; + GenesysRegister *r; + uint32_t z1, z2; + + /* get step multiplier */ + unsigned step_multiplier = gl843_get_step_multiplier (reg); + + use_fast_fed = 0; + + if ((scan_yres >= 300 && feed_steps > 900) || (has_flag(flags, MotorFlag::FEED))) { + use_fast_fed = 1; + } + + lincnt=scan_lines; + reg->set24(REG_LINCNT, lincnt); + DBG(DBG_io, "%s: lincnt=%d\n", __func__, lincnt); + + /* compute register 02 value */ + r = sanei_genesys_get_address(reg, REG_0x02); + r->value = 0x00; + sanei_genesys_set_motor_power(*reg, true); + + if (use_fast_fed) { + r->value |= REG_0x02_FASTFED; + } else { + r->value &= ~REG_0x02_FASTFED; + } + + /* in case of automatic go home, move until home sensor */ + if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) { + r->value |= REG_0x02_AGOHOME | REG_0x02_NOTHOME; + } + + /* disable backtracking */ + if (has_flag(flags, MotorFlag::DISABLE_BUFFER_FULL_MOVE) + ||(scan_yres>=2400 && dev->model->model_id != ModelId::CANON_4400F) + ||(scan_yres>=sensor.optical_res)) + { + r->value |= REG_0x02_ACDCDIS; + } + + if (has_flag(flags, MotorFlag::REVERSE)) { + r->value |= REG_0x02_MTRREV; + } else { + r->value &= ~REG_0x02_MTRREV; + } + + /* scan and backtracking slope table */ + auto scan_table = sanei_genesys_slope_table(dev->model->asic_type, scan_yres, exposure, + dev->motor.base_ydpi, step_multiplier, + motor_profile); + + gl843_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.steps_count); + gl843_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.steps_count); + + reg->set8(REG_STEPNO, scan_table.steps_count / step_multiplier); + reg->set8(REG_FASTNO, scan_table.steps_count / step_multiplier); + + // fast table + unsigned fast_yres = sanei_genesys_get_lowest_ydpi(dev); + auto fast_table = sanei_genesys_slope_table(dev->model->asic_type, fast_yres, exposure, + dev->motor.base_ydpi, step_multiplier, + motor_profile); + gl843_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.steps_count); + gl843_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.steps_count); + gl843_send_slope_table(dev, HOME_TABLE, fast_table.table, fast_table.steps_count); + + reg->set8(REG_FSHDEC, fast_table.steps_count / step_multiplier); + reg->set8(REG_FMOVNO, fast_table.steps_count / step_multiplier); + + /* substract acceleration distance from feedl */ + feedl=feed_steps; + feedl <<= static_cast<unsigned>(motor_profile.step_type); + + dist = scan_table.steps_count / step_multiplier; + if (use_fast_fed) + { + dist += (fast_table.steps_count / step_multiplier) * 2; + } + DBG(DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); + + /* get sure when don't insane value : XXX STEF XXX in this case we should + * fall back to single table move */ + if (dist < feedl) { + feedl -= dist; + } else { + feedl = 1; + } + + reg->set24(REG_FEEDL, feedl); + DBG(DBG_io, "%s: feedl=%d\n", __func__, feedl); + + /* doesn't seem to matter that much */ + sanei_genesys_calculate_zmod(use_fast_fed, + exposure, + scan_table.table, + scan_table.steps_count / step_multiplier, + feedl, + scan_table.steps_count / step_multiplier, + &z1, + &z2); + if(scan_yres>600) + { + z1=0; + z2=0; + } + + reg->set24(REG_Z1MOD, z1); + DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); + + reg->set24(REG_Z2MOD, z2); + DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); + + r = sanei_genesys_get_address(reg, REG_0x1E); + r->value &= 0xf0; /* 0 dummy lines */ + r->value |= scan_dummy; /* dummy lines */ + + reg->set8_mask(REG_0x67, static_cast<unsigned>(motor_profile.step_type) << REG_0x67S_STEPSEL, 0xc0); + reg->set8_mask(REG_0x68, static_cast<unsigned>(motor_profile.step_type) << REG_0x68S_FSTPSEL, 0xc0); + + // steps for STOP table + reg->set8(REG_FMOVDEC, fast_table.steps_count / step_multiplier); + + /* Vref XXX STEF XXX : optical divider or step type ? */ + r = sanei_genesys_get_address (reg, 0x80); + if (!(dev->model->flags & GENESYS_FLAG_FULL_HWDPI_MODE)) + { + r->value = 0x50; + coeff = sensor.get_hwdpi_divisor_for_dpi(scan_yres); + if (dev->model->motor_id == MotorId::KVSS080) { + if(coeff>=1) + { + r->value |= 0x05; + } + } + else { + switch(coeff) + { + case 4: + r->value |= 0x0a; + break; + case 2: + r->value |= 0x0f; + break; + case 1: + r->value |= 0x0f; + break; + } + } + } +} + + +/** @brief setup optical related registers + * start and pixels are expressed in optical sensor resolution coordinate + * space. + * @param dev device to use + * @param reg registers to set up + * @param exposure exposure time to use + * @param used_res scanning resolution used, may differ from + * scan's one + * @param start logical start pixel coordinate + * @param pixels logical number of pixels to use + * @param channels number of color channles used (1 or 3) + * @param depth bit depth of the scan (1, 8 or 16 bits) + * @param ccd_size_divisor true specifies how much x coordinates must be shrunk + * @param color_filter to choose the color channel used in gray scans + * @param flags to drive specific settings such no calibration, XPA use ... + */ +static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, unsigned int exposure, + const ScanSession& session) +{ + DBG_HELPER_ARGS(dbg, "exposure=%d", exposure); + unsigned int dpihw; + unsigned int tgtime; /**> exposure time multiplier */ + GenesysRegister *r; + + /* tgtime */ + tgtime = exposure / 65536 + 1; + DBG(DBG_io2, "%s: tgtime=%d\n", __func__, tgtime); + + // to manage high resolution device while keeping good low resolution scanning speed, we make + // hardware dpi vary + dpihw = sensor.get_register_hwdpi(session.output_resolution); + DBG(DBG_io2, "%s: dpihw=%d\n", __func__, dpihw); + + /* sensor parameters */ + gl843_setup_sensor(dev, sensor, reg); + + // resolution is divided according to CKSEL + unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); + DBG(DBG_io2, "%s: ccd_pixels_per_system_pixel=%d\n", __func__, ccd_pixels_per_system_pixel); + + dev->cmd_set->set_fe(dev, sensor, AFE_SET); + + /* enable shading */ + regs_set_optical_off(dev->model->asic_type, *reg); + r = sanei_genesys_get_address (reg, REG_0x01); + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || + (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION || + (dev->model->flags & GENESYS_FLAG_CALIBRATION_HOST_SIDE))) + { + r->value &= ~REG_0x01_DVDSET; + } else { + r->value |= REG_0x01_DVDSET; + } + + bool use_shdarea = dpihw > 600; + if (dev->model->model_id == ModelId::CANON_4400F) { + use_shdarea = session.params.xres <= 600; + } else if (dev->model->model_id == ModelId::CANON_8400F) { + use_shdarea = session.params.xres <= 400; + } + if (use_shdarea) { + r->value |= REG_0x01_SHDAREA; + } else { + r->value &= ~REG_0x01_SHDAREA; + } + + r = sanei_genesys_get_address (reg, REG_0x03); + if (dev->model->model_id == ModelId::CANON_8600F) { + r->value |= REG_0x03_AVEENB; + } else { + r->value &= ~REG_0x03_AVEENB; + } + + // FIXME: we probably don't need to set exposure to registers at this point. It was this way + // before a refactor. + sanei_genesys_set_lamp_power(dev, sensor, *reg, + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); + + /* select XPA */ + r->value &= ~REG_0x03_XPASEL; + if (has_flag(session.params.flags, ScanFlag::USE_XPA)) { + r->value |= REG_0x03_XPASEL; + } + reg->state.is_xpa_on = has_flag(session.params.flags, ScanFlag::USE_XPA); + + /* BW threshold */ + r = sanei_genesys_get_address(reg, REG_0x2E); + r->value = dev->settings.threshold; + r = sanei_genesys_get_address(reg, REG_0x2F); + r->value = dev->settings.threshold; + + /* monochrome / color scan */ + r = sanei_genesys_get_address(reg, REG_0x04); + switch (session.params.depth) { + case 8: + r->value &= ~(REG_0x04_LINEART | REG_0x04_BITSET); + break; + case 16: + r->value &= ~REG_0x04_LINEART; + r->value |= REG_0x04_BITSET; + break; + } + + r->value &= ~(REG_0x04_FILTER | REG_0x04_AFEMOD); + if (session.params.channels == 1) + { + switch (session.params.color_filter) + { + case ColorFilter::RED: + r->value |= 0x14; + break; + case ColorFilter::BLUE: + r->value |= 0x1c; + break; + case ColorFilter::GREEN: + r->value |= 0x18; + break; + default: + break; // should not happen + } + } else { + switch (dev->frontend.layout.type) { + case FrontendType::WOLFSON: + r->value |= 0x10; // pixel by pixel + break; + case FrontendType::ANALOG_DEVICES: + r->value |= 0x20; // slow color pixel by pixel + break; + default: + throw SaneException("Invalid frontend type %d", + static_cast<unsigned>(dev->frontend.layout.type)); + } + } + + sanei_genesys_set_dpihw(*reg, sensor, dpihw); + + if (should_enable_gamma(session, sensor)) { + reg->find_reg(REG_0x05).value |= REG_0x05_GMMENB; + } else { + reg->find_reg(REG_0x05).value &= ~REG_0x05_GMMENB; + } + + unsigned dpiset = session.output_resolution * session.ccd_size_divisor * + ccd_pixels_per_system_pixel; + + if (sensor.dpiset_override != 0) { + dpiset = sensor.dpiset_override; + } + reg->set16(REG_DPISET, dpiset); + DBG(DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); + + reg->set16(REG_STRPIXEL, session.pixel_startx); + reg->set16(REG_ENDPIXEL, session.pixel_endx); + + /* MAXWD is expressed in 2 words unit */ + /* nousedspace = (mem_bank_range * 1024 / 256 -1 ) * 4; */ + // BUG: the division by ccd_size_divisor likely does not make sense + reg->set24(REG_MAXWD, (session.output_line_bytes / session.ccd_size_divisor) >> 1); + + reg->set16(REG_LPERIOD, exposure / tgtime); + DBG(DBG_io2, "%s: exposure used=%d\n", __func__, exposure/tgtime); + + r = sanei_genesys_get_address (reg, REG_DUMMY); + r->value = sensor.dummy_pixel; +} + +void CommandSetGl843::init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const +{ + DBG_HELPER(dbg); + session.assert_computed(); + + int exposure; + + int slope_dpi = 0; + int dummy = 0; + + /* we enable true gray for cis scanners only, and just when doing + * scan since color calibration is OK for this mode + */ + + dummy = 0; + if (dev->model->model_id == ModelId::CANON_4400F && session.params.yres == 1200) { + dummy = 1; + } + + /* slope_dpi */ + /* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */ + if (dev->model->is_cis) + slope_dpi = session.params.yres * session.params.channels; + else + slope_dpi = session.params.yres; + slope_dpi = slope_dpi * (1 + dummy); + + /* scan_step_type */ + exposure = sensor.exposure_lperiod; + if (exposure < 0) { + throw std::runtime_error("Exposure not defined in sensor definition"); + } + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl843_motor_profiles, + dev->model->motor_id, + exposure); + + DBG(DBG_info, "%s : exposure=%d pixels\n", __func__, exposure); + DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, + static_cast<unsigned>(motor_profile.step_type)); + + // now _LOGICAL_ optical values used are known, setup registers + gl843_init_optical_regs_scan(dev, sensor, reg, exposure, session); + + /*** motor parameters ***/ + MotorFlag mflags = MotorFlag::NONE; + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { + mflags |= MotorFlag::DISABLE_BUFFER_FULL_MOVE; + } + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { + mflags |= MotorFlag::FEED; + } + if (has_flag(session.params.flags, ScanFlag::USE_XPA)) { + mflags |= MotorFlag::USE_XPA; + } + if (has_flag(session.params.flags, ScanFlag::REVERSE)) { + mflags |= MotorFlag::REVERSE; + } + + unsigned scan_lines = dev->model->is_cis ? session.output_line_count * session.params.channels + : session.output_line_count; + + gl843_init_motor_regs_scan(dev, sensor, reg, motor_profile, exposure, slope_dpi, + scan_lines, dummy, session.params.starty, mflags); + + dev->read_buffer.clear(); + dev->read_buffer.alloc(session.buffer_size_read); + + build_image_pipeline(dev, session); + + dev->read_active = true; + + dev->session = session; + + dev->total_bytes_read = 0; + dev->total_bytes_to_read = session.output_line_bytes_requested * session.params.lines; + + DBG(DBG_info, "%s: total bytes to send = %zu\n", __func__, dev->total_bytes_to_read); +} + +ScanSession CommandSetGl843::calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const +{ + DBG_HELPER(dbg); + debug_dump(DBG_info, settings); + + int start; + + /* we have 2 domains for ccd: xres below or above half ccd max dpi */ + unsigned ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(settings.xres); + + if (settings.scan_method == ScanMethod::TRANSPARENCY || + settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + start = static_cast<int>(dev->model->x_offset_ta); + } else { + start = static_cast<int>(dev->model->x_offset); + } + + if (dev->model->model_id == ModelId::CANON_8600F) + { + // FIXME: this is probably just an artifact of a bug elsewhere + start /= ccd_size_divisor; + } + + start += static_cast<int>(settings.tl_x); + start = static_cast<int>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = settings.xres; + session.params.yres = settings.yres; + session.params.startx = start; // not used + session.params.starty = 0; // not used + session.params.pixels = settings.pixels; + session.params.requested_pixels = settings.requested_pixels; + session.params.lines = settings.lines; + session.params.depth = settings.depth; + session.params.channels = settings.get_channels(); + session.params.scan_method = settings.scan_method; + session.params.scan_mode = settings.scan_mode; + session.params.color_filter = settings.color_filter; + session.params.flags = ScanFlag::NONE; + + compute_session(dev, session, sensor); + + return session; +} + +/** + * for fast power saving methods only, like disabling certain amplifiers + * @param dev device to use + * @param enable true to set inot powersaving + * */ +void CommandSetGl843::save_power(Genesys_Device* dev, bool enable) const +{ + DBG_HELPER_ARGS(dbg, "enable = %d", enable); + + // switch KV-SS080 lamp off + if (dev->model->gpio_id == GpioId::KVSS080) { + uint8_t val = dev->interface->read_register(REG_0x6C); + if (enable) { + val &= 0xef; + } else { + val |= 0x10; + } + dev->interface->write_register(REG_0x6C, val); + } +} + +void CommandSetGl843::set_powersaving(Genesys_Device* dev, int delay /* in minutes */) const +{ + (void) dev; + DBG_HELPER_ARGS(dbg, "delay = %d", delay); +} + +static bool gl843_get_paper_sensor(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + + uint8_t val = dev->interface->read_register(REG_0x6D); + + return (val & 0x1) == 0; +} + +void CommandSetGl843::eject_document(Genesys_Device* dev) const +{ + (void) dev; + DBG_HELPER(dbg); +} + + +void CommandSetGl843::load_document(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + (void) dev; +} + +/** + * detects end of document and adjust current scan + * to take it into account + * used by sheetfed scanners + */ +void CommandSetGl843::detect_document_end(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + bool paper_loaded = gl843_get_paper_sensor(dev); + + /* sheetfed scanner uses home sensor as paper present */ + if (dev->document && !paper_loaded) { + DBG(DBG_info, "%s: no more document\n", __func__); + dev->document = false; + + unsigned scanned_lines = 0; + catch_all_exceptions(__func__, [&](){ sanei_genesys_read_scancnt(dev, &scanned_lines); }); + + std::size_t output_lines = dev->session.output_line_count; + + std::size_t offset_lines = static_cast<std::size_t>( + (dev->model->post_scan * dev->session.params.yres) / MM_PER_INCH); + + std::size_t scan_end_lines = scanned_lines + offset_lines; + + std::size_t remaining_lines = dev->get_pipeline_source().remaining_bytes() / + dev->session.output_line_bytes_raw; + + DBG(DBG_io, "%s: scanned_lines=%u\n", __func__, scanned_lines); + DBG(DBG_io, "%s: scan_end_lines=%zu\n", __func__, scan_end_lines); + DBG(DBG_io, "%s: output_lines=%zu\n", __func__, output_lines); + DBG(DBG_io, "%s: remaining_lines=%zu\n", __func__, remaining_lines); + + if (scan_end_lines > output_lines) { + auto skip_lines = scan_end_lines - output_lines; + + if (remaining_lines > skip_lines) { + DBG(DBG_io, "%s: skip_lines=%zu\n", __func__, skip_lines); + + remaining_lines -= skip_lines; + dev->get_pipeline_source().set_remaining_bytes(remaining_lines * + dev->session.output_line_bytes_raw); + dev->total_bytes_to_read -= skip_lines * dev->session.output_line_bytes_requested; + } + } + } +} + +// enables or disables XPA slider motor +void gl843_set_xpa_motor_power(Genesys_Device* dev, Genesys_Register_Set& regs, bool set) +{ + DBG_HELPER(dbg); + uint8_t val; + + if (dev->model->model_id == ModelId::CANON_8400F) { + + if (set) { + val = dev->interface->read_register(0x6c); + val &= ~(REG_0x6C_GPIO16 | REG_0x6C_GPIO13); + if (dev->session.output_resolution >= 2400) { + val &= ~REG_0x6C_GPIO10; + } + dev->interface->write_register(0x6c, val); + + val = dev->interface->read_register(0xa9); + val |= REG_0xA9_GPO30; + val &= ~REG_0xA9_GPO29; + dev->interface->write_register(0xa9, val); + } else { + val = dev->interface->read_register(0x6c); + val |= REG_0x6C_GPIO16 | REG_0x6C_GPIO13; + dev->interface->write_register(0x6c, val); + + val = dev->interface->read_register(0xa9); + val &= ~REG_0xA9_GPO30; + val |= REG_0xA9_GPO29; + dev->interface->write_register(0xa9, val); + } + } else if (dev->model->model_id == ModelId::CANON_8600F) { + if (set) { + val = dev->interface->read_register(REG_0x6C); + val &= ~REG_0x6C_GPIO14; + if (dev->session.output_resolution >= 2400) { + val |= REG_0x6C_GPIO10; + } + dev->interface->write_register(REG_0x6C, val); + + val = dev->interface->read_register(REG_0xA6); + val |= REG_0xA6_GPIO17; + val &= ~REG_0xA6_GPIO23; + dev->interface->write_register(REG_0xA6, val); + } else { + val = dev->interface->read_register(REG_0x6C); + val |= REG_0x6C_GPIO14; + val &= ~REG_0x6C_GPIO10; + dev->interface->write_register(REG_0x6C, val); + + val = dev->interface->read_register(REG_0xA6); + val &= ~REG_0xA6_GPIO17; + val &= ~REG_0xA6_GPIO23; + dev->interface->write_register(REG_0xA6, val); + } + } else if (dev->model->model_id == ModelId::HP_SCANJET_G4050) { + if (set) { + // set MULTFILM et GPOADF + val = dev->interface->read_register(REG_0x6B); + val |=REG_0x6B_MULTFILM|REG_0x6B_GPOADF; + dev->interface->write_register(REG_0x6B, val); + + val = dev->interface->read_register(REG_0x6C); + val &= ~REG_0x6C_GPIO15; + dev->interface->write_register(REG_0x6C, val); + + /* Motor power ? No move at all without this one */ + val = dev->interface->read_register(REG_0xA6); + val |= REG_0xA6_GPIO20; + dev->interface->write_register(REG_0xA6, val); + + val = dev->interface->read_register(REG_0xA8); + val &= ~REG_0xA8_GPO27; + dev->interface->write_register(REG_0xA8, val); + + val = dev->interface->read_register(REG_0xA9); + val |= REG_0xA9_GPO32|REG_0xA9_GPO31; + dev->interface->write_register(REG_0xA9, val); + } else { + // unset GPOADF + val = dev->interface->read_register(REG_0x6B); + val &= ~REG_0x6B_GPOADF; + dev->interface->write_register(REG_0x6B, val); + + val = dev->interface->read_register(REG_0xA8); + val |= REG_0xA8_GPO27; + dev->interface->write_register(REG_0xA8, val); + + val = dev->interface->read_register(REG_0xA9); + val &= ~REG_0xA9_GPO31; + dev->interface->write_register(REG_0xA9, val); + } + } + regs.state.is_xpa_motor_on = set; +} + + +/** @brief light XPA lamp + * toggle gpios to switch off regular lamp and light on the + * XPA light + * @param dev device to set up + */ +static void gl843_set_xpa_lamp_power(Genesys_Device* dev, bool set) +{ + DBG_HELPER(dbg); + + struct LampSettings { + ModelId model_id; + ScanMethod scan_method; + GenesysRegisterSettingSet regs_on; + GenesysRegisterSettingSet regs_off; + }; + + // FIXME: BUG: we're not clearing the registers to the previous state when returning back when + // turning off the lamp + LampSettings settings[] = { + { ModelId::CANON_8400F, ScanMethod::TRANSPARENCY, { + { 0xa6, 0x34, 0xf4 }, + }, { + { 0xa6, 0x40, 0x70 }, + } + }, + { ModelId::CANON_8400F, ScanMethod::TRANSPARENCY_INFRARED, { + { 0x6c, 0x40, 0x40 }, + { 0xa6, 0x01, 0xff }, + }, { + { 0x6c, 0x00, 0x40 }, + { 0xa6, 0x00, 0xff }, + } + }, + { ModelId::CANON_8600F, ScanMethod::TRANSPARENCY, { + { 0xa6, 0x34, 0xf4 }, + { 0xa7, 0xe0, 0xe0 }, + }, { + { 0xa6, 0x40, 0x70 }, + } + }, + { ModelId::CANON_8600F, ScanMethod::TRANSPARENCY_INFRARED, { + { 0xa6, 0x00, 0xc0 }, + { 0xa7, 0xe0, 0xe0 }, + { 0x6c, 0x80, 0x80 }, + }, { + { 0xa6, 0x00, 0xc0 }, + { 0x6c, 0x00, 0x80 }, + } + }, + { ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY, { + }, { + { 0xa6, 0x40, 0x70 }, // BUG: remove this cleanup write, it was enabled by accident + } + }, + { ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY_INFRARED, { + { 0xa8, 0x07, 0x07 }, + }, { + { 0xa8, 0x00, 0x07 }, + } + }, + { ModelId::PLUSTEK_OPTICFILM_7300, ScanMethod::TRANSPARENCY, {}, {} }, + { ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY, {}, {} }, + { ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY_INFRARED, { + { 0xa8, 0x07, 0x07 }, + }, { + { 0xa8, 0x00, 0x07 }, + } + }, + }; + + for (const auto& setting : settings) { + if (setting.model_id == dev->model->model_id && + setting.scan_method == dev->settings.scan_method) + { + apply_reg_settings_to_device(*dev, set ? setting.regs_on : setting.regs_off); + return; + } + } + + // BUG: we're currently calling the function in shut down path of regular lamp + if (set) { + throw SaneException("Unexpected code path entered"); + } + + GenesysRegisterSettingSet regs = { + { 0xa6, 0x40, 0x70 }, + }; + apply_reg_settings_to_device(*dev, regs); + // TODO: throw exception when we're only calling this function in error return path + // throw SaneException("Could not find XPA lamp settings"); +} + +// Send the low-level scan command +void CommandSetGl843::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, bool start_motor) const +{ + DBG_HELPER(dbg); + (void) sensor; + + /* set up GPIO for scan */ + switch(dev->model->gpio_id) { + /* KV case */ + case GpioId::KVSS080: + dev->interface->write_register(REG_0xA9, 0x00); + dev->interface->write_register(REG_0xA6, 0xf6); + // blinking led + dev->interface->write_register(0x7e, 0x04); + break; + case GpioId::G4050: + dev->interface->write_register(REG_0xA7, 0xfe); + dev->interface->write_register(REG_0xA8, 0x3e); + dev->interface->write_register(REG_0xA9, 0x06); + if ((reg->get8(0x05) & REG_0x05_DPIHW) == REG_0x05_DPIHW_600) { + dev->interface->write_register(REG_0x6C, 0x20); + dev->interface->write_register(REG_0xA6, 0x44); + } else { + dev->interface->write_register(REG_0x6C, 0x60); + dev->interface->write_register(REG_0xA6, 0x46); + } + + if (reg->state.is_xpa_on && reg->state.is_lamp_on) { + gl843_set_xpa_lamp_power(dev, true); + } + + if (reg->state.is_xpa_on) { + gl843_set_xpa_motor_power(dev, *reg, true); + } + + // blinking led + dev->interface->write_register(REG_0x7E, 0x01); + break; + case GpioId::CANON_8400F: + case GpioId::CANON_8600F: + if (reg->state.is_xpa_on && reg->state.is_lamp_on) { + gl843_set_xpa_lamp_power(dev, true); + } + if (reg->state.is_xpa_on) { + gl843_set_xpa_motor_power(dev, *reg, true); + } + break; + case GpioId::PLUSTEK_OPTICFILM_7200I: + case GpioId::PLUSTEK_OPTICFILM_7300: + case GpioId::PLUSTEK_OPTICFILM_7500I: { + if (reg->state.is_xpa_on && reg->state.is_lamp_on) { + gl843_set_xpa_lamp_power(dev, true); + } + break; + } + case GpioId::CANON_4400F: + default: + break; + } + + // clear scan and feed count + dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT); + + // enable scan and motor + uint8_t val = dev->interface->read_register(REG_0x01); + val |= REG_0x01_SCAN; + dev->interface->write_register(REG_0x01, val); + + scanner_start_action(*dev, start_motor); + + if (reg->state.is_motor_on) { + dev->advance_head_pos_by_session(ScanHeadId::PRIMARY); + } + if (reg->state.is_xpa_motor_on) { + dev->advance_head_pos_by_session(ScanHeadId::SECONDARY); + } +} + + +// Send the stop scan command +void CommandSetGl843::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg, + bool check_stop) const +{ + DBG_HELPER_ARGS(dbg, "check_stop = %d", check_stop); + + // post scan gpio + dev->interface->write_register(0x7e, 0x00); + + // turn off XPA lamp if needed + // BUG: the if condition below probably shouldn't be enabled when XPA is off + if (reg->state.is_xpa_on || reg->state.is_lamp_on) { + gl843_set_xpa_lamp_power(dev, false); + } + + if (!dev->model->is_sheetfed) { + scanner_stop_action(*dev); + } +} + +/** @brief Moves the slider to the home (top) position slowly + * */ +void CommandSetGl843::move_back_home(Genesys_Device* dev, bool wait_until_home) const +{ + scanner_move_back_home(*dev, wait_until_home); +} + +// Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi +// from very top of scanner +void CommandSetGl843::search_start_position(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + Genesys_Register_Set local_reg; + + int pixels = 600; + int dpi = 300; + + local_reg = dev->reg; + + /* sets for a 200 lines * 600 pixels */ + /* normal scan with no shading */ + + // FIXME: the current approach of doing search only for one resolution does not work on scanners + // whith employ different sensors with potentially different settings. + const auto& sensor = sanei_genesys_find_sensor(dev, dpi, 1, dev->model->default_method); + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; // we should give a small offset here - ~60 steps + session.params.pixels = 600; + session.params.lines = dev->model->search_lines; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::GREEN; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE | + ScanFlag::DISABLE_BUFFER_FULL_MOVE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + // send to scanner + dev->interface->write_registers(local_reg); + + dev->cmd_set->begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_start_position"); + end_scan(dev, &local_reg, true); + dev->reg = local_reg; + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + Image image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes_raw); + + scanner_stop_action_no_move(*dev, local_reg); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl843_search_position.pnm", image); + } + + dev->cmd_set->end_scan(dev, &local_reg, true); + + /* update regs to copy ASIC internal state */ + dev->reg = local_reg; + + for (auto& sensor_update : + sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method)) + { + sanei_genesys_search_reference_point(dev, sensor_update, image.get_row_ptr(0), 0, dpi, + pixels, dev->model->search_lines); + } +} + +// sets up register for coarse gain calibration +// todo: check it for scanners using it +void CommandSetGl843::init_regs_for_coarse_calibration(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { + flags |= ScanFlag::USE_XPA; + } + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = sensor.optical_res / sensor.ccd_pixels_per_system_pixel(); + session.params.lines = 20; + session.params.depth = 16; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = flags; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + sanei_genesys_set_motor_power(regs, false); + + DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, + sensor.optical_res / sensor.ccd_pixels_per_system_pixel(), dev->settings.xres); + + dev->interface->write_registers(regs); +} + +// init registers for shading calibration shading calibration is done at dpihw +void CommandSetGl843::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int move, resolution, dpihw, factor; + + /* initial calibration reg values */ + regs = dev->reg; + + dev->calib_channels = 3; + + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + dev->calib_lines = dev->model->shading_ta_lines; + } else { + dev->calib_lines = dev->model->shading_lines; + } + + dpihw = sensor.get_logical_hwdpi(dev->settings.xres); + factor=sensor.optical_res/dpihw; + resolution=dpihw; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, dev->calib_channels, + dev->settings.scan_method); + + if ((dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) && + dev->model->model_id == ModelId::CANON_8600F && + dev->settings.xres == 4800) + { + float offset = static_cast<float>(dev->model->x_offset_ta); + offset /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); + offset = static_cast<float>((offset * calib_sensor.optical_res) / MM_PER_INCH); + + float size = static_cast<float>(dev->model->x_size_ta); + size /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); + size = static_cast<float>((size * calib_sensor.optical_res) / MM_PER_INCH); + + dev->calib_pixels_offset = static_cast<std::size_t>(offset); + dev->calib_pixels = static_cast<std::size_t>(size); + } + else + { + dev->calib_pixels_offset = 0; + dev->calib_pixels = calib_sensor.sensor_pixels / factor; + } + + dev->calib_resolution = resolution; + + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + // note: move_to_ta() function has already been called and the sensor is at the + // transparency adapter + move = static_cast<int>(dev->model->y_offset_calib_white_ta - dev->model->y_offset_sensor_to_ta); + flags |= ScanFlag::USE_XPA; + } else { + move = static_cast<int>(dev->model->y_offset_calib_white); + } + + move = static_cast<int>((move * resolution) / MM_PER_INCH); + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = dev->calib_pixels_offset; + session.params.starty = move; + session.params.pixels = dev->calib_pixels; + session.params.lines = dev->calib_lines; + session.params.depth = 16; + session.params.channels = dev->calib_channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = flags; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + // the pixel number may be updated to conform to scanner constraints + dev->calib_pixels = session.output_pixels; + + dev->calib_session = session; + dev->calib_total_bytes_to_read = session.output_total_bytes_raw; + + dev->interface->write_registers(regs); +} + +/** @brief set up registers for the actual scan + */ +void CommandSetGl843::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + float move; + int move_dpi; + float start; + + debug_dump(DBG_info, dev->settings); + + move_dpi = dev->motor.base_ydpi; + + ScanFlag flags = ScanFlag::NONE; + + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + // note: move_to_ta() function has already been called and the sensor is at the + // transparency adapter + if (dev->ignore_offsets) { + move = 0; + } else { + move = static_cast<float>(dev->model->y_offset_ta - dev->model->y_offset_sensor_to_ta); + } + flags |= ScanFlag::USE_XPA; + } else { + if (dev->ignore_offsets) { + move = 0; + } else { + move = static_cast<float>(dev->model->y_offset); + } + } + + move += static_cast<float>(dev->settings.tl_y); + move = static_cast<float>((move * move_dpi) / MM_PER_INCH); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + /* start */ + if (dev->settings.scan_method==ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + start = static_cast<float>(dev->model->x_offset_ta); + } else { + start = static_cast<float>(dev->model->x_offset); + } + + if (dev->model->model_id == ModelId::CANON_8400F || + dev->model->model_id == ModelId::CANON_8600F) + { + // FIXME: this is probably just an artifact of a bug elsewhere + start /= sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres); + } + + start = static_cast<float>(start + dev->settings.tl_x); + start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = static_cast<unsigned>(start); + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = dev->settings.pixels; + session.params.requested_pixels = dev->settings.requested_pixels; + session.params.lines = dev->settings.lines; + session.params.depth = dev->settings.depth; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = flags; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &dev->reg, session); +} + +/** + * This function sends gamma tables to ASIC + */ +void CommandSetGl843::send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + int size; + int i; + + size = 256; + + /* allocate temporary gamma tables: 16 bits words, 3 channels */ + std::vector<uint8_t> gamma(size * 2 * 3); + + std::vector<uint16_t> rgamma = get_gamma_table(dev, sensor, GENESYS_RED); + std::vector<uint16_t> ggamma = get_gamma_table(dev, sensor, GENESYS_GREEN); + std::vector<uint16_t> bgamma = get_gamma_table(dev, sensor, GENESYS_BLUE); + + // copy sensor specific's gamma tables + for (i = 0; i < size; i++) { + gamma[i * 2 + size * 0 + 0] = rgamma[i] & 0xff; + gamma[i * 2 + size * 0 + 1] = (rgamma[i] >> 8) & 0xff; + gamma[i * 2 + size * 2 + 0] = ggamma[i] & 0xff; + gamma[i * 2 + size * 2 + 1] = (ggamma[i] >> 8) & 0xff; + gamma[i * 2 + size * 4 + 0] = bgamma[i] & 0xff; + gamma[i * 2 + size * 4 + 1] = (bgamma[i] >> 8) & 0xff; + } + + dev->interface->write_gamma(0x28, 0x0000, gamma.data(), size * 2 * 3, + ScannerInterface::FLAG_SWAP_REGISTERS); +} + +/* this function does the led calibration by scanning one line of the calibration + area below scanner's top on white strip. + +-needs working coarse/gain +*/ +SensorExposure CommandSetGl843::led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int num_pixels; + int avg[3], avga, avge; + int turn; + uint16_t expr, expg, expb; + + // offset calibration is always done in color mode + unsigned channels = 3; + + // take a copy, as we're going to modify exposure + auto calib_sensor = sanei_genesys_find_sensor(dev, sensor.optical_res, channels, + dev->settings.scan_method); + + num_pixels = (calib_sensor.sensor_pixels * calib_sensor.optical_res) / calib_sensor.optical_res; + + /* initial calibration reg values */ + regs = dev->reg; + + ScanSession session; + session.params.xres = calib_sensor.sensor_pixels; + session.params.yres = dev->motor.base_ydpi; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + dev->interface->write_registers(regs); + +/* + we try to get equal bright leds here: + + loop: + average per color + adjust exposure times + */ + + expr = calib_sensor.exposure.red; + expg = calib_sensor.exposure.green; + expb = calib_sensor.exposure.blue; + + turn = 0; + + bool acceptable = false; + do + { + + calib_sensor.exposure.red = expr; + calib_sensor.exposure.green = expg; + calib_sensor.exposure.blue = expb; + + regs_set_exposure(dev->model->asic_type, regs, calib_sensor.exposure); + + dev->interface->write_registers(regs); + + DBG(DBG_info, "%s: starting first line reading\n", __func__); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("led_calibration"); + move_back_home(dev, true); + return calib_sensor.exposure; + } + + auto image = read_unshuffled_image_from_scanner(dev, session, + session.output_total_bytes_raw); + scanner_stop_action_no_move(*dev, regs); + + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl843_led_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, image); + } + + acceptable = true; + + for (unsigned ch = 0; ch < channels; ch++) { + avg[ch] = 0; + for (std::size_t x = 0; x < image.get_width(); x++) { + avg[ch] += image.get_raw_channel(x, 0, ch); + } + avg[ch] /= image.get_width(); + } + + DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); + + acceptable = true; + + if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 || + avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 || + avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95) + acceptable = false; + + if (!acceptable) + { + avga = (avg[0] + avg[1] + avg[2]) / 3; + expr = (expr * avga) / avg[0]; + expg = (expg * avga) / avg[1]; + expb = (expb * avga) / avg[2]; +/* + keep the resulting exposures below this value. + too long exposure drives the ccd into saturation. + we may fix this by relying on the fact that + we get a striped scan without shading, by means of + statistical calculation +*/ + avge = (expr + expg + expb) / 3; + + /* don't overflow max exposure */ + if (avge > 3000) + { + expr = (expr * 2000) / avge; + expg = (expg * 2000) / avge; + expb = (expb * 2000) / avge; + } + if (avge < 50) + { + expr = (expr * 50) / avge; + expg = (expg * 50) / avge; + expb = (expb * 50) / avge; + } + + } + scanner_stop_action(*dev); + + turn++; + + } + while (!acceptable && turn < 100); + + DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, expr, expg, expb); + + move_back_home(dev, true); + + return calib_sensor.exposure; +} + + + +/** + * average dark pixels of a 8 bits scan of a given channel + */ +static int dark_average_channel(const Image& image, unsigned black, unsigned channel) +{ + auto channels = get_pixel_channels(image.get_format()); + + unsigned avg[3]; + + // computes average values on black margin + for (unsigned ch = 0; ch < channels; ch++) { + avg[ch] = 0; + unsigned count = 0; + // FIXME: start with the second line because the black pixels often have noise on the first + // line; the cause is probably incorrectly cleaned up previous scan + for (std::size_t y = 1; y < image.get_height(); y++) { + for (unsigned j = 0; j < black; j++) { + avg[ch] += image.get_raw_channel(j, y, ch); + count++; + } + } + if (count > 0) { + avg[ch] /= count; + } + DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, ch, avg[ch]); + } + DBG(DBG_info, "%s: average = %d\n", __func__, avg[channel]); + return avg[channel]; +} + +/** @brief calibrate AFE offset + * Iterate doing scans at target dpi until AFE offset if correct. One + * color line is scanned at a time. Scanning head doesn't move. + * @param dev device to calibrate + */ +void CommandSetGl843::offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + + if (dev->frontend.layout.type != FrontendType::WOLFSON) + return; + + unsigned channels; + int pass, resolution, lines; + int topavg[3], bottomavg[3], avg[3]; + int top[3], bottom[3], black_pixels, pixels, factor, dpihw; + + /* offset calibration is always done in color mode */ + channels = 3; + lines = 8; + + // compute divider factor to compute final pixels number + dpihw = sensor.get_logical_hwdpi(dev->settings.xres); + factor = sensor.optical_res / dpihw; + resolution = dpihw; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels, + dev->settings.scan_method); + + int target_pixels = calib_sensor.sensor_pixels / factor; + int start_pixel = 0; + black_pixels = calib_sensor.black_pixels / factor; + + if ((dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) && + dev->model->model_id == ModelId::CANON_8600F && + dev->settings.xres == 4800) + { + start_pixel = static_cast<int>(dev->model->x_offset_ta); + start_pixel /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); + start_pixel = static_cast<int>((start_pixel * calib_sensor.optical_res) / MM_PER_INCH); + + target_pixels = static_cast<int>(dev->model->x_size_ta); + target_pixels /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); + target_pixels = static_cast<int>((target_pixels * calib_sensor.optical_res) / MM_PER_INCH); + } + + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + flags |= ScanFlag::USE_XPA; + } + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = start_pixel; + session.params.starty = 0; + session.params.pixels = target_pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = ColorFilter::RED; + session.params.flags = flags; + compute_session(dev, session, calib_sensor); + pixels = session.output_pixels; + + DBG(DBG_io, "%s: dpihw =%d\n", __func__, dpihw); + DBG(DBG_io, "%s: factor =%d\n", __func__, factor); + DBG(DBG_io, "%s: resolution =%d\n", __func__, resolution); + DBG(DBG_io, "%s: pixels =%d\n", __func__, pixels); + DBG(DBG_io, "%s: black_pixels=%d\n", __func__, black_pixels); + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + sanei_genesys_set_motor_power(regs, false); + + // init gain and offset + for (unsigned ch = 0; ch < 3; ch++) + { + bottom[ch] = 10; + dev->frontend.set_offset(ch, bottom[ch]); + dev->frontend.set_gain(ch, 0); + } + dev->cmd_set->set_fe(dev, calib_sensor, AFE_SET); + + // scan with bottom AFE settings + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting first line reading\n", __func__); + + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("offset_calibration"); + scanner_stop_action_no_move(*dev, regs); + return; + } + + auto first_line = read_unshuffled_image_from_scanner(dev, session, + session.output_total_bytes_raw); + scanner_stop_action_no_move(*dev, regs); + + if (DBG_LEVEL >= DBG_data) + { + char fn[40]; + std::snprintf(fn, 40, "gl843_bottom_offset_%03d_%03d_%03d.pnm", + bottom[0], bottom[1], bottom[2]); + sanei_genesys_write_pnm_file(fn, first_line); + } + + for (unsigned ch = 0; ch < 3; ch++) { + bottomavg[ch] = dark_average_channel(first_line, black_pixels, ch); + DBG(DBG_io2, "%s: bottom avg %d=%d\n", __func__, ch, bottomavg[ch]); + } + + // now top value + for (unsigned ch = 0; ch < 3; ch++) { + top[ch] = 255; + dev->frontend.set_offset(ch, top[ch]); + } + dev->cmd_set->set_fe(dev, calib_sensor, AFE_SET); + + // scan with top AFE values + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + auto second_line = read_unshuffled_image_from_scanner(dev, session, + session.output_total_bytes_raw); + scanner_stop_action_no_move(*dev, regs); + + for (unsigned ch = 0; ch < 3; ch++){ + topavg[ch] = dark_average_channel(second_line, black_pixels, ch); + DBG(DBG_io2, "%s: top avg %d=%d\n", __func__, ch, topavg[ch]); + } + + pass = 0; + + std::vector<uint8_t> debug_image; + size_t debug_image_lines = 0; + std::string debug_image_info; + + /* loop until acceptable level */ + while ((pass < 32) + && ((top[0] - bottom[0] > 1) + || (top[1] - bottom[1] > 1) || (top[2] - bottom[2] > 1))) + { + pass++; + + // settings for new scan + for (unsigned ch = 0; ch < 3; ch++) { + if (top[ch] - bottom[ch] > 1) { + dev->frontend.set_offset(ch, (top[ch] + bottom[ch]) / 2); + } + } + dev->cmd_set->set_fe(dev, calib_sensor, AFE_SET); + + // scan with no move + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + second_line = read_unshuffled_image_from_scanner(dev, session, + session.output_total_bytes_raw); + scanner_stop_action_no_move(*dev, regs); + + if (DBG_LEVEL >= DBG_data) + { + char title[100]; + std::snprintf(title, 100, "lines: %d pixels_per_line: %d offsets[0..2]: %d %d %d\n", + lines, pixels, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); + debug_image_info += title; + std::copy(second_line.get_row_ptr(0), + second_line.get_row_ptr(0) + second_line.get_row_bytes() * second_line.get_height(), + std::back_inserter(debug_image)); + debug_image_lines += lines; + } + + for (unsigned ch = 0; ch < 3; ch++) { + avg[ch] = dark_average_channel(second_line, black_pixels, ch); + DBG(DBG_info, "%s: avg[%d]=%d offset=%d\n", __func__, ch, avg[ch], + dev->frontend.get_offset(ch)); + } + + // compute new boundaries + for (unsigned ch = 0; ch < 3; ch++) { + if (topavg[ch] >= avg[ch]) { + topavg[ch] = avg[ch]; + top[ch] = dev->frontend.get_offset(ch); + } else { + bottomavg[ch] = avg[ch]; + bottom[ch] = dev->frontend.get_offset(ch); + } + } + } + + if (DBG_LEVEL >= DBG_data) + { + sanei_genesys_write_file("gl843_offset_all_desc.txt", + reinterpret_cast<const std::uint8_t*>(debug_image_info.data()), + debug_image_info.size()); + sanei_genesys_write_pnm_file("gl843_offset_all.pnm", + debug_image.data(), session.params.depth, channels, pixels, + debug_image_lines); + } + + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); +} + + +/* alternative coarse gain calibration + this on uses the settings from offset_calibration and + uses only one scanline + */ +/* + with offset and coarse calibration we only want to get our input range into + a reasonable shape. the fine calibration of the upper and lower bounds will + be done with shading. + */ +void CommandSetGl843::coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const +{ + DBG_HELPER_ARGS(dbg, "dpi = %d", dpi); + int factor, dpihw; + float coeff; + int lines; + int resolution; + + if (dev->frontend.layout.type != FrontendType::WOLFSON) + return; + + dpihw = sensor.get_logical_hwdpi(dpi); + factor=sensor.optical_res/dpihw; + + // coarse gain calibration is always done in color mode + unsigned channels = 3; + + /* follow CKSEL */ + if (dev->model->sensor_id == SensorId::CCD_KVSS080) { + if(dev->settings.xres<sensor.optical_res) + { + coeff = 0.9f; + } + else + { + coeff=1.0; + } + } + else + { + coeff=1.0; + } + resolution=dpihw; + lines=10; + int target_pixels = sensor.sensor_pixels / factor; + + ScanFlag flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == ScanMethod::TRANSPARENCY || + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + flags |= ScanFlag::USE_XPA; + } + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels, + dev->settings.scan_method); + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = target_pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = flags; + compute_session(dev, session, calib_sensor); + std::size_t pixels = session.output_pixels; + + try { + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + } catch (...) { + catch_all_exceptions(__func__, [&](){ sanei_genesys_set_motor_power(regs, false); }); + throw; + } + + sanei_genesys_set_motor_power(regs, false); + + dev->interface->write_registers(regs); + + dev->cmd_set->set_fe(dev, calib_sensor, AFE_SET); + dev->cmd_set->begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("coarse_gain_calibration"); + scanner_stop_action(*dev); + move_back_home(dev, true); + return; + } + + auto line = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes_raw); + scanner_stop_action_no_move(*dev, regs); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl843_gain.pnm", line); + } + + // average value on each channel + for (unsigned ch = 0; ch < channels; ch++) { + + std::vector<uint16_t> values; + // FIXME: start from the second line because the first line often has artifacts. Probably + // caused by unclean cleanup of previous scan + for (std::size_t x = pixels / 4; x < (pixels * 3 / 4); x++) { + values.push_back(line.get_raw_channel(x, 1, ch)); + } + + // pick target value at 95th percentile of all values. There may be a lot of black values + // in transparency scans for example + std::sort(values.begin(), values.end()); + uint16_t curr_output = values[unsigned((values.size() - 1) * 0.95)]; + float target_value = calib_sensor.gain_white_ref * coeff; + + int code = compute_frontend_gain(curr_output, target_value, dev->frontend.layout.type); + dev->frontend.set_gain(ch, code); + + DBG(DBG_proc, "%s: channel %d, max=%d, target=%d, setting:%d\n", __func__, ch, curr_output, + static_cast<int>(target_value), code); + } + + if (dev->model->is_cis) { + uint8_t gain0 = dev->frontend.get_gain(0); + if (gain0 > dev->frontend.get_gain(1)) { + gain0 = dev->frontend.get_gain(1); + } + if (gain0 > dev->frontend.get_gain(2)) { + gain0 = dev->frontend.get_gain(2); + } + dev->frontend.set_gain(0, gain0); + dev->frontend.set_gain(1, gain0); + dev->frontend.set_gain(2, gain0); + } + + if (channels == 1) { + dev->frontend.set_gain(0, dev->frontend.get_gain(1)); + dev->frontend.set_gain(2, dev->frontend.get_gain(1)); + } + + scanner_stop_action(*dev); + + move_back_home(dev, true); +} + +// wait for lamp warmup by scanning the same line until difference +// between 2 scans is below a threshold +void CommandSetGl843::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, int* channels, + int* total_size) const +{ + DBG_HELPER(dbg); + int num_pixels; + int dpihw; + int resolution; + int factor; + + /* setup scan */ + *channels=3; + resolution=600; + dpihw = sensor.get_logical_hwdpi(resolution); + resolution=dpihw; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, *channels, + dev->settings.scan_method); + factor = calib_sensor.optical_res/dpihw; + num_pixels = calib_sensor.sensor_pixels/(factor*2); + *total_size = num_pixels * 3 * 1; + + *reg = dev->reg; + + ScanSession session; + session.params.xres = resolution; + session.params.yres = resolution; + session.params.startx = num_pixels/2; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 8; + session.params.channels = *channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, reg, session); + + sanei_genesys_set_motor_power(*reg, false); + dev->interface->write_registers(*reg); +} + +/** + * set up GPIO/GPOE for idle state +WRITE GPIO[17-21]= GPIO19 +WRITE GPOE[17-21]= GPOE21 GPOE20 GPOE19 GPOE18 +genesys_write_register(0xa8,0x3e) +GPIO(0xa8)=0x3e + */ +static void gl843_init_gpio(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + apply_registers_ordered(dev->gpo.regs, { 0x6e, 0x6f }, [&](const GenesysRegisterSetting& reg) + { + dev->interface->write_register(reg.address, reg.value); + }); +} + + +/* * + * initialize ASIC from power on condition + */ +void CommandSetGl843::asic_boot(Genesys_Device* dev, bool cold) const +{ + DBG_HELPER(dbg); + uint8_t val; + + if (cold) { + dev->interface->write_register(0x0e, 0x01); + dev->interface->write_register(0x0e, 0x00); + } + + if(dev->usb_mode == 1) + { + val = 0x14; + } + else + { + val = 0x11; + } + dev->interface->write_0x8c(0x0f, val); + + // test CHKVER + val = dev->interface->read_register(REG_0x40); + if (val & REG_0x40_CHKVER) { + val = dev->interface->read_register(0x00); + DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); + } + + /* Set default values for registers */ + gl843_init_registers (dev); + + if (dev->model->model_id == ModelId::CANON_8600F) { + // turns on vref control for maximum current of the motor driver + dev->interface->write_register(REG_0x6B, 0x72); + } else { + dev->interface->write_register(REG_0x6B, 0x02); + } + + // Write initial registers + dev->interface->write_registers(dev->reg); + + // Enable DRAM by setting a rising edge on bit 3 of reg 0x0b + val = dev->reg.find_reg(0x0b).value & REG_0x0B_DRAMSEL; + val = (val | REG_0x0B_ENBDRAM); + dev->interface->write_register(REG_0x0B, val); + dev->reg.find_reg(0x0b).value = val; + + if (dev->model->model_id == ModelId::CANON_8400F) { + dev->interface->write_0x8c(0x1e, 0x01); + dev->interface->write_0x8c(0x10, 0xb4); + dev->interface->write_0x8c(0x0f, 0x02); + } + else if (dev->model->model_id == ModelId::CANON_8600F) { + dev->interface->write_0x8c(0x10, 0xc8); + } else if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + dev->interface->write_0x8c(0x10, 0xd4); + } else { + dev->interface->write_0x8c(0x10, 0xb4); + } + + /* CLKSET */ + int clock_freq = REG_0x0B_48MHZ; + switch (dev->model->model_id) { + case ModelId::CANON_8600F: + clock_freq = REG_0x0B_60MHZ; + break; + case ModelId::PLUSTEK_OPTICFILM_7200I: + clock_freq = REG_0x0B_30MHZ; + break; + case ModelId::PLUSTEK_OPTICFILM_7300: + case ModelId::PLUSTEK_OPTICFILM_7500I: + clock_freq = REG_0x0B_40MHZ; + break; + default: + break; + } + + val = (dev->reg.find_reg(0x0b).value & ~REG_0x0B_CLKSET) | clock_freq; + + dev->interface->write_register(REG_0x0B, val); + dev->reg.find_reg(0x0b).value = val; + + /* prevent further writings by bulk write register */ + dev->reg.remove_reg(0x0b); + + if (dev->model->model_id != ModelId::CANON_8600F) { + // set up end access + // FIXME: this is overwritten in gl843_init_gpio + dev->interface->write_register(REG_0xA7, 0x04); + dev->interface->write_register(REG_0xA9, 0x00); + } + + // set RAM read address + dev->interface->write_register(REG_0x29, 0x00); + dev->interface->write_register(REG_0x2A, 0x00); + dev->interface->write_register(REG_0x2B, 0x00); + + // setup gpio + gl843_init_gpio(dev); + + scanner_move(*dev, dev->model->default_method, 300, Direction::FORWARD); + dev->interface->sleep_ms(100); +} + +/* * + * initialize backend and ASIC : registers, motor tables, and gamma tables + * then ensure scanner's head is at home + */ +void CommandSetGl843::init(Genesys_Device* dev) const +{ + DBG_INIT (); + DBG_HELPER(dbg); + + sanei_genesys_asic_init(dev, 0); +} + +void CommandSetGl843::update_hardware_sensors(Genesys_Scanner* s) const +{ + DBG_HELPER(dbg); + /* do what is needed to get a new set of events, but try to not lose + any of them. + */ + + uint8_t val = s->dev->interface->read_register(REG_0x6D); + + switch (s->dev->model->gpio_id) + { + case GpioId::KVSS080: + s->buttons[BUTTON_SCAN_SW].write((val & 0x04) == 0); + break; + case GpioId::G4050: + s->buttons[BUTTON_SCAN_SW].write((val & 0x01) == 0); + s->buttons[BUTTON_FILE_SW].write((val & 0x02) == 0); + s->buttons[BUTTON_EMAIL_SW].write((val & 0x04) == 0); + s->buttons[BUTTON_COPY_SW].write((val & 0x08) == 0); + break; + case GpioId::CANON_4400F: + case GpioId::CANON_8400F: + default: + break; + } +} + +/** @brief move sensor to transparency adaptor + * Move sensor to the calibration of the transparency adapator (XPA). + * @param dev device to use + */ +void CommandSetGl843::move_to_ta(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + + const auto& resolution_settings = dev->model->get_resolution_settings(dev->model->default_method); + float resolution = resolution_settings.get_min_resolution_y(); + + unsigned multiplier = 16; + if (dev->model->model_id == ModelId::CANON_8400F) { + multiplier = 4; + } + unsigned feed = static_cast<unsigned>(multiplier * (dev->model->y_offset_sensor_to_ta * resolution) / + MM_PER_INCH); + scanner_move(*dev, dev->model->default_method, feed, Direction::FORWARD); +} + + +/** @brief search for a full width black or white strip. + * This function searches for a black or white stripe across the scanning area. + * When searching backward, the searched area must completely be of the desired + * color since this area will be used for calibration which scans forward. + * @param dev scanner device + * @param forward true if searching forward, false if searching backward + * @param black true if searching for a black strip, false for a white strip + */ +void CommandSetGl843::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const +{ + DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse"); + unsigned int pixels, lines, channels; + Genesys_Register_Set local_reg; + int dpi; + unsigned int pass, count, found, x, y; + + dev->cmd_set->set_fe(dev, sensor, AFE_SET); + scanner_stop_action(*dev); + + /* set up for a gray scan at lowest dpi */ + dpi = sanei_genesys_get_lowest_dpi(dev); + channels = 1; + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, dpi, channels, + dev->settings.scan_method); + + /* 10 MM */ + /* lines = (10 * dpi) / MM_PER_INCH; */ + /* shading calibation is done with dev->motor.base_ydpi */ + lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; + pixels = (calib_sensor.sensor_pixels * dpi) / calib_sensor.optical_res; + + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + + local_reg = dev->reg; + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_SHADING; + if (!forward) { + session.params.flags = ScanFlag::REVERSE; + } + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, &local_reg, session); + + dev->interface->write_registers(local_reg); + + dev->cmd_set->begin_scan(dev, calib_sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_strip"); + scanner_stop_action(*dev); + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + auto data = read_unshuffled_image_from_scanner(dev, session, + session.output_total_bytes_raw); + + scanner_stop_action(*dev); + + pass = 0; + if (DBG_LEVEL >= DBG_data) + { + char fn[40]; + std::snprintf(fn, 40, "gl843_search_strip_%s_%s%02d.pnm", + black ? "black" : "white", forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file(fn, data); + } + + /* loop until strip is found or maximum pass number done */ + found = 0; + while (pass < 20 && !found) + { + dev->interface->write_registers(local_reg); + + // now start scan + dev->cmd_set->begin_scan(dev, calib_sensor, &local_reg, true); + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + data = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes_raw); + + scanner_stop_action(*dev); + + if (DBG_LEVEL >= DBG_data) + { + char fn[40]; + std::snprintf(fn, 40, "gl843_search_strip_%s_%s%02d.pnm", + black ? "black" : "white", forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file(fn, data); + } + + /* search data to find black strip */ + /* when searching forward, we only need one line of the searched color since we + * will scan forward. But when doing backward search, we need all the area of the + * same color */ + if (forward) + { + for (y = 0; y < lines && !found; y++) + { + count = 0; + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data.get_raw_channel(x, y, 0) > 90) { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data.get_raw_channel(x, y, 0) < 60) { + count++; + } + } + + /* at end of line, if count >= 3%, line is not fully of the desired color + * so we must go to next line of the buffer */ + /* count*100/pixels < 3 */ + if ((count * 100) / pixels < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, + pass, y); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + } + else /* since calibration scans are done forward, we need the whole area + to be of the required color when searching backward */ + { + count = 0; + for (y = 0; y < lines; y++) + { + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + // when searching for black, detect white pixels + if (black && data.get_raw_channel(x, y, 0) > 90) { + count++; + } + // when searching for white, detect black pixels + if (!black && data.get_raw_channel(x, y, 0) < 60) { + count++; + } + } + } + + /* at end of area, if count >= 3%, area is not fully of the desired color + * so we must go to next buffer */ + if ((count * 100) / (pixels * lines) < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + pass++; + } + if (found) + { + DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); + } + else + { + throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white"); + } +} + +/** + * Send shading calibration data. The buffer is considered to always hold values + * for all the channels. + */ +void CommandSetGl843::send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + uint8_t* data, int size) const +{ + DBG_HELPER(dbg); + uint32_t final_size, length, i; + uint8_t *buffer; + int count,offset; + GenesysRegister *r; + uint16_t strpixel, endpixel, startx; + + offset=0; + length=size; + r = sanei_genesys_get_address(&dev->reg, REG_0x01); + if (r->value & REG_0x01_SHDAREA) + { + /* recompute STRPIXEL used shading calibration so we can + * compute offset within data for SHDAREA case */ + + // FIXME: the following is likely incorrect + // start coordinate in optical dpi coordinates + startx = (sensor.dummy_pixel / sensor.ccd_pixels_per_system_pixel()) / dev->session.hwdpi_divisor; + startx *= dev->session.pixel_count_multiplier; + + /* current scan coordinates */ + strpixel = dev->session.pixel_startx; + endpixel = dev->session.pixel_endx; + + if (dev->model->model_id == ModelId::CANON_4400F || + dev->model->model_id == ModelId::CANON_8600F) + { + int half_ccd_factor = dev->session.optical_resolution / + sensor.get_logical_hwdpi(dev->session.output_resolution); + strpixel /= half_ccd_factor * sensor.ccd_pixels_per_system_pixel(); + endpixel /= half_ccd_factor * sensor.ccd_pixels_per_system_pixel(); + } + + /* 16 bit words, 2 words per color, 3 color channels */ + offset=(strpixel-startx)*2*2*3; + length=(endpixel-strpixel)*2*2*3; + DBG(DBG_info, "%s: STRPIXEL=%d, ENDPIXEL=%d, startx=%d\n", __func__, strpixel, endpixel, + startx); + } + + dev->interface->record_key_value("shading_offset", std::to_string(offset)); + dev->interface->record_key_value("shading_length", std::to_string(length)); + + /* compute and allocate size for final data */ + final_size = ((length+251) / 252) * 256; + DBG(DBG_io, "%s: final shading size=%04x (length=%d)\n", __func__, final_size, length); + std::vector<uint8_t> final_data(final_size, 0); + + /* copy regular shading data to the expected layout */ + buffer = final_data.data(); + count = 0; + + /* loop over calibration data */ + for (i = 0; i < length; i++) + { + buffer[count] = data[offset+i]; + count++; + if ((count % (256*2)) == (252*2)) + { + count += 4*2; + } + } + + dev->interface->write_buffer(0x3c, 0, final_data.data(), count, + ScannerInterface::FLAG_SMALL_ADDRESS); +} + +bool CommandSetGl843::needs_home_before_init_regs_for_scan(Genesys_Device* dev) const +{ + (void) dev; + return true; +} + +void CommandSetGl843::wait_for_motor_stop(Genesys_Device* dev) const +{ + (void) dev; +} + +std::unique_ptr<CommandSet> create_gl843_cmd_set() +{ + return std::unique_ptr<CommandSet>(new CommandSetGl843{}); +} + +} // namespace gl843 +} // namespace genesys diff --git a/backend/genesys/gl843.h b/backend/genesys/gl843.h new file mode 100644 index 0000000..9f0a9e9 --- /dev/null +++ b/backend/genesys/gl843.h @@ -0,0 +1,139 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#include "genesys.h" +#include "command_set.h" + +#ifndef BACKEND_GENESYS_GL843_H +#define BACKEND_GENESYS_GL843_H + +namespace genesys { +namespace gl843 { + +class CommandSetGl843 : public CommandSet +{ +public: + ~CommandSetGl843() override = default; + + bool needs_home_before_init_regs_for_scan(Genesys_Device* dev) const override; + + void init(Genesys_Device* dev) const override; + + void init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const override; + + void init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const override; + + void set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const override; + void set_powersaving(Genesys_Device* dev, int delay) const override; + void save_power(Genesys_Device* dev, bool enable) const override; + + void begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, bool start_motor) const override; + + void end_scan(Genesys_Device* dev, Genesys_Register_Set* regs, bool check_stop) const override; + + void send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void search_start_position(Genesys_Device* dev) const override; + + void offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const override; + + SensorExposure led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void wait_for_motor_stop(Genesys_Device* dev) const override; + + void move_back_home(Genesys_Device* dev, bool wait_until_home) const override; + + void update_hardware_sensors(struct Genesys_Scanner* s) const override; + + void load_document(Genesys_Device* dev) const override; + + void detect_document_end(Genesys_Device* dev) const override; + + void eject_document(Genesys_Device* dev) const override; + + void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const override; + + void move_to_ta(Genesys_Device* dev) const override; + + void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data, + int size) const override; + + ScanSession calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const override; + + void asic_boot(Genesys_Device* dev, bool cold) const override; +}; + +enum SlopeTable +{ + SCAN_TABLE = 0, // table 1 at 0x4000 + BACKTRACK_TABLE = 1, // table 2 at 0x4800 + STOP_TABLE = 2, // table 3 at 0x5000 + FAST_TABLE = 3, // table 4 at 0x5800 + HOME_TABLE = 4, // table 5 at 0x6000 +}; + +} // namespace gl843 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL843_H diff --git a/backend/genesys/gl843_registers.h b/backend/genesys/gl843_registers.h new file mode 100644 index 0000000..8ecb0fc --- /dev/null +++ b/backend/genesys/gl843_registers.h @@ -0,0 +1,382 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL843_REGISTERS_H +#define BACKEND_GENESYS_GL843_REGISTERS_H + +#include <cstdint> + +namespace genesys { +namespace gl843 { + +using RegAddr = std::uint16_t; +using RegMask = std::uint8_t; +using RegShift = unsigned; + +static constexpr RegAddr REG_0x01 = 0x01; +static constexpr RegMask REG_0x01_CISSET = 0x80; +static constexpr RegMask REG_0x01_DOGENB = 0x40; +static constexpr RegMask REG_0x01_DVDSET = 0x20; +static constexpr RegMask REG_0x01_STAGGER = 0x10; +static constexpr RegMask REG_0x01_COMPENB = 0x08; +static constexpr RegMask REG_0x01_TRUEGRAY = 0x04; +static constexpr RegMask REG_0x01_SHDAREA = 0x02; +static constexpr RegMask REG_0x01_SCAN = 0x01; + +static constexpr RegAddr REG_0x02 = 0x02; +static constexpr RegMask REG_0x02_NOTHOME = 0x80; +static constexpr RegMask REG_0x02_ACDCDIS = 0x40; +static constexpr RegMask REG_0x02_AGOHOME = 0x20; +static constexpr RegMask REG_0x02_MTRPWR = 0x10; +static constexpr RegMask REG_0x02_FASTFED = 0x08; +static constexpr RegMask REG_0x02_MTRREV = 0x04; +static constexpr RegMask REG_0x02_HOMENEG = 0x02; +static constexpr RegMask REG_0x02_LONGCURV = 0x01; + +static constexpr RegAddr REG_0x03 = 0x03; +static constexpr RegMask REG_0x03_LAMPDOG = 0x80; +static constexpr RegMask REG_0x03_AVEENB = 0x40; +static constexpr RegMask REG_0x03_XPASEL = 0x20; +static constexpr RegMask REG_0x03_LAMPPWR = 0x10; +static constexpr RegMask REG_0x03_LAMPTIM = 0x0f; + +static constexpr RegAddr REG_0x04 = 0x04; +static constexpr RegMask REG_0x04_LINEART = 0x80; +static constexpr RegMask REG_0x04_BITSET = 0x40; +static constexpr RegMask REG_0x04_AFEMOD = 0x30; +static constexpr RegMask REG_0x04_FILTER = 0x0c; +static constexpr RegMask REG_0x04_FESET = 0x03; + +static constexpr RegShift REG_0x04S_AFEMOD = 4; + +static constexpr RegAddr REG_0x05 = 0x05; +static constexpr RegMask REG_0x05_DPIHW = 0xc0; +static constexpr RegMask REG_0x05_DPIHW_600 = 0x00; +static constexpr RegMask REG_0x05_DPIHW_1200 = 0x40; +static constexpr RegMask REG_0x05_DPIHW_2400 = 0x80; +static constexpr RegMask REG_0x05_DPIHW_4800 = 0xc0; +static constexpr RegMask REG_0x05_MTLLAMP = 0x30; +static constexpr RegMask REG_0x05_GMMENB = 0x08; +static constexpr RegMask REG_0x05_MTLBASE = 0x03; + +static constexpr RegAddr REG_0x06 = 0x06; +static constexpr RegMask REG_0x06_SCANMOD = 0xe0; +static constexpr RegShift REG_0x06S_SCANMOD = 5; +static constexpr RegMask REG_0x06_PWRBIT = 0x10; +static constexpr RegMask REG_0x06_GAIN4 = 0x08; +static constexpr RegMask REG_0x06_OPTEST = 0x07; + +static constexpr RegMask REG_0x07_LAMPSIM = 0x80; + +static constexpr RegMask REG_0x08_DECFLAG = 0x40; +static constexpr RegMask REG_0x08_GMMFFR = 0x20; +static constexpr RegMask REG_0x08_GMMFFG = 0x10; +static constexpr RegMask REG_0x08_GMMFFB = 0x08; +static constexpr RegMask REG_0x08_GMMZR = 0x04; +static constexpr RegMask REG_0x08_GMMZG = 0x02; +static constexpr RegMask REG_0x08_GMMZB = 0x01; + +static constexpr RegMask REG_0x09_MCNTSET = 0xc0; +static constexpr RegMask REG_0x09_EVEN1ST = 0x20; +static constexpr RegMask REG_0x09_BLINE1ST = 0x10; +static constexpr RegMask REG_0x09_BACKSCAN = 0x08; +static constexpr RegMask REG_0x09_ENHANCE = 0x04; +static constexpr RegMask REG_0x09_SHORTTG = 0x02; +static constexpr RegMask REG_0x09_NWAIT = 0x01; + +static constexpr RegShift REG_0x09S_MCNTSET = 6; +static constexpr RegShift REG_0x09S_CLKSET = 4; + +static constexpr RegAddr REG_0x0B = 0x0b; +static constexpr RegMask REG_0x0B_DRAMSEL = 0x07; +static constexpr RegMask REG_0x0B_ENBDRAM = 0x08; +static constexpr RegMask REG_0x0B_RFHDIS = 0x10; +static constexpr RegMask REG_0x0B_CLKSET = 0xe0; +static constexpr RegMask REG_0x0B_24MHZ = 0x00; +static constexpr RegMask REG_0x0B_30MHZ = 0x20; +static constexpr RegMask REG_0x0B_40MHZ = 0x40; +static constexpr RegMask REG_0x0B_48MHZ = 0x60; +static constexpr RegMask REG_0x0B_60MHZ = 0x80; + +static constexpr RegAddr REG_0x0D = 0x0d; +static constexpr RegMask REG_0x0D_JAMPCMD = 0x80; +static constexpr RegMask REG_0x0D_DOCCMD = 0x40; +static constexpr RegMask REG_0x0D_CCDCMD = 0x20; +static constexpr RegMask REG_0x0D_FULLSTP = 0x10; +static constexpr RegMask REG_0x0D_SEND = 0x08; +static constexpr RegMask REG_0x0D_CLRMCNT = 0x04; +static constexpr RegMask REG_0x0D_CLRDOCJM = 0x02; +static constexpr RegMask REG_0x0D_CLRLNCNT = 0x01; + +static constexpr RegAddr REG_0x0F = 0x0f; + +static constexpr RegAddr REG_EXPR = 0x10; +static constexpr RegAddr REG_EXPG = 0x12; +static constexpr RegAddr REG_EXPB = 0x14; + +static constexpr RegMask REG_0x16_CTRLHI = 0x80; +static constexpr RegMask REG_0x16_TOSHIBA = 0x40; +static constexpr RegMask REG_0x16_TGINV = 0x20; +static constexpr RegMask REG_0x16_CK1INV = 0x10; +static constexpr RegMask REG_0x16_CK2INV = 0x08; +static constexpr RegMask REG_0x16_CTRLINV = 0x04; +static constexpr RegMask REG_0x16_CKDIS = 0x02; +static constexpr RegMask REG_0x16_CTRLDIS = 0x01; + +static constexpr RegMask REG_0x17_TGMODE = 0xc0; +static constexpr RegMask REG_0x17_TGMODE_NO_DUMMY = 0x00; +static constexpr RegMask REG_0x17_TGMODE_REF = 0x40; +static constexpr RegMask REG_0x17_TGMODE_XPA = 0x80; +static constexpr RegMask REG_0x17_TGW = 0x3f; +static constexpr RegShift REG_0x17S_TGW = 0; + +static constexpr RegAddr REG_0x18 = 0x18; +static constexpr RegMask REG_0x18_CNSET = 0x80; +static constexpr RegMask REG_0x18_DCKSEL = 0x60; +static constexpr RegMask REG_0x18_CKTOGGLE = 0x10; +static constexpr RegMask REG_0x18_CKDELAY = 0x0c; +static constexpr RegMask REG_0x18_CKSEL = 0x03; + +static constexpr RegAddr REG_EXPDMY = 0x19; + +static constexpr RegMask REG_0x1A_TGLSW2 = 0x80; +static constexpr RegMask REG_0x1A_TGLSW1 = 0x40; +static constexpr RegMask REG_0x1A_MANUAL3 = 0x02; +static constexpr RegMask REG_0x1A_MANUAL1 = 0x01; +static constexpr RegMask REG_0x1A_CK4INV = 0x08; +static constexpr RegMask REG_0x1A_CK3INV = 0x04; +static constexpr RegMask REG_0x1A_LINECLP = 0x02; + +static constexpr RegAddr REG_0x1C = 0x1c; +static constexpr RegMask REG_0x1C_TGTIME = 0x07; + +static constexpr RegMask REG_0x1D_CK4LOW = 0x80; +static constexpr RegMask REG_0x1D_CK3LOW = 0x40; +static constexpr RegMask REG_0x1D_CK1LOW = 0x20; +static constexpr RegMask REG_0x1D_TGSHLD = 0x1f; +static constexpr RegShift REG_0x1DS_TGSHLD = 0; + + +static constexpr RegAddr REG_0x1E = 0x1e; +static constexpr RegMask REG_0x1E_WDTIME = 0xf0; +static constexpr RegShift REG_0x1ES_WDTIME = 4; +static constexpr RegMask REG_0x1E_LINESEL = 0x0f; +static constexpr RegShift REG_0x1ES_LINESEL = 0; + +static constexpr RegAddr REG_0x21 = 0x21; +static constexpr RegAddr REG_STEPNO = 0x21; +static constexpr RegAddr REG_FWDSTEP = 0x22; +static constexpr RegAddr REG_BWDSTEP = 0x23; +static constexpr RegAddr REG_FASTNO = 0x24; +static constexpr RegAddr REG_LINCNT = 0x25; + +static constexpr RegAddr REG_0x29 = 0x29; +static constexpr RegAddr REG_0x2A = 0x2a; +static constexpr RegAddr REG_0x2B = 0x2b; +static constexpr RegAddr REG_DPISET = 0x2c; +static constexpr RegAddr REG_0x2E = 0x2e; +static constexpr RegAddr REG_0x2F = 0x2f; + +static constexpr RegAddr REG_STRPIXEL = 0x30; +static constexpr RegAddr REG_ENDPIXEL = 0x32; +static constexpr RegAddr REG_DUMMY = 0x34; +static constexpr RegAddr REG_MAXWD = 0x35; +static constexpr RegAddr REG_LPERIOD = 0x38; +static constexpr RegAddr REG_FEEDL = 0x3d; + +static constexpr RegAddr REG_0x40 = 0x40; +static constexpr RegMask REG_0x40_DOCSNR = 0x80; +static constexpr RegMask REG_0x40_ADFSNR = 0x40; +static constexpr RegMask REG_0x40_COVERSNR = 0x20; +static constexpr RegMask REG_0x40_CHKVER = 0x10; +static constexpr RegMask REG_0x40_DOCJAM = 0x08; +static constexpr RegMask REG_0x40_HISPDFLG = 0x04; +static constexpr RegMask REG_0x40_MOTMFLG = 0x02; +static constexpr RegMask REG_0x40_DATAENB = 0x01; + +static constexpr RegMask REG_0x41_PWRBIT = 0x80; +static constexpr RegMask REG_0x41_BUFEMPTY = 0x40; +static constexpr RegMask REG_0x41_FEEDFSH = 0x20; +static constexpr RegMask REG_0x41_SCANFSH = 0x10; +static constexpr RegMask REG_0x41_HOMESNR = 0x08; +static constexpr RegMask REG_0x41_LAMPSTS = 0x04; +static constexpr RegMask REG_0x41_FEBUSY = 0x02; +static constexpr RegMask REG_0x41_MOTORENB = 0x01; + +static constexpr RegMask REG_0x58_VSMP = 0xf8; +static constexpr RegShift REG_0x58S_VSMP = 3; +static constexpr RegMask REG_0x58_VSMPW = 0x07; +static constexpr RegShift REG_0x58S_VSMPW = 0; + +static constexpr RegMask REG_0x59_BSMP = 0xf8; +static constexpr RegShift REG_0x59S_BSMP = 3; +static constexpr RegMask REG_0x59_BSMPW = 0x07; +static constexpr RegShift REG_0x59S_BSMPW = 0; + +static constexpr RegMask REG_0x5A_ADCLKINV = 0x80; +static constexpr RegMask REG_0x5A_RLCSEL = 0x40; +static constexpr RegMask REG_0x5A_CDSREF = 0x30; +static constexpr RegShift REG_0x5AS_CDSREF = 4; +static constexpr RegMask REG_0x5A_RLC = 0x0f; +static constexpr RegShift REG_0x5AS_RLC = 0; + +static constexpr RegAddr REG_0x5E = 0x5e; +static constexpr RegMask REG_0x5E_DECSEL = 0xe0; +static constexpr RegShift REG_0x5ES_DECSEL = 5; +static constexpr RegMask REG_0x5E_STOPTIM = 0x1f; +static constexpr RegShift REG_0x5ES_STOPTIM = 0; + +static constexpr RegAddr REG_FMOVDEC = 0x5f; + +static constexpr RegAddr REG_0x60 = 0x60; +static constexpr RegMask REG_0x60_Z1MOD = 0x1f; +static constexpr RegAddr REG_0x61 = 0x61; +static constexpr RegMask REG_0x61_Z1MOD = 0xff; +static constexpr RegAddr REG_0x62 = 0x62; +static constexpr RegMask REG_0x62_Z1MOD = 0xff; + +static constexpr RegAddr REG_0x63 = 0x63; +static constexpr RegMask REG_0x63_Z2MOD = 0x1f; +static constexpr RegAddr REG_0x64 = 0x64; +static constexpr RegMask REG_0x64_Z2MOD = 0xff; +static constexpr RegAddr REG_0x65 = 0x65; +static constexpr RegMask REG_0x65_Z2MOD = 0xff; + +static constexpr RegAddr REG_0x67 = 0x67; + +static constexpr RegAddr REG_0x68 = 0x68; + +static constexpr RegShift REG_0x67S_STEPSEL = 6; +static constexpr RegMask REG_0x67_STEPSEL = 0xc0; +static constexpr RegMask REG_0x67_FULLSTEP = 0x00; +static constexpr RegMask REG_0x67_HALFSTEP = 0x20; +static constexpr RegMask REG_0x67_EIGHTHSTEP = 0x60; +static constexpr RegMask REG_0x67_16THSTEP = 0x80; + +static constexpr RegShift REG_0x68S_FSTPSEL = 6; +static constexpr RegMask REG_0x68_FSTPSEL = 0xc0; +static constexpr RegMask REG_0x68_FULLSTEP = 0x00; +static constexpr RegMask REG_0x68_HALFSTEP = 0x20; +static constexpr RegMask REG_0x68_EIGHTHSTEP = 0x60; +static constexpr RegMask REG_0x68_16THSTEP = 0x80; + +static constexpr RegAddr REG_FSHDEC = 0x69; +static constexpr RegAddr REG_FMOVNO = 0x6a; + +static constexpr RegAddr REG_0x6B = 0x6b; +static constexpr RegMask REG_0x6B_MULTFILM = 0x80; +static constexpr RegMask REG_0x6B_GPOM13 = 0x40; +static constexpr RegMask REG_0x6B_GPOM12 = 0x20; +static constexpr RegMask REG_0x6B_GPOM11 = 0x10; +static constexpr RegMask REG_0x6B_GPOCK4 = 0x08; +static constexpr RegMask REG_0x6B_GPOCP = 0x04; +static constexpr RegMask REG_0x6B_GPOLEDB = 0x02; +static constexpr RegMask REG_0x6B_GPOADF = 0x01; + +static constexpr RegAddr REG_0x6C = 0x6c; +static constexpr RegMask REG_0x6C_GPIO16 = 0x80; +static constexpr RegMask REG_0x6C_GPIO15 = 0x40; +static constexpr RegMask REG_0x6C_GPIO14 = 0x20; +static constexpr RegMask REG_0x6C_GPIO13 = 0x10; +static constexpr RegMask REG_0x6C_GPIO12 = 0x08; +static constexpr RegMask REG_0x6C_GPIO11 = 0x04; +static constexpr RegMask REG_0x6C_GPIO10 = 0x02; +static constexpr RegMask REG_0x6C_GPIO9 = 0x01; +static constexpr RegMask REG_0x6C_GPIOH = 0xff; +static constexpr RegMask REG_0x6C_GPIOL = 0xff; + +static constexpr RegAddr REG_Z1MOD = 0x60; +static constexpr RegAddr REG_Z2MOD = 0x63; + +static constexpr RegAddr REG_0x6D = 0x6d; +static constexpr RegAddr REG_0x6E = 0x6e; +static constexpr RegAddr REG_0x6F = 0x6f; + +static constexpr RegAddr REG_CK1MAP = 0x74; +static constexpr RegAddr REG_CK3MAP = 0x77; +static constexpr RegAddr REG_CK4MAP = 0x7a; + +static constexpr RegAddr REG_0x7E = 0x7e; + +static constexpr RegAddr REG_0x9D = 0x9d; +static constexpr RegShift REG_0x9DS_STEPTIM = 2; + +static constexpr RegMask REG_0x87_LEDADD = 0x04; + +static constexpr RegAddr REG_0xA6 = 0xa6; +static constexpr RegMask REG_0xA6_GPIO24 = 0x80; +static constexpr RegMask REG_0xA6_GPIO23 = 0x40; +static constexpr RegMask REG_0xA6_GPIO22 = 0x20; +static constexpr RegMask REG_0xA6_GPIO21 = 0x10; +static constexpr RegMask REG_0xA6_GPIO20 = 0x08; +static constexpr RegMask REG_0xA6_GPIO19 = 0x04; +static constexpr RegMask REG_0xA6_GPIO18 = 0x02; +static constexpr RegMask REG_0xA6_GPIO17 = 0x01; +static constexpr RegAddr REG_0xA7 = 0xa7; +static constexpr RegMask REG_0xA7_GPOE24 = 0x80; +static constexpr RegMask REG_0xA7_GPOE23 = 0x40; +static constexpr RegMask REG_0xA7_GPOE22 = 0x20; +static constexpr RegMask REG_0xA7_GPOE21 = 0x10; +static constexpr RegMask REG_0xA7_GPOE20 = 0x08; +static constexpr RegMask REG_0xA7_GPOE19 = 0x04; +static constexpr RegMask REG_0xA7_GPOE18 = 0x02; +static constexpr RegMask REG_0xA7_GPOE17 = 0x01; +static constexpr RegAddr REG_0xA8 = 0xa8; +static constexpr RegMask REG_0xA8_GPOE27 = 0x20; +static constexpr RegMask REG_0xA8_GPOE26 = 0x10; +static constexpr RegMask REG_0xA8_GPOE25 = 0x08; +static constexpr RegMask REG_0xA8_GPO27 = 0x04; +static constexpr RegMask REG_0xA8_GPO26 = 0x02; +static constexpr RegMask REG_0xA8_GPO25 = 0x01; +static constexpr RegAddr REG_0xA9 = 0xa9; +static constexpr RegMask REG_0xA9_GPO33 = 0x20; +static constexpr RegMask REG_0xA9_GPO32 = 0x10; +static constexpr RegMask REG_0xA9_GPO31 = 0x08; +static constexpr RegMask REG_0xA9_GPO30 = 0x04; +static constexpr RegMask REG_0xA9_GPO29 = 0x02; +static constexpr RegMask REG_0xA9_GPO28 = 0x01; + +} // namespace gl843 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL843_REGISTERS_H diff --git a/backend/genesys/gl846.cpp b/backend/genesys/gl846.cpp new file mode 100644 index 0000000..d309d29 --- /dev/null +++ b/backend/genesys/gl846.cpp @@ -0,0 +1,2098 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2012-2013 Stéphane Voltz <stef.dev@free.fr> + + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +/** @file + * + * This file handles GL846 and GL845 ASICs since they are really close to each other. + */ + +#define DEBUG_DECLARE_ONLY + +#include "gl846.h" +#include "gl846_registers.h" +#include "test_settings.h" + +#include <vector> + +namespace genesys { +namespace gl846 { + +/** + * compute the step multiplier used + */ +static int +gl846_get_step_multiplier (Genesys_Register_Set * regs) +{ + GenesysRegister *r = sanei_genesys_get_address(regs, 0x9d); + int value = 1; + if (r != nullptr) { + value = (r->value & 0x0f)>>1; + value = 1 << value; + } + DBG (DBG_io, "%s: step multiplier is %d\n", __func__, value); + return value; +} + +/** @brief sensor specific settings +*/ +static void gl846_setup_sensor(Genesys_Device * dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs) +{ + DBG_HELPER(dbg); + + for (const auto& reg : sensor.custom_regs) { + regs->set8(reg.address, reg.value); + } + + regs->set16(REG_EXPR, sensor.exposure.red); + regs->set16(REG_EXPG, sensor.exposure.green); + regs->set16(REG_EXPB, sensor.exposure.blue); + + dev->segment_order = sensor.segment_order; +} + + +/** @brief set all registers to default values . + * This function is called only once at the beginning and + * fills register startup values for registers reused across scans. + * Those that are rarely modified or not modified are written + * individually. + * @param dev device structure holding register set to initialize + */ +static void +gl846_init_registers (Genesys_Device * dev) +{ + DBG_HELPER(dbg); + + dev->reg.clear(); + + dev->reg.init_reg(0x01, 0x60); + dev->reg.init_reg(0x02, 0x38); + dev->reg.init_reg(0x03, 0x03); + dev->reg.init_reg(0x04, 0x22); + dev->reg.init_reg(0x05, 0x60); + dev->reg.init_reg(0x06, 0x10); + dev->reg.init_reg(0x08, 0x60); + dev->reg.init_reg(0x09, 0x00); + dev->reg.init_reg(0x0a, 0x00); + dev->reg.init_reg(0x0b, 0x8b); + dev->reg.init_reg(0x0c, 0x00); + dev->reg.init_reg(0x0d, 0x00); + dev->reg.init_reg(0x10, 0x00); + dev->reg.init_reg(0x11, 0x00); + dev->reg.init_reg(0x12, 0x00); + dev->reg.init_reg(0x13, 0x00); + dev->reg.init_reg(0x14, 0x00); + dev->reg.init_reg(0x15, 0x00); + dev->reg.init_reg(0x16, 0xbb); // SENSOR_DEF + dev->reg.init_reg(0x17, 0x13); // SENSOR_DEF + dev->reg.init_reg(0x18, 0x10); // SENSOR_DEF + dev->reg.init_reg(0x19, 0x2a); // SENSOR_DEF + dev->reg.init_reg(0x1a, 0x34); // SENSOR_DEF + dev->reg.init_reg(0x1b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x1c, 0x20); // SENSOR_DEF + dev->reg.init_reg(0x1d, 0x06); // SENSOR_DEF + dev->reg.init_reg(0x1e, 0xf0); + dev->reg.init_reg(0x1f, 0x01); + dev->reg.init_reg(0x20, 0x03); + dev->reg.init_reg(0x21, 0x10); + dev->reg.init_reg(0x22, 0x60); + dev->reg.init_reg(0x23, 0x60); + dev->reg.init_reg(0x24, 0x60); + dev->reg.init_reg(0x25, 0x00); + dev->reg.init_reg(0x26, 0x00); + dev->reg.init_reg(0x27, 0x00); + dev->reg.init_reg(0x2c, 0x00); + dev->reg.init_reg(0x2d, 0x00); + dev->reg.init_reg(0x2e, 0x80); + dev->reg.init_reg(0x2f, 0x80); + dev->reg.init_reg(0x30, 0x00); + dev->reg.init_reg(0x31, 0x00); + dev->reg.init_reg(0x32, 0x00); + dev->reg.init_reg(0x33, 0x00); + dev->reg.init_reg(0x34, 0x1f); + dev->reg.init_reg(0x35, 0x00); + dev->reg.init_reg(0x36, 0x40); + dev->reg.init_reg(0x37, 0x00); + dev->reg.init_reg(0x38, 0x2a); + dev->reg.init_reg(0x39, 0xf8); + dev->reg.init_reg(0x3d, 0x00); + dev->reg.init_reg(0x3e, 0x00); + dev->reg.init_reg(0x3f, 0x01); + dev->reg.init_reg(0x52, 0x02); // SENSOR_DEF + dev->reg.init_reg(0x53, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x54, 0x06); // SENSOR_DEF + dev->reg.init_reg(0x55, 0x08); // SENSOR_DEF + dev->reg.init_reg(0x56, 0x0a); // SENSOR_DEF + dev->reg.init_reg(0x57, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x58, 0x59); // SENSOR_DEF + dev->reg.init_reg(0x59, 0x31); // SENSOR_DEF + dev->reg.init_reg(0x5a, 0x40); // SENSOR_DEF + dev->reg.init_reg(0x5e, 0x1f); + dev->reg.init_reg(0x5f, 0x01); + dev->reg.init_reg(0x60, 0x00); + dev->reg.init_reg(0x61, 0x00); + dev->reg.init_reg(0x62, 0x00); + dev->reg.init_reg(0x63, 0x00); + dev->reg.init_reg(0x64, 0x00); + dev->reg.init_reg(0x65, 0x00); + dev->reg.init_reg(0x67, 0x7f); + dev->reg.init_reg(0x68, 0x7f); + dev->reg.init_reg(0x69, 0x01); + dev->reg.init_reg(0x6a, 0x01); + dev->reg.init_reg(0x70, 0x01); + dev->reg.init_reg(0x71, 0x00); + dev->reg.init_reg(0x72, 0x02); + dev->reg.init_reg(0x73, 0x01); + dev->reg.init_reg(0x74, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x75, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x76, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x77, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x78, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x79, 0x3f); // SENSOR_DEF + dev->reg.init_reg(0x7a, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x7b, 0x09); // SENSOR_DEF + dev->reg.init_reg(0x7c, 0x99); // SENSOR_DEF + dev->reg.init_reg(0x7d, 0x20); + dev->reg.init_reg(0x7f, 0x05); + dev->reg.init_reg(0x80, 0x4f); + dev->reg.init_reg(0x87, 0x02); + dev->reg.init_reg(0x94, 0xff); + dev->reg.init_reg(0x9d, 0x04); + dev->reg.init_reg(0x9e, 0x00); + dev->reg.init_reg(0xa1, 0xe0); + dev->reg.init_reg(0xa2, 0x1f); + dev->reg.init_reg(0xab, 0xc0); + dev->reg.init_reg(0xbb, 0x00); + dev->reg.init_reg(0xbc, 0x0f); + dev->reg.init_reg(0xdb, 0xff); + dev->reg.init_reg(0xfe, 0x08); + dev->reg.init_reg(0xff, 0x02); + dev->reg.init_reg(0x98, 0x20); + dev->reg.init_reg(0x99, 0x00); + dev->reg.init_reg(0x9a, 0x90); + dev->reg.init_reg(0x9b, 0x00); + dev->reg.init_reg(0xf8, 0x05); + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + sanei_genesys_set_dpihw(dev->reg, sensor, sensor.optical_res); + + /* initalize calibration reg */ + dev->calib_reg = dev->reg; +} + +/**@brief send slope table for motor movement + * Send slope_table in machine byte order + * @param dev device to send slope table + * @param table_nr index of the slope table in ASIC memory + * Must be in the [0-4] range. + * @param slope_table pointer to 16 bit values array of the slope table + * @param steps number of elements in the slope table + */ +static void gl846_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, + int steps) +{ + DBG_HELPER_ARGS(dbg, "table_nr = %d, steps = %d", table_nr, steps); + int i; + char msg[10000]; + + /* sanity check */ + if(table_nr<0 || table_nr>4) + { + throw SaneException("invalid table number %d", table_nr); + } + + std::vector<uint8_t> table(steps * 2); + for (i = 0; i < steps; i++) + { + table[i * 2] = slope_table[i] & 0xff; + table[i * 2 + 1] = slope_table[i] >> 8; + } + + if (DBG_LEVEL >= DBG_io) + { + std::sprintf(msg, "write slope %d (%d)=", table_nr, steps); + for (i = 0; i < steps; i++) + { + std::sprintf(msg+strlen(msg), "%d", slope_table[i]); + } + DBG (DBG_io, "%s: %s\n", __func__, msg); + } + + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } + // slope table addresses are fixed + dev->interface->write_ahb(0x10000000 + 0x4000 * table_nr, steps * 2, table.data()); +} + +/** + * Set register values of Analog Device type frontend + * */ +static void gl846_set_adi_fe(Genesys_Device* dev, uint8_t set) +{ + DBG_HELPER(dbg); + int i; + + // wait for FE to be ready + auto status = scanner_read_status(*dev); + while (status.is_front_end_busy) { + dev->interface->sleep_ms(10); + status = scanner_read_status(*dev); + }; + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + dev->frontend = dev->frontend_initial; + } + + // write them to analog frontend + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); + + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x02 + i, dev->frontend.get_gain(i)); + } + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x05 + i, dev->frontend.get_offset(i)); + } +} + +// Set values of analog frontend +void CommandSetGl846::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const +{ + DBG_HELPER_ARGS(dbg, "%s", set == AFE_INIT ? "init" : + set == AFE_SET ? "set" : + set == AFE_POWER_SAVE ? "powersave" : "huh?"); + (void) sensor; + + /* route to specific analog frontend setup */ + uint8_t frontend_type = dev->reg.find_reg(0x04).value & REG_0x04_FESET; + switch (frontend_type) { + case 0x02: /* ADI FE */ + gl846_set_adi_fe(dev, set); + break; + default: + throw SaneException("unsupported frontend type %d", frontend_type); + } +} + + +// @brief set up motor related register for scan +static void gl846_init_motor_regs_scan(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const Motor_Profile& motor_profile, + unsigned int scan_exposure_time, + unsigned scan_yres, + unsigned int scan_lines, + unsigned int scan_dummy, + unsigned int feed_steps, + MotorFlag flags) +{ + DBG_HELPER_ARGS(dbg, "scan_exposure_time=%d, scan_yres=%d, step_type=%d, scan_lines=%d, " + "scan_dummy=%d, feed_steps=%d, flags=%x", + scan_exposure_time, scan_yres, static_cast<unsigned>(motor_profile.step_type), + scan_lines, scan_dummy, feed_steps, static_cast<unsigned>(flags)); + int use_fast_fed; + unsigned int fast_dpi; + unsigned int feedl, dist; + GenesysRegister *r; + uint32_t z1, z2; + unsigned int min_restep = 0x20; + uint8_t val; + unsigned int ccdlmt,tgtime; + + unsigned step_multiplier = gl846_get_step_multiplier(reg); + + use_fast_fed=0; + /* no fast fed since feed works well */ + if (dev->settings.yres == 4444 && feed_steps > 100 && !has_flag(flags, MotorFlag::FEED)) { + use_fast_fed = 1; + } + DBG (DBG_io, "%s: use_fast_fed=%d\n", __func__, use_fast_fed); + + reg->set24(REG_LINCNT, scan_lines); + DBG (DBG_io, "%s: lincnt=%d\n", __func__, scan_lines); + + /* compute register 02 value */ + r = sanei_genesys_get_address(reg, REG_0x02); + r->value = 0x00; + sanei_genesys_set_motor_power(*reg, true); + + if (use_fast_fed) + r->value |= REG_0x02_FASTFED; + else + r->value &= ~REG_0x02_FASTFED; + + if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) { + r->value |= REG_0x02_AGOHOME | REG_0x02_NOTHOME; + } + + if (has_flag(flags, MotorFlag::DISABLE_BUFFER_FULL_MOVE) ||(scan_yres>=sensor.optical_res)) { + r->value |= REG_0x02_ACDCDIS; + } + if (has_flag(flags, MotorFlag::REVERSE)) { + r->value |= REG_0x02_MTRREV; + } else { + r->value &= ~REG_0x02_MTRREV; + } + + /* scan and backtracking slope table */ + auto scan_table = sanei_genesys_slope_table(dev->model->asic_type, scan_yres, + scan_exposure_time, dev->motor.base_ydpi, + step_multiplier, motor_profile); + + gl846_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.steps_count); + gl846_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.steps_count); + + /* fast table */ + fast_dpi=sanei_genesys_get_lowest_ydpi(dev); + + // BUG: looks like for fast moves we use inconsistent step type + StepType fast_step_type = motor_profile.step_type; + if (static_cast<unsigned>(motor_profile.step_type) >= static_cast<unsigned>(StepType::QUARTER)) { + fast_step_type = StepType::QUARTER; + } + + Motor_Profile fast_motor_profile = motor_profile; + fast_motor_profile.step_type = fast_step_type; + + auto fast_table = sanei_genesys_slope_table(dev->model->asic_type, fast_dpi, + scan_exposure_time, dev->motor.base_ydpi, + step_multiplier, fast_motor_profile); + + gl846_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.steps_count); + gl846_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.steps_count); + gl846_send_slope_table(dev, HOME_TABLE, fast_table.table, fast_table.steps_count); + + /* correct move distance by acceleration and deceleration amounts */ + feedl=feed_steps; + if (use_fast_fed) + { + feedl <<= static_cast<unsigned>(fast_step_type); + dist = (scan_table.steps_count + 2 * fast_table.steps_count); + /* TODO read and decode REG_0xAB */ + r = sanei_genesys_get_address (reg, 0x5e); + dist += (r->value & 31); + /* FEDCNT */ + r = sanei_genesys_get_address(reg, REG_FEDCNT); + dist += r->value; + } + else + { + feedl <<= static_cast<unsigned>(motor_profile.step_type); + dist = scan_table.steps_count; + if (has_flag(flags, MotorFlag::FEED)) { + dist *= 2; + } + } + DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); + + /* check for overflow */ + if (dist < feedl) { + feedl -= dist; + } else { + feedl = 0; + } + + reg->set24(REG_FEEDL, feedl); + DBG (DBG_io ,"%s: feedl=%d\n",__func__,feedl); + + r = sanei_genesys_get_address(reg, REG_0x0C); + ccdlmt = (r->value & REG_0x0C_CCDLMT) + 1; + + r = sanei_genesys_get_address(reg, REG_0x1C); + tgtime = 1 << (r->value & REG_0x1C_TGTIME); + + /* hi res motor speed GPIO */ + /* + uint8_t effective = dev->interface->read_register(REG_0x6C); + */ + + /* if quarter step, bipolar Vref2 */ + /* XXX STEF XXX GPIO + if (motor_profile.step_type > 1) + { + if (motor_profile.step_type < 3) + { + val = effective & ~REG_0x6C_GPIO13; + } + else + { + val = effective | REG_0x6C_GPIO13; + } + } + else + { + val = effective; + } + dev->interface->write_register(REG_0x6C, val); + */ + + /* effective scan */ + /* + effective = dev->interface->read_register(REG_0x6C); + val = effective | REG_0x6C_GPIO10; + dev->interface->write_register(REG_0x6C, val); + */ + + if(dev->model->gpio_id == GpioId::IMG101) { + if (scan_yres == sensor.get_register_hwdpi(scan_yres)) { + val=1; + } + else + { + val=0; + } + dev->interface->write_register(REG_0x7E, val); + } + + min_restep = (scan_table.steps_count / step_multiplier) / 2 - 1; + if (min_restep < 1) { + min_restep = 1; + } + r = sanei_genesys_get_address(reg, REG_FWDSTEP); + r->value = min_restep; + r = sanei_genesys_get_address(reg, REG_BWDSTEP); + r->value = min_restep; + + sanei_genesys_calculate_zmod(use_fast_fed, + scan_exposure_time*ccdlmt*tgtime, + scan_table.table, + scan_table.steps_count, + feedl, + min_restep * step_multiplier, + &z1, + &z2); + + DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); + reg->set24(REG_0x60, z1 | (static_cast<unsigned>(motor_profile.step_type) << (16 + REG_0x60S_STEPSEL))); + + DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); + reg->set24(REG_0x63, z2 | (static_cast<unsigned>(motor_profile.step_type) << (16 + REG_0x63S_FSTPSEL))); + + r = sanei_genesys_get_address (reg, 0x1e); + r->value &= 0xf0; /* 0 dummy lines */ + r->value |= scan_dummy; /* dummy lines */ + + r = sanei_genesys_get_address(reg, REG_0x67); + r->value = 0x7f; + + r = sanei_genesys_get_address(reg, REG_0x68); + r->value = 0x7f; + + reg->set8(REG_STEPNO, scan_table.steps_count / step_multiplier); + reg->set8(REG_FASTNO, scan_table.steps_count / step_multiplier); + reg->set8(REG_FSHDEC, scan_table.steps_count / step_multiplier); + reg->set8(REG_FMOVNO, fast_table.steps_count / step_multiplier); + reg->set8(REG_FMOVDEC, fast_table.steps_count / step_multiplier); +} + + +/** @brief set up registers related to sensor + * Set up the following registers + 0x01 + 0x03 + 0x10-0x015 R/G/B exposures + 0x19 EXPDMY + 0x2e BWHI + 0x2f BWLO + 0x04 + 0x87 + 0x05 + 0x2c,0x2d DPISET + 0x30,0x31 STRPIXEL + 0x32,0x33 ENDPIXEL + 0x35,0x36,0x37 MAXWD [25:2] (>>2) + 0x38,0x39 LPERIOD + 0x34 DUMMY + */ +static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, unsigned int exposure_time, + const ScanSession& session) +{ + DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time); + unsigned int dpihw; + GenesysRegister *r; + + // resolution is divided according to ccd_pixels_per_system_pixel() + unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); + DBG(DBG_io2, "%s: ccd_pixels_per_system_pixel=%d\n", __func__, ccd_pixels_per_system_pixel); + + // to manage high resolution device while keeping good low resolution scanning speed, + // we make hardware dpi vary + dpihw = sensor.get_register_hwdpi(session.params.xres * ccd_pixels_per_system_pixel); + DBG(DBG_io2, "%s: dpihw=%d\n", __func__, dpihw); + + gl846_setup_sensor(dev, sensor, reg); + + dev->cmd_set->set_fe(dev, sensor, AFE_SET); + + /* enable shading */ + regs_set_optical_off(dev->model->asic_type, *reg); + r = sanei_genesys_get_address(reg, REG_0x01); + r->value |= REG_0x01_SHDAREA; + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || + (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) + { + r->value &= ~REG_0x01_DVDSET; + } + else + { + r->value |= REG_0x01_DVDSET; + } + + r = sanei_genesys_get_address(reg, REG_0x03); + r->value &= ~REG_0x03_AVEENB; + + sanei_genesys_set_lamp_power(dev, sensor, *reg, + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); + + /* BW threshold */ + r = sanei_genesys_get_address (reg, 0x2e); + r->value = dev->settings.threshold; + r = sanei_genesys_get_address (reg, 0x2f); + r->value = dev->settings.threshold; + + /* monochrome / color scan */ + r = sanei_genesys_get_address(reg, REG_0x04); + switch (session.params.depth) { + case 8: + r->value &= ~(REG_0x04_LINEART | REG_0x04_BITSET); + break; + case 16: + r->value &= ~REG_0x04_LINEART; + r->value |= REG_0x04_BITSET; + break; + } + + r->value &= ~(REG_0x04_FILTER | REG_0x04_AFEMOD); + if (session.params.channels == 1) + { + switch (session.params.color_filter) + { + case ColorFilter::RED: + r->value |= 0x24; + break; + case ColorFilter::BLUE: + r->value |= 0x2c; + break; + case ColorFilter::GREEN: + r->value |= 0x28; + break; + default: + break; // should not happen + } + } else { + r->value |= 0x20; // mono + } + + sanei_genesys_set_dpihw(*reg, sensor, dpihw); + + if (should_enable_gamma(session, sensor)) { + reg->find_reg(REG_0x05).value |= REG_0x05_GMMENB; + } else { + reg->find_reg(REG_0x05).value &= ~REG_0x05_GMMENB; + } + + /* CIS scanners can do true gray by setting LEDADD */ + /* we set up LEDADD only when asked */ + if (dev->model->is_cis) { + r = sanei_genesys_get_address (reg, 0x87); + r->value &= ~REG_0x87_LEDADD; + if (session.enable_ledadd) { + r->value |= REG_0x87_LEDADD; + } + /* RGB weighting + r = sanei_genesys_get_address (reg, 0x01); + r->value &= ~REG_0x01_TRUEGRAY; + if (session.enable_ledadd)) + { + r->value |= REG_0x01_TRUEGRAY; + }*/ + } + + unsigned dpiset = session.params.xres * ccd_pixels_per_system_pixel; + reg->set16(REG_DPISET, dpiset); + DBG(DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); + + reg->set16(REG_STRPIXEL, session.pixel_startx); + reg->set16(REG_ENDPIXEL, session.pixel_endx); + + build_image_pipeline(dev, session); + + /* MAXWD is expressed in 4 words unit */ + // BUG: we shouldn't multiply by channels here + reg->set24(REG_MAXWD, (session.output_line_bytes_raw * session.params.channels >> 2)); + + reg->set16(REG_LPERIOD, exposure_time); + DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time); + + r = sanei_genesys_get_address (reg, 0x34); + r->value = sensor.dummy_pixel; +} + +void CommandSetGl846::init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const +{ + DBG_HELPER(dbg); + session.assert_computed(); + + int move; + int exposure_time; + + int slope_dpi = 0; + int dummy = 0; + + dummy = 3-session.params.channels; + +/* slope_dpi */ +/* cis color scan is effectively a gray scan with 3 gray lines per color + line and a FILTER of 0 */ + if (dev->model->is_cis) { + slope_dpi = session.params.yres * session.params.channels; + } else { + slope_dpi = session.params.yres; + } + + slope_dpi = slope_dpi * (1 + dummy); + + exposure_time = sensor.exposure_lperiod; + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl846_motor_profiles, + dev->model->motor_id, + exposure_time); + + DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); + DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, + static_cast<unsigned>(motor_profile.step_type)); + + /* we enable true gray for cis scanners only, and just when doing + * scan since color calibration is OK for this mode + */ + gl846_init_optical_regs_scan(dev, sensor, reg, exposure_time, session); + +/*** motor parameters ***/ + + /* add tl_y to base movement */ + move = session.params.starty; + DBG(DBG_info, "%s: move=%d steps\n", __func__, move); + + MotorFlag mflags = MotorFlag::NONE; + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { + mflags |= MotorFlag::DISABLE_BUFFER_FULL_MOVE; + } + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { + mflags |= MotorFlag::FEED; + } + if (has_flag(session.params.flags, ScanFlag::REVERSE)) { + mflags |= MotorFlag::REVERSE; + } + + gl846_init_motor_regs_scan(dev, sensor, reg, motor_profile, exposure_time, slope_dpi, + dev->model->is_cis ? session.output_line_count * session.params.channels + : session.output_line_count, + dummy, move, mflags); + + /*** prepares data reordering ***/ + + dev->read_buffer.clear(); + dev->read_buffer.alloc(session.buffer_size_read); + + dev->read_active = true; + + dev->session = session; + + dev->total_bytes_read = 0; + dev->total_bytes_to_read = session.output_line_bytes_requested * session.params.lines; + + DBG(DBG_info, "%s: total bytes to send = %zu\n", __func__, dev->total_bytes_to_read); +} + +ScanSession CommandSetGl846::calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const +{ + int start; + + DBG(DBG_info, "%s ", __func__); + debug_dump(DBG_info, settings); + + /* start */ + start = static_cast<int>(dev->model->x_offset); + start += static_cast<int>(settings.tl_x); + start = static_cast<int>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = settings.xres; + session.params.yres = settings.yres; + session.params.startx = start; // not used + session.params.starty = 0; // not used + session.params.pixels = settings.pixels; + session.params.requested_pixels = settings.requested_pixels; + session.params.lines = settings.lines; + session.params.depth = settings.depth; + session.params.channels = settings.get_channels(); + session.params.scan_method = settings.scan_method; + session.params.scan_mode = settings.scan_mode; + session.params.color_filter = settings.color_filter; + session.params.flags = ScanFlag::NONE; + + compute_session(dev, session, sensor); + + return session; +} + +// for fast power saving methods only, like disabling certain amplifiers +void CommandSetGl846::save_power(Genesys_Device* dev, bool enable) const +{ + (void) dev; + DBG_HELPER_ARGS(dbg, "enable = %d", enable); +} + +void CommandSetGl846::set_powersaving(Genesys_Device* dev, int delay /* in minutes */) const +{ + (void) dev; + DBG_HELPER_ARGS(dbg, "delay = %d", delay); +} + +// Send the low-level scan command +void CommandSetGl846::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, bool start_motor) const +{ + DBG_HELPER(dbg); + (void) sensor; + uint8_t val; + GenesysRegister *r; + + /* XXX STEF XXX SCAN GPIO */ + /* + val = dev->interface->read_register(REG_0x6C); + dev->interface->write_register(REG_0x6C, val); + */ + + val = REG_0x0D_CLRLNCNT; + dev->interface->write_register(REG_0x0D, val); + val = REG_0x0D_CLRMCNT; + dev->interface->write_register(REG_0x0D, val); + + val = dev->interface->read_register(REG_0x01); + val |= REG_0x01_SCAN; + dev->interface->write_register(REG_0x01, val); + r = sanei_genesys_get_address (reg, REG_0x01); + r->value = val; + + scanner_start_action(*dev, start_motor); + + dev->advance_head_pos_by_session(ScanHeadId::PRIMARY); +} + + +// Send the stop scan command +void CommandSetGl846::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg, + bool check_stop) const +{ + (void) reg; + DBG_HELPER_ARGS(dbg, "check_stop = %d", check_stop); + + if (!dev->model->is_sheetfed) { + scanner_stop_action(*dev); + } +} + +// Moves the slider to the home (top) postion slowly +void CommandSetGl846::move_back_home(Genesys_Device* dev, bool wait_until_home) const +{ + scanner_move_back_home(*dev, wait_until_home); +} + +// Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi +// from very top of scanner +void CommandSetGl846::search_start_position(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + int size; + Genesys_Register_Set local_reg; + + int pixels = 600; + int dpi = 300; + + local_reg = dev->reg; + + /* sets for a 200 lines * 600 pixels */ + /* normal scan with no shading */ + + // FIXME: the current approach of doing search only for one resolution does not work on scanners + // whith employ different sensors with potentially different settings. + const auto& sensor = sanei_genesys_find_sensor(dev, dpi, 1, dev->model->default_method); + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; /*we should give a small offset here~60 steps */ + session.params.pixels = 600; + session.params.lines = dev->model->search_lines; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::GREEN; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + // send to scanner + dev->interface->write_registers(local_reg); + + size = pixels * dev->model->search_lines; + + std::vector<uint8_t> data(size); + + begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_start_position"); + end_scan(dev, &local_reg, true); + dev->reg = local_reg; + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl846_search_position.pnm", data.data(), 8, 1, pixels, + dev->model->search_lines); + } + + end_scan(dev, &local_reg, true); + + /* update regs to copy ASIC internal state */ + dev->reg = local_reg; + + // TODO: find out where sanei_genesys_search_reference_point stores information, + // and use that correctly + for (auto& sensor_update : + sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method)) + { + sanei_genesys_search_reference_point(dev, sensor_update, data.data(), 0, dpi, pixels, + dev->model->search_lines); + } +} + +// sets up register for coarse gain calibration +// todo: check it for scanners using it +void CommandSetGl846::init_regs_for_coarse_calibration(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = sensor.optical_res / sensor.ccd_pixels_per_system_pixel(); + session.params.lines = 20; + session.params.depth = 16; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, + sensor.optical_res / sensor.ccd_pixels_per_system_pixel(), dev->settings.xres); + + dev->interface->write_registers(regs); +} + +// init registers for shading calibration +void CommandSetGl846::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + float move; + + dev->calib_channels = 3; + + /* initial calibration reg values */ + regs = dev->reg; + + dev->calib_resolution = sensor.get_register_hwdpi(dev->settings.xres); + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, dev->calib_resolution, + dev->calib_channels, + dev->settings.scan_method); + dev->calib_total_bytes_to_read = 0; + dev->calib_lines = dev->model->shading_lines; + if (dev->calib_resolution==4800) { + dev->calib_lines *= 2; + } + dev->calib_pixels = (calib_sensor.sensor_pixels * dev->calib_resolution) / + calib_sensor.optical_res; + + DBG(DBG_io, "%s: calib_lines = %zu\n", __func__, dev->calib_lines); + DBG(DBG_io, "%s: calib_pixels = %zu\n", __func__, dev->calib_pixels); + + /* this is aworkaround insufficent distance for slope + * motor acceleration TODO special motor slope for shading */ + move=1; + if(dev->calib_resolution<1200) + { + move=40; + } + + ScanSession session; + session.params.xres = dev->calib_resolution; + session.params.yres = dev->calib_resolution; + session.params.startx = 0; + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = dev->calib_pixels; + session.params.lines = dev->calib_lines; + session.params.depth = 16; + session.params.channels = dev->calib_channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + dev->interface->write_registers(regs); + + /* we use GENESYS_FLAG_SHADING_REPARK */ + dev->set_head_pos_zero(ScanHeadId::PRIMARY); +} + +/** @brief set up registers for the actual scan + */ +void CommandSetGl846::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + float move; + int move_dpi; + float start; + + debug_dump(DBG_info, dev->settings); + + /* steps to move to reach scanning area: + - first we move to physical start of scanning + either by a fixed steps amount from the black strip + or by a fixed amount from parking position, + minus the steps done during shading calibration + - then we move by the needed offset whitin physical + scanning area + + assumption: steps are expressed at maximum motor resolution + + we need: + float y_offset; + float y_size; + float y_offset_calib; + mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */ + + /* if scanner uses GENESYS_FLAG_SEARCH_START y_offset is + relative from origin, else, it is from parking position */ + + move_dpi = dev->motor.base_ydpi; + + move = static_cast<float>(dev->model->y_offset); + move = static_cast<float>(move + dev->settings.tl_y); + move = static_cast<float>((move * move_dpi) / MM_PER_INCH); + move -= dev->head_pos(ScanHeadId::PRIMARY); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + /* fast move to scan area */ + /* we don't move fast the whole distance since it would involve + * computing acceleration/deceleration distance for scan + * resolution. So leave a remainder for it so scan makes the final + * move tuning */ + if (dev->settings.get_channels() * dev->settings.yres >= 600 && move > 700) { + scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move - 500), + Direction::FORWARD); + move=500; + } + + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + /* start */ + start = static_cast<float>(dev->model->x_offset); + start = static_cast<float>(start + dev->settings.tl_x); + start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = static_cast<unsigned>(start); + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = dev->settings.pixels; + session.params.requested_pixels = dev->settings.requested_pixels; + session.params.lines = dev->settings.lines; + session.params.depth = dev->settings.depth; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + // backtracking isn't handled well, so don't enable it + session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &dev->reg, session); +} + + +/** + * Send shading calibration data. The buffer is considered to always hold values + * for all the channels. + */ +void CommandSetGl846::send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + uint8_t* data, int size) const +{ + DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size); + uint32_t addr, length, i, x, factor, pixels; + uint32_t dpiset, dpihw; + uint8_t val,*ptr,*src; + + /* shading data is plit in 3 (up to 5 with IR) areas + write(0x10014000,0x00000dd8) + URB 23429 bulk_out len 3544 wrote 0x33 0x10 0x.... + write(0x1003e000,0x00000dd8) + write(0x10068000,0x00000dd8) + */ + length = static_cast<uint32_t>(size / 3); + unsigned strpixel = dev->session.pixel_startx; + unsigned endpixel = dev->session.pixel_endx; + + /* compute deletion factor */ + dpiset = dev->reg.get16(REG_DPISET); + dpihw = sensor.get_register_hwdpi(dpiset); + factor=dpihw/dpiset; + DBG(DBG_io2, "%s: factor=%d\n", __func__, factor); + + pixels=endpixel-strpixel; + + /* since we're using SHDAREA, substract startx coordinate from shading */ + strpixel -= (sensor.ccd_start_xoffset * 600) / sensor.optical_res; + + /* turn pixel value into bytes 2x16 bits words */ + strpixel*=2*2; + pixels*=2*2; + + dev->interface->record_key_value("shading_offset", std::to_string(strpixel)); + dev->interface->record_key_value("shading_pixels", std::to_string(pixels)); + dev->interface->record_key_value("shading_length", std::to_string(length)); + dev->interface->record_key_value("shading_factor", std::to_string(factor)); + + std::vector<uint8_t> buffer(pixels, 0); + + DBG(DBG_io2, "%s: using chunks of %d (0x%04x) bytes\n", __func__, pixels, pixels); + + /* base addr of data has been written in reg D0-D4 in 4K word, so AHB address + * is 8192*reg value */ + + /* write actual color channel data */ + for(i=0;i<3;i++) + { + /* build up actual shading data by copying the part from the full width one + * to the one corresponding to SHDAREA */ + ptr = buffer.data(); + + /* iterate on both sensor segment */ + for(x=0;x<pixels;x+=4*factor) + { + /* coefficient source */ + src=(data+strpixel+i*length)+x; + + /* coefficient copy */ + ptr[0]=src[0]; + ptr[1]=src[1]; + ptr[2]=src[2]; + ptr[3]=src[3]; + + /* next shading coefficient */ + ptr+=4; + } + + val = dev->interface->read_register(0xd0+i); + addr = val * 8192 + 0x10000000; + dev->interface->write_ahb(addr, pixels, buffer.data()); + } +} + +/** @brief calibrates led exposure + * Calibrate exposure by scanning a white area until the used exposure gives + * data white enough. + * @param dev device to calibrate + */ +SensorExposure CommandSetGl846::led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int num_pixels; + int total_size; + int used_res; + int i, j; + int val; + int channels; + int avg[3], top[3], bottom[3]; + int turn; + uint16_t exp[3]; + + float move = static_cast<float>(dev->model->y_offset_calib_white); + move = static_cast<float>((move * (dev->motor.base_ydpi / 4)) / MM_PER_INCH); + if(move>20) + { + scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move), + Direction::FORWARD); + } + DBG(DBG_io, "%s: move=%f steps\n", __func__, move); + + /* offset calibration is always done in color mode */ + channels = 3; + used_res = sensor.get_register_hwdpi(dev->settings.xres); + const auto& calib_sensor = sanei_genesys_find_sensor(dev, used_res, channels, + dev->settings.scan_method); + num_pixels = (calib_sensor.sensor_pixels * used_res) / calib_sensor.optical_res; + + /* initial calibration reg values */ + regs = dev->reg; + + ScanSession session; + session.params.xres = used_res; + session.params.yres = used_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + total_size = num_pixels * channels * (session.params.depth / 8) * 1; + std::vector<uint8_t> line(total_size); + + /* initial loop values and boundaries */ + exp[0] = calib_sensor.exposure.red; + exp[1] = calib_sensor.exposure.green; + exp[2] = calib_sensor.exposure.blue; + + bottom[0]=29000; + bottom[1]=29000; + bottom[2]=29000; + + top[0]=41000; + top[1]=51000; + top[2]=51000; + + turn = 0; + + /* no move during led calibration */ + sanei_genesys_set_motor_power(regs, false); + bool acceptable = false; + do + { + // set up exposure + regs.set16(REG_EXPR, exp[0]); + regs.set16(REG_EXPG, exp[1]); + regs.set16(REG_EXPB, exp[2]); + + // write registers and scan data + dev->interface->write_registers(regs); + + DBG(DBG_info, "%s: starting line reading\n", __func__); + begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("led_calibration"); + scanner_stop_action(*dev); + move_back_home(dev, true); + return calib_sensor.exposure; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + // stop scanning + scanner_stop_action(*dev); + + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl846_led_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, line.data(), session.params.depth, + channels, num_pixels, 1); + } + + /* compute average */ + for (j = 0; j < channels; j++) + { + avg[j] = 0; + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + line[i * 2 + j * 2 * num_pixels + 1] * 256 + + line[i * 2 + j * 2 * num_pixels]; + else + val = + line[i * 2 * channels + 2 * j + 1] * 256 + + line[i * 2 * channels + 2 * j]; + avg[j] += val; + } + + avg[j] /= num_pixels; + } + + DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); + + /* check if exposure gives average within the boundaries */ + acceptable = true; + for(i=0;i<3;i++) + { + if(avg[i]<bottom[i]) + { + exp[i]=(exp[i]*bottom[i])/avg[i]; + acceptable = false; + } + if(avg[i]>top[i]) + { + exp[i]=(exp[i]*top[i])/avg[i]; + acceptable = false; + } + } + + turn++; + } + while (!acceptable && turn < 100); + + DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); + + // set these values as final ones for scan + dev->reg.set16(REG_EXPR, exp[0]); + dev->reg.set16(REG_EXPG, exp[1]); + dev->reg.set16(REG_EXPB, exp[2]); + + /* go back home */ + if(move>20) + { + move_back_home(dev, true); + } + + return { exp[0], exp[1], exp[2] }; +} + +/** + * set up GPIO/GPOE for idle state + */ +static void gl846_init_gpio(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + int idx=0; + + /* search GPIO profile */ + while (gpios[idx].gpio_id != GpioId::UNKNOWN && dev->model->gpio_id != gpios[idx].gpio_id) { + idx++; + } + if (gpios[idx].gpio_id == GpioId::UNKNOWN) + { + throw SaneException("failed to find GPIO profile for sensor_id=%d", + static_cast<unsigned>(dev->model->sensor_id)); + } + + dev->interface->write_register(REG_0xA7, gpios[idx].ra7); + dev->interface->write_register(REG_0xA6, gpios[idx].ra6); + + dev->interface->write_register(REG_0x6B, gpios[idx].r6b); + dev->interface->write_register(REG_0x6C, gpios[idx].r6c); + dev->interface->write_register(REG_0x6D, gpios[idx].r6d); + dev->interface->write_register(REG_0x6E, gpios[idx].r6e); + dev->interface->write_register(REG_0x6F, gpios[idx].r6f); + + dev->interface->write_register(REG_0xA8, gpios[idx].ra8); + dev->interface->write_register(REG_0xA9, gpios[idx].ra9); +} + +/** + * set memory layout by filling values in dedicated registers + */ +static void gl846_init_memory_layout(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + int idx = 0, i; + uint8_t val; + + /* point to per model memory layout */ + idx = 0; + while (layouts[idx].model != nullptr && strcmp(dev->model->name,layouts[idx].model)!=0) { + if(strcmp(dev->model->name,layouts[idx].model)!=0) + idx++; + } + if (layouts[idx].model == nullptr) { + throw SaneException("failed to find memory layout for model %s", dev->model->name); + } + + /* CLKSET and DRAMSEL */ + val = layouts[idx].dramsel; + dev->interface->write_register(REG_0x0B, val); + dev->reg.find_reg(0x0b).value = val; + + /* prevent further writings by bulk write register */ + dev->reg.remove_reg(0x0b); + + /* setup base address for shading and scanned data. */ + for(i=0;i<10;i++) + { + dev->interface->write_register(0xe0+i, layouts[idx].rx[i]); + } +} + +/* * + * initialize ASIC from power on condition + */ +void CommandSetGl846::asic_boot(Genesys_Device* dev, bool cold) const +{ + DBG_HELPER(dbg); + uint8_t val; + + // reset ASIC if cold boot + if (cold) { + dev->interface->write_register(0x0e, 0x01); + dev->interface->write_register(0x0e, 0x00); + } + + if(dev->usb_mode == 1) + { + val = 0x14; + } + else + { + val = 0x11; + } + dev->interface->write_0x8c(0x0f, val); + + // test CHKVER + val = dev->interface->read_register(REG_0x40); + if (val & REG_0x40_CHKVER) { + val = dev->interface->read_register(0x00); + DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); + } + + /* Set default values for registers */ + gl846_init_registers (dev); + + // Write initial registers + dev->interface->write_registers(dev->reg); + + /* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */ + val = dev->reg.find_reg(0x0b).value & REG_0x0B_DRAMSEL; + val = (val | REG_0x0B_ENBDRAM); + dev->interface->write_register(REG_0x0B, val); + dev->reg.find_reg(0x0b).value = val; + + /* CIS_LINE */ + if (dev->model->is_cis) + { + dev->reg.init_reg(0x08, REG_0x08_CIS_LINE); + dev->interface->write_register(0x08, dev->reg.find_reg(0x08).value); + } + + // set up clocks + dev->interface->write_0x8c(0x10, 0x0e); + dev->interface->write_0x8c(0x13, 0x0e); + + // setup gpio + gl846_init_gpio(dev); + + // setup internal memory layout + gl846_init_memory_layout(dev); + + dev->reg.init_reg(0xf8, 0x05); + dev->interface->write_register(0xf8, dev->reg.find_reg(0xf8).value); +} + +/** + * initialize backend and ASIC : registers, motor tables, and gamma tables + * then ensure scanner's head is at home + */ +void CommandSetGl846::init(Genesys_Device* dev) const +{ + DBG_INIT (); + DBG_HELPER(dbg); + + sanei_genesys_asic_init(dev, 0); +} + +void CommandSetGl846::update_hardware_sensors(Genesys_Scanner* s) const +{ + DBG_HELPER(dbg); + /* do what is needed to get a new set of events, but try to not lose + any of them. + */ + uint8_t val; + uint8_t scan, file, email, copy; + switch(s->dev->model->gpio_id) + { + default: + scan=0x01; + file=0x02; + email=0x04; + copy=0x08; + } + val = s->dev->interface->read_register(REG_0x6D); + + s->buttons[BUTTON_SCAN_SW].write((val & scan) == 0); + s->buttons[BUTTON_FILE_SW].write((val & file) == 0); + s->buttons[BUTTON_EMAIL_SW].write((val & email) == 0); + s->buttons[BUTTON_COPY_SW].write((val & copy) == 0); +} + + +void CommandSetGl846::update_home_sensor_gpio(Genesys_Device& dev) const +{ + DBG_HELPER(dbg); + + std::uint8_t val = dev.interface->read_register(REG_0x6C); + val |= 0x41; + dev.interface->write_register(REG_0x6C, val); +} + +/** @brief search for a full width black or white strip. + * This function searches for a black or white stripe across the scanning area. + * When searching backward, the searched area must completely be of the desired + * color since this area will be used for calibration which scans forward. + * @param dev scanner device + * @param forward true if searching forward, false if searching backward + * @param black true if searching for a black strip, false for a white strip + */ +void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward, + bool black) const +{ + DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse"); + unsigned int pixels, lines, channels; + Genesys_Register_Set local_reg; + size_t size; + unsigned int pass, count, found, x, y; + char title[80]; + + set_fe(dev, sensor, AFE_SET); + + scanner_stop_action(*dev); + + // set up for a gray scan at lowest dpi + const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method); + unsigned dpi = resolution_settings.get_min_resolution_x(); + channels = 1; + /* 10 MM */ + /* lines = (10 * dpi) / MM_PER_INCH; */ + /* shading calibation is done with dev->motor.base_ydpi */ + lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; + pixels = (sensor.sensor_pixels * dpi) / sensor.optical_res; + + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + + local_reg = dev->reg; + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA; + if (!forward) { + session.params.flags |= ScanFlag::REVERSE; + } + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + size = pixels * channels * lines * (session.params.depth / 8); + std::vector<uint8_t> data(size); + + dev->interface->write_registers(local_reg); + + begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_strip"); + scanner_stop_action(*dev); + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + scanner_stop_action(*dev); + + pass = 0; + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm", + black ? "black" : "white", forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, + channels, pixels, lines); + } + + /* loop until strip is found or maximum pass number done */ + found = 0; + while (pass < 20 && !found) + { + dev->interface->write_registers(local_reg); + + // now start scan + begin_scan(dev, sensor, &local_reg, true); + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + scanner_stop_action(*dev); + + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm", + black ? "black" : "white", forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, + channels, pixels, lines); + } + + /* search data to find black strip */ + /* when searching forward, we only need one line of the searched color since we + * will scan forward. But when doing backward search, we need all the area of the + * same color */ + if (forward) + { + for (y = 0; y < lines && !found; y++) + { + count = 0; + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * pixels + x] > 90) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * pixels + x] < 60) + { + count++; + } + } + + /* at end of line, if count >= 3%, line is not fully of the desired color + * so we must go to next line of the buffer */ + /* count*100/pixels < 3 */ + if ((count * 100) / pixels < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, + pass, y); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + } + else /* since calibration scans are done forward, we need the whole area + to be of the required color when searching backward */ + { + count = 0; + for (y = 0; y < lines; y++) + { + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * pixels + x] > 90) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * pixels + x] < 60) + { + count++; + } + } + } + + /* at end of area, if count >= 3%, area is not fully of the desired color + * so we must go to next buffer */ + if ((count * 100) / (pixels * lines) < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + pass++; + } + + if (found) + { + DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); + } + else + { + throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white"); + } +} + +/** + * average dark pixels of a 8 bits scan + */ +static int +dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, + unsigned int channels, unsigned int black) +{ + unsigned int i, j, k, average, count; + unsigned int avg[3]; + uint8_t val; + + /* computes average value on black margin */ + for (k = 0; k < channels; k++) + { + avg[k] = 0; + count = 0; + for (i = 0; i < lines; i++) + { + for (j = 0; j < black; j++) + { + val = data[i * channels * pixels + j + k]; + avg[k] += val; + count++; + } + } + if (count) + avg[k] /= count; + DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); + } + average = 0; + for (i = 0; i < channels; i++) + average += avg[i]; + average /= channels; + DBG(DBG_info, "%s: average = %d\n", __func__, average); + return average; +} + +void CommandSetGl846::offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + unsigned channels; + int pass = 0, avg, total_size; + int topavg, bottomavg, lines; + int top, bottom, black_pixels, pixels; + + // no gain nor offset for AKM AFE + uint8_t reg04 = dev->interface->read_register(REG_0x04); + if ((reg04 & REG_0x04_FESET) == 0x02) { + return; + } + + /* offset calibration is always done in color mode */ + channels = 3; + dev->calib_pixels = sensor.sensor_pixels; + lines=1; + pixels = (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res; + black_pixels = (sensor.black_pixels * sensor.optical_res) / sensor.optical_res; + DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = sensor.optical_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + sanei_genesys_set_motor_power(regs, false); + + total_size = pixels * channels * lines * (session.params.depth / 8); + + std::vector<uint8_t> first_line(total_size); + std::vector<uint8_t> second_line(total_size); + + /* init gain */ + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + + /* scan with no move */ + bottom = 10; + dev->frontend.set_offset(0, bottom); + dev->frontend.set_offset(1, bottom); + dev->frontend.set_offset(2, bottom); + + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting first line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("offset_calibration"); + return; + } + + sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size); + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl846_offset%03d.pnm", bottom); + sanei_genesys_write_pnm_file(fn, first_line.data(), session.params.depth, + channels, pixels, lines); + } + + bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); + + /* now top value */ + top = 255; + dev->frontend.set_offset(0, top); + dev->frontend.set_offset(1, top); + dev->frontend.set_offset(2, top); + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + + topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); + + /* loop until acceptable level */ + while ((pass < 32) && (top - bottom > 1)) + { + pass++; + + /* settings for new scan */ + dev->frontend.set_offset(0, (top + bottom) / 2); + dev->frontend.set_offset(1, (top + bottom) / 2); + dev->frontend.set_offset(2, (top + bottom) / 2); + + // scan with no move + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl846_offset%03d.pnm", dev->frontend.get_offset(1)); + sanei_genesys_write_pnm_file(fn, second_line.data(), session.params.depth, + channels, pixels, lines); + } + + avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); + + /* compute new boundaries */ + if (topavg == avg) + { + topavg = avg; + top = dev->frontend.get_offset(1); + } + else + { + bottomavg = avg; + bottom = dev->frontend.get_offset(1); + } + } + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); +} + +void CommandSetGl846::coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const +{ + DBG_HELPER(dbg); + int pixels; + int total_size; + int i, j, channels; + int max[3]; + float gain[3],coeff; + int val, code, lines; + + DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi); + + // no gain nor offset for AKM AFE + uint8_t reg04 = dev->interface->read_register(REG_0x04); + if ((reg04 & REG_0x04_FESET) == 0x02) { + return; + } + + /* coarse gain calibration is always done in color mode */ + channels = 3; + + /* follow CKSEL */ + if(dev->settings.xres<sensor.optical_res) + { + coeff = 0.9f; + } + else + { + coeff=1.0; + } + lines=10; + pixels = (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res; + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = sensor.optical_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + try { + init_regs_for_scan_session(dev, sensor, ®s, session); + } catch (...) { + catch_all_exceptions(__func__, [&](){ sanei_genesys_set_motor_power(regs, false); }); + throw; + } + + sanei_genesys_set_motor_power(regs, false); + + dev->interface->write_registers(regs); + + total_size = pixels * channels * (16 / session.params.depth) * lines; + + std::vector<uint8_t> line(total_size); + + set_fe(dev, sensor, AFE_SET); + begin_scan(dev, sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("coarse_gain_calibration"); + scanner_stop_action(*dev); + move_back_home(dev, true); + return; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl846_gain.pnm", line.data(), session.params.depth, + channels, pixels, lines); + } + + /* average value on each channel */ + for (j = 0; j < channels; j++) + { + max[j] = 0; + for (i = pixels/4; i < (pixels*3/4); i++) + { + if (dev->model->is_cis) + val = line[i + j * pixels]; + else + val = line[i * channels + j]; + + max[j] += val; + } + max[j] = max[j] / (pixels/2); + + gain[j] = (static_cast<float>(sensor.gain_white_ref) * coeff) / max[j]; + + /* turn logical gain value into gain code, checking for overflow */ + code = static_cast<int>(283 - 208 / gain[j]); + if (code > 255) + code = 255; + else if (code < 0) + code = 0; + dev->frontend.set_gain(j, code); + + DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], + dev->frontend.get_gain(j)); + } + + if (dev->model->is_cis) { + uint8_t gain0 = dev->frontend.get_gain(0); + if (gain0 > dev->frontend.get_gain(1)) { + gain0 = dev->frontend.get_gain(1); + } + if (gain0 > dev->frontend.get_gain(2)) { + gain0 = dev->frontend.get_gain(2); + } + dev->frontend.set_gain(0, gain0); + dev->frontend.set_gain(1, gain0); + dev->frontend.set_gain(2, gain0); + } + + scanner_stop_action(*dev); + + move_back_home(dev, true); +} + +bool CommandSetGl846::needs_home_before_init_regs_for_scan(Genesys_Device* dev) const +{ + (void) dev; + return false; +} + +void CommandSetGl846::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const +{ + (void) dev; + (void) sensor; + (void) regs; + (void) channels; + (void) total_size; + throw SaneException("not implemented"); +} + +void CommandSetGl846::send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + sanei_genesys_send_gamma_table(dev, sensor); +} + +void CommandSetGl846::wait_for_motor_stop(Genesys_Device* dev) const +{ + (void) dev; +} + +void CommandSetGl846::load_document(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl846::detect_document_end(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl846::eject_document(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl846::move_to_ta(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +std::unique_ptr<CommandSet> create_gl846_cmd_set() +{ + return std::unique_ptr<CommandSet>(new CommandSetGl846{}); +} + +} // namespace gl846 +} // namespace genesys diff --git a/backend/genesys/gl846.h b/backend/genesys/gl846.h new file mode 100644 index 0000000..258015a --- /dev/null +++ b/backend/genesys/gl846.h @@ -0,0 +1,218 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2012-2013 Stéphane Voltz <stef.dev@free.fr> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#include "genesys.h" +#include "command_set.h" + +#ifndef BACKEND_GENESYS_GL846_H +#define BACKEND_GENESYS_GL846_H + +namespace genesys { +namespace gl846 { + +typedef struct +{ + GpioId gpio_id; + uint8_t r6b; + uint8_t r6c; + uint8_t r6d; + uint8_t r6e; + uint8_t r6f; + uint8_t ra6; + uint8_t ra7; + uint8_t ra8; + uint8_t ra9; +} Gpio_Profile; + +static Gpio_Profile gpios[]={ + { GpioId::IMG101, 0x72, 0x1f, 0xa4, 0x13, 0xa7, 0x11, 0xff, 0x19, 0x05}, + { GpioId::PLUSTEK_OPTICBOOK_3800, 0x30, 0x01, 0x80, 0x2d, 0x80, 0x0c, 0x8f, 0x08, 0x04}, + { GpioId::UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +}; + +typedef struct +{ + const char *model; + uint8_t dramsel; + /* shading data address */ + uint8_t rd0; + uint8_t rd1; + uint8_t rd2; + /* scanned data address */ + uint8_t rx[24]; +} Memory_layout; + +static Memory_layout layouts[]={ + /* Image formula 101 */ + { + "canon-image-formula-101", + 0x8b, + 0x0a, 0x1b, 0x00, + { /* RED ODD START / RED ODD END */ + 0x00, 0xb0, 0x05, 0xe7, /* [0x00b0, 0x05e7] 1336*4000w */ + /* RED EVEN START / RED EVEN END */ + 0x05, 0xe8, 0x0b, 0x1f, /* [0x05e8, 0x0b1f] */ + /* GREEN ODD START / GREEN ODD END */ + 0x0b, 0x20, 0x10, 0x57, /* [0x0b20, 0x1057] */ + /* GREEN EVEN START / GREEN EVEN END */ + 0x10, 0x58, 0x15, 0x8f, /* [0x1058, 0x158f] */ + /* BLUE ODD START / BLUE ODD END */ + 0x15, 0x90, 0x1a, 0xc7, /* [0x1590,0x1ac7] */ + /* BLUE EVEN START / BLUE EVEN END */ + 0x1a, 0xc8, 0x1f, 0xff /* [0x1ac8,0x1fff] */ + } + }, + /* OpticBook 3800 */ + { + "plustek-opticbook-3800", + 0x2a, + 0x0a, 0x0a, 0x0a, + { /* RED ODD START / RED ODD END */ + 0x00, 0x68, 0x03, 0x00, + /* RED EVEN START / RED EVEN END */ + 0x03, 0x01, 0x05, 0x99, + /* GREEN ODD START / GREEN ODD END */ + 0x05, 0x9a, 0x08, 0x32, + /* GREEN EVEN START / GREEN EVEN END */ + 0x08, 0x33, 0x0a, 0xcb, + /* BLUE ODD START / BLUE ODD END */ + 0x0a, 0xcc, 0x0d, 0x64, + /* BLUE EVEN START / BLUE EVEN END */ + 0x0d, 0x65, 0x0f, 0xfd + } + }, + /* list terminating entry */ + { nullptr, 0, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} } +}; + +class CommandSetGl846 : public CommandSet +{ +public: + ~CommandSetGl846() override = default; + + bool needs_home_before_init_regs_for_scan(Genesys_Device* dev) const override; + + void init(Genesys_Device* dev) const override; + + void init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const override; + + void init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const override; + + void set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const override; + void set_powersaving(Genesys_Device* dev, int delay) const override; + void save_power(Genesys_Device* dev, bool enable) const override; + + void begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, bool start_motor) const override; + + void end_scan(Genesys_Device* dev, Genesys_Register_Set* regs, bool check_stop) const override; + + void send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void search_start_position(Genesys_Device* dev) const override; + + void offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const override; + + SensorExposure led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void wait_for_motor_stop(Genesys_Device* dev) const override; + + void move_back_home(Genesys_Device* dev, bool wait_until_home) const override; + + void update_hardware_sensors(struct Genesys_Scanner* s) const override; + + bool needs_update_home_sensor_gpio() const override { return true; } + + void update_home_sensor_gpio(Genesys_Device& dev) const override; + + void load_document(Genesys_Device* dev) const override; + + void detect_document_end(Genesys_Device* dev) const override; + + void eject_document(Genesys_Device* dev) const override; + + void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const override; + + void move_to_ta(Genesys_Device* dev) const override; + + void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data, + int size) const override; + + ScanSession calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const override; + + void asic_boot(Genesys_Device* dev, bool cold) const override; +}; + +enum SlopeTable +{ + SCAN_TABLE = 0, // table 1 at 0x4000 + BACKTRACK_TABLE = 1, // table 2 at 0x4800 + STOP_TABLE = 2, // table 3 at 0x5000 + FAST_TABLE = 3, // table 4 at 0x5800 + HOME_TABLE = 4, // table 5 at 0x6000 +}; + +} // namespace gl846 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL846_H diff --git a/backend/genesys/gl846_registers.h b/backend/genesys/gl846_registers.h new file mode 100644 index 0000000..39b3029 --- /dev/null +++ b/backend/genesys/gl846_registers.h @@ -0,0 +1,351 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL846_REGISTERS_H +#define BACKEND_GENESYS_GL846_REGISTERS_H + +#include <cstdint> + +namespace genesys { +namespace gl846 { + +using RegAddr = std::uint16_t; +using RegMask = std::uint8_t; +using RegShift = unsigned; + +static constexpr RegAddr REG_0x01 = 0x01; +static constexpr RegMask REG_0x01_CISSET = 0x80; +static constexpr RegMask REG_0x01_DOGENB = 0x40; +static constexpr RegMask REG_0x01_DVDSET = 0x20; +static constexpr RegMask REG_0x01_STAGGER = 0x10; +static constexpr RegMask REG_0x01_COMPENB = 0x08; +static constexpr RegMask REG_0x01_TRUEGRAY = 0x04; +static constexpr RegMask REG_0x01_SHDAREA = 0x02; +static constexpr RegMask REG_0x01_SCAN = 0x01; + +static constexpr RegAddr REG_0x02 = 0x02; +static constexpr RegMask REG_0x02_NOTHOME = 0x80; +static constexpr RegMask REG_0x02_ACDCDIS = 0x40; +static constexpr RegMask REG_0x02_AGOHOME = 0x20; +static constexpr RegMask REG_0x02_MTRPWR = 0x10; +static constexpr RegMask REG_0x02_FASTFED = 0x08; +static constexpr RegMask REG_0x02_MTRREV = 0x04; +static constexpr RegMask REG_0x02_HOMENEG = 0x02; +static constexpr RegMask REG_0x02_LONGCURV = 0x01; + +static constexpr RegAddr REG_0x03 = 0x03; +static constexpr RegMask REG_0x03_LAMPDOG = 0x80; +static constexpr RegMask REG_0x03_AVEENB = 0x40; +static constexpr RegMask REG_0x03_XPASEL = 0x20; +static constexpr RegMask REG_0x03_LAMPPWR = 0x10; +static constexpr RegMask REG_0x03_LAMPTIM = 0x0f; + +static constexpr RegAddr REG_0x04 = 0x04; +static constexpr RegMask REG_0x04_LINEART = 0x80; +static constexpr RegMask REG_0x04_BITSET = 0x40; +static constexpr RegMask REG_0x04_AFEMOD = 0x30; +static constexpr RegMask REG_0x04_FILTER = 0x0c; +static constexpr RegMask REG_0x04_FESET = 0x03; + +static constexpr RegShift REG_0x04S_AFEMOD = 4; + +static constexpr RegAddr REG_0x05 = 0x05; +static constexpr RegMask REG_0x05_DPIHW = 0xc0; +static constexpr RegMask REG_0x05_DPIHW_600 = 0x00; +static constexpr RegMask REG_0x05_DPIHW_1200 = 0x40; +static constexpr RegMask REG_0x05_DPIHW_2400 = 0x80; +static constexpr RegMask REG_0x05_DPIHW_4800 = 0xc0; +static constexpr RegMask REG_0x05_MTLLAMP = 0x30; +static constexpr RegMask REG_0x05_GMMENB = 0x08; +static constexpr RegMask REG_0x05_MTLBASE = 0x03; + +static constexpr RegAddr REG_0x06 = 0x06; +static constexpr RegMask REG_0x06_SCANMOD = 0xe0; +static constexpr RegShift REG_0x06S_SCANMOD = 5; +static constexpr RegMask REG_0x06_PWRBIT = 0x10; +static constexpr RegMask REG_0x06_GAIN4 = 0x08; +static constexpr RegMask REG_0x06_OPTEST = 0x07; + +static constexpr RegMask REG_0x07_LAMPSIM = 0x80; + +static constexpr RegMask REG_0x08_DRAM2X = 0x80; +static constexpr RegMask REG_0x08_MPENB = 0x20; +static constexpr RegMask REG_0x08_CIS_LINE = 0x10; +static constexpr RegMask REG_0x08_IR1ENB = 0x08; +static constexpr RegMask REG_0x08_IR2ENB = 0x04; +static constexpr RegMask REG_0x08_ENB24M = 0x01; + +static constexpr RegMask REG_0x09_MCNTSET = 0xc0; +static constexpr RegMask REG_0x09_EVEN1ST = 0x20; +static constexpr RegMask REG_0x09_BLINE1ST = 0x10; +static constexpr RegMask REG_0x09_BACKSCAN = 0x08; +static constexpr RegMask REG_0x09_ENHANCE = 0x04; +static constexpr RegMask REG_0x09_SHORTTG = 0x02; +static constexpr RegMask REG_0x09_NWAIT = 0x01; + +static constexpr RegShift REG_0x09S_MCNTSET = 6; +static constexpr RegShift REG_0x09S_CLKSET = 4; + + +static constexpr RegAddr REG_0x0A_LPWMEN = 0x10; + +static constexpr RegAddr REG_0x0B = 0x0b; +static constexpr RegMask REG_0x0B_DRAMSEL = 0x07; +static constexpr RegMask REG_0x0B_ENBDRAM = 0x08; +static constexpr RegMask REG_0x0B_RFHDIS = 0x10; +static constexpr RegMask REG_0x0B_CLKSET = 0xe0; +static constexpr RegMask REG_0x0B_24MHZ = 0x00; +static constexpr RegMask REG_0x0B_30MHZ = 0x20; +static constexpr RegMask REG_0x0B_40MHZ = 0x40; +static constexpr RegMask REG_0x0B_48MHZ = 0x60; +static constexpr RegMask REG_0x0B_60MHZ = 0x80; + +static constexpr RegAddr REG_0x0C = 0x0c; +static constexpr RegMask REG_0x0C_CCDLMT = 0x0f; + +static constexpr RegAddr REG_0x0D = 0x0d; +static constexpr RegMask REG_0x0D_SCSYNC = 0x40; +static constexpr RegMask REG_0x0D_CLRERR = 0x20; +static constexpr RegMask REG_0x0D_FULLSTP = 0x10; +static constexpr RegMask REG_0x0D_SEND = 0x80; +static constexpr RegMask REG_0x0D_CLRMCNT = 0x04; +static constexpr RegMask REG_0x0D_CLRDOCJM = 0x02; +static constexpr RegMask REG_0x0D_CLRLNCNT = 0x01; + +static constexpr RegAddr REG_0x0F = 0x0f; + +static constexpr RegMask REG_0x16_CTRLHI = 0x80; +static constexpr RegMask REG_0x16_TOSHIBA = 0x40; +static constexpr RegMask REG_0x16_TGINV = 0x20; +static constexpr RegMask REG_0x16_CK1INV = 0x10; +static constexpr RegMask REG_0x16_CK2INV = 0x08; +static constexpr RegMask REG_0x16_CTRLINV = 0x04; +static constexpr RegMask REG_0x16_CKDIS = 0x02; +static constexpr RegMask REG_0x16_CTRLDIS = 0x01; + +static constexpr RegMask REG_0x17_TGMODE = 0xc0; +static constexpr RegMask REG_0x17_TGMODE_NO_DUMMY = 0x00; +static constexpr RegMask REG_0x17_TGMODE_REF = 0x40; +static constexpr RegMask REG_0x17_TGMODE_XPA = 0x80; +static constexpr RegMask REG_0x17_TGW = 0x3f; +static constexpr RegAddr REG_0x17S_TGW = 0; + +static constexpr RegAddr REG_0x18 = 0x18; +static constexpr RegMask REG_0x18_CNSET = 0x80; +static constexpr RegMask REG_0x18_DCKSEL = 0x60; +static constexpr RegMask REG_0x18_CKTOGGLE = 0x10; +static constexpr RegMask REG_0x18_CKDELAY = 0x0c; +static constexpr RegMask REG_0x18_CKSEL = 0x03; + +static constexpr RegMask REG_0x1A_SW2SET = 0x80; +static constexpr RegMask REG_0x1A_SW1SET = 0x40; +static constexpr RegMask REG_0x1A_MANUAL3 = 0x02; +static constexpr RegMask REG_0x1A_MANUAL1 = 0x01; +static constexpr RegMask REG_0x1A_CK4INV = 0x08; +static constexpr RegMask REG_0x1A_CK3INV = 0x04; +static constexpr RegMask REG_0x1A_LINECLP = 0x02; + +static constexpr RegAddr REG_0x1C = 0x1c; +static constexpr RegMask REG_0x1C_TGTIME = 0x07; + +static constexpr RegMask REG_0x1D_CK4LOW = 0x80; +static constexpr RegMask REG_0x1D_CK3LOW = 0x40; +static constexpr RegMask REG_0x1D_CK1LOW = 0x20; +static constexpr RegMask REG_0x1D_TGSHLD = 0x1f; +static constexpr RegShift REG_0x1DS_TGSHLD = 0; + + +static constexpr RegMask REG_0x1E_WDTIME = 0xf0; +static constexpr RegShift REG_0x1ES_WDTIME = 4; +static constexpr RegMask REG_0x1E_LINESEL = 0x0f; +static constexpr RegShift REG_0x1ES_LINESEL = 0; + +static constexpr RegAddr REG_FEDCNT = 0x1f; + +static constexpr RegAddr REG_0x24 = 0x1c; +static constexpr RegAddr REG_0x40 = 0x40; +static constexpr RegMask REG_0x40_DOCSNR = 0x80; +static constexpr RegMask REG_0x40_ADFSNR = 0x40; +static constexpr RegMask REG_0x40_COVERSNR = 0x20; +static constexpr RegMask REG_0x40_CHKVER = 0x10; +static constexpr RegMask REG_0x40_DOCJAM = 0x08; +static constexpr RegMask REG_0x40_HISPDFLG = 0x04; +static constexpr RegMask REG_0x40_MOTMFLG = 0x02; +static constexpr RegMask REG_0x40_DATAENB = 0x01; + +static constexpr RegMask REG_0x41_PWRBIT = 0x80; +static constexpr RegMask REG_0x41_BUFEMPTY = 0x40; +static constexpr RegMask REG_0x41_FEEDFSH = 0x20; +static constexpr RegMask REG_0x41_SCANFSH = 0x10; +static constexpr RegMask REG_0x41_HOMESNR = 0x08; +static constexpr RegMask REG_0x41_LAMPSTS = 0x04; +static constexpr RegMask REG_0x41_FEBUSY = 0x02; +static constexpr RegMask REG_0x41_MOTORENB = 0x01; + +static constexpr RegMask REG_0x58_VSMP = 0xf8; +static constexpr RegShift REG_0x58S_VSMP = 3; +static constexpr RegMask REG_0x58_VSMPW = 0x07; +static constexpr RegAddr REG_0x58S_VSMPW = 0; + +static constexpr RegMask REG_0x59_BSMP = 0xf8; +static constexpr RegAddr REG_0x59S_BSMP = 3; +static constexpr RegMask REG_0x59_BSMPW = 0x07; +static constexpr RegShift REG_0x59S_BSMPW = 0; + +static constexpr RegMask REG_0x5A_ADCLKINV = 0x80; +static constexpr RegMask REG_0x5A_RLCSEL = 0x40; +static constexpr RegMask REG_0x5A_CDSREF = 0x30; +static constexpr RegShift REG_0x5AS_CDSREF = 4; +static constexpr RegMask REG_0x5A_RLC = 0x0f; +static constexpr RegShift REG_0x5AS_RLC = 0; + +static constexpr RegMask REG_0x5E_DECSEL = 0xe0; +static constexpr RegShift REG_0x5ES_DECSEL = 5; +static constexpr RegMask REG_0x5E_STOPTIM = 0x1f; +static constexpr RegShift REG_0x5ES_STOPTIM = 0; + +static constexpr RegAddr REG_0x60 = 0x60; +static constexpr RegMask REG_0x60_Z1MOD = 0x1f; +static constexpr RegAddr REG_0x61 = 0x61; +static constexpr RegMask REG_0x61_Z1MOD = 0xff; +static constexpr RegAddr REG_0x62 = 0x62; +static constexpr RegMask REG_0x62_Z1MOD = 0xff; + +static constexpr RegAddr REG_0x63 = 0x63; +static constexpr RegMask REG_0x63_Z2MOD = 0x1f; +static constexpr RegAddr REG_0x64 = 0x64; +static constexpr RegMask REG_0x64_Z2MOD = 0xff; +static constexpr RegAddr REG_0x65 = 0x65; +static constexpr RegMask REG_0x65_Z2MOD = 0xff; + +static constexpr RegShift REG_0x60S_STEPSEL = 5; +static constexpr RegMask REG_0x60_STEPSEL = 0xe0; +static constexpr RegMask REG_0x60_FULLSTEP = 0x00; +static constexpr RegMask REG_0x60_HALFSTEP = 0x20; +static constexpr RegMask REG_0x60_EIGHTHSTEP = 0x60; +static constexpr RegMask REG_0x60_16THSTEP = 0x80; + +static constexpr RegShift REG_0x63S_FSTPSEL = 5; +static constexpr RegMask REG_0x63_FSTPSEL = 0xe0; +static constexpr RegMask REG_0x63_FULLSTEP = 0x00; +static constexpr RegMask REG_0x63_HALFSTEP = 0x20; +static constexpr RegMask REG_0x63_EIGHTHSTEP = 0x60; +static constexpr RegMask REG_0x63_16THSTEP = 0x80; + +static constexpr RegAddr REG_0x67 = 0x67; +static constexpr RegMask REG_0x67_MTRPWM = 0x80; + +static constexpr RegAddr REG_0x68 = 0x68; +static constexpr RegMask REG_0x68_FASTPWM = 0x80; + +static constexpr RegAddr REG_0x6B = 0x6b; +static constexpr RegMask REG_0x6B_MULTFILM = 0x80; +static constexpr RegMask REG_0x6B_GPOM13 = 0x40; +static constexpr RegMask REG_0x6B_GPOM12 = 0x20; +static constexpr RegMask REG_0x6B_GPOM11 = 0x10; +static constexpr RegMask REG_0x6B_GPO18 = 0x02; +static constexpr RegMask REG_0x6B_GPO17 = 0x01; + +static constexpr RegAddr REG_0x6C = 0x6c; +static constexpr RegMask REG_0x6C_GPIO16 = 0x80; +static constexpr RegMask REG_0x6C_GPIO15 = 0x40; +static constexpr RegMask REG_0x6C_GPIO14 = 0x20; +static constexpr RegMask REG_0x6C_GPIO13 = 0x10; +static constexpr RegMask REG_0x6C_GPIO12 = 0x08; +static constexpr RegMask REG_0x6C_GPIO11 = 0x04; +static constexpr RegMask REG_0x6C_GPIO10 = 0x02; +static constexpr RegMask REG_0x6C_GPIO9 = 0x01; +static constexpr RegMask REG_0x6C_GPIOH = 0xff; +static constexpr RegMask REG_0x6C_GPIOL = 0xff; + +static constexpr RegAddr REG_0x6D = 0x6d; +static constexpr RegAddr REG_0x6E = 0x6e; +static constexpr RegAddr REG_0x6F = 0x6f; +static constexpr RegAddr REG_0x7E = 0x7e; + +static constexpr RegMask REG_0x87_ACYCNRLC = 0x10; +static constexpr RegMask REG_0x87_ENOFFSET = 0x08; +static constexpr RegMask REG_0x87_LEDADD = 0x04; +static constexpr RegMask REG_0x87_CK4ADC = 0x02; +static constexpr RegMask REG_0x87_AUTOCONF = 0x01; + +static constexpr RegAddr REG_0x9E = 0x9e; +static constexpr RegAddr REG_0x9F = 0x9f; + +static constexpr RegAddr REG_0xA6 = 0xa6; +static constexpr RegAddr REG_0xA7 = 0xa7; +static constexpr RegAddr REG_0xA8 = 0xa8; +static constexpr RegAddr REG_0xA9 = 0xa9; +static constexpr RegAddr REG_0xAB = 0xab; + +static constexpr RegAddr REG_EXPR = 0x10; +static constexpr RegAddr REG_EXPG = 0x12; +static constexpr RegAddr REG_EXPB = 0x14; +static constexpr RegAddr REG_EXPDMY = 0x19; +static constexpr RegAddr REG_STEPNO = 0x21; +static constexpr RegAddr REG_FWDSTEP = 0x22; +static constexpr RegAddr REG_BWDSTEP = 0x23; +static constexpr RegAddr REG_FASTNO = 0x24; +static constexpr RegAddr REG_DPISET = 0x2c; +static constexpr RegAddr REG_STRPIXEL = 0x30; +static constexpr RegAddr REG_ENDPIXEL = 0x32; +static constexpr RegAddr REG_LINCNT = 0x25; +static constexpr RegAddr REG_MAXWD = 0x35; +static constexpr RegAddr REG_LPERIOD = 0x38; +static constexpr RegAddr REG_FEEDL = 0x3d; +static constexpr RegAddr REG_FMOVDEC = 0x5f; +static constexpr RegAddr REG_FSHDEC = 0x69; +static constexpr RegAddr REG_FMOVNO = 0x6a; +static constexpr RegAddr REG_CK1MAP = 0x74; +static constexpr RegAddr REG_CK3MAP = 0x77; +static constexpr RegAddr REG_CK4MAP = 0x7a; + +static constexpr RegAddr REG_0xF8 = 0xf8; +static constexpr RegMask REG_0xF8_MAXSEL = 0xf0; +static constexpr RegShift REG_0xF8_SMAXSEL = 4; +static constexpr RegMask REG_0xF8_MINSEL = 0x0f; + +} // namespace gl846 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL846_REGISTERS_H diff --git a/backend/genesys/gl847.cpp b/backend/genesys/gl847.cpp new file mode 100644 index 0000000..cb0b527 --- /dev/null +++ b/backend/genesys/gl847.cpp @@ -0,0 +1,2140 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> + + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "gl847.h" +#include "gl847_registers.h" +#include "test_settings.h" + +#include <vector> + +namespace genesys { +namespace gl847 { + +/** + * compute the step multiplier used + */ +static int +gl847_get_step_multiplier (Genesys_Register_Set * regs) +{ + GenesysRegister *r = sanei_genesys_get_address(regs, 0x9d); + int value = 1; + if (r != nullptr) + { + value = (r->value & 0x0f)>>1; + value = 1 << value; + } + DBG (DBG_io, "%s: step multiplier is %d\n", __func__, value); + return value; +} + +/** @brief sensor specific settings +*/ +static void gl847_setup_sensor(Genesys_Device * dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs) +{ + DBG_HELPER(dbg); + + for (const auto& reg : sensor.custom_regs) { + regs->set8(reg.address, reg.value); + } + + regs->set16(REG_EXPR, sensor.exposure.red); + regs->set16(REG_EXPG, sensor.exposure.green); + regs->set16(REG_EXPB, sensor.exposure.blue); + + dev->segment_order = sensor.segment_order; +} + + +/** @brief set all registers to default values . + * This function is called only once at the beginning and + * fills register startup values for registers reused across scans. + * Those that are rarely modified or not modified are written + * individually. + * @param dev device structure holding register set to initialize + */ +static void +gl847_init_registers (Genesys_Device * dev) +{ + DBG_HELPER(dbg); + int lide700=0; + uint8_t val; + + /* 700F class needs some different initial settings */ + if (dev->model->model_id == ModelId::CANON_LIDE_700F) { + lide700 = 1; + } + + dev->reg.clear(); + + dev->reg.init_reg(0x01, 0x82); + dev->reg.init_reg(0x02, 0x18); + dev->reg.init_reg(0x03, 0x50); + dev->reg.init_reg(0x04, 0x12); + dev->reg.init_reg(0x05, 0x80); + dev->reg.init_reg(0x06, 0x50); // FASTMODE + POWERBIT + dev->reg.init_reg(0x08, 0x10); + dev->reg.init_reg(0x09, 0x01); + dev->reg.init_reg(0x0a, 0x00); + dev->reg.init_reg(0x0b, 0x01); + dev->reg.init_reg(0x0c, 0x02); + + // LED exposures + dev->reg.init_reg(0x10, 0x00); + dev->reg.init_reg(0x11, 0x00); + dev->reg.init_reg(0x12, 0x00); + dev->reg.init_reg(0x13, 0x00); + dev->reg.init_reg(0x14, 0x00); + dev->reg.init_reg(0x15, 0x00); + + dev->reg.init_reg(0x16, 0x10); // SENSOR_DEF + dev->reg.init_reg(0x17, 0x08); // SENSOR_DEF + dev->reg.init_reg(0x18, 0x00); // SENSOR_DEF + + // EXPDMY + dev->reg.init_reg(0x19, 0x50); // SENSOR_DEF + + dev->reg.init_reg(0x1a, 0x34); // SENSOR_DEF + dev->reg.init_reg(0x1b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x1c, 0x02); // SENSOR_DEF + dev->reg.init_reg(0x1d, 0x04); // SENSOR_DEF + dev->reg.init_reg(0x1e, 0x10); + dev->reg.init_reg(0x1f, 0x04); + dev->reg.init_reg(0x20, 0x02); + dev->reg.init_reg(0x21, 0x10); + dev->reg.init_reg(0x22, 0x7f); + dev->reg.init_reg(0x23, 0x7f); + dev->reg.init_reg(0x24, 0x10); + dev->reg.init_reg(0x25, 0x00); + dev->reg.init_reg(0x26, 0x00); + dev->reg.init_reg(0x27, 0x00); + dev->reg.init_reg(0x2c, 0x09); + dev->reg.init_reg(0x2d, 0x60); + dev->reg.init_reg(0x2e, 0x80); + dev->reg.init_reg(0x2f, 0x80); + dev->reg.init_reg(0x30, 0x00); + dev->reg.init_reg(0x31, 0x10); + dev->reg.init_reg(0x32, 0x15); + dev->reg.init_reg(0x33, 0x0e); + dev->reg.init_reg(0x34, 0x40); + dev->reg.init_reg(0x35, 0x00); + dev->reg.init_reg(0x36, 0x2a); + dev->reg.init_reg(0x37, 0x30); + dev->reg.init_reg(0x38, 0x2a); + dev->reg.init_reg(0x39, 0xf8); + dev->reg.init_reg(0x3d, 0x00); + dev->reg.init_reg(0x3e, 0x00); + dev->reg.init_reg(0x3f, 0x00); + dev->reg.init_reg(0x52, 0x03); // SENSOR_DEF + dev->reg.init_reg(0x53, 0x07); // SENSOR_DEF + dev->reg.init_reg(0x54, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x55, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x56, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x57, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x58, 0x2a); // SENSOR_DEF + dev->reg.init_reg(0x59, 0xe1); // SENSOR_DEF + dev->reg.init_reg(0x5a, 0x55); // SENSOR_DEF + dev->reg.init_reg(0x5e, 0x41); + dev->reg.init_reg(0x5f, 0x40); + dev->reg.init_reg(0x60, 0x00); + dev->reg.init_reg(0x61, 0x21); + dev->reg.init_reg(0x62, 0x40); + dev->reg.init_reg(0x63, 0x00); + dev->reg.init_reg(0x64, 0x21); + dev->reg.init_reg(0x65, 0x40); + dev->reg.init_reg(0x67, 0x80); + dev->reg.init_reg(0x68, 0x80); + dev->reg.init_reg(0x69, 0x20); + dev->reg.init_reg(0x6a, 0x20); + + // CK1MAP + dev->reg.init_reg(0x74, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x75, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x76, 0x3c); // SENSOR_DEF + + // CK3MAP + dev->reg.init_reg(0x77, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x78, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x79, 0x9f); // SENSOR_DEF + + // CK4MAP + dev->reg.init_reg(0x7a, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x7b, 0x00); // SENSOR_DEF + dev->reg.init_reg(0x7c, 0x55); // SENSOR_DEF + + dev->reg.init_reg(0x7d, 0x00); + + // NOTE: autoconf is a non working option + dev->reg.init_reg(0x87, 0x02); + dev->reg.init_reg(0x9d, 0x06); + dev->reg.init_reg(0xa2, 0x0f); + dev->reg.init_reg(0xbd, 0x18); + dev->reg.init_reg(0xfe, 0x08); + + // gamma[0] and gamma[256] values + dev->reg.init_reg(0xbe, 0x00); + dev->reg.init_reg(0xc5, 0x00); + dev->reg.init_reg(0xc6, 0x00); + dev->reg.init_reg(0xc7, 0x00); + dev->reg.init_reg(0xc8, 0x00); + dev->reg.init_reg(0xc9, 0x00); + dev->reg.init_reg(0xca, 0x00); + + /* LiDE 700 fixups */ + if (lide700) { + dev->reg.init_reg(0x5f, 0x04); + dev->reg.init_reg(0x7d, 0x80); + + /* we write to these registers only once */ + val=0; + dev->interface->write_register(REG_0x7E, val); + dev->interface->write_register(REG_0x9E, val); + dev->interface->write_register(REG_0x9F, val); + dev->interface->write_register(REG_0xAB, val); + } + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + sanei_genesys_set_dpihw(dev->reg, sensor, sensor.optical_res); + + /* initalize calibration reg */ + dev->calib_reg = dev->reg; +} + +/**@brief send slope table for motor movement + * Send slope_table in machine byte order + * @param dev device to send slope table + * @param table_nr index of the slope table in ASIC memory + * Must be in the [0-4] range. + * @param slope_table pointer to 16 bit values array of the slope table + * @param steps number of elements in the slope table + */ +static void gl847_send_slope_table(Genesys_Device* dev, int table_nr, + const std::vector<uint16_t>& slope_table, + int steps) +{ + DBG_HELPER_ARGS(dbg, "table_nr = %d, steps = %d", table_nr, steps); + int i; + char msg[10000]; + + /* sanity check */ + if(table_nr<0 || table_nr>4) + { + throw SaneException("invalid table number %d", table_nr); + } + + std::vector<uint8_t> table(steps * 2); + for (i = 0; i < steps; i++) + { + table[i * 2] = slope_table[i] & 0xff; + table[i * 2 + 1] = slope_table[i] >> 8; + } + + if (DBG_LEVEL >= DBG_io) + { + std::sprintf(msg, "write slope %d (%d)=", table_nr, steps); + for (i = 0; i < steps; i++) + { + std::sprintf(msg + std::strlen(msg), "%d", slope_table[i]); + } + DBG (DBG_io, "%s: %s\n", __func__, msg); + } + + if (dev->interface->is_mock()) { + dev->interface->record_slope_table(table_nr, slope_table); + } + // slope table addresses are fixed + dev->interface->write_ahb(0x10000000 + 0x4000 * table_nr, steps * 2, table.data()); +} + +/** + * Set register values of Analog Device type frontend + * */ +static void gl847_set_ad_fe(Genesys_Device* dev, uint8_t set) +{ + DBG_HELPER(dbg); + int i; + + // wait for FE to be ready + auto status = scanner_read_status(*dev); + while (status.is_front_end_busy) { + dev->interface->sleep_ms(10); + status = scanner_read_status(*dev); + }; + + if (set == AFE_INIT) + { + DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, + static_cast<unsigned>(dev->model->adc_id)); + + dev->frontend = dev->frontend_initial; + } + + // reset DAC + dev->interface->write_fe_register(0x00, 0x80); + + // write them to analog frontend + dev->interface->write_fe_register(0x00, dev->frontend.regs.get_value(0x00)); + + dev->interface->write_fe_register(0x01, dev->frontend.regs.get_value(0x01)); + + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x02 + i, dev->frontend.get_gain(i)); + } + for (i = 0; i < 3; i++) { + dev->interface->write_fe_register(0x05 + i, dev->frontend.get_offset(i)); + } +} + +// Set values of analog frontend +void CommandSetGl847::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const +{ + DBG_HELPER_ARGS(dbg, "%s", set == AFE_INIT ? "init" : + set == AFE_SET ? "set" : + set == AFE_POWER_SAVE ? "powersave" : "huh?"); + + (void) sensor; + + uint8_t val = dev->interface->read_register(REG_0x04); + uint8_t frontend_type = val & REG_0x04_FESET; + + // route to AD devices + if (frontend_type == 0x02) { + gl847_set_ad_fe(dev, set); + return; + } + + throw SaneException("unsupported frontend type %d", frontend_type); +} + + +// @brief set up motor related register for scan +static void gl847_init_motor_regs_scan(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const Motor_Profile& motor_profile, + unsigned int scan_exposure_time, + unsigned scan_yres, + unsigned int scan_lines, + unsigned int scan_dummy, + unsigned int feed_steps, + MotorFlag flags) +{ + DBG_HELPER_ARGS(dbg, "scan_exposure_time=%d, can_yres=%d, step_type=%d, scan_lines=%d, " + "scan_dummy=%d, feed_steps=%d, flags=%x", + scan_exposure_time, scan_yres, static_cast<unsigned>(motor_profile.step_type), + scan_lines, scan_dummy, feed_steps, static_cast<unsigned>(flags)); + int use_fast_fed; + unsigned int fast_dpi; + unsigned int feedl, dist; + GenesysRegister *r; + uint32_t z1, z2; + unsigned int min_restep = 0x20; + uint8_t val; + unsigned int ccdlmt,tgtime; + + unsigned step_multiplier = gl847_get_step_multiplier (reg); + + use_fast_fed=0; + /* no fast fed since feed works well */ + if (dev->settings.yres==4444 && feed_steps > 100 && (!has_flag(flags, MotorFlag::FEED))) + { + use_fast_fed=1; + } + DBG(DBG_io, "%s: use_fast_fed=%d\n", __func__, use_fast_fed); + + reg->set24(REG_LINCNT, scan_lines); + DBG(DBG_io, "%s: lincnt=%d\n", __func__, scan_lines); + + /* compute register 02 value */ + r = sanei_genesys_get_address(reg, REG_0x02); + r->value = 0x00; + sanei_genesys_set_motor_power(*reg, true); + + if (use_fast_fed) { + r->value |= REG_0x02_FASTFED; + } else { + r->value &= ~REG_0x02_FASTFED; + } + + if (has_flag(flags, MotorFlag::AUTO_GO_HOME)) { + r->value |= REG_0x02_AGOHOME | REG_0x02_NOTHOME; + } + + if (has_flag(flags, MotorFlag::DISABLE_BUFFER_FULL_MOVE) + ||(scan_yres>=sensor.optical_res)) + { + r->value |= REG_0x02_ACDCDIS; + } + + if (has_flag(flags, MotorFlag::REVERSE)) { + r->value |= REG_0x02_MTRREV; + } else { + r->value &= ~REG_0x02_MTRREV; + } + + /* scan and backtracking slope table */ + auto scan_table = sanei_genesys_slope_table(dev->model->asic_type, scan_yres, + scan_exposure_time, dev->motor.base_ydpi, + step_multiplier, motor_profile); + gl847_send_slope_table(dev, SCAN_TABLE, scan_table.table, scan_table.steps_count); + gl847_send_slope_table(dev, BACKTRACK_TABLE, scan_table.table, scan_table.steps_count); + + /* fast table */ + fast_dpi=sanei_genesys_get_lowest_ydpi(dev); + StepType fast_step_type = motor_profile.step_type; + if (static_cast<unsigned>(motor_profile.step_type) >= static_cast<unsigned>(StepType::QUARTER)) { + fast_step_type = StepType::QUARTER; + } + + Motor_Profile fast_motor_profile = motor_profile; + fast_motor_profile.step_type = fast_step_type; + + auto fast_table = sanei_genesys_slope_table(dev->model->asic_type, fast_dpi, + scan_exposure_time, dev->motor.base_ydpi, + step_multiplier, fast_motor_profile); + + gl847_send_slope_table(dev, STOP_TABLE, fast_table.table, fast_table.steps_count); + gl847_send_slope_table(dev, FAST_TABLE, fast_table.table, fast_table.steps_count); + gl847_send_slope_table(dev, HOME_TABLE, fast_table.table, fast_table.steps_count); + + /* correct move distance by acceleration and deceleration amounts */ + feedl=feed_steps; + if (use_fast_fed) + { + feedl <<= static_cast<unsigned>(fast_step_type); + dist = (scan_table.steps_count + 2 * fast_table.steps_count); + /* TODO read and decode REG_0xAB */ + r = sanei_genesys_get_address (reg, 0x5e); + dist += (r->value & 31); + /* FEDCNT */ + r = sanei_genesys_get_address (reg, REG_FEDCNT); + dist += r->value; + } + else + { + feedl <<= static_cast<unsigned>(motor_profile.step_type); + dist = scan_table.steps_count; + if (has_flag(flags, MotorFlag::FEED)) { + dist *= 2; + } + } + DBG(DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); + + /* check for overflow */ + if (dist < feedl) { + feedl -= dist; + } else { + feedl = 0; + } + + reg->set24(REG_FEEDL, feedl); + DBG(DBG_io ,"%s: feedl=%d\n", __func__, feedl); + + r = sanei_genesys_get_address(reg, REG_0x0C); + ccdlmt = (r->value & REG_0x0C_CCDLMT) + 1; + + r = sanei_genesys_get_address(reg, REG_0x1C); + tgtime = 1<<(r->value & REG_0x1C_TGTIME); + + // hi res motor speed GPIO + uint8_t effective = dev->interface->read_register(REG_0x6C); + + // if quarter step, bipolar Vref2 + + if (motor_profile.step_type == StepType::QUARTER) { + val = effective & ~REG_0x6C_GPIO13; + } else if (static_cast<unsigned>(motor_profile.step_type) > static_cast<unsigned>(StepType::QUARTER)) { + val = effective | REG_0x6C_GPIO13; + } else { + val = effective; + } + dev->interface->write_register(REG_0x6C, val); + + // effective scan + effective = dev->interface->read_register(REG_0x6C); + val = effective | REG_0x6C_GPIO10; + dev->interface->write_register(REG_0x6C, val); + + min_restep = scan_table.steps_count / (2 * step_multiplier) - 1; + if (min_restep < 1) { + min_restep = 1; + } + r = sanei_genesys_get_address(reg, REG_FWDSTEP); + r->value = min_restep; + r = sanei_genesys_get_address(reg, REG_BWDSTEP); + r->value = min_restep; + + sanei_genesys_calculate_zmod(use_fast_fed, + scan_exposure_time*ccdlmt*tgtime, + scan_table.table, + scan_table.steps_count, + feedl, + min_restep * step_multiplier, + &z1, + &z2); + + DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); + reg->set24(REG_0x60, z1 | (static_cast<unsigned>(motor_profile.step_type) << (16+REG_0x60S_STEPSEL))); + + DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); + reg->set24(REG_0x63, z2 | (static_cast<unsigned>(motor_profile.step_type) << (16+REG_0x63S_FSTPSEL))); + + r = sanei_genesys_get_address (reg, 0x1e); + r->value &= 0xf0; /* 0 dummy lines */ + r->value |= scan_dummy; /* dummy lines */ + + r = sanei_genesys_get_address(reg, REG_0x67); + r->value = REG_0x67_MTRPWM; + + r = sanei_genesys_get_address(reg, REG_0x68); + r->value = REG_0x68_FASTPWM; + + reg->set8(REG_STEPNO, scan_table.steps_count / step_multiplier); + reg->set8(REG_FASTNO, scan_table.steps_count / step_multiplier); + reg->set8(REG_FSHDEC, scan_table.steps_count / step_multiplier); + reg->set8(REG_FMOVNO, fast_table.steps_count / step_multiplier); + reg->set8(REG_FMOVDEC, fast_table.steps_count / step_multiplier); +} + + +/** @brief set up registers related to sensor + * Set up the following registers + 0x01 + 0x03 + 0x10-0x015 R/G/B exposures + 0x19 EXPDMY + 0x2e BWHI + 0x2f BWLO + 0x04 + 0x87 + 0x05 + 0x2c,0x2d DPISET + 0x30,0x31 STRPIXEL + 0x32,0x33 ENDPIXEL + 0x35,0x36,0x37 MAXWD [25:2] (>>2) + 0x38,0x39 LPERIOD + 0x34 DUMMY + */ +static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, unsigned int exposure_time, + const ScanSession& session) +{ + DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time); + unsigned dpihw; + GenesysRegister *r; + + // resolution is divided according to ccd_pixels_per_system_pixel() + unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); + DBG(DBG_io2, "%s: ccd_pixels_per_system_pixel=%d\n", __func__, ccd_pixels_per_system_pixel); + + // to manage high resolution device while keeping good low resolution scanning speed, we make + // hardware dpi vary + dpihw = sensor.get_register_hwdpi(session.params.xres * ccd_pixels_per_system_pixel); + DBG(DBG_io2, "%s: dpihw=%d\n", __func__, dpihw); + + gl847_setup_sensor(dev, sensor, reg); + + dev->cmd_set->set_fe(dev, sensor, AFE_SET); + + /* enable shading */ + regs_set_optical_off(dev->model->asic_type, *reg); + r = sanei_genesys_get_address(reg, REG_0x01); + r->value |= REG_0x01_SHDAREA; + + if (has_flag(session.params.flags, ScanFlag::DISABLE_SHADING) || + (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) + { + r->value &= ~REG_0x01_DVDSET; + } + else + { + r->value |= REG_0x01_DVDSET; + } + + r = sanei_genesys_get_address (reg, REG_0x03); + r->value &= ~REG_0x03_AVEENB; + + sanei_genesys_set_lamp_power(dev, sensor, *reg, + !has_flag(session.params.flags, ScanFlag::DISABLE_LAMP)); + + /* BW threshold */ + r = sanei_genesys_get_address (reg, 0x2e); + r->value = dev->settings.threshold; + r = sanei_genesys_get_address (reg, 0x2f); + r->value = dev->settings.threshold; + + /* monochrome / color scan */ + r = sanei_genesys_get_address (reg, REG_0x04); + switch (session.params.depth) { + case 8: + r->value &= ~(REG_0x04_LINEART | REG_0x04_BITSET); + break; + case 16: + r->value &= ~REG_0x04_LINEART; + r->value |= REG_0x04_BITSET; + break; + } + + r->value &= ~(REG_0x04_FILTER | REG_0x04_AFEMOD); + if (session.params.channels == 1) + { + switch (session.params.color_filter) + { + + case ColorFilter::RED: + r->value |= 0x14; + break; + case ColorFilter::BLUE: + r->value |= 0x1c; + break; + case ColorFilter::GREEN: + r->value |= 0x18; + break; + default: + break; // should not happen + } + } else { + r->value |= 0x10; // mono + } + + sanei_genesys_set_dpihw(*reg, sensor, dpihw); + + if (should_enable_gamma(session, sensor)) { + reg->find_reg(REG_0x05).value |= REG_0x05_GMMENB; + } else { + reg->find_reg(REG_0x05).value &= ~REG_0x05_GMMENB; + } + + /* CIS scanners can do true gray by setting LEDADD */ + /* we set up LEDADD only when asked */ + if (dev->model->is_cis) { + r = sanei_genesys_get_address (reg, 0x87); + r->value &= ~REG_0x87_LEDADD; + if (session.enable_ledadd) { + r->value |= REG_0x87_LEDADD; + } + /* RGB weighting + r = sanei_genesys_get_address (reg, 0x01); + r->value &= ~REG_0x01_TRUEGRAY; + if (session.enable_ledadd) { + r->value |= REG_0x01_TRUEGRAY; + } + */ + } + + unsigned dpiset = session.params.xres * ccd_pixels_per_system_pixel; + reg->set16(REG_DPISET, dpiset); + DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); + + reg->set16(REG_STRPIXEL, session.pixel_startx); + reg->set16(REG_ENDPIXEL, session.pixel_endx); + + build_image_pipeline(dev, session); + + /* MAXWD is expressed in 4 words unit */ + // BUG: we shouldn't multiply by channels here + reg->set24(REG_MAXWD, (session.output_line_bytes_raw * session.params.channels >> 2)); + + reg->set16(REG_LPERIOD, exposure_time); + DBG(DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time); + + r = sanei_genesys_get_address (reg, 0x34); + r->value = sensor.dummy_pixel; +} + +void CommandSetGl847::init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const +{ + DBG_HELPER(dbg); + session.assert_computed(); + + int move; + int exposure_time; + + int slope_dpi = 0; + int dummy = 0; + + dummy = 3 - session.params.channels; + +/* slope_dpi */ +/* cis color scan is effectively a gray scan with 3 gray lines per color + line and a FILTER of 0 */ + if (dev->model->is_cis) { + slope_dpi = session.params.yres * session.params.channels; + } else { + slope_dpi = session.params.yres; + } + + slope_dpi = slope_dpi * (1 + dummy); + + exposure_time = sensor.exposure_lperiod; + const auto& motor_profile = sanei_genesys_get_motor_profile(*gl847_motor_profiles, + dev->model->motor_id, + exposure_time); + + DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); + DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, + static_cast<unsigned>(motor_profile.step_type)); + + /* we enable true gray for cis scanners only, and just when doing + * scan since color calibration is OK for this mode + */ + gl847_init_optical_regs_scan(dev, sensor, reg, exposure_time, session); + + move = session.params.starty; + DBG(DBG_info, "%s: move=%d steps\n", __func__, move); + + MotorFlag mflags = MotorFlag::NONE; + if (has_flag(session.params.flags, ScanFlag::DISABLE_BUFFER_FULL_MOVE)) { + mflags |= MotorFlag::DISABLE_BUFFER_FULL_MOVE; + } + if (has_flag(session.params.flags, ScanFlag::FEEDING)) { + mflags |= MotorFlag::FEED; + } + if (has_flag(session.params.flags, ScanFlag::REVERSE)) { + mflags |= MotorFlag::REVERSE; + } + + gl847_init_motor_regs_scan(dev, sensor, reg, motor_profile, exposure_time, slope_dpi, + dev->model->is_cis ? session.output_line_count * session.params.channels + : session.output_line_count, + dummy, move, mflags); + + dev->read_buffer.clear(); + dev->read_buffer.alloc(session.buffer_size_read); + + dev->read_active = true; + + dev->session = session; + + dev->total_bytes_read = 0; + dev->total_bytes_to_read = session.output_line_bytes_requested * session.params.lines; + + DBG(DBG_info, "%s: total bytes to send = %zu\n", __func__, dev->total_bytes_to_read); +} + +ScanSession CommandSetGl847::calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const +{ + int start; + + DBG(DBG_info, "%s ", __func__); + debug_dump(DBG_info, settings); + + /* start */ + start = static_cast<int>(dev->model->x_offset); + start = static_cast<int>(start + settings.tl_x); + start = static_cast<int>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = settings.xres; + session.params.yres = settings.yres; + session.params.startx = start; // not used + session.params.starty = 0; // not used + session.params.pixels = settings.pixels; + session.params.requested_pixels = settings.requested_pixels; + session.params.lines = settings.lines; + session.params.depth = settings.depth; + session.params.channels = settings.get_channels(); + session.params.scan_method = settings.scan_method; + session.params.scan_mode = settings.scan_mode; + session.params.color_filter = settings.color_filter; + session.params.flags = ScanFlag::NONE; + + compute_session(dev, session, sensor); + + return session; +} + +// for fast power saving methods only, like disabling certain amplifiers +void CommandSetGl847::save_power(Genesys_Device* dev, bool enable) const +{ + DBG_HELPER_ARGS(dbg, "enable = %d", enable); + (void) dev; +} + +void CommandSetGl847::set_powersaving(Genesys_Device* dev, int delay /* in minutes */) const +{ + (void) dev; + DBG_HELPER_ARGS(dbg, "delay = %d", delay); +} + +// Send the low-level scan command +void CommandSetGl847::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, bool start_motor) const +{ + DBG_HELPER(dbg); + (void) sensor; + uint8_t val; + GenesysRegister *r; + + // clear GPIO 10 + if (dev->model->gpio_id != GpioId::CANON_LIDE_700F) { + val = dev->interface->read_register(REG_0x6C); + val &= ~REG_0x6C_GPIO10; + dev->interface->write_register(REG_0x6C, val); + } + + val = REG_0x0D_CLRLNCNT; + dev->interface->write_register(REG_0x0D, val); + val = REG_0x0D_CLRMCNT; + dev->interface->write_register(REG_0x0D, val); + + val = dev->interface->read_register(REG_0x01); + val |= REG_0x01_SCAN; + dev->interface->write_register(REG_0x01, val); + r = sanei_genesys_get_address (reg, REG_0x01); + r->value = val; + + scanner_start_action(*dev, start_motor); + + dev->advance_head_pos_by_session(ScanHeadId::PRIMARY); +} + + +// Send the stop scan command +void CommandSetGl847::end_scan(Genesys_Device* dev, Genesys_Register_Set* reg, + bool check_stop) const +{ + (void) reg; + DBG_HELPER_ARGS(dbg, "check_stop = %d", check_stop); + + if (!dev->model->is_sheetfed) { + scanner_stop_action(*dev); + } +} + +/** Park head + * Moves the slider to the home (top) position slowly + * @param dev device to park + * @param wait_until_home true to make the function waiting for head + * to be home before returning, if fals returne immediately +*/ +void CommandSetGl847::move_back_home(Genesys_Device* dev, bool wait_until_home) const +{ + scanner_move_back_home(*dev, wait_until_home); +} + +// Automatically set top-left edge of the scan area by scanning a 200x200 pixels area at 600 dpi +// from very top of scanner +void CommandSetGl847::search_start_position(Genesys_Device* dev) const +{ + DBG_HELPER(dbg); + int size; + Genesys_Register_Set local_reg; + + int pixels = 600; + int dpi = 300; + + local_reg = dev->reg; + + /* sets for a 200 lines * 600 pixels */ + /* normal scan with no shading */ + + // FIXME: the current approach of doing search only for one resolution does not work on scanners + // whith employ different sensors with potentially different settings. + const auto& sensor = sanei_genesys_find_sensor(dev, dpi, 1, dev->model->default_method); + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; /*we should give a small offset here~60 steps */ + session.params.pixels = 600; + session.params.lines = dev->model->search_lines; + session.params.depth = 8; + session.params.channels = 1; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::GREEN; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + // send to scanner + dev->interface->write_registers(local_reg); + + size = pixels * dev->model->search_lines; + + std::vector<uint8_t> data(size); + + begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_start_position"); + end_scan(dev, &local_reg, true); + dev->reg = local_reg; + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl847_search_position.pnm", data.data(), 8, 1, pixels, + dev->model->search_lines); + } + + end_scan(dev, &local_reg, true); + + /* update regs to copy ASIC internal state */ + dev->reg = local_reg; + + // TODO: find out where sanei_genesys_search_reference_point stores information, + // and use that correctly + for (auto& sensor_update : + sanei_genesys_find_sensors_all_for_write(dev, dev->model->default_method)) + { + sanei_genesys_search_reference_point(dev, sensor_update, data.data(), 0, dpi, pixels, + dev->model->search_lines); + } +} + +// sets up register for coarse gain calibration +// todo: check it for scanners using it +void CommandSetGl847::init_regs_for_coarse_calibration(Genesys_Device* dev, + const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = sensor.optical_res / sensor.ccd_pixels_per_system_pixel(); + session.params.lines = 20; + session.params.depth = 16; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, + sensor.optical_res / sensor.ccd_pixels_per_system_pixel(), dev->settings.xres); + + dev->interface->write_registers(regs); +} + +// init registers for shading calibration +void CommandSetGl847::init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + + dev->calib_channels = 3; + + /* initial calibration reg values */ + regs = dev->reg; + + dev->calib_resolution = sensor.get_register_hwdpi(dev->settings.xres); + + const auto& calib_sensor = sanei_genesys_find_sensor(dev, dev->calib_resolution, + dev->calib_channels, + dev->settings.scan_method); + + dev->calib_total_bytes_to_read = 0; + dev->calib_lines = dev->model->shading_lines; + if (dev->calib_resolution == 4800) { + dev->calib_lines *= 2; + } + dev->calib_pixels = (calib_sensor.sensor_pixels * dev->calib_resolution) / + calib_sensor.optical_res; + + DBG(DBG_io, "%s: calib_lines = %zu\n", __func__, dev->calib_lines); + DBG(DBG_io, "%s: calib_pixels = %zu\n", __func__, dev->calib_pixels); + + ScanSession session; + session.params.xres = dev->calib_resolution; + session.params.yres = dev->motor.base_ydpi; + session.params.startx = 0; + session.params.starty = 20; + session.params.pixels = dev->calib_pixels; + session.params.lines = dev->calib_lines; + session.params.depth = 16; + session.params.channels = dev->calib_channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::DISABLE_BUFFER_FULL_MOVE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + dev->interface->write_registers(regs); + + /* we use GENESYS_FLAG_SHADING_REPARK */ + dev->set_head_pos_zero(ScanHeadId::PRIMARY); +} + +/** @brief set up registers for the actual scan + */ +void CommandSetGl847::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + DBG_HELPER(dbg); + float move; + int move_dpi; + float start; + + debug_dump(DBG_info, dev->settings); + + /* steps to move to reach scanning area: + - first we move to physical start of scanning + either by a fixed steps amount from the black strip + or by a fixed amount from parking position, + minus the steps done during shading calibration + - then we move by the needed offset whitin physical + scanning area + + assumption: steps are expressed at maximum motor resolution + + we need: + float y_offset; + float y_size; + float y_offset_calib; + mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */ + + /* if scanner uses GENESYS_FLAG_SEARCH_START y_offset is + relative from origin, else, it is from parking position */ + + move_dpi = dev->motor.base_ydpi; + + move = static_cast<float>(dev->model->y_offset); + move = static_cast<float>(move + dev->settings.tl_y); + move = static_cast<float>((move * move_dpi) / MM_PER_INCH); + move -= dev->head_pos(ScanHeadId::PRIMARY); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + /* fast move to scan area */ + /* we don't move fast the whole distance since it would involve + * computing acceleration/deceleration distance for scan + * resolution. So leave a remainder for it so scan makes the final + * move tuning */ + if (dev->settings.get_channels() * dev->settings.yres >= 600 && move > 700) { + scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move - 500), + Direction::FORWARD); + move=500; + } + + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + DBG(DBG_info, "%s: move=%f steps\n", __func__, move); + + /* start */ + start = static_cast<float>(dev->model->x_offset); + start = static_cast<float>(start + dev->settings.tl_x); + start = static_cast<float>((start * sensor.optical_res) / MM_PER_INCH); + + ScanSession session; + session.params.xres = dev->settings.xres; + session.params.yres = dev->settings.yres; + session.params.startx = static_cast<unsigned>(start); + session.params.starty = static_cast<unsigned>(move); + session.params.pixels = dev->settings.pixels; + session.params.requested_pixels = dev->settings.requested_pixels; + session.params.lines = dev->settings.lines; + session.params.depth = dev->settings.depth; + session.params.channels = dev->settings.get_channels(); + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = dev->settings.scan_mode; + session.params.color_filter = dev->settings.color_filter; + // backtracking isn't handled well, so don't enable it + session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, &dev->reg, session); +} + + +/** + * Send shading calibration data. The buffer is considered to always hold values + * for all the channels. + */ +void CommandSetGl847::send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + uint8_t* data, int size) const +{ + DBG_HELPER_ARGS(dbg, "writing %d bytes of shading data", size); + uint32_t addr, length, i, x, factor, pixels; + uint32_t dpiset, dpihw; + uint8_t val,*ptr,*src; + + /* shading data is plit in 3 (up to 5 with IR) areas + write(0x10014000,0x00000dd8) + URB 23429 bulk_out len 3544 wrote 0x33 0x10 0x.... + write(0x1003e000,0x00000dd8) + write(0x10068000,0x00000dd8) + */ + length = static_cast<std::uint32_t>(size / 3); + std::uint32_t strpixel = dev->session.pixel_startx; + std::uint32_t endpixel = dev->session.pixel_endx; + + /* compute deletion factor */ + dpiset = dev->reg.get16(REG_DPISET); + dpihw = sensor.get_register_hwdpi(dpiset); + factor=dpihw/dpiset; + DBG(DBG_io2, "%s: factor=%d\n", __func__, factor); + + pixels=endpixel-strpixel; + + /* since we're using SHDAREA, substract startx coordinate from shading */ + strpixel -= (sensor.ccd_start_xoffset * 600) / sensor.optical_res; + + /* turn pixel value into bytes 2x16 bits words */ + strpixel*=2*2; + pixels*=2*2; + + dev->interface->record_key_value("shading_offset", std::to_string(strpixel)); + dev->interface->record_key_value("shading_pixels", std::to_string(pixels)); + dev->interface->record_key_value("shading_length", std::to_string(length)); + dev->interface->record_key_value("shading_factor", std::to_string(factor)); + + std::vector<uint8_t> buffer(pixels, 0); + + DBG(DBG_io2, "%s: using chunks of %d (0x%04x) bytes\n", __func__, pixels, pixels); + + /* base addr of data has been written in reg D0-D4 in 4K word, so AHB address + * is 8192*reg value */ + + /* write actual color channel data */ + for(i=0;i<3;i++) + { + /* build up actual shading data by copying the part from the full width one + * to the one corresponding to SHDAREA */ + ptr = buffer.data(); + + /* iterate on both sensor segment */ + for(x=0;x<pixels;x+=4*factor) + { + /* coefficient source */ + src=(data+strpixel+i*length)+x; + + /* coefficient copy */ + ptr[0]=src[0]; + ptr[1]=src[1]; + ptr[2]=src[2]; + ptr[3]=src[3]; + + /* next shading coefficient */ + ptr+=4; + } + + val = dev->interface->read_register(0xd0+i); + addr = val * 8192 + 0x10000000; + dev->interface->write_ahb(addr, pixels, buffer.data()); + } +} + +/** @brief calibrates led exposure + * Calibrate exposure by scanning a white area until the used exposure gives + * data white enough. + * @param dev device to calibrate + */ +SensorExposure CommandSetGl847::led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + int num_pixels; + int total_size; + int used_res; + int i, j; + int val; + int channels; + int avg[3], top[3], bottom[3]; + int turn; + uint16_t exp[3]; + float move; + + move = static_cast<float>(dev->model->y_offset_calib_white); + move = static_cast<float>((move * (dev->motor.base_ydpi / 4)) / MM_PER_INCH); + if (move > 20) { + scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move), + Direction::FORWARD); + } + DBG(DBG_io, "%s: move=%f steps\n", __func__, move); + + /* offset calibration is always done in color mode */ + channels = 3; + used_res = sensor.get_register_hwdpi(dev->settings.xres); + const auto& calib_sensor = sanei_genesys_find_sensor(dev, used_res, channels, + dev->settings.scan_method); + num_pixels = (calib_sensor.sensor_pixels * used_res) / calib_sensor.optical_res; + + /* initial calibration reg values */ + regs = dev->reg; + + ScanSession session; + session.params.xres = used_res; + session.params.yres = used_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = num_pixels; + session.params.lines = 1; + session.params.depth = 16; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, calib_sensor); + + init_regs_for_scan_session(dev, calib_sensor, ®s, session); + + total_size = num_pixels * channels * (session.params.depth/8) * 1; + std::vector<uint8_t> line(total_size); + + // initial loop values and boundaries + exp[0] = calib_sensor.exposure.red; + exp[1] = calib_sensor.exposure.green; + exp[2] = calib_sensor.exposure.blue; + + bottom[0] = 28000; + bottom[1] = 28000; + bottom[2] = 28000; + + top[0] = 32000; + top[1] = 32000; + top[2] = 32000; + + turn = 0; + + /* no move during led calibration */ + bool acceptable = false; + sanei_genesys_set_motor_power(regs, false); + do + { + // set up exposure + regs.set16(REG_EXPR,exp[0]); + regs.set16(REG_EXPG,exp[1]); + regs.set16(REG_EXPB,exp[2]); + + // write registers and scan data + dev->interface->write_registers(regs); + + DBG(DBG_info, "%s: starting line reading\n", __func__); + begin_scan(dev, calib_sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("led_calibration"); + scanner_stop_action(*dev); + move_back_home(dev, true); + return calib_sensor.exposure; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + // stop scanning + scanner_stop_action(*dev); + + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl847_led_%02d.pnm", turn); + sanei_genesys_write_pnm_file(fn, line.data(), session.params.depth, + channels, num_pixels, 1); + } + + /* compute average */ + for (j = 0; j < channels; j++) + { + avg[j] = 0; + for (i = 0; i < num_pixels; i++) + { + if (dev->model->is_cis) + val = + line[i * 2 + j * 2 * num_pixels + 1] * 256 + + line[i * 2 + j * 2 * num_pixels]; + else + val = + line[i * 2 * channels + 2 * j + 1] * 256 + + line[i * 2 * channels + 2 * j]; + avg[j] += val; + } + + avg[j] /= num_pixels; + } + + DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); + + /* check if exposure gives average within the boundaries */ + acceptable = true; + for(i=0;i<3;i++) + { + if (avg[i] < bottom[i] || avg[i] > top[i]) { + auto target = (bottom[i] + top[i]) / 2; + exp[i] = (exp[i] * target) / avg[i]; + acceptable = false; + } + } + + turn++; + } + while (!acceptable && turn < 100); + + DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); + + // set these values as final ones for scan + dev->reg.set16(REG_EXPR, exp[0]); + dev->reg.set16(REG_EXPG, exp[1]); + dev->reg.set16(REG_EXPB, exp[2]); + + // go back home + if (move>20) { + move_back_home(dev, true); + } + + return { exp[0], exp[1], exp[2] }; +} + +/** + * set up GPIO/GPOE for idle state + */ +static void gl847_init_gpio(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + int idx=0; + + /* search GPIO profile */ + while(gpios[idx].gpio_id != GpioId::UNKNOWN && dev->model->gpio_id != gpios[idx].gpio_id) { + idx++; + } + if (gpios[idx].gpio_id == GpioId::UNKNOWN) { + throw SaneException("failed to find GPIO profile for sensor_id=%d", + static_cast<unsigned>(dev->model->sensor_id)); + } + + dev->interface->write_register(REG_0xA7, gpios[idx].ra7); + dev->interface->write_register(REG_0xA6, gpios[idx].ra6); + + dev->interface->write_register(REG_0x6E, gpios[idx].r6e); + dev->interface->write_register(REG_0x6C, 0x00); + + dev->interface->write_register(REG_0x6B, gpios[idx].r6b); + dev->interface->write_register(REG_0x6C, gpios[idx].r6c); + dev->interface->write_register(REG_0x6D, gpios[idx].r6d); + dev->interface->write_register(REG_0x6E, gpios[idx].r6e); + dev->interface->write_register(REG_0x6F, gpios[idx].r6f); + + dev->interface->write_register(REG_0xA8, gpios[idx].ra8); + dev->interface->write_register(REG_0xA9, gpios[idx].ra9); +} + +/** + * set memory layout by filling values in dedicated registers + */ +static void gl847_init_memory_layout(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + int idx = 0; + uint8_t val; + + /* point to per model memory layout */ + idx = 0; + if (dev->model->model_id == ModelId::CANON_LIDE_100) { + idx = 0; + } + if (dev->model->model_id == ModelId::CANON_LIDE_200) { + idx = 1; + } + if (dev->model->model_id == ModelId::CANON_5600F) { + idx = 2; + } + if (dev->model->model_id == ModelId::CANON_LIDE_700F) { + idx = 3; + } + + /* CLKSET nd DRAMSEL */ + val = layouts[idx].dramsel; + dev->interface->write_register(REG_0x0B, val); + dev->reg.find_reg(0x0b).value = val; + + /* prevent further writings by bulk write register */ + dev->reg.remove_reg(0x0b); + + /* setup base address for shading data. */ + /* values must be multiplied by 8192=0x4000 to give address on AHB */ + /* R-Channel shading bank0 address setting for CIS */ + dev->interface->write_register(0xd0, layouts[idx].rd0); + /* G-Channel shading bank0 address setting for CIS */ + dev->interface->write_register(0xd1, layouts[idx].rd1); + /* B-Channel shading bank0 address setting for CIS */ + dev->interface->write_register(0xd2, layouts[idx].rd2); + + /* setup base address for scanned data. */ + /* values must be multiplied by 1024*2=0x0800 to give address on AHB */ + /* R-Channel ODD image buffer 0x0124->0x92000 */ + /* size for each buffer is 0x16d*1k word */ + dev->interface->write_register(0xe0, layouts[idx].re0); + dev->interface->write_register(0xe1, layouts[idx].re1); + /* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/ + dev->interface->write_register(0xe2, layouts[idx].re2); + dev->interface->write_register(0xe3, layouts[idx].re3); + + /* R-Channel EVEN image buffer 0x0292 */ + dev->interface->write_register(0xe4, layouts[idx].re4); + dev->interface->write_register(0xe5, layouts[idx].re5); + /* R-Channel EVEN image buffer end-address 0x03ff*/ + dev->interface->write_register(0xe6, layouts[idx].re6); + dev->interface->write_register(0xe7, layouts[idx].re7); + + /* same for green, since CIS, same addresses */ + dev->interface->write_register(0xe8, layouts[idx].re0); + dev->interface->write_register(0xe9, layouts[idx].re1); + dev->interface->write_register(0xea, layouts[idx].re2); + dev->interface->write_register(0xeb, layouts[idx].re3); + dev->interface->write_register(0xec, layouts[idx].re4); + dev->interface->write_register(0xed, layouts[idx].re5); + dev->interface->write_register(0xee, layouts[idx].re6); + dev->interface->write_register(0xef, layouts[idx].re7); + +/* same for blue, since CIS, same addresses */ + dev->interface->write_register(0xf0, layouts[idx].re0); + dev->interface->write_register(0xf1, layouts[idx].re1); + dev->interface->write_register(0xf2, layouts[idx].re2); + dev->interface->write_register(0xf3, layouts[idx].re3); + dev->interface->write_register(0xf4, layouts[idx].re4); + dev->interface->write_register(0xf5, layouts[idx].re5); + dev->interface->write_register(0xf6, layouts[idx].re6); + dev->interface->write_register(0xf7, layouts[idx].re7); +} + +/* * + * initialize ASIC from power on condition + */ +void CommandSetGl847::asic_boot(Genesys_Device* dev, bool cold) const +{ + DBG_HELPER(dbg); + + // reset ASIC if cold boot + if (cold) { + dev->interface->write_register(0x0e, 0x01); + dev->interface->write_register(0x0e, 0x00); + } + + // test CHKVER + uint8_t val = dev->interface->read_register(REG_0x40); + if (val & REG_0x40_CHKVER) { + val = dev->interface->read_register(0x00); + DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); + } + + /* Set default values for registers */ + gl847_init_registers (dev); + + // Write initial registers + dev->interface->write_registers(dev->reg); + + /* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */ + val = dev->reg.find_reg(0x0b).value & REG_0x0B_DRAMSEL; + val = (val | REG_0x0B_ENBDRAM); + dev->interface->write_register(REG_0x0B, val); + dev->reg.find_reg(0x0b).value = val; + + /* CIS_LINE */ + dev->reg.init_reg(0x08, REG_0x08_CIS_LINE); + dev->interface->write_register(0x08, dev->reg.find_reg(0x08).value); + + // set up end access + dev->interface->write_0x8c(0x10, 0x0b); + dev->interface->write_0x8c(0x13, 0x0e); + + // setup gpio + gl847_init_gpio(dev); + + // setup internal memory layout + gl847_init_memory_layout (dev); + + dev->reg.init_reg(0xf8, 0x01); + dev->interface->write_register(0xf8, dev->reg.find_reg(0xf8).value); +} + +/** + * initialize backend and ASIC : registers, motor tables, and gamma tables + * then ensure scanner's head is at home + */ +void CommandSetGl847::init(Genesys_Device* dev) const +{ + DBG_INIT (); + DBG_HELPER(dbg); + + sanei_genesys_asic_init(dev, 0); +} + +void CommandSetGl847::update_hardware_sensors(Genesys_Scanner* s) const +{ + DBG_HELPER(dbg); + /* do what is needed to get a new set of events, but try to not lose + any of them. + */ + uint8_t val; + uint8_t scan, file, email, copy; + switch(s->dev->model->gpio_id) { + case GpioId::CANON_LIDE_700F: + scan=0x04; + file=0x02; + email=0x01; + copy=0x08; + break; + default: + scan=0x01; + file=0x02; + email=0x04; + copy=0x08; + } + val = s->dev->interface->read_register(REG_0x6D); + + s->buttons[BUTTON_SCAN_SW].write((val & scan) == 0); + s->buttons[BUTTON_FILE_SW].write((val & file) == 0); + s->buttons[BUTTON_EMAIL_SW].write((val & email) == 0); + s->buttons[BUTTON_COPY_SW].write((val & copy) == 0); +} + +void CommandSetGl847::update_home_sensor_gpio(Genesys_Device& dev) const +{ + DBG_HELPER(dbg); + + if (dev.model->gpio_id == GpioId::CANON_LIDE_700F) { + std::uint8_t val = dev.interface->read_register(REG_0x6C); + val &= ~REG_0x6C_GPIO10; + dev.interface->write_register(REG_0x6C, val); + } else { + std::uint8_t val = dev.interface->read_register(REG_0x6C); + val |= REG_0x6C_GPIO10; + dev.interface->write_register(REG_0x6C, val); + } +} + +/** @brief search for a full width black or white strip. + * This function searches for a black or white stripe across the scanning area. + * When searching backward, the searched area must completely be of the desired + * color since this area will be used for calibration which scans forward. + * @param dev scanner device + * @param forward true if searching forward, false if searching backward + * @param black true if searching for a black strip, false for a white strip + */ +void CommandSetGl847::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward, + bool black) const +{ + DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse"); + unsigned int pixels, lines, channels; + Genesys_Register_Set local_reg; + size_t size; + unsigned int pass, count, found, x, y; + char title[80]; + + set_fe(dev, sensor, AFE_SET); + scanner_stop_action(*dev); + + // set up for a gray scan at lowest dpi + const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method); + unsigned dpi = resolution_settings.get_min_resolution_x(); + channels = 1; + /* 10 MM */ + /* lines = (10 * dpi) / MM_PER_INCH; */ + /* shading calibation is done with dev->motor.base_ydpi */ + lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; + pixels = (sensor.sensor_pixels * dpi) / sensor.optical_res; + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + + local_reg = dev->reg; + + ScanSession session; + session.params.xres = dpi; + session.params.yres = dpi; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::GRAY; + session.params.color_filter = ColorFilter::RED; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA; + if (!forward) { + session.params.flags |= ScanFlag::REVERSE; + } + compute_session(dev, session, sensor); + + size = pixels * channels * lines * (session.params.depth / 8); + std::vector<uint8_t> data(size); + + init_regs_for_scan_session(dev, sensor, &local_reg, session); + + dev->interface->write_registers(local_reg); + + begin_scan(dev, sensor, &local_reg, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("search_strip"); + scanner_stop_action(*dev); + return; + } + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + scanner_stop_action(*dev); + + pass = 0; + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl847_search_strip_%s_%s%02d.pnm", + black ? "black" : "white", forward ? "fwd" : "bwd", pass); + sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, + channels, pixels, lines); + } + + /* loop until strip is found or maximum pass number done */ + found = 0; + while (pass < 20 && !found) + { + dev->interface->write_registers(local_reg); + + // now start scan + begin_scan(dev, sensor, &local_reg, true); + + wait_until_buffer_non_empty(dev); + + // now we're on target, we can read data + sanei_genesys_read_data_from_scanner(dev, data.data(), size); + + scanner_stop_action(*dev); + + if (DBG_LEVEL >= DBG_data) + { + std::sprintf(title, "gl847_search_strip_%s_%s%02d.pnm", + black ? "black" : "white", + forward ? "fwd" : "bwd", static_cast<int>(pass)); + sanei_genesys_write_pnm_file(title, data.data(), session.params.depth, + channels, pixels, lines); + } + + /* search data to find black strip */ + /* when searching forward, we only need one line of the searched color since we + * will scan forward. But when doing backward search, we need all the area of the + * same color */ + if (forward) + { + for (y = 0; y < lines && !found; y++) + { + count = 0; + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * pixels + x] > 90) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * pixels + x] < 60) + { + count++; + } + } + + /* at end of line, if count >= 3%, line is not fully of the desired color + * so we must go to next line of the buffer */ + /* count*100/pixels < 3 */ + if ((count * 100) / pixels < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, + pass, y); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + } + else /* since calibration scans are done forward, we need the whole area + to be of the required color when searching backward */ + { + count = 0; + for (y = 0; y < lines; y++) + { + /* count of white/black pixels depending on the color searched */ + for (x = 0; x < pixels; x++) + { + /* when searching for black, detect white pixels */ + if (black && data[y * pixels + x] > 90) + { + count++; + } + /* when searching for white, detect black pixels */ + if (!black && data[y * pixels + x] < 60) + { + count++; + } + } + } + + /* at end of area, if count >= 3%, area is not fully of the desired color + * so we must go to next buffer */ + if ((count * 100) / (pixels * lines) < 3) + { + found = 1; + DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); + } + else + { + DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, + (100 * count) / pixels); + } + } + pass++; + } + + if (found) + { + DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); + } + else + { + throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white"); + } +} + +/** + * average dark pixels of a 8 bits scan + */ +static int +dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, + unsigned int channels, unsigned int black) +{ + unsigned int i, j, k, average, count; + unsigned int avg[3]; + uint8_t val; + + /* computes average value on black margin */ + for (k = 0; k < channels; k++) + { + avg[k] = 0; + count = 0; + for (i = 0; i < lines; i++) + { + for (j = 0; j < black; j++) + { + val = data[i * channels * pixels + j + k]; + avg[k] += val; + count++; + } + } + if (count) + avg[k] /= count; + DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); + } + average = 0; + for (i = 0; i < channels; i++) + average += avg[i]; + average /= channels; + DBG(DBG_info, "%s: average = %d\n", __func__, average); + return average; +} + +void CommandSetGl847::offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const +{ + DBG_HELPER(dbg); + unsigned channels; + int pass = 0, avg, total_size; + int topavg, bottomavg, lines; + int top, bottom, black_pixels, pixels; + + // no gain nor offset for AKM AFE + uint8_t reg04 = dev->interface->read_register(REG_0x04); + if ((reg04 & REG_0x04_FESET) == 0x02) { + return; + } + + /* offset calibration is always done in color mode */ + channels = 3; + dev->calib_pixels = sensor.sensor_pixels; + lines=1; + pixels= (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res; + black_pixels = (sensor.black_pixels * sensor.optical_res) / sensor.optical_res; + DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = sensor.optical_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + init_regs_for_scan_session(dev, sensor, ®s, session); + + sanei_genesys_set_motor_power(regs, false); + + /* allocate memory for scans */ + total_size = pixels * channels * lines * (session.params.depth / 8); /* colors * bytes_per_color * scan lines */ + + std::vector<uint8_t> first_line(total_size); + std::vector<uint8_t> second_line(total_size); + + /* init gain */ + dev->frontend.set_gain(0, 0); + dev->frontend.set_gain(1, 0); + dev->frontend.set_gain(2, 0); + + /* scan with no move */ + bottom = 10; + dev->frontend.set_offset(0, bottom); + dev->frontend.set_offset(1, bottom); + dev->frontend.set_offset(2, bottom); + + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting first line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("offset_calibration"); + return; + } + + sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size); + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl847_offset%03d.pnm", bottom); + sanei_genesys_write_pnm_file(fn, first_line.data(), session.params.depth, + channels, pixels, lines); + } + + bottomavg = dark_average (first_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); + + /* now top value */ + top = 255; + dev->frontend.set_offset(0, top); + dev->frontend.set_offset(1, top); + dev->frontend.set_offset(2, top); + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + + topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); + + /* loop until acceptable level */ + while ((pass < 32) && (top - bottom > 1)) + { + pass++; + + /* settings for new scan */ + dev->frontend.set_offset(0, (top + bottom) / 2); + dev->frontend.set_offset(1, (top + bottom) / 2); + dev->frontend.set_offset(2, (top + bottom) / 2); + + // scan with no move + set_fe(dev, sensor, AFE_SET); + dev->interface->write_registers(regs); + DBG(DBG_info, "%s: starting second line reading\n", __func__); + begin_scan(dev, sensor, ®s, true); + sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) + { + char fn[30]; + std::snprintf(fn, 30, "gl847_offset%03d.pnm", dev->frontend.get_offset(1)); + sanei_genesys_write_pnm_file(fn, second_line.data(), session.params.depth, + channels, pixels, lines); + } + + avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); + DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); + + /* compute new boundaries */ + if (topavg == avg) + { + topavg = avg; + top = dev->frontend.get_offset(1); + } + else + { + bottomavg = avg; + bottom = dev->frontend.get_offset(1); + } + } + DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, + dev->frontend.get_offset(0), + dev->frontend.get_offset(1), + dev->frontend.get_offset(2)); +} + +void CommandSetGl847::coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const +{ + DBG_HELPER_ARGS(dbg, "dpi = %d", dpi); + int pixels; + int total_size; + int i, j, channels; + int max[3]; + float gain[3],coeff; + int val, code, lines; + + // no gain nor offset for AKM AFE + uint8_t reg04 = dev->interface->read_register(REG_0x04); + if ((reg04 & REG_0x04_FESET) == 0x02) { + return; + } + + /* coarse gain calibration is always done in color mode */ + channels = 3; + + /* follow CKSEL */ + if(dev->settings.xres<sensor.optical_res) + { + coeff = 0.9f; + } + else + { + coeff=1.0; + } + lines=10; + pixels = (sensor.sensor_pixels * sensor.optical_res) / sensor.optical_res; + + ScanSession session; + session.params.xres = sensor.optical_res; + session.params.yres = sensor.optical_res; + session.params.startx = 0; + session.params.starty = 0; + session.params.pixels = pixels; + session.params.lines = lines; + session.params.depth = 8; + session.params.channels = channels; + session.params.scan_method = dev->settings.scan_method; + session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; + session.params.color_filter = dev->settings.color_filter; + session.params.flags = ScanFlag::DISABLE_SHADING | + ScanFlag::DISABLE_GAMMA | + ScanFlag::SINGLE_LINE | + ScanFlag::IGNORE_LINE_DISTANCE; + compute_session(dev, session, sensor); + + try { + init_regs_for_scan_session(dev, sensor, ®s, session); + } catch (...) { + catch_all_exceptions(__func__, [&](){ sanei_genesys_set_motor_power(regs, false); }); + throw; + } + + sanei_genesys_set_motor_power(regs, false); + + dev->interface->write_registers(regs); + + total_size = pixels * channels * (16 / session.params.depth) * lines; + + std::vector<uint8_t> line(total_size); + + set_fe(dev, sensor, AFE_SET); + begin_scan(dev, sensor, ®s, true); + + if (is_testing_mode()) { + dev->interface->test_checkpoint("coarse_gain_calibration"); + scanner_stop_action(*dev); + move_back_home(dev, true); + return; + } + + sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); + + if (DBG_LEVEL >= DBG_data) { + sanei_genesys_write_pnm_file("gl847_gain.pnm", line.data(), session.params.depth, + channels, pixels, lines); + } + + /* average value on each channel */ + for (j = 0; j < channels; j++) + { + max[j] = 0; + for (i = pixels/4; i < (pixels*3/4); i++) + { + if (dev->model->is_cis) { + val = line[i + j * pixels]; + } else { + val = line[i * channels + j]; + } + + max[j] += val; + } + max[j] = max[j] / (pixels/2); + + gain[j] = (static_cast<float>(sensor.gain_white_ref) * coeff) / max[j]; + + /* turn logical gain value into gain code, checking for overflow */ + code = static_cast<int>(283 - 208 / gain[j]); + if (code > 255) + code = 255; + else if (code < 0) + code = 0; + dev->frontend.set_gain(j, code); + + DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], + dev->frontend.get_gain(j)); + } + + if (dev->model->is_cis) { + uint8_t gain0 = dev->frontend.get_gain(0); + if (gain0 > dev->frontend.get_gain(1)) { + gain0 = dev->frontend.get_gain(1); + } + if (gain0 > dev->frontend.get_gain(2)) { + gain0 = dev->frontend.get_gain(2); + } + dev->frontend.set_gain(0, gain0); + dev->frontend.set_gain(1, gain0); + dev->frontend.set_gain(2, gain0); + } + + if (channels == 1) { + dev->frontend.set_gain(0, dev->frontend.get_gain(1)); + dev->frontend.set_gain(2, dev->frontend.get_gain(1)); + } + + scanner_stop_action(*dev); + + move_back_home(dev, true); +} + +bool CommandSetGl847::needs_home_before_init_regs_for_scan(Genesys_Device* dev) const +{ + (void) dev; + return false; +} + +void CommandSetGl847::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const +{ + (void) dev; + (void) sensor; + (void) regs; + (void) channels; + (void) total_size; + throw SaneException("not implemented"); +} + +void CommandSetGl847::send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const +{ + sanei_genesys_send_gamma_table(dev, sensor); +} + +void CommandSetGl847::wait_for_motor_stop(Genesys_Device* dev) const +{ + (void) dev; +} + +void CommandSetGl847::load_document(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl847::detect_document_end(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl847::eject_document(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +void CommandSetGl847::move_to_ta(Genesys_Device* dev) const +{ + (void) dev; + throw SaneException("not implemented"); +} + +std::unique_ptr<CommandSet> create_gl847_cmd_set() +{ + return std::unique_ptr<CommandSet>(new CommandSetGl847{}); +} + +} // namespace gl847 +} // namespace genesys diff --git a/backend/genesys/gl847.h b/backend/genesys/gl847.h new file mode 100644 index 0000000..a51c293 --- /dev/null +++ b/backend/genesys/gl847.h @@ -0,0 +1,206 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL847_H +#define BACKEND_GENESYS_GL847_H + +#include "genesys.h" +#include "command_set.h" + +namespace genesys { +namespace gl847 { + +typedef struct +{ + GpioId gpio_id; + uint8_t r6b; + uint8_t r6c; + uint8_t r6d; + uint8_t r6e; + uint8_t r6f; + uint8_t ra6; + uint8_t ra7; + uint8_t ra8; + uint8_t ra9; +} Gpio_Profile; + +static Gpio_Profile gpios[]={ + { GpioId::CANON_LIDE_200, 0x02, 0xf9, 0x20, 0xff, 0x00, 0x04, 0x04, 0x00, 0x00}, + { GpioId::CANON_LIDE_700F, 0x06, 0xdb, 0xff, 0xff, 0x80, 0x15, 0x07, 0x20, 0x10}, + { GpioId::UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, +}; + +typedef struct +{ + uint8_t dramsel; + uint8_t rd0; + uint8_t rd1; + uint8_t rd2; + uint8_t re0; + uint8_t re1; + uint8_t re2; + uint8_t re3; + uint8_t re4; + uint8_t re5; + uint8_t re6; + uint8_t re7; +} Memory_layout; + +static Memory_layout layouts[]={ + /* LIDE 100 */ + { + 0x29, + 0x0a, 0x15, 0x20, + 0x00, 0xac, 0x02, 0x55, 0x02, 0x56, 0x03, 0xff + }, + /* LIDE 200 */ + { + 0x29, + 0x0a, 0x1f, 0x34, + 0x01, 0x24, 0x02, 0x91, 0x02, 0x92, 0x03, 0xff + }, + /* 5600F */ + { + 0x29, + 0x0a, 0x1f, 0x34, + 0x01, 0x24, 0x02, 0x91, 0x02, 0x92, 0x03, 0xff + }, + /* LIDE 700F */ + { + 0x2a, + 0x0a, 0x33, 0x5c, + 0x02, 0x14, 0x09, 0x09, 0x09, 0x0a, 0x0f, 0xff + } +}; + +class CommandSetGl847 : public CommandSet +{ +public: + ~CommandSetGl847() override = default; + + bool needs_home_before_init_regs_for_scan(Genesys_Device* dev) const override; + + void init(Genesys_Device* dev) const override; + + void init_regs_for_warmup(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, int* channels, + int* total_size) const override; + + void init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_shading(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void init_regs_for_scan(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void init_regs_for_scan_session(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* reg, + const ScanSession& session) const override; + + void set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const override; + void set_powersaving(Genesys_Device* dev, int delay) const override; + void save_power(Genesys_Device* dev, bool enable) const override; + + void begin_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set* regs, bool start_motor) const override; + + void end_scan(Genesys_Device* dev, Genesys_Register_Set* regs, bool check_stop) const override; + + void send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) const override; + + void search_start_position(Genesys_Device* dev) const override; + + void offset_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void coarse_gain_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, int dpi) const override; + + SensorExposure led_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs) const override; + + void wait_for_motor_stop(Genesys_Device* dev) const override; + + void move_back_home(Genesys_Device* dev, bool wait_until_home) const override; + + void update_hardware_sensors(struct Genesys_Scanner* s) const override; + + bool needs_update_home_sensor_gpio() const override { return true; } + + void update_home_sensor_gpio(Genesys_Device& dev) const override; + + void load_document(Genesys_Device* dev) const override; + + void detect_document_end(Genesys_Device* dev) const override; + + void eject_document(Genesys_Device* dev) const override; + + void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, + bool forward, bool black) const override; + + void move_to_ta(Genesys_Device* dev) const override; + + void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data, + int size) const override; + + ScanSession calculate_scan_session(const Genesys_Device* dev, + const Genesys_Sensor& sensor, + const Genesys_Settings& settings) const override; + + void asic_boot(Genesys_Device* dev, bool cold) const override; +}; + +enum SlopeTable +{ + SCAN_TABLE = 0, // table 1 at 0x4000 + BACKTRACK_TABLE = 1, // table 2 at 0x4800 + STOP_TABLE = 2, // table 3 at 0x5000 + FAST_TABLE = 3, // table 4 at 0x5800 + HOME_TABLE = 4, // table 5 at 0x6000 +}; + +} // namespace gl847 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL847_H diff --git a/backend/genesys/gl847_registers.h b/backend/genesys/gl847_registers.h new file mode 100644 index 0000000..0603a6a --- /dev/null +++ b/backend/genesys/gl847_registers.h @@ -0,0 +1,333 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_GL847_REGISTERS_H +#define BACKEND_GENESYS_GL847_REGISTERS_H + +#include <cstdint> + +namespace genesys { +namespace gl847 { + +using RegAddr = std::uint16_t; +using RegMask = std::uint8_t; +using RegShift = unsigned; + +static constexpr RegAddr REG_0x01 = 0x01; +static constexpr RegMask REG_0x01_CISSET = 0x80; +static constexpr RegMask REG_0x01_DOGENB = 0x40; +static constexpr RegMask REG_0x01_DVDSET = 0x20; +static constexpr RegMask REG_0x01_STAGGER = 0x10; +static constexpr RegMask REG_0x01_COMPENB = 0x08; +static constexpr RegMask REG_0x01_TRUEGRAY = 0x04; +static constexpr RegMask REG_0x01_SHDAREA = 0x02; +static constexpr RegMask REG_0x01_SCAN = 0x01; + +static constexpr RegAddr REG_0x02 = 0x02; +static constexpr RegMask REG_0x02_NOTHOME = 0x80; +static constexpr RegMask REG_0x02_ACDCDIS = 0x40; +static constexpr RegMask REG_0x02_AGOHOME = 0x20; +static constexpr RegMask REG_0x02_MTRPWR = 0x10; +static constexpr RegMask REG_0x02_FASTFED = 0x08; +static constexpr RegMask REG_0x02_MTRREV = 0x04; +static constexpr RegMask REG_0x02_HOMENEG = 0x02; +static constexpr RegMask REG_0x02_LONGCURV = 0x01; + +static constexpr RegAddr REG_0x03 = 0x03; +static constexpr RegMask REG_0x03_LAMPDOG = 0x80; +static constexpr RegMask REG_0x03_AVEENB = 0x40; +static constexpr RegMask REG_0x03_XPASEL = 0x20; +static constexpr RegMask REG_0x03_LAMPPWR = 0x10; +static constexpr RegMask REG_0x03_LAMPTIM = 0x0f; + +static constexpr RegAddr REG_0x04 = 0x04; +static constexpr RegMask REG_0x04_LINEART = 0x80; +static constexpr RegMask REG_0x04_BITSET = 0x40; +static constexpr RegMask REG_0x04_AFEMOD = 0x30; +static constexpr RegMask REG_0x04_FILTER = 0x0c; +static constexpr RegMask REG_0x04_FESET = 0x03; +static constexpr RegShift REG_0x04S_AFEMOD = 4; + +static constexpr RegAddr REG_0x05 = 0x05; +static constexpr RegMask REG_0x05_DPIHW = 0xc0; +static constexpr RegMask REG_0x05_DPIHW_600 = 0x00; +static constexpr RegMask REG_0x05_DPIHW_1200 = 0x40; +static constexpr RegMask REG_0x05_DPIHW_2400 = 0x80; +static constexpr RegMask REG_0x05_DPIHW_4800 = 0xc0; +static constexpr RegMask REG_0x05_MTLLAMP = 0x30; +static constexpr RegMask REG_0x05_GMMENB = 0x08; +static constexpr RegMask REG_0x05_MTLBASE = 0x03; + +static constexpr RegAddr REG_0x06 = 0x06; +static constexpr RegMask REG_0x06_SCANMOD = 0xe0; +static constexpr RegMask REG_0x06S_SCANMOD = 5; +static constexpr RegMask REG_0x06_PWRBIT = 0x10; +static constexpr RegMask REG_0x06_GAIN4 = 0x08; +static constexpr RegMask REG_0x06_OPTEST = 0x07; + +static constexpr RegMask REG_0x07_LAMPSIM = 0x80; + +static constexpr RegMask REG_0x08_DRAM2X = 0x80; +static constexpr RegMask REG_0x08_MPENB = 0x20; +static constexpr RegMask REG_0x08_CIS_LINE = 0x10; +static constexpr RegMask REG_0x08_IR1ENB = 0x08; +static constexpr RegMask REG_0x08_IR2ENB = 0x04; +static constexpr RegMask REG_0x08_ENB24M = 0x01; + +static constexpr RegMask REG_0x09_MCNTSET = 0xc0; +static constexpr RegMask REG_0x09_EVEN1ST = 0x20; +static constexpr RegMask REG_0x09_BLINE1ST = 0x10; +static constexpr RegMask REG_0x09_BACKSCAN = 0x08; +static constexpr RegMask REG_0x09_ENHANCE = 0x04; +static constexpr RegMask REG_0x09_SHORTTG = 0x02; +static constexpr RegMask REG_0x09_NWAIT = 0x01; + +static constexpr RegShift REG_0x09S_MCNTSET = 6; +static constexpr RegShift REG_0x09S_CLKSET = 4; + +static constexpr RegMask REG_0x0A_LPWMEN = 0x10; + +static constexpr RegAddr REG_0x0B = 0x0b; +static constexpr RegMask REG_0x0B_DRAMSEL = 0x07; +static constexpr RegMask REG_0x0B_ENBDRAM = 0x08; +static constexpr RegMask REG_0x0B_RFHDIS = 0x10; +static constexpr RegMask REG_0x0B_CLKSET = 0xe0; +static constexpr RegMask REG_0x0B_24MHZ = 0x00; +static constexpr RegMask REG_0x0B_30MHZ = 0x20; +static constexpr RegMask REG_0x0B_40MHZ = 0x40; +static constexpr RegMask REG_0x0B_48MHZ = 0x60; +static constexpr RegMask REG_0x0B_60MHZ = 0x80; + +static constexpr RegAddr REG_0x0C = 0x0c; +static constexpr RegMask REG_0x0C_CCDLMT = 0x0f; + +static constexpr RegAddr REG_0x0D = 0x0d; +static constexpr RegMask REG_0x0D_FULLSTP = 0x10; +static constexpr RegMask REG_0x0D_SEND = 0x80; +static constexpr RegMask REG_0x0D_CLRMCNT = 0x04; +static constexpr RegMask REG_0x0D_CLRDOCJM = 0x02; +static constexpr RegMask REG_0x0D_CLRLNCNT = 0x01; + +static constexpr RegAddr REG_0x0F = 0x0f; + +static constexpr RegMask REG_0x16_CTRLHI = 0x80; +static constexpr RegMask REG_0x16_TOSHIBA = 0x40; +static constexpr RegMask REG_0x16_TGINV = 0x20; +static constexpr RegMask REG_0x16_CK1INV = 0x10; +static constexpr RegMask REG_0x16_CK2INV = 0x08; +static constexpr RegMask REG_0x16_CTRLINV = 0x04; +static constexpr RegMask REG_0x16_CKDIS = 0x02; +static constexpr RegMask REG_0x16_CTRLDIS = 0x01; + +static constexpr RegMask REG_0x17_TGMODE = 0xc0; +static constexpr RegMask REG_0x17_TGMODE_NO_DUMMY = 0x00; +static constexpr RegMask REG_0x17_TGMODE_REF = 0x40; +static constexpr RegMask REG_0x17_TGMODE_XPA = 0x80; +static constexpr RegMask REG_0x17_TGW = 0x3f; +static constexpr RegMask REG_0x17S_TGW = 0; + +static constexpr RegAddr REG_0x18 = 0x18; +static constexpr RegMask REG_0x18_CNSET = 0x80; +static constexpr RegMask REG_0x18_DCKSEL = 0x60; +static constexpr RegMask REG_0x18_CKTOGGLE = 0x10; +static constexpr RegMask REG_0x18_CKDELAY = 0x0c; +static constexpr RegMask REG_0x18_CKSEL = 0x03; + +static constexpr RegMask REG_0x1A_SW2SET = 0x80; +static constexpr RegMask REG_0x1A_SW1SET = 0x40; +static constexpr RegMask REG_0x1A_MANUAL3 = 0x02; +static constexpr RegMask REG_0x1A_MANUAL1 = 0x01; +static constexpr RegMask REG_0x1A_CK4INV = 0x08; +static constexpr RegMask REG_0x1A_CK3INV = 0x04; +static constexpr RegMask REG_0x1A_LINECLP = 0x02; + +static constexpr RegAddr REG_0x1C = 0x1c; +static constexpr RegMask REG_0x1C_TGTIME = 0x07; + +static constexpr RegMask REG_0x1D_CK4LOW = 0x80; +static constexpr RegMask REG_0x1D_CK3LOW = 0x40; +static constexpr RegMask REG_0x1D_CK1LOW = 0x20; +static constexpr RegMask REG_0x1D_TGSHLD = 0x1f; +static constexpr RegMask REG_0x1DS_TGSHLD = 0; + +static constexpr RegMask REG_0x1E_WDTIME = 0xf0; +static constexpr RegMask REG_0x1ES_WDTIME = 4; +static constexpr RegMask REG_0x1E_LINESEL = 0x0f; +static constexpr RegMask REG_0x1ES_LINESEL = 0; + +static constexpr RegAddr REG_FEDCNT = 0x1f; + +static constexpr RegAddr REG_0x24 = 0x1c; +static constexpr RegAddr REG_0x40 = 0x40; +static constexpr RegMask REG_0x40_CHKVER = 0x10; +static constexpr RegMask REG_0x40_HISPDFLG = 0x04; +static constexpr RegMask REG_0x40_MOTMFLG = 0x02; +static constexpr RegMask REG_0x40_DATAENB = 0x01; + +static constexpr RegMask REG_0x41_PWRBIT = 0x80; +static constexpr RegMask REG_0x41_BUFEMPTY = 0x40; +static constexpr RegMask REG_0x41_FEEDFSH = 0x20; +static constexpr RegMask REG_0x41_SCANFSH = 0x10; +static constexpr RegMask REG_0x41_HOMESNR = 0x08; +static constexpr RegMask REG_0x41_LAMPSTS = 0x04; +static constexpr RegMask REG_0x41_FEBUSY = 0x02; +static constexpr RegMask REG_0x41_MOTORENB = 0x01; + +static constexpr RegMask REG_0x58_VSMP = 0xf8; +static constexpr RegShift REG_0x58S_VSMP = 3; +static constexpr RegMask REG_0x58_VSMPW = 0x07; +static constexpr RegShift REG_0x58S_VSMPW = 0; + +static constexpr RegMask REG_0x59_BSMP = 0xf8; +static constexpr RegShift REG_0x59S_BSMP = 3; +static constexpr RegMask REG_0x59_BSMPW = 0x07; +static constexpr RegShift REG_0x59S_BSMPW = 0; + +static constexpr RegMask REG_0x5A_ADCLKINV = 0x80; +static constexpr RegMask REG_0x5A_RLCSEL = 0x40; +static constexpr RegMask REG_0x5A_CDSREF = 0x30; +static constexpr RegShift REG_0x5AS_CDSREF = 4; +static constexpr RegMask REG_0x5A_RLC = 0x0f; +static constexpr RegShift REG_0x5AS_RLC = 0; + +static constexpr RegMask REG_0x5E_DECSEL = 0xe0; +static constexpr RegShift REG_0x5ES_DECSEL = 5; +static constexpr RegMask REG_0x5E_STOPTIM = 0x1f; +static constexpr RegShift REG_0x5ES_STOPTIM = 0; + +static constexpr RegAddr REG_0x60 = 0x60; +static constexpr RegMask REG_0x60_Z1MOD = 0x1f; +static constexpr RegAddr REG_0x61 = 0x61; +static constexpr RegMask REG_0x61_Z1MOD = 0xff; +static constexpr RegAddr REG_0x62 = 0x62; +static constexpr RegMask REG_0x62_Z1MOD = 0xff; + +static constexpr RegAddr REG_0x63 = 0x63; +static constexpr RegMask REG_0x63_Z2MOD = 0x1f; +static constexpr RegAddr REG_0x64 = 0x64; +static constexpr RegMask REG_0x64_Z2MOD = 0xff; +static constexpr RegAddr REG_0x65 = 0x65; +static constexpr RegMask REG_0x65_Z2MOD = 0xff; + +static constexpr RegShift REG_0x60S_STEPSEL = 5; +static constexpr RegMask REG_0x60_STEPSEL = 0xe0; +static constexpr RegMask REG_0x60_FULLSTEP = 0x00; +static constexpr RegMask REG_0x60_HALFSTEP = 0x20; +static constexpr RegMask REG_0x60_EIGHTHSTEP = 0x60; +static constexpr RegMask REG_0x60_16THSTEP = 0x80; + +static constexpr RegShift REG_0x63S_FSTPSEL = 5; +static constexpr RegMask REG_0x63_FSTPSEL = 0xe0; +static constexpr RegMask REG_0x63_FULLSTEP = 0x00; +static constexpr RegMask REG_0x63_HALFSTEP = 0x20; +static constexpr RegMask REG_0x63_EIGHTHSTEP = 0x60; +static constexpr RegMask REG_0x63_16THSTEP = 0x80; + +static constexpr RegAddr REG_0x67 = 0x67; +static constexpr RegMask REG_0x67_MTRPWM = 0x80; + +static constexpr RegAddr REG_0x68 = 0x68; +static constexpr RegMask REG_0x68_FASTPWM = 0x80; + +static constexpr RegAddr REG_0x6B = 0x6b; +static constexpr RegMask REG_0x6B_MULTFILM = 0x80; +static constexpr RegMask REG_0x6B_GPOM13 = 0x40; +static constexpr RegMask REG_0x6B_GPOM12 = 0x20; +static constexpr RegMask REG_0x6B_GPOM11 = 0x10; +static constexpr RegMask REG_0x6B_GPO18 = 0x02; +static constexpr RegMask REG_0x6B_GPO17 = 0x01; + +static constexpr RegShift REG_0x6C = 0x6c; +static constexpr RegMask REG_0x6C_GPIO16 = 0x80; +static constexpr RegMask REG_0x6C_GPIO15 = 0x40; +static constexpr RegMask REG_0x6C_GPIO14 = 0x20; +static constexpr RegMask REG_0x6C_GPIO13 = 0x10; +static constexpr RegMask REG_0x6C_GPIO12 = 0x08; +static constexpr RegMask REG_0x6C_GPIO11 = 0x04; +static constexpr RegMask REG_0x6C_GPIO10 = 0x02; +static constexpr RegMask REG_0x6C_GPIO9 = 0x01; +static constexpr RegMask REG_0x6C_GPIOH = 0xff; +static constexpr RegMask REG_0x6C_GPIOL = 0xff; + +static constexpr RegAddr REG_0x6D = 0x6d; +static constexpr RegAddr REG_0x6E = 0x6e; +static constexpr RegAddr REG_0x6F = 0x6f; +static constexpr RegAddr REG_0x7E = 0x7e; + +static constexpr RegMask REG_0x87_LEDADD = 0x04; + +static constexpr RegAddr REG_0x9E = 0x9e; +static constexpr RegAddr REG_0x9F = 0x9f; + +static constexpr RegAddr REG_0xA6 = 0xa6; +static constexpr RegAddr REG_0xA7 = 0xa7; +static constexpr RegAddr REG_0xA8 = 0xa8; +static constexpr RegAddr REG_0xA9 = 0xa9; +static constexpr RegAddr REG_0xAB = 0xab; + +static constexpr RegAddr REG_EXPR = 0x10; +static constexpr RegAddr REG_EXPG = 0x12; +static constexpr RegAddr REG_EXPB = 0x14; +static constexpr RegAddr REG_EXPDMY = 0x19; +static constexpr RegAddr REG_STEPNO = 0x21; +static constexpr RegAddr REG_FWDSTEP = 0x22; +static constexpr RegAddr REG_BWDSTEP = 0x23; +static constexpr RegAddr REG_FASTNO = 0x24; +static constexpr RegAddr REG_DPISET = 0x2c; +static constexpr RegAddr REG_STRPIXEL = 0x30; +static constexpr RegAddr REG_ENDPIXEL = 0x32; +static constexpr RegAddr REG_LINCNT = 0x25; +static constexpr RegAddr REG_MAXWD = 0x35; +static constexpr RegAddr REG_LPERIOD = 0x38; +static constexpr RegAddr REG_FEEDL = 0x3d; +static constexpr RegAddr REG_FMOVDEC = 0x5f; +static constexpr RegAddr REG_FSHDEC = 0x69; +static constexpr RegAddr REG_FMOVNO = 0x6a; +static constexpr RegAddr REG_CK1MAP = 0x74; +static constexpr RegAddr REG_CK3MAP = 0x77; +static constexpr RegAddr REG_CK4MAP = 0x7a; + +} // namespace gl847 +} // namespace genesys + +#endif // BACKEND_GENESYS_GL847_REGISTERS_H diff --git a/backend/genesys/image.cpp b/backend/genesys/image.cpp new file mode 100644 index 0000000..7d386c6 --- /dev/null +++ b/backend/genesys/image.cpp @@ -0,0 +1,204 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "image.h" + +#include <array> + +namespace genesys { + +Image::Image() = default; + +Image::Image(std::size_t width, std::size_t height, PixelFormat format) : + width_{width}, + height_{height}, + format_{format}, + row_bytes_{get_pixel_row_bytes(format_, width_)} +{ + data_.resize(get_row_bytes() * height); +} + +std::uint8_t* Image::get_row_ptr(std::size_t y) +{ + return data_.data() + row_bytes_ * y; +} + +const std::uint8_t* Image::get_row_ptr(std::size_t y) const +{ + return data_.data() + row_bytes_ * y; +} + +Pixel Image::get_pixel(std::size_t x, std::size_t y) const +{ + return get_pixel_from_row(get_row_ptr(y), x, format_); +} + +void Image::set_pixel(std::size_t x, std::size_t y, const Pixel& pixel) +{ + set_pixel_to_row(get_row_ptr(y), x, pixel, format_); +} + +RawPixel Image::get_raw_pixel(std::size_t x, std::size_t y) const +{ + return get_raw_pixel_from_row(get_row_ptr(y), x, format_); +} + +std::uint16_t Image::get_raw_channel(std::size_t x, std::size_t y, unsigned channel) const +{ + return get_raw_channel_from_row(get_row_ptr(y), x, channel, format_); +} + +void Image::set_raw_pixel(std::size_t x, std::size_t y, const RawPixel& pixel) +{ + set_raw_pixel_to_row(get_row_ptr(y), x, pixel, format_); +} + +void Image::resize(std::size_t width, std::size_t height, PixelFormat format) +{ + width_ = width; + height_ = height; + format_ = format; + row_bytes_ = get_pixel_row_bytes(format_, width_); + data_.resize(get_row_bytes() * height); +} + +template<PixelFormat SrcFormat, PixelFormat DstFormat> +void convert_pixel_row_impl2(const std::uint8_t* in_data, std::uint8_t* out_data, + std::size_t count) +{ + for (std::size_t i = 0; i < count; ++i) { + Pixel pixel = get_pixel_from_row(in_data, i, SrcFormat); + set_pixel_to_row(out_data, i, pixel, DstFormat); + } +} + +template<PixelFormat SrcFormat> +void convert_pixel_row_impl(const std::uint8_t* in_data, std::uint8_t* out_data, + PixelFormat out_format, std::size_t count) +{ + switch (out_format) { + case PixelFormat::I1: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::I1>(in_data, out_data, count); + return; + } + case PixelFormat::RGB111: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::RGB111>(in_data, out_data, count); + return; + } + case PixelFormat::I8: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::I8>(in_data, out_data, count); + return; + } + case PixelFormat::RGB888: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::RGB888>(in_data, out_data, count); + return; + } + case PixelFormat::BGR888: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::BGR888>(in_data, out_data, count); + return; + } + case PixelFormat::I16: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::I16>(in_data, out_data, count); + return; + } + case PixelFormat::RGB161616: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::RGB161616>(in_data, out_data, count); + return; + } + case PixelFormat::BGR161616: { + convert_pixel_row_impl2<SrcFormat, PixelFormat::BGR161616>(in_data, out_data, count); + return; + } + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(out_format)); + } +} +void convert_pixel_row_format(const std::uint8_t* in_data, PixelFormat in_format, + std::uint8_t* out_data, PixelFormat out_format, std::size_t count) +{ + if (in_format == out_format) { + std::memcpy(out_data, in_data, get_pixel_row_bytes(in_format, count)); + return; + } + + switch (in_format) { + case PixelFormat::I1: { + convert_pixel_row_impl<PixelFormat::I1>(in_data, out_data, out_format, count); + return; + } + case PixelFormat::RGB111: { + convert_pixel_row_impl<PixelFormat::RGB111>(in_data, out_data, out_format, count); + return; + } + case PixelFormat::I8: { + convert_pixel_row_impl<PixelFormat::I8>(in_data, out_data, out_format, count); + return; + } + case PixelFormat::RGB888: { + convert_pixel_row_impl<PixelFormat::RGB888>(in_data, out_data, out_format, count); + return; + } + case PixelFormat::BGR888: { + convert_pixel_row_impl<PixelFormat::BGR888>(in_data, out_data, out_format, count); + return; + } + case PixelFormat::I16: { + convert_pixel_row_impl<PixelFormat::I16>(in_data, out_data, out_format, count); + return; + } + case PixelFormat::RGB161616: { + convert_pixel_row_impl<PixelFormat::RGB161616>(in_data, out_data, out_format, count); + return; + } + case PixelFormat::BGR161616: { + convert_pixel_row_impl<PixelFormat::BGR161616>(in_data, out_data, out_format, count); + return; + } + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(in_format)); + } +} + +} // namespace genesys diff --git a/backend/genesys/image.h b/backend/genesys/image.h new file mode 100644 index 0000000..c96b1bb --- /dev/null +++ b/backend/genesys/image.h @@ -0,0 +1,87 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_IMAGE_H +#define BACKEND_GENESYS_IMAGE_H + +#include "image_pixel.h" +#include <vector> + +namespace genesys { + +class Image +{ +public: + Image(); + Image(std::size_t width, std::size_t height, PixelFormat format); + + std::size_t get_width() const { return width_; } + std::size_t get_height() const { return height_; } + PixelFormat get_format() const { return format_; } + std::size_t get_row_bytes() const { return row_bytes_; } + + std::uint8_t* get_row_ptr(std::size_t y); + const std::uint8_t* get_row_ptr(std::size_t y) const; + + Pixel get_pixel(std::size_t x, std::size_t y) const; + void set_pixel(std::size_t x, std::size_t y, const Pixel& pixel); + + RawPixel get_raw_pixel(std::size_t x, std::size_t y) const; + std::uint16_t get_raw_channel(std::size_t x, std::size_t y, unsigned channel) const; + void set_raw_pixel(std::size_t x, std::size_t y, const RawPixel& pixel); + + void resize(std::size_t width, std::size_t height, PixelFormat format); +private: + std::size_t width_ = 0; + std::size_t height_ = 0; + PixelFormat format_ = PixelFormat::UNKNOWN; + std::size_t row_bytes_ = 0; + std::vector<std::uint8_t> data_; +}; + +void convert_pixel_row_format(const std::uint8_t* in_data, PixelFormat in_format, + std::uint8_t* out_data, PixelFormat out_format, std::size_t count); + +} // namespace genesys + +#endif // ifndef BACKEND_GENESYS_IMAGE_H diff --git a/backend/genesys/image_buffer.cpp b/backend/genesys/image_buffer.cpp new file mode 100644 index 0000000..07c6987 --- /dev/null +++ b/backend/genesys/image_buffer.cpp @@ -0,0 +1,203 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "image_buffer.h" +#include "image.h" + +namespace genesys { + +ImageBuffer::ImageBuffer(std::size_t size, ProducerCallback producer) : + producer_{producer}, + size_{size}, + buffer_offset_{size} +{ + buffer_.resize(size_); +} + +bool ImageBuffer::get_data(std::size_t size, std::uint8_t* out_data) +{ + const std::uint8_t* out_data_end = out_data + size; + + auto copy_buffer = [&]() + { + std::size_t bytes_copy = std::min<std::size_t>(out_data_end - out_data, available()); + std::memcpy(out_data, buffer_.data() + buffer_offset_, bytes_copy); + out_data += bytes_copy; + buffer_offset_ += bytes_copy; + }; + + // first, read remaining data from buffer + if (available() > 0) { + copy_buffer(); + } + + if (out_data == out_data_end) { + return true; + } + + // now the buffer is empty and there's more data to be read + bool got_data = true; + do { + buffer_offset_ = 0; + got_data &= producer_(size_, buffer_.data()); + + copy_buffer(); + } while(out_data < out_data_end && got_data); + + return got_data; +} + +void FakeBufferModel::push_step(std::size_t buffer_size, std::size_t row_bytes) +{ + sizes_.push_back(buffer_size); + available_sizes_.push_back(0); + row_bytes_.push_back(row_bytes); +} + +std::size_t FakeBufferModel::available_space() const +{ + if (sizes_.empty()) + throw SaneException("Model has not been setup"); + return sizes_.front() - available_sizes_.front(); +} + +void FakeBufferModel::simulate_read(std::size_t size) +{ + if (sizes_.empty()) { + throw SaneException("Model has not been setup"); + } + if (available_space() < size) { + throw SaneException("Attempted to simulate read of too much memory"); + } + + available_sizes_.front() += size; + + for (unsigned i = 1; i < sizes_.size(); ++i) { + auto avail_src = available_sizes_[i - 1]; + auto avail_dst = sizes_[i] - available_sizes_[i]; + + auto avail = (std::min(avail_src, avail_dst) / row_bytes_[i]) * row_bytes_[i]; + available_sizes_[i - 1] -= avail; + available_sizes_[i] += avail; + } + available_sizes_.back() = 0; +} + +ImageBufferGenesysUsb::ImageBufferGenesysUsb(std::size_t total_size, + const FakeBufferModel& buffer_model, + ProducerCallback producer) : + remaining_size_{total_size}, + buffer_model_{buffer_model}, + producer_{producer} +{} + +bool ImageBufferGenesysUsb::get_data(std::size_t size, std::uint8_t* out_data) +{ + const std::uint8_t* out_data_end = out_data + size; + + auto copy_buffer = [&]() + { + std::size_t bytes_copy = std::min<std::size_t>(out_data_end - out_data, available()); + std::memcpy(out_data, buffer_.data() + buffer_offset_, bytes_copy); + out_data += bytes_copy; + buffer_offset_ += bytes_copy; + }; + + // first, read remaining data from buffer + if (available() > 0) { + copy_buffer(); + } + + if (out_data == out_data_end) { + return true; + } + + // now the buffer is empty and there's more data to be read + do { + if (remaining_size_ == 0) + return false; + + auto bytes_to_read = get_read_size(); + buffer_offset_ = 0; + buffer_end_ = bytes_to_read; + buffer_.resize(bytes_to_read); + + producer_(bytes_to_read, buffer_.data()); + + if (remaining_size_ < bytes_to_read) { + remaining_size_ = 0; + } else { + remaining_size_ -= bytes_to_read; + } + + copy_buffer(); + } while(out_data < out_data_end); + return true; +} + +std::size_t ImageBufferGenesysUsb::get_read_size() +{ + std::size_t size = buffer_model_.available_space(); + + // never read an odd number. exception: last read + // the chip internal counter does not count half words. + size &= ~1; + + // Some setups need the reads to be multiples of 256 bytes + size &= ~0xff; + + if (remaining_size_ < size) { + size = remaining_size_; + /*round up to a multiple of 256 bytes */ + size += (size & 0xff) ? 0x100 : 0x00; + size &= ~0xff; + } + + buffer_model_.simulate_read(size); + + return size; +} + +} // namespace genesys diff --git a/backend/genesys/image_buffer.h b/backend/genesys/image_buffer.h new file mode 100644 index 0000000..43c3eb7 --- /dev/null +++ b/backend/genesys/image_buffer.h @@ -0,0 +1,129 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_IMAGE_BUFFER_H +#define BACKEND_GENESYS_IMAGE_BUFFER_H + +#include "enums.h" +#include "row_buffer.h" +#include <algorithm> +#include <functional> + +namespace genesys { + +// This class allows reading from row-based source in smaller or larger chunks of data +class ImageBuffer +{ +public: + using ProducerCallback = std::function<bool(std::size_t size, std::uint8_t* out_data)>; + + ImageBuffer() {} + ImageBuffer(std::size_t size, ProducerCallback producer); + + std::size_t size() const { return size_; } + std::size_t available() const { return size_ - buffer_offset_; } + + bool get_data(std::size_t size, std::uint8_t* out_data); + +private: + ProducerCallback producer_; + std::size_t size_ = 0; + + std::size_t buffer_offset_ = 0; + std::vector<std::uint8_t> buffer_; +}; + +class FakeBufferModel +{ +public: + FakeBufferModel() {} + + void push_step(std::size_t buffer_size, std::size_t row_bytes); + + std::size_t available_space() const; + + void simulate_read(std::size_t size); + +private: + std::vector<std::size_t> sizes_; + std::vector<std::size_t> available_sizes_; + std::vector<std::size_t> row_bytes_; +}; + +// This class is similar to ImageBuffer, but preserves historical peculiarities of buffer handling +// in the backend to preserve exact behavior +class ImageBufferGenesysUsb +{ +public: + using ProducerCallback = std::function<void(std::size_t size, std::uint8_t* out_data)>; + + ImageBufferGenesysUsb() {} + ImageBufferGenesysUsb(std::size_t total_size, const FakeBufferModel& buffer_model, + ProducerCallback producer); + + std::size_t remaining_size() const { return remaining_size_; } + + void set_remaining_size(std::size_t bytes) { remaining_size_ = bytes; } + + std::size_t available() const { return buffer_end_ - buffer_offset_; } + + bool get_data(std::size_t size, std::uint8_t* out_data); + +private: + + std::size_t get_read_size(); + + std::size_t remaining_size_ = 0; + + std::size_t buffer_offset_ = 0; + std::size_t buffer_end_ = 0; + std::vector<std::uint8_t> buffer_; + + FakeBufferModel buffer_model_; + + ProducerCallback producer_; +}; + +} // namespace genesys + +#endif // BACKEND_GENESYS_IMAGE_BUFFER_H diff --git a/backend/genesys/image_pipeline.cpp b/backend/genesys/image_pipeline.cpp new file mode 100644 index 0000000..c01b7f4 --- /dev/null +++ b/backend/genesys/image_pipeline.cpp @@ -0,0 +1,839 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "image_pipeline.h" +#include "image.h" +#include "low.h" +#include <cmath> +#include <numeric> + +namespace genesys { + +ImagePipelineNode::~ImagePipelineNode() {} + +std::size_t ImagePipelineNodeBytesSource::consume_remaining_bytes(std::size_t bytes) +{ + if (bytes > remaining_bytes_) { + bytes = remaining_bytes_; + } + remaining_bytes_ -= bytes; + return bytes; +} + +bool ImagePipelineNodeCallableSource::get_next_row_data(std::uint8_t* out_data) +{ + bool got_data = producer_(get_row_bytes(), out_data); + if (!got_data) + eof_ = true; + return got_data; +} + +ImagePipelineNodeBufferedCallableSource::ImagePipelineNodeBufferedCallableSource( + std::size_t width, std::size_t height, PixelFormat format, std::size_t input_batch_size, + ProducerCallback producer) : + width_{width}, + height_{height}, + format_{format}, + buffer_{input_batch_size, producer} +{ + set_remaining_bytes(height_ * get_row_bytes()); +} + +bool ImagePipelineNodeBufferedCallableSource::get_next_row_data(std::uint8_t* out_data) +{ + if (curr_row_ >= get_height()) { + DBG(DBG_warn, "%s: reading out of bounds. Row %zu, height: %zu\n", __func__, + curr_row_, get_height()); + eof_ = true; + return false; + } + + bool got_data = true; + + auto row_bytes = get_row_bytes(); + auto bytes_to_ask = consume_remaining_bytes(row_bytes); + if (bytes_to_ask < row_bytes) { + got_data = false; + } + + got_data &= buffer_.get_data(bytes_to_ask, out_data); + curr_row_++; + if (!got_data) { + eof_ = true; + } + return got_data; +} + + +ImagePipelineNodeBufferedGenesysUsb::ImagePipelineNodeBufferedGenesysUsb( + std::size_t width, std::size_t height, PixelFormat format, std::size_t total_size, + const FakeBufferModel& buffer_model, ProducerCallback producer) : + width_{width}, + height_{height}, + format_{format}, + buffer_{total_size, buffer_model, producer} +{ + set_remaining_bytes(total_size); +} + +bool ImagePipelineNodeBufferedGenesysUsb::get_next_row_data(std::uint8_t* out_data) +{ + if (remaining_bytes() != buffer_.remaining_size() + buffer_.available()) { + buffer_.set_remaining_size(remaining_bytes() - buffer_.available()); + } + bool got_data = true; + + std::size_t row_bytes = get_row_bytes(); + std::size_t ask_bytes = consume_remaining_bytes(row_bytes); + if (ask_bytes < row_bytes) { + got_data = false; + } + got_data &= buffer_.get_data(ask_bytes, out_data); + if (!got_data) { + eof_ = true; + } + return got_data; +} + +ImagePipelineNodeArraySource::ImagePipelineNodeArraySource(std::size_t width, std::size_t height, + PixelFormat format, + std::vector<std::uint8_t> data) : + width_{width}, + height_{height}, + format_{format}, + data_{std::move(data)}, + next_row_{0} +{ + auto size = get_row_bytes() * height_; + if (data_.size() < size) { + throw SaneException("The given array is too small (%zu bytes). Need at least %zu", + data_.size(), size); + } + set_remaining_bytes(size); +} + +bool ImagePipelineNodeArraySource::get_next_row_data(std::uint8_t* out_data) +{ + if (next_row_ >= height_) { + eof_ = true; + return false; + } + + bool got_data = true; + + auto row_bytes = get_row_bytes(); + auto bytes_to_ask = consume_remaining_bytes(row_bytes); + if (bytes_to_ask < row_bytes) { + got_data = false; + } + + std::memcpy(out_data, data_.data() + get_row_bytes() * next_row_, bytes_to_ask); + next_row_++; + + if (!got_data) { + eof_ = true; + } + return got_data; +} + + +ImagePipelineNodeImageSource::ImagePipelineNodeImageSource(const Image& source) : + source_{source} +{} + +bool ImagePipelineNodeImageSource::get_next_row_data(std::uint8_t* out_data) +{ + if (next_row_ >= get_height()) { + return false; + } + std::memcpy(out_data, source_.get_row_ptr(next_row_), get_row_bytes()); + next_row_++; + return true; +} + +bool ImagePipelineNodeFormatConvert::get_next_row_data(std::uint8_t* out_data) +{ + auto src_format = source_.get_format(); + if (src_format == dst_format_) { + return source_.get_next_row_data(out_data); + } + + buffer_.clear(); + buffer_.resize(source_.get_row_bytes()); + bool got_data = source_.get_next_row_data(buffer_.data()); + + convert_pixel_row_format(buffer_.data(), src_format, out_data, dst_format_, get_width()); + return got_data; +} + +ImagePipelineNodeDesegment::ImagePipelineNodeDesegment(ImagePipelineNode& source, + std::size_t output_width, + const std::vector<unsigned>& segment_order, + std::size_t segment_pixels, + std::size_t interleaved_lines, + std::size_t pixels_per_chunk) : + source_(source), + output_width_{output_width}, + segment_order_{segment_order}, + segment_pixels_{segment_pixels}, + interleaved_lines_{interleaved_lines}, + pixels_per_chunk_{pixels_per_chunk}, + buffer_{source_.get_row_bytes()} +{ + DBG_HELPER_ARGS(dbg, "segment_count=%zu, segment_size=%zu, interleaved_lines=%zu, " + "pixels_per_shunk=%zu", segment_order.size(), segment_pixels, + interleaved_lines, pixels_per_chunk); + + if (source_.get_height() % interleaved_lines_ > 0) { + throw SaneException("Height is not a multiple of the number of lines to interelave %zu/%zu", + source_.get_height(), interleaved_lines_); + } +} + +ImagePipelineNodeDesegment::ImagePipelineNodeDesegment(ImagePipelineNode& source, + std::size_t output_width, + std::size_t segment_count, + std::size_t segment_pixels, + std::size_t interleaved_lines, + std::size_t pixels_per_chunk) : + source_(source), + output_width_{output_width}, + segment_pixels_{segment_pixels}, + interleaved_lines_{interleaved_lines}, + pixels_per_chunk_{pixels_per_chunk}, + buffer_{source_.get_row_bytes()} +{ + DBG_HELPER_ARGS(dbg, "segment_count=%zu, segment_size=%zu, interleaved_lines=%zu, " + "pixels_per_shunk=%zu", segment_count, segment_pixels, interleaved_lines, + pixels_per_chunk); + + segment_order_.resize(segment_count); + std::iota(segment_order_.begin(), segment_order_.end(), 0); +} + +bool ImagePipelineNodeDesegment::get_next_row_data(uint8_t* out_data) +{ + bool got_data = true; + + buffer_.clear(); + for (std::size_t i = 0; i < interleaved_lines_; ++i) { + buffer_.push_back(); + got_data &= source_.get_next_row_data(buffer_.get_row_ptr(i)); + } + if (!buffer_.is_linear()) { + throw SaneException("Buffer is not linear"); + } + + auto format = get_format(); + auto segment_count = segment_order_.size(); + + const std::uint8_t* in_data = buffer_.get_row_ptr(0); + + std::size_t groups_count = output_width_ / (segment_order_.size() * pixels_per_chunk_); + + for (std::size_t igroup = 0; igroup < groups_count; ++igroup) { + for (std::size_t isegment = 0; isegment < segment_count; ++isegment) { + auto input_offset = igroup * pixels_per_chunk_; + input_offset += segment_pixels_ * segment_order_[isegment]; + auto output_offset = (igroup * segment_count + isegment) * pixels_per_chunk_; + + for (std::size_t ipixel = 0; ipixel < pixels_per_chunk_; ++ipixel) { + auto pixel = get_raw_pixel_from_row(in_data, input_offset + ipixel, format); + set_raw_pixel_to_row(out_data, output_offset + ipixel, pixel, format); + } + } + } + return got_data; +} + +ImagePipelineNodeDeinterleaveLines::ImagePipelineNodeDeinterleaveLines( + ImagePipelineNode& source, std::size_t interleaved_lines, std::size_t pixels_per_chunk) : + ImagePipelineNodeDesegment(source, source.get_width() * interleaved_lines, + interleaved_lines, source.get_width(), + interleaved_lines, pixels_per_chunk) +{} + +ImagePipelineNodeSwap16BitEndian::ImagePipelineNodeSwap16BitEndian(ImagePipelineNode& source) : + source_(source), + needs_swapping_{false} +{ + if (get_pixel_format_depth(source_.get_format()) == 16) { + needs_swapping_ = true; + } else { + DBG(DBG_info, "%s: this pipeline node does nothing for non 16-bit formats", __func__); + } +} + +bool ImagePipelineNodeSwap16BitEndian::get_next_row_data(std::uint8_t* out_data) +{ + bool got_data = source_.get_next_row_data(out_data); + if (needs_swapping_) { + std::size_t pixels = get_row_bytes() / 2; + for (std::size_t i = 0; i < pixels; ++i) { + std::swap(*out_data, *(out_data + 1)); + out_data += 2; + } + } + return got_data; +} + +ImagePipelineNodeMergeMonoLines::ImagePipelineNodeMergeMonoLines(ImagePipelineNode& source, + ColorOrder color_order) : + source_(source), + buffer_(source_.get_row_bytes()) +{ + DBG_HELPER_ARGS(dbg, "color_order %d", static_cast<unsigned>(color_order)); + + output_format_ = get_output_format(source_.get_format(), color_order); +} + +bool ImagePipelineNodeMergeMonoLines::get_next_row_data(std::uint8_t* out_data) +{ + bool got_data = true; + + buffer_.clear(); + for (unsigned i = 0; i < 3; ++i) { + buffer_.push_back(); + got_data &= source_.get_next_row_data(buffer_.get_row_ptr(i)); + } + + const auto* row0 = buffer_.get_row_ptr(0); + const auto* row1 = buffer_.get_row_ptr(1); + const auto* row2 = buffer_.get_row_ptr(2); + + auto format = source_.get_format(); + + for (std::size_t x = 0, width = get_width(); x < width; ++x) { + std::uint16_t ch0 = get_raw_channel_from_row(row0, x, 0, format); + std::uint16_t ch1 = get_raw_channel_from_row(row1, x, 0, format); + std::uint16_t ch2 = get_raw_channel_from_row(row2, x, 0, format); + set_raw_channel_to_row(out_data, x, 0, ch0, output_format_); + set_raw_channel_to_row(out_data, x, 1, ch1, output_format_); + set_raw_channel_to_row(out_data, x, 2, ch2, output_format_); + } + return got_data; +} + +PixelFormat ImagePipelineNodeMergeMonoLines::get_output_format(PixelFormat input_format, + ColorOrder order) +{ + switch (input_format) { + case PixelFormat::I1: { + if (order == ColorOrder::RGB) { + return PixelFormat::RGB111; + } + break; + } + case PixelFormat::I8: { + if (order == ColorOrder::RGB) { + return PixelFormat::RGB888; + } + if (order == ColorOrder::BGR) { + return PixelFormat::BGR888; + } + break; + } + case PixelFormat::I16: { + if (order == ColorOrder::RGB) { + return PixelFormat::RGB161616; + } + if (order == ColorOrder::BGR) { + return PixelFormat::BGR161616; + } + break; + } + default: break; + } + throw SaneException("Unsupported format combidation %d %d", + static_cast<unsigned>(input_format), + static_cast<unsigned>(order)); +} + +ImagePipelineNodeSplitMonoLines::ImagePipelineNodeSplitMonoLines(ImagePipelineNode& source) : + source_(source), + next_channel_{0} +{ + output_format_ = get_output_format(source_.get_format()); +} + +bool ImagePipelineNodeSplitMonoLines::get_next_row_data(std::uint8_t* out_data) +{ + bool got_data = true; + + if (next_channel_ == 0) { + buffer_.resize(source_.get_row_bytes()); + got_data &= source_.get_next_row_data(buffer_.data()); + } + + const auto* row = buffer_.data(); + auto format = source_.get_format(); + + for (std::size_t x = 0, width = get_width(); x < width; ++x) { + std::uint16_t ch = get_raw_channel_from_row(row, x, next_channel_, format); + set_raw_channel_to_row(out_data, x, 0, ch, output_format_); + } + next_channel_ = (next_channel_ + 1) % 3; + + return got_data; +} + +PixelFormat ImagePipelineNodeSplitMonoLines::get_output_format(PixelFormat input_format) +{ + switch (input_format) { + case PixelFormat::RGB111: return PixelFormat::I1; + case PixelFormat::RGB888: + case PixelFormat::BGR888: return PixelFormat::I8; + case PixelFormat::RGB161616: + case PixelFormat::BGR161616: return PixelFormat::I16; + default: break; + } + throw SaneException("Unsupported input format %d", static_cast<unsigned>(input_format)); +} + +ImagePipelineNodeComponentShiftLines::ImagePipelineNodeComponentShiftLines( + ImagePipelineNode& source, unsigned shift_r, unsigned shift_g, unsigned shift_b) : + source_(source), + buffer_{source.get_row_bytes()} +{ + DBG_HELPER_ARGS(dbg, "shifts={%d, %d, %d}", shift_r, shift_g, shift_b); + + switch (source.get_format()) { + case PixelFormat::RGB111: + case PixelFormat::RGB888: + case PixelFormat::RGB161616: { + channel_shifts_ = { shift_r, shift_g, shift_b }; + break; + } + case PixelFormat::BGR888: + case PixelFormat::BGR161616: { + channel_shifts_ = { shift_b, shift_g, shift_r }; + break; + } + default: + throw SaneException("Unsupported input format %d", + static_cast<unsigned>(source.get_format())); + } + extra_height_ = *std::max_element(channel_shifts_.begin(), channel_shifts_.end()); +} + +bool ImagePipelineNodeComponentShiftLines::get_next_row_data(std::uint8_t* out_data) +{ + bool got_data = true; + + if (!buffer_.empty()) { + buffer_.pop_front(); + } + while (buffer_.height() < extra_height_ + 1) { + buffer_.push_back(); + got_data &= source_.get_next_row_data(buffer_.get_back_row_ptr()); + } + + auto format = get_format(); + const auto* row0 = buffer_.get_row_ptr(channel_shifts_[0]); + const auto* row1 = buffer_.get_row_ptr(channel_shifts_[1]); + const auto* row2 = buffer_.get_row_ptr(channel_shifts_[2]); + + for (std::size_t x = 0, width = get_width(); x < width; ++x) { + std::uint16_t ch0 = get_raw_channel_from_row(row0, x, 0, format); + std::uint16_t ch1 = get_raw_channel_from_row(row1, x, 1, format); + std::uint16_t ch2 = get_raw_channel_from_row(row2, x, 2, format); + set_raw_channel_to_row(out_data, x, 0, ch0, format); + set_raw_channel_to_row(out_data, x, 1, ch1, format); + set_raw_channel_to_row(out_data, x, 2, ch2, format); + } + return got_data; +} + +ImagePipelineNodePixelShiftLines::ImagePipelineNodePixelShiftLines( + ImagePipelineNode& source, const std::vector<std::size_t>& shifts) : + source_(source), + pixel_shifts_{shifts}, + buffer_{get_row_bytes()} +{ + DBG_HELPER(dbg); + DBG(DBG_proc, "%s: shifts={", __func__); + for (auto el : pixel_shifts_) { + DBG(DBG_proc, " %zu", el); + } + DBG(DBG_proc, " }\n"); + + if (pixel_shifts_.size() > MAX_SHIFTS) { + throw SaneException("Unsupported number of shift configurations %zu", pixel_shifts_.size()); + } + + extra_height_ = *std::max_element(pixel_shifts_.begin(), pixel_shifts_.end()); +} + +bool ImagePipelineNodePixelShiftLines::get_next_row_data(std::uint8_t* out_data) +{ + bool got_data = true; + + if (!buffer_.empty()) { + buffer_.pop_front(); + } + while (buffer_.height() < extra_height_ + 1) { + buffer_.push_back(); + got_data &= source_.get_next_row_data(buffer_.get_back_row_ptr()); + } + + auto format = get_format(); + auto shift_count = pixel_shifts_.size(); + + std::array<std::uint8_t*, MAX_SHIFTS> rows; + + for (std::size_t irow = 0; irow < shift_count; ++irow) { + rows[irow] = buffer_.get_row_ptr(pixel_shifts_[irow]); + } + + for (std::size_t x = 0, width = get_width(); x < width;) { + for (std::size_t irow = 0; irow < shift_count && x < width; irow++, x++) { + RawPixel pixel = get_raw_pixel_from_row(rows[irow], x, format); + set_raw_pixel_to_row(out_data, x, pixel, format); + } + } + return got_data; +} + +ImagePipelineNodeExtract::ImagePipelineNodeExtract(ImagePipelineNode& source, + std::size_t offset_x, std::size_t offset_y, + std::size_t width, std::size_t height) : + source_(source), + offset_x_{offset_x}, + offset_y_{offset_y}, + width_{width}, + height_{height} +{ + cached_line_.resize(source_.get_row_bytes()); +} + +ImagePipelineNodeExtract::~ImagePipelineNodeExtract() {} + +ImagePipelineNodeScaleRows::ImagePipelineNodeScaleRows(ImagePipelineNode& source, + std::size_t width) : + source_(source), + width_{width} +{ + cached_line_.resize(source_.get_row_bytes()); +} + +bool ImagePipelineNodeScaleRows::get_next_row_data(std::uint8_t* out_data) +{ + auto src_width = source_.get_width(); + auto dst_width = width_; + + bool got_data = source_.get_next_row_data(cached_line_.data()); + + const auto* src_data = cached_line_.data(); + auto format = get_format(); + auto channels = get_pixel_channels(format); + + if (src_width > dst_width) { + // average + std::uint32_t counter = src_width / 2; + unsigned src_x = 0; + for (unsigned dst_x = 0; dst_x < dst_width; dst_x++) { + unsigned avg[3] = {0, 0, 0}; + unsigned count = 0; + while (counter < src_width && src_x < src_width) { + counter += dst_width; + + for (unsigned c = 0; c < channels; c++) { + avg[c] += get_raw_channel_from_row(src_data, src_x, c, format); + } + + src_x++; + count++; + } + counter -= src_width; + + for (unsigned c = 0; c < channels; c++) { + set_raw_channel_to_row(out_data, dst_x, c, avg[c] / count, format); + } + } + } else { + // interpolate and copy pixels + std::uint32_t counter = dst_width / 2; + unsigned dst_x = 0; + + for (unsigned src_x = 0; src_x < src_width; src_x++) { + unsigned avg[3] = {0, 0, 0}; + for (unsigned c = 0; c < channels; c++) { + avg[c] += get_raw_channel_from_row(src_data, src_x, c, format); + } + while ((counter < dst_width || src_x + 1 == src_width) && dst_x < dst_width) { + counter += src_width; + + for (unsigned c = 0; c < channels; c++) { + set_raw_channel_to_row(out_data, dst_x, c, avg[c], format); + } + dst_x++; + } + counter -= dst_width; + } + } + return got_data; +} + +bool ImagePipelineNodeExtract::get_next_row_data(std::uint8_t* out_data) +{ + bool got_data = true; + + while (current_line_ < offset_y_) { + got_data &= source_.get_next_row_data(cached_line_.data()); + current_line_++; + } + if (current_line_ >= offset_y_ + source_.get_height()) { + std::fill(out_data, out_data + get_row_bytes(), 0); + current_line_++; + return got_data; + } + // now we're sure that the following holds: + // offset_y_ <= current_line_ < offset_y_ + source_.get_height()) + got_data &= source_.get_next_row_data(cached_line_.data()); + + auto format = get_format(); + auto x_src_width = source_.get_width() > offset_x_ ? source_.get_width() - offset_x_ : 0; + x_src_width = std::min(x_src_width, width_); + auto x_pad_after = width_ > x_src_width ? width_ - x_src_width : 0; + + if (get_pixel_format_depth(format) < 8) { + // we need to copy pixels one-by-one as there's no per-bit addressing + for (std::size_t i = 0; i < x_src_width; ++i) { + auto pixel = get_raw_pixel_from_row(cached_line_.data(), i + offset_x_, format); + set_raw_pixel_to_row(out_data, i, pixel, format); + } + for (std::size_t i = 0; i < x_pad_after; ++i) { + set_raw_pixel_to_row(out_data, i + x_src_width, RawPixel{}, format); + } + } else { + std::size_t bpp = get_pixel_format_depth(format) / 8; + if (x_src_width > 0) { + std::memcpy(out_data, cached_line_.data() + offset_x_ * bpp, + x_src_width * bpp); + } + if (x_pad_after > 0) { + std::fill(out_data + x_src_width * bpp, + out_data + (x_src_width + x_pad_after) * bpp, 0); + } + } + + current_line_++; + + return got_data; +} + +ImagePipelineNodeCalibrate::ImagePipelineNodeCalibrate(ImagePipelineNode& source, + const std::vector<std::uint16_t>& bottom, + const std::vector<std::uint16_t>& top) : + source_{source} +{ + auto size = std::min(bottom.size(), top.size()); + offset_.reserve(size); + multiplier_.reserve(size); + + for (std::size_t i = 0; i < size; ++i) { + offset_.push_back(bottom[i] / 65535.0f); + multiplier_.push_back(65535.0f / (top[i] - bottom[i])); + } +} + +bool ImagePipelineNodeCalibrate::get_next_row_data(std::uint8_t* out_data) +{ + bool ret = source_.get_next_row_data(out_data); + + auto format = get_format(); + auto depth = get_pixel_format_depth(format); + std::size_t max_value = 1; + switch (depth) { + case 8: max_value = 255; break; + case 16: max_value = 65535; break; + default: + throw SaneException("Unsupported depth for calibration %d", depth); + } + unsigned channels = get_pixel_channels(format); + + std::size_t max_calib_i = offset_.size(); + std::size_t curr_calib_i = 0; + + for (std::size_t x = 0, width = get_width(); x < width && curr_calib_i < max_calib_i; ++x) { + for (unsigned ch = 0; ch < channels && curr_calib_i < max_calib_i; ++ch) { + std::int32_t value = get_raw_channel_from_row(out_data, x, ch, format); + + float value_f = static_cast<float>(value) / max_value; + value_f = (value_f - offset_[curr_calib_i]) * multiplier_[curr_calib_i]; + value_f = std::round(value_f * max_value); + value = clamp<std::int32_t>(static_cast<std::int32_t>(value_f), 0, max_value); + set_raw_channel_to_row(out_data, x, ch, value, format); + + curr_calib_i++; + } + } + return ret; +} + +ImagePipelineNodeDebug::ImagePipelineNodeDebug(ImagePipelineNode& source, + const std::string& path) : + source_(source), + path_{path}, + buffer_{source_.get_row_bytes()} +{} + +ImagePipelineNodeDebug::~ImagePipelineNodeDebug() +{ + catch_all_exceptions(__func__, [&]() + { + if (buffer_.empty()) + return; + + auto format = get_format(); + buffer_.linearize(); + sanei_genesys_write_pnm_file(path_.c_str(), buffer_.get_front_row_ptr(), + get_pixel_format_depth(format), + get_pixel_channels(format), + get_width(), buffer_.height()); + }); +} + +bool ImagePipelineNodeDebug::get_next_row_data(std::uint8_t* out_data) +{ + buffer_.push_back(); + bool got_data = source_.get_next_row_data(out_data); + std::memcpy(buffer_.get_back_row_ptr(), out_data, get_row_bytes()); + return got_data; +} + +std::size_t ImagePipelineStack::get_input_width() const +{ + ensure_node_exists(); + return nodes_.front()->get_width(); +} + +std::size_t ImagePipelineStack::get_input_height() const +{ + ensure_node_exists(); + return nodes_.front()->get_height(); +} + +PixelFormat ImagePipelineStack::get_input_format() const +{ + ensure_node_exists(); + return nodes_.front()->get_format(); +} + +std::size_t ImagePipelineStack::get_input_row_bytes() const +{ + ensure_node_exists(); + return nodes_.front()->get_row_bytes(); +} + +std::size_t ImagePipelineStack::get_output_width() const +{ + ensure_node_exists(); + return nodes_.back()->get_width(); +} + +std::size_t ImagePipelineStack::get_output_height() const +{ + ensure_node_exists(); + return nodes_.back()->get_height(); +} + +PixelFormat ImagePipelineStack::get_output_format() const +{ + ensure_node_exists(); + return nodes_.back()->get_format(); +} + +std::size_t ImagePipelineStack::get_output_row_bytes() const +{ + ensure_node_exists(); + return nodes_.back()->get_row_bytes(); +} + +void ImagePipelineStack::ensure_node_exists() const +{ + if (nodes_.empty()) { + throw SaneException("The pipeline does not contain any nodes"); + } +} + +void ImagePipelineStack::clear() +{ + // we need to destroy the nodes back to front, so that the destructors still have valid + // references to sources + for (auto it = nodes_.rbegin(); it != nodes_.rend(); ++it) { + it->reset(); + } + nodes_.clear(); +} + +std::vector<std::uint8_t> ImagePipelineStack::get_all_data() +{ + auto row_bytes = get_output_row_bytes(); + auto height = get_output_height(); + + std::vector<std::uint8_t> ret; + ret.resize(row_bytes * height); + + for (std::size_t i = 0; i < height; ++i) { + get_next_row_data(ret.data() + row_bytes * i); + } + return ret; +} + +Image ImagePipelineStack::get_image() +{ + auto height = get_output_height(); + + Image ret; + ret.resize(get_output_width(), height, get_output_format()); + + for (std::size_t i = 0; i < height; ++i) { + get_next_row_data(ret.get_row_ptr(i)); + } + return ret; +} + +} // namespace genesys diff --git a/backend/genesys/image_pipeline.h b/backend/genesys/image_pipeline.h new file mode 100644 index 0000000..2986837 --- /dev/null +++ b/backend/genesys/image_pipeline.h @@ -0,0 +1,572 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_IMAGE_PIPELINE_H +#define BACKEND_GENESYS_IMAGE_PIPELINE_H + +#include "image.h" +#include "image_pixel.h" +#include "image_buffer.h" + +#include <algorithm> +#include <functional> +#include <memory> + +namespace genesys { + +class ImagePipelineNode +{ +public: + virtual ~ImagePipelineNode(); + + virtual std::size_t get_width() const = 0; + virtual std::size_t get_height() const = 0; + virtual PixelFormat get_format() const = 0; + + std::size_t get_row_bytes() const + { + return get_pixel_row_bytes(get_format(), get_width()); + } + + virtual bool eof() const = 0; + + // returns true if the row was filled successfully, false otherwise (e.g. if not enough data + // was available. + virtual bool get_next_row_data(std::uint8_t* out_data) = 0; +}; + +class ImagePipelineNodeBytesSource : public ImagePipelineNode +{ +public: + std::size_t remaining_bytes() const { return remaining_bytes_; } + void set_remaining_bytes(std::size_t bytes) { remaining_bytes_ = bytes; } + + std::size_t consume_remaining_bytes(std::size_t bytes); + +private: + std::size_t remaining_bytes_ = 0; +}; + +// A pipeline node that produces data from a callable +class ImagePipelineNodeCallableSource : public ImagePipelineNode +{ +public: + using ProducerCallback = std::function<bool(std::size_t size, std::uint8_t* out_data)>; + + ImagePipelineNodeCallableSource(std::size_t width, std::size_t height, PixelFormat format, + ProducerCallback producer) : + producer_{producer}, + width_{width}, + height_{height}, + format_{format} + {} + + std::size_t get_width() const override { return width_; } + std::size_t get_height() const override { return height_; } + PixelFormat get_format() const override { return format_; } + + bool eof() const override { return eof_; } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ProducerCallback producer_; + std::size_t width_ = 0; + std::size_t height_ = 0; + PixelFormat format_ = PixelFormat::UNKNOWN; + bool eof_ = false; +}; + +// A pipeline node that produces data from a callable requesting fixed-size chunks. +class ImagePipelineNodeBufferedCallableSource : public ImagePipelineNodeBytesSource +{ +public: + using ProducerCallback = std::function<bool(std::size_t size, std::uint8_t* out_data)>; + + ImagePipelineNodeBufferedCallableSource(std::size_t width, std::size_t height, + PixelFormat format, std::size_t input_batch_size, + ProducerCallback producer); + + std::size_t get_width() const override { return width_; } + std::size_t get_height() const override { return height_; } + PixelFormat get_format() const override { return format_; } + + bool eof() const override { return eof_; } + + bool get_next_row_data(std::uint8_t* out_data) override; + + std::size_t buffer_size() const { return buffer_.size(); } + std::size_t buffer_available() const { return buffer_.available(); } + +private: + ProducerCallback producer_; + std::size_t width_ = 0; + std::size_t height_ = 0; + PixelFormat format_ = PixelFormat::UNKNOWN; + + bool eof_ = false; + std::size_t curr_row_ = 0; + + ImageBuffer buffer_; +}; + +class ImagePipelineNodeBufferedGenesysUsb : public ImagePipelineNodeBytesSource +{ +public: + using ProducerCallback = std::function<void(std::size_t size, std::uint8_t* out_data)>; + + ImagePipelineNodeBufferedGenesysUsb(std::size_t width, std::size_t height, + PixelFormat format, std::size_t total_size, + const FakeBufferModel& buffer_model, + ProducerCallback producer); + + std::size_t get_width() const override { return width_; } + std::size_t get_height() const override { return height_; } + PixelFormat get_format() const override { return format_; } + + bool eof() const override { return eof_; } + + bool get_next_row_data(std::uint8_t* out_data) override; + + std::size_t buffer_available() const { return buffer_.available(); } + +private: + ProducerCallback producer_; + std::size_t width_ = 0; + std::size_t height_ = 0; + PixelFormat format_ = PixelFormat::UNKNOWN; + + bool eof_ = false; + + ImageBufferGenesysUsb buffer_; +}; + +// A pipeline node that produces data from the given array. +class ImagePipelineNodeArraySource : public ImagePipelineNodeBytesSource +{ +public: + ImagePipelineNodeArraySource(std::size_t width, std::size_t height, PixelFormat format, + std::vector<std::uint8_t> data); + + std::size_t get_width() const override { return width_; } + std::size_t get_height() const override { return height_; } + PixelFormat get_format() const override { return format_; } + + bool eof() const override { return eof_; } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + std::size_t width_ = 0; + std::size_t height_ = 0; + PixelFormat format_ = PixelFormat::UNKNOWN; + + bool eof_ = false; + + std::vector<std::uint8_t> data_; + std::size_t next_row_ = 0; +}; + + +/// A pipeline node that produces data from the given image +class ImagePipelineNodeImageSource : public ImagePipelineNode +{ +public: + ImagePipelineNodeImageSource(const Image& source); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return next_row_ >= get_height(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + const Image& source_; + std::size_t next_row_ = 0; +}; + +// A pipeline node that converts between pixel formats +class ImagePipelineNodeFormatConvert : public ImagePipelineNode +{ +public: + ImagePipelineNodeFormatConvert(ImagePipelineNode& source, PixelFormat dst_format) : + source_(source), + dst_format_{dst_format} + {} + + ~ImagePipelineNodeFormatConvert() override = default; + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return dst_format_; } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + PixelFormat dst_format_; + std::vector<std::uint8_t> buffer_; +}; + +// A pipeline node that handles data that comes out of segmented sensors. Note that the width of +// the output data does not necessarily match the input data width, because in many cases almost +// all width of the image needs to be read in order to desegment it. +class ImagePipelineNodeDesegment : public ImagePipelineNode +{ +public: + ImagePipelineNodeDesegment(ImagePipelineNode& source, + std::size_t output_width, + const std::vector<unsigned>& segment_order, + std::size_t segment_pixels, + std::size_t interleaved_lines, + std::size_t pixels_per_chunk); + + ImagePipelineNodeDesegment(ImagePipelineNode& source, + std::size_t output_width, + std::size_t segment_count, + std::size_t segment_pixels, + std::size_t interleaved_lines, + std::size_t pixels_per_chunk); + + ~ImagePipelineNodeDesegment() override = default; + + std::size_t get_width() const override { return output_width_; } + std::size_t get_height() const override { return source_.get_height() / interleaved_lines_; } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + std::size_t output_width_; + std::vector<unsigned> segment_order_; + std::size_t segment_pixels_ = 0; + std::size_t interleaved_lines_ = 0; + std::size_t pixels_per_chunk_ = 0; + + RowBuffer buffer_; +}; + +// A pipeline node that deinterleaves data on multiple lines +class ImagePipelineNodeDeinterleaveLines : public ImagePipelineNodeDesegment +{ +public: + ImagePipelineNodeDeinterleaveLines(ImagePipelineNode& source, + std::size_t interleaved_lines, + std::size_t pixels_per_chunk); +}; + +// A pipeline that swaps bytes in 16-bit components on big-endian systems +class ImagePipelineNodeSwap16BitEndian : public ImagePipelineNode +{ +public: + ImagePipelineNodeSwap16BitEndian(ImagePipelineNode& source); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + bool needs_swapping_ = false; +}; + +// A pipeline node that merges 3 mono lines into a color channel +class ImagePipelineNodeMergeMonoLines : public ImagePipelineNode +{ +public: + ImagePipelineNodeMergeMonoLines(ImagePipelineNode& source, + ColorOrder color_order); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height() / 3; } + PixelFormat get_format() const override { return output_format_; } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + static PixelFormat get_output_format(PixelFormat input_format, ColorOrder order); + + ImagePipelineNode& source_; + PixelFormat output_format_ = PixelFormat::UNKNOWN; + + RowBuffer buffer_; +}; + +// A pipeline node that splits a color channel into 3 mono lines +class ImagePipelineNodeSplitMonoLines : public ImagePipelineNode +{ +public: + ImagePipelineNodeSplitMonoLines(ImagePipelineNode& source); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height() * 3; } + PixelFormat get_format() const override { return output_format_; } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + static PixelFormat get_output_format(PixelFormat input_format); + + ImagePipelineNode& source_; + PixelFormat output_format_ = PixelFormat::UNKNOWN; + + std::vector<std::uint8_t> buffer_; + unsigned next_channel_ = 0; +}; + +// A pipeline node that shifts colors across lines by the given offsets +class ImagePipelineNodeComponentShiftLines : public ImagePipelineNode +{ +public: + ImagePipelineNodeComponentShiftLines(ImagePipelineNode& source, + unsigned shift_r, unsigned shift_g, unsigned shift_b); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height() - extra_height_; } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + std::size_t extra_height_ = 0; + + std::array<unsigned, 3> channel_shifts_; + + RowBuffer buffer_; +}; + +// A pipeline node that shifts pixels across lines by the given offsets (performs unstaggering) +class ImagePipelineNodePixelShiftLines : public ImagePipelineNode +{ +public: + constexpr static std::size_t MAX_SHIFTS = 2; + + ImagePipelineNodePixelShiftLines(ImagePipelineNode& source, + const std::vector<std::size_t>& shifts); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height() - extra_height_; } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + std::size_t extra_height_ = 0; + + std::vector<std::size_t> pixel_shifts_; + + RowBuffer buffer_; +}; + +// A pipeline node that extracts a sub-image from the image. Padding and cropping is done as needed. +// The class can't pad to the left of the image currently, as only positive offsets are accepted. +class ImagePipelineNodeExtract : public ImagePipelineNode +{ +public: + ImagePipelineNodeExtract(ImagePipelineNode& source, + std::size_t offset_x, std::size_t offset_y, + std::size_t width, std::size_t height); + + ~ImagePipelineNodeExtract() override; + + std::size_t get_width() const override { return width_; } + std::size_t get_height() const override { return height_; } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + std::size_t offset_x_ = 0; + std::size_t offset_y_ = 0; + std::size_t width_ = 0; + std::size_t height_ = 0; + + std::size_t current_line_ = 0; + std::vector<std::uint8_t> cached_line_; +}; + +// A pipeline node that scales rows to the specified width by using a point filter +class ImagePipelineNodeScaleRows : public ImagePipelineNode +{ +public: + ImagePipelineNodeScaleRows(ImagePipelineNode& source, std::size_t width); + + std::size_t get_width() const override { return width_; } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + std::size_t width_ = 0; + + std::vector<std::uint8_t> cached_line_; +}; + +// A pipeline node that mimics the calibration behavior on Genesys chips +class ImagePipelineNodeCalibrate : public ImagePipelineNode +{ +public: + + ImagePipelineNodeCalibrate(ImagePipelineNode& source, const std::vector<std::uint16_t>& bottom, + const std::vector<std::uint16_t>& top); + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + + std::vector<float> offset_; + std::vector<float> multiplier_; +}; + +class ImagePipelineNodeDebug : public ImagePipelineNode +{ +public: + ImagePipelineNodeDebug(ImagePipelineNode& source, const std::string& path); + ~ImagePipelineNodeDebug() override; + + std::size_t get_width() const override { return source_.get_width(); } + std::size_t get_height() const override { return source_.get_height(); } + PixelFormat get_format() const override { return source_.get_format(); } + + bool eof() const override { return source_.eof(); } + + bool get_next_row_data(std::uint8_t* out_data) override; + +private: + ImagePipelineNode& source_; + std::string path_; + RowBuffer buffer_; +}; + +class ImagePipelineStack +{ +public: + ImagePipelineStack() {} + ~ImagePipelineStack() { clear(); } + + std::size_t get_input_width() const; + std::size_t get_input_height() const; + PixelFormat get_input_format() const; + std::size_t get_input_row_bytes() const; + + std::size_t get_output_width() const; + std::size_t get_output_height() const; + PixelFormat get_output_format() const; + std::size_t get_output_row_bytes() const; + + ImagePipelineNode& front() { return *(nodes_.front().get()); } + + bool eof() const { return nodes_.back()->eof(); } + + void clear(); + + template<class Node, class... Args> + void push_first_node(Args&&... args) + { + if (!nodes_.empty()) { + throw SaneException("Trying to append first node when there are existing nodes"); + } + nodes_.emplace_back(std::unique_ptr<Node>(new Node(std::forward<Args>(args)...))); + } + + template<class Node, class... Args> + void push_node(Args&&... args) + { + ensure_node_exists(); + nodes_.emplace_back(std::unique_ptr<Node>(new Node(*nodes_.back(), + std::forward<Args>(args)...))); + } + + bool get_next_row_data(std::uint8_t* out_data) + { + return nodes_.back()->get_next_row_data(out_data); + } + + std::vector<std::uint8_t> get_all_data(); + + Image get_image(); + +private: + void ensure_node_exists() const; + + std::vector<std::unique_ptr<ImagePipelineNode>> nodes_; +}; + +} // namespace genesys + +#endif // ifndef BACKEND_GENESYS_IMAGE_PIPELINE_H diff --git a/backend/genesys/image_pixel.cpp b/backend/genesys/image_pixel.cpp new file mode 100644 index 0000000..1b83e12 --- /dev/null +++ b/backend/genesys/image_pixel.cpp @@ -0,0 +1,509 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "image.h" + +#include <array> + +namespace genesys { + +struct PixelFormatDesc +{ + PixelFormat format; + unsigned depth; + unsigned channels; + ColorOrder order; +}; + +const PixelFormatDesc s_known_pixel_formats[] = { + { PixelFormat::I1, 1, 1, ColorOrder::RGB }, + { PixelFormat::I8, 8, 1, ColorOrder::RGB }, + { PixelFormat::I16, 16, 1, ColorOrder::RGB }, + { PixelFormat::RGB111, 1, 3, ColorOrder::RGB }, + { PixelFormat::RGB888, 8, 3, ColorOrder::RGB }, + { PixelFormat::RGB161616, 16, 3, ColorOrder::RGB }, + { PixelFormat::BGR888, 8, 3, ColorOrder::BGR }, + { PixelFormat::BGR161616, 16, 3, ColorOrder::BGR }, +}; + + +ColorOrder get_pixel_format_color_order(PixelFormat format) +{ + for (const auto& desc : s_known_pixel_formats) { + if (desc.format == format) + return desc.order; + } + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); +} + + +unsigned get_pixel_format_depth(PixelFormat format) +{ + for (const auto& desc : s_known_pixel_formats) { + if (desc.format == format) + return desc.depth; + } + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); +} + +unsigned get_pixel_channels(PixelFormat format) +{ + for (const auto& desc : s_known_pixel_formats) { + if (desc.format == format) + return desc.channels; + } + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); +} + +std::size_t get_pixel_row_bytes(PixelFormat format, std::size_t width) +{ + std::size_t depth = get_pixel_format_depth(format) * get_pixel_channels(format); + std::size_t total_bits = depth * width; + return total_bits / 8 + ((total_bits % 8 > 0) ? 1 : 0); +} + +std::size_t get_pixels_from_row_bytes(PixelFormat format, std::size_t row_bytes) +{ + std::size_t depth = get_pixel_format_depth(format) * get_pixel_channels(format); + return (row_bytes * 8) / depth; +} + +PixelFormat create_pixel_format(unsigned depth, unsigned channels, ColorOrder order) +{ + for (const auto& desc : s_known_pixel_formats) { + if (desc.depth == depth && desc.channels == channels && desc.order == order) { + return desc.format; + } + } + throw SaneException("Unknown pixel format %d %d %d", depth, channels, + static_cast<unsigned>(order)); +} + +static inline unsigned read_bit(const std::uint8_t* data, std::size_t x) +{ + return (data[x / 8] >> (7 - (x % 8))) & 0x1; +} + +static inline void write_bit(std::uint8_t* data, std::size_t x, unsigned value) +{ + value = (value & 0x1) << (7 - (x % 8)); + std::uint8_t mask = 0x1 << (7 - (x % 8)); + + data[x / 8] = (data[x / 8] & ~mask) | (value & mask); +} + +Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format) +{ + switch (format) { + case PixelFormat::I1: { + std::uint16_t val = read_bit(data, x) ? 0xffff : 0x0000; + return Pixel(val, val, val); + } + case PixelFormat::RGB111: { + x *= 3; + std::uint16_t r = read_bit(data, x) ? 0xffff : 0x0000; + std::uint16_t g = read_bit(data, x + 1) ? 0xffff : 0x0000; + std::uint16_t b = read_bit(data, x + 2) ? 0xffff : 0x0000; + return Pixel(r, g, b); + } + case PixelFormat::I8: { + std::uint16_t val = std::uint16_t(data[x]) | (data[x] << 8); + return Pixel(val, val, val); + } + case PixelFormat::I16: { + x *= 2; + std::uint16_t val = std::uint16_t(data[x]) | (data[x + 1] << 8); + return Pixel(val, val, val); + } + case PixelFormat::RGB888: { + x *= 3; + std::uint16_t r = std::uint16_t(data[x]) | (data[x] << 8); + std::uint16_t g = std::uint16_t(data[x + 1]) | (data[x + 1] << 8); + std::uint16_t b = std::uint16_t(data[x + 2]) | (data[x + 2] << 8); + return Pixel(r, g, b); + } + case PixelFormat::BGR888: { + x *= 3; + std::uint16_t b = std::uint16_t(data[x]) | (data[x] << 8); + std::uint16_t g = std::uint16_t(data[x + 1]) | (data[x + 1] << 8); + std::uint16_t r = std::uint16_t(data[x + 2]) | (data[x + 2] << 8); + return Pixel(r, g, b); + } + case PixelFormat::RGB161616: { + x *= 6; + std::uint16_t r = std::uint16_t(data[x]) | (data[x + 1] << 8); + std::uint16_t g = std::uint16_t(data[x + 2]) | (data[x + 3] << 8); + std::uint16_t b = std::uint16_t(data[x + 4]) | (data[x + 5] << 8); + return Pixel(r, g, b); + } + case PixelFormat::BGR161616: { + x *= 6; + std::uint16_t b = std::uint16_t(data[x]) | (data[x + 1] << 8); + std::uint16_t g = std::uint16_t(data[x + 2]) | (data[x + 3] << 8); + std::uint16_t r = std::uint16_t(data[x + 4]) | (data[x + 5] << 8); + return Pixel(r, g, b); + } + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); + } +} + +void set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel, PixelFormat format) +{ + switch (format) { + case PixelFormat::I1: + write_bit(data, x, pixel.r & 0x8000 ? 1 : 0); + return; + case PixelFormat::RGB111: { + x *= 3; + write_bit(data, x, pixel.r & 0x8000 ? 1 : 0); + write_bit(data, x + 1,pixel.g & 0x8000 ? 1 : 0); + write_bit(data, x + 2, pixel.b & 0x8000 ? 1 : 0); + return; + } + case PixelFormat::I8: { + float val = (pixel.r >> 8) * 0.3f; + val += (pixel.g >> 8) * 0.59f; + val += (pixel.b >> 8) * 0.11f; + data[x] = static_cast<std::uint16_t>(val); + return; + } + case PixelFormat::I16: { + x *= 2; + float val = pixel.r * 0.3f; + val += pixel.g * 0.59f; + val += pixel.b * 0.11f; + auto val16 = static_cast<std::uint16_t>(val); + data[x] = val16 & 0xff; + data[x + 1] = (val16 >> 8) & 0xff; + return; + } + case PixelFormat::RGB888: { + x *= 3; + data[x] = pixel.r >> 8; + data[x + 1] = pixel.g >> 8; + data[x + 2] = pixel.b >> 8; + return; + } + case PixelFormat::BGR888: { + x *= 3; + data[x] = pixel.b >> 8; + data[x + 1] = pixel.g >> 8; + data[x + 2] = pixel.r >> 8; + return; + } + case PixelFormat::RGB161616: { + x *= 6; + data[x] = pixel.r & 0xff; + data[x + 1] = (pixel.r >> 8) & 0xff; + data[x + 2] = pixel.g & 0xff; + data[x + 3] = (pixel.g >> 8) & 0xff; + data[x + 4] = pixel.b & 0xff; + data[x + 5] = (pixel.b >> 8) & 0xff; + return; + } + case PixelFormat::BGR161616: + x *= 6; + data[x] = pixel.b & 0xff; + data[x + 1] = (pixel.b >> 8) & 0xff; + data[x + 2] = pixel.g & 0xff; + data[x + 3] = (pixel.g >> 8) & 0xff; + data[x + 4] = pixel.r & 0xff; + data[x + 5] = (pixel.r >> 8) & 0xff; + return; + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); + } +} + +RawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format) +{ + switch (format) { + case PixelFormat::I1: + return RawPixel(read_bit(data, x)); + case PixelFormat::RGB111: { + x *= 3; + return RawPixel(read_bit(data, x) << 2 | + (read_bit(data, x + 1) << 1) | + (read_bit(data, x + 2))); + } + case PixelFormat::I8: + return RawPixel(data[x]); + case PixelFormat::I16: { + x *= 2; + return RawPixel(data[x], data[x + 1]); + } + case PixelFormat::RGB888: + case PixelFormat::BGR888: { + x *= 3; + return RawPixel(data[x], data[x + 1], data[x + 2]); + } + case PixelFormat::RGB161616: + case PixelFormat::BGR161616: { + x *= 6; + return RawPixel(data[x], data[x + 1], data[x + 2], + data[x + 3], data[x + 4], data[x + 5]); + } + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); + } +} + +void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel, PixelFormat format) +{ + switch (format) { + case PixelFormat::I1: + write_bit(data, x, pixel.data[0] & 0x1); + return; + case PixelFormat::RGB111: { + x *= 3; + write_bit(data, x, (pixel.data[0] >> 2) & 0x1); + write_bit(data, x + 1, (pixel.data[0] >> 1) & 0x1); + write_bit(data, x + 2, (pixel.data[0]) & 0x1); + return; + } + case PixelFormat::I8: + data[x] = pixel.data[0]; + return; + case PixelFormat::I16: { + x *= 2; + data[x] = pixel.data[0]; + data[x + 1] = pixel.data[1]; + return; + } + case PixelFormat::RGB888: + case PixelFormat::BGR888: { + x *= 3; + data[x] = pixel.data[0]; + data[x + 1] = pixel.data[1]; + data[x + 2] = pixel.data[2]; + return; + } + case PixelFormat::RGB161616: + case PixelFormat::BGR161616: { + x *= 6; + data[x] = pixel.data[0]; + data[x + 1] = pixel.data[1]; + data[x + 2] = pixel.data[2]; + data[x + 3] = pixel.data[3]; + data[x + 4] = pixel.data[4]; + data[x + 5] = pixel.data[5]; + return; + } + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); + } +} + +std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel, + PixelFormat format) +{ + switch (format) { + case PixelFormat::I1: + return read_bit(data, x); + case PixelFormat::RGB111: + return read_bit(data, x * 3 + channel); + case PixelFormat::I8: + return data[x]; + case PixelFormat::I16: { + x *= 2; + return data[x] | (data[x + 1] << 8); + } + case PixelFormat::RGB888: + case PixelFormat::BGR888: + return data[x * 3 + channel]; + case PixelFormat::RGB161616: + case PixelFormat::BGR161616: + return data[x * 6 + channel * 2] | (data[x * 6 + channel * 2 + 1]) << 8; + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); + } +} + +void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, + std::uint16_t pixel, PixelFormat format) +{ + switch (format) { + case PixelFormat::I1: + write_bit(data, x, pixel & 0x1); + return; + case PixelFormat::RGB111: { + write_bit(data, x * 3 + channel, pixel & 0x1); + return; + } + case PixelFormat::I8: + data[x] = pixel; + return; + case PixelFormat::I16: { + x *= 2; + data[x] = pixel; + data[x + 1] = pixel >> 8; + return; + } + case PixelFormat::RGB888: + case PixelFormat::BGR888: { + x *= 3; + data[x + channel] = pixel; + return; + } + case PixelFormat::RGB161616: + case PixelFormat::BGR161616: { + x *= 6; + data[x + channel * 2] = pixel; + data[x + channel * 2 + 1] = pixel >> 8; + return; + } + default: + throw SaneException("Unknown pixel format %d", static_cast<unsigned>(format)); + } +} + +template<PixelFormat Format> +Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x) +{ + return get_pixel_from_row(data, x, Format); +} + +template<PixelFormat Format> +void set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel) +{ + set_pixel_to_row(data, x, pixel, Format); +} + +template<PixelFormat Format> +RawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x) +{ + return get_raw_pixel_from_row(data, x, Format); +} + +template<PixelFormat Format> +void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel) +{ + set_raw_pixel_to_row(data, x, pixel, Format); +} + +template<PixelFormat Format> +std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel) +{ + return get_raw_channel_from_row(data, x, channel, Format); +} + +template<PixelFormat Format> +void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel) +{ + set_raw_channel_to_row(data, x, channel, pixel, Format); +} + +template Pixel get_pixel_from_row<PixelFormat::I1>(const std::uint8_t* data, std::size_t x); +template Pixel get_pixel_from_row<PixelFormat::RGB111>(const std::uint8_t* data, std::size_t x); +template Pixel get_pixel_from_row<PixelFormat::I8>(const std::uint8_t* data, std::size_t x); +template Pixel get_pixel_from_row<PixelFormat::RGB888>(const std::uint8_t* data, std::size_t x); +template Pixel get_pixel_from_row<PixelFormat::BGR888>(const std::uint8_t* data, std::size_t x); +template Pixel get_pixel_from_row<PixelFormat::I16>(const std::uint8_t* data, std::size_t x); +template Pixel get_pixel_from_row<PixelFormat::RGB161616>(const std::uint8_t* data, std::size_t x); +template Pixel get_pixel_from_row<PixelFormat::BGR161616>(const std::uint8_t* data, std::size_t x); + +template RawPixel get_raw_pixel_from_row<PixelFormat::I1>(const std::uint8_t* data, std::size_t x); +template RawPixel get_raw_pixel_from_row<PixelFormat::RGB111>(const std::uint8_t* data, std::size_t x); +template RawPixel get_raw_pixel_from_row<PixelFormat::I8>(const std::uint8_t* data, std::size_t x); +template RawPixel get_raw_pixel_from_row<PixelFormat::RGB888>(const std::uint8_t* data, std::size_t x); +template RawPixel get_raw_pixel_from_row<PixelFormat::BGR888>(const std::uint8_t* data, std::size_t x); +template RawPixel get_raw_pixel_from_row<PixelFormat::I16>(const std::uint8_t* data, std::size_t x); +template RawPixel get_raw_pixel_from_row<PixelFormat::RGB161616>(const std::uint8_t* data, std::size_t x); +template RawPixel get_raw_pixel_from_row<PixelFormat::BGR161616>(const std::uint8_t* data, std::size_t x); + +template std::uint16_t get_raw_channel_from_row<PixelFormat::I1>( + const std::uint8_t* data, std::size_t x, unsigned channel); +template std::uint16_t get_raw_channel_from_row<PixelFormat::RGB111>( + const std::uint8_t* data, std::size_t x, unsigned channel); +template std::uint16_t get_raw_channel_from_row<PixelFormat::I8>( + const std::uint8_t* data, std::size_t x, unsigned channel); +template std::uint16_t get_raw_channel_from_row<PixelFormat::RGB888>( + const std::uint8_t* data, std::size_t x, unsigned channel); +template std::uint16_t get_raw_channel_from_row<PixelFormat::BGR888>( + const std::uint8_t* data, std::size_t x, unsigned channel); +template std::uint16_t get_raw_channel_from_row<PixelFormat::I16>( + const std::uint8_t* data, std::size_t x, unsigned channel); +template std::uint16_t get_raw_channel_from_row<PixelFormat::RGB161616>( + const std::uint8_t* data, std::size_t x, unsigned channel); +template std::uint16_t get_raw_channel_from_row<PixelFormat::BGR161616> + (const std::uint8_t* data, std::size_t x, unsigned channel); + +template void set_pixel_to_row<PixelFormat::I1>(std::uint8_t* data, std::size_t x, Pixel pixel); +template void set_pixel_to_row<PixelFormat::RGB111>(std::uint8_t* data, std::size_t x, Pixel pixel); +template void set_pixel_to_row<PixelFormat::I8>(std::uint8_t* data, std::size_t x, Pixel pixel); +template void set_pixel_to_row<PixelFormat::RGB888>(std::uint8_t* data, std::size_t x, Pixel pixel); +template void set_pixel_to_row<PixelFormat::BGR888>(std::uint8_t* data, std::size_t x, Pixel pixel); +template void set_pixel_to_row<PixelFormat::I16>(std::uint8_t* data, std::size_t x, Pixel pixel); +template void set_pixel_to_row<PixelFormat::RGB161616>(std::uint8_t* data, std::size_t x, Pixel pixel); +template void set_pixel_to_row<PixelFormat::BGR161616>(std::uint8_t* data, std::size_t x, Pixel pixel); + +template void set_raw_pixel_to_row<PixelFormat::I1>(std::uint8_t* data, std::size_t x, RawPixel pixel); +template void set_raw_pixel_to_row<PixelFormat::RGB111>(std::uint8_t* data, std::size_t x, RawPixel pixel); +template void set_raw_pixel_to_row<PixelFormat::I8>(std::uint8_t* data, std::size_t x, RawPixel pixel); +template void set_raw_pixel_to_row<PixelFormat::RGB888>(std::uint8_t* data, std::size_t x, RawPixel pixel); +template void set_raw_pixel_to_row<PixelFormat::BGR888>(std::uint8_t* data, std::size_t x, RawPixel pixel); +template void set_raw_pixel_to_row<PixelFormat::I16>(std::uint8_t* data, std::size_t x, RawPixel pixel); +template void set_raw_pixel_to_row<PixelFormat::RGB161616>(std::uint8_t* data, std::size_t x, RawPixel pixel); +template void set_raw_pixel_to_row<PixelFormat::BGR161616>(std::uint8_t* data, std::size_t x, RawPixel pixel); + +template void set_raw_channel_to_row<PixelFormat::I1>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); +template void set_raw_channel_to_row<PixelFormat::RGB111>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); +template void set_raw_channel_to_row<PixelFormat::I8>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); +template void set_raw_channel_to_row<PixelFormat::RGB888>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); +template void set_raw_channel_to_row<PixelFormat::BGR888>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); +template void set_raw_channel_to_row<PixelFormat::I16>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); +template void set_raw_channel_to_row<PixelFormat::RGB161616>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); +template void set_raw_channel_to_row<PixelFormat::BGR161616>( + std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel); + +} // namespace genesys diff --git a/backend/genesys/image_pixel.h b/backend/genesys/image_pixel.h new file mode 100644 index 0000000..2dda271 --- /dev/null +++ b/backend/genesys/image_pixel.h @@ -0,0 +1,144 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_IMAGE_PIXEL_H +#define BACKEND_GENESYS_IMAGE_PIXEL_H + +#include "enums.h" +#include <algorithm> +#include <cstdint> +#include <cstddef> + +namespace genesys { + +enum class PixelFormat +{ + UNKNOWN, + I1, + RGB111, + I8, + RGB888, + BGR888, + I16, + RGB161616, + BGR161616, +}; + +struct Pixel +{ + Pixel() = default; + Pixel(std::uint16_t red, std::uint16_t green, std::uint16_t blue) : + r{red}, g{green}, b{blue} {} + + std::uint16_t r = 0; + std::uint16_t g = 0; + std::uint16_t b = 0; + + bool operator==(const Pixel& other) const + { + return r == other.r && g == other.g && b == other.b; + } +}; + +struct RawPixel +{ + RawPixel() = default; + RawPixel(std::uint8_t d0) : data{d0, 0, 0, 0, 0, 0} {} + RawPixel(std::uint8_t d0, std::uint8_t d1) : data{d0, d1, 0, 0, 0, 0} {} + RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2) : data{d0, d1, d2, 0, 0, 0} {} + RawPixel(std::uint8_t d0, std::uint8_t d1, std::uint8_t d2, + std::uint8_t d3, std::uint8_t d4, std::uint8_t d5) : data{d0, d1, d2, d3, d4, d5} {} + std::uint8_t data[6] = {}; + + bool operator==(const RawPixel& other) const + { + return std::equal(std::begin(data), std::end(data), + std::begin(other.data)); + } +}; + +ColorOrder get_pixel_format_color_order(PixelFormat format); +unsigned get_pixel_format_depth(PixelFormat format); +unsigned get_pixel_channels(PixelFormat format); +std::size_t get_pixel_row_bytes(PixelFormat format, std::size_t width); + +std::size_t get_pixels_from_row_bytes(PixelFormat format, std::size_t row_bytes); + +PixelFormat create_pixel_format(unsigned depth, unsigned channels, ColorOrder order); + +// retrieves or sets the logical pixel values in 16-bit range. +Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); +void set_pixel_to_row(std::uint8_t* data, std::size_t x, Pixel pixel, PixelFormat format); + +// retrieves or sets the physical pixel values. The low bytes of the RawPixel are interpreted as +// the retrieved values / values to set +RawPixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x, PixelFormat format); +void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel, PixelFormat format); + +// retrieves or sets the physical value of specific channel of the pixel. The channels are numbered +// in the same order as the pixel is laid out in memory, that is, whichever channel comes first +// has the index 0. E.g. 0-th channel in RGB888 is the red byte, but in BGR888 is the blue byte. +std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel, + PixelFormat format); +void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, std::uint16_t pixel, + PixelFormat format); + +template<PixelFormat Format> +Pixel get_pixel_from_row(const std::uint8_t* data, std::size_t x); +template<PixelFormat Format> +void set_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); + +template<PixelFormat Format> +Pixel get_raw_pixel_from_row(const std::uint8_t* data, std::size_t x); +template<PixelFormat Format> +void set_raw_pixel_to_row(std::uint8_t* data, std::size_t x, RawPixel pixel); + +template<PixelFormat Format> +std::uint16_t get_raw_channel_from_row(const std::uint8_t* data, std::size_t x, unsigned channel); +template<PixelFormat Format> +void set_raw_channel_to_row(std::uint8_t* data, std::size_t x, unsigned channel, + std::uint16_t pixel); + +} // namespace genesys + +#endif // BACKEND_GENESYS_IMAGE_PIXEL_H diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp new file mode 100644 index 0000000..7937fcc --- /dev/null +++ b/backend/genesys/low.cpp @@ -0,0 +1,1994 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> + + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "low.h" +#include "assert.h" +#include "test_settings.h" + +#include "gl124_registers.h" +#include "gl646_registers.h" +#include "gl841_registers.h" +#include "gl843_registers.h" +#include "gl846_registers.h" +#include "gl847_registers.h" +#include "gl646_registers.h" + +#include <cstdio> +#include <cmath> +#include <vector> + +/* ------------------------------------------------------------------------ */ +/* functions calling ASIC specific functions */ +/* ------------------------------------------------------------------------ */ + +namespace genesys { + +/** + * setup the hardware dependent functions + */ + +namespace gl124 { std::unique_ptr<CommandSet> create_gl124_cmd_set(); } +namespace gl646 { std::unique_ptr<CommandSet> create_gl646_cmd_set(); } +namespace gl841 { std::unique_ptr<CommandSet> create_gl841_cmd_set(); } +namespace gl843 { std::unique_ptr<CommandSet> create_gl843_cmd_set(); } +namespace gl846 { std::unique_ptr<CommandSet> create_gl846_cmd_set(); } +namespace gl847 { std::unique_ptr<CommandSet> create_gl847_cmd_set(); } + +void sanei_genesys_init_cmd_set(Genesys_Device* dev) +{ + DBG_INIT (); + DBG_HELPER(dbg); + switch (dev->model->asic_type) { + case AsicType::GL646: dev->cmd_set = gl646::create_gl646_cmd_set(); break; + case AsicType::GL841: dev->cmd_set = gl841::create_gl841_cmd_set(); break; + case AsicType::GL843: dev->cmd_set = gl843::create_gl843_cmd_set(); break; + case AsicType::GL845: // since only a few reg bits differs we handle both together + case AsicType::GL846: dev->cmd_set = gl846::create_gl846_cmd_set(); break; + case AsicType::GL847: dev->cmd_set = gl847::create_gl847_cmd_set(); break; + case AsicType::GL124: dev->cmd_set = gl124::create_gl124_cmd_set(); break; + default: throw SaneException(SANE_STATUS_INVAL, "unknown ASIC type"); + } +} + +/* ------------------------------------------------------------------------ */ +/* General IO and debugging functions */ +/* ------------------------------------------------------------------------ */ + +void sanei_genesys_write_file(const char* filename, const std::uint8_t* data, std::size_t length) +{ + DBG_HELPER(dbg); + std::FILE* out = std::fopen(filename, "w"); + if (!out) { + throw SaneException("could not open %s for writing: %s", filename, strerror(errno)); + } + std::fwrite(data, 1, length, out); + std::fclose(out); +} + +// Write data to a pnm file (e.g. calibration). For debugging only +// data is RGB or grey, with little endian byte order +void sanei_genesys_write_pnm_file(const char* filename, const std::uint8_t* data, int depth, + int channels, int pixels_per_line, int lines) +{ + DBG_HELPER_ARGS(dbg, "depth=%d, channels=%d, ppl=%d, lines=%d", depth, channels, + pixels_per_line, lines); + int count; + + std::FILE* out = std::fopen(filename, "w"); + if (!out) + { + throw SaneException("could not open %s for writing: %s\n", filename, strerror(errno)); + } + if(depth==1) + { + fprintf (out, "P4\n%d\n%d\n", pixels_per_line, lines); + } + else + { + std::fprintf(out, "P%c\n%d\n%d\n%d\n", channels == 1 ? '5' : '6', pixels_per_line, lines, + static_cast<int>(std::pow(static_cast<double>(2), + static_cast<double>(depth - 1)))); + } + if (channels == 3) + { + for (count = 0; count < (pixels_per_line * lines * 3); count++) + { + if (depth == 16) + fputc (*(data + 1), out); + fputc (*(data++), out); + if (depth == 16) + data++; + } + } + else + { + if (depth==1) + { + pixels_per_line/=8; + } + for (count = 0; count < (pixels_per_line * lines); count++) + { + switch (depth) + { + case 8: + fputc (*(data + count), out); + break; + case 16: + fputc (*(data + 1), out); + fputc (*(data), out); + data += 2; + break; + default: + fputc(data[count], out); + break; + } + } + } + std::fclose(out); +} + +void sanei_genesys_write_pnm_file16(const char* filename, const uint16_t* data, unsigned channels, + unsigned pixels_per_line, unsigned lines) +{ + DBG_HELPER_ARGS(dbg, "channels=%d, ppl=%d, lines=%d", channels, + pixels_per_line, lines); + + std::FILE* out = std::fopen(filename, "w"); + if (!out) { + throw SaneException("could not open %s for writing: %s\n", filename, strerror(errno)); + } + std::fprintf(out, "P%c\n%d\n%d\n%d\n", channels == 1 ? '5' : '6', + pixels_per_line, lines, 256 * 256 - 1); + + for (unsigned count = 0; count < (pixels_per_line * lines * channels); count++) { + fputc(*data >> 8, out); + fputc(*data & 0xff, out); + data++; + } + std::fclose(out); +} + +bool is_supported_write_pnm_file_image_format(PixelFormat format) +{ + switch (format) { + case PixelFormat::I1: + case PixelFormat::RGB111: + case PixelFormat::I8: + case PixelFormat::RGB888: + case PixelFormat::I16: + case PixelFormat::RGB161616: + return true; + default: + return false; + } +} + +void sanei_genesys_write_pnm_file(const char* filename, const Image& image) +{ + if (!is_supported_write_pnm_file_image_format(image.get_format())) { + throw SaneException("Unsupported format %d", static_cast<unsigned>(image.get_format())); + } + + sanei_genesys_write_pnm_file(filename, image.get_row_ptr(0), + get_pixel_format_depth(image.get_format()), + get_pixel_channels(image.get_format()), + image.get_width(), image.get_height()); +} + +/* ------------------------------------------------------------------------ */ +/* Read and write RAM, registers and AFE */ +/* ------------------------------------------------------------------------ */ + +unsigned sanei_genesys_get_bulk_max_size(AsicType asic_type) +{ + /* Genesys supports 0xFE00 maximum size in general, wheraus GL646 supports + 0xFFC0. We use 0xF000 because that's the packet limit in the Linux usbmon + USB capture stack. By default it limits packet size to b_size / 5 where + b_size is the size of the ring buffer. By default it's 300*1024, so the + packet is limited 61440 without any visibility to acquiring software. + */ + if (asic_type == AsicType::GL124 || + asic_type == AsicType::GL846 || + asic_type == AsicType::GL847) + { + return 0xeff0; + } + return 0xf000; +} + +// Set address for writing data +void sanei_genesys_set_buffer_address(Genesys_Device* dev, uint32_t addr) +{ + DBG_HELPER(dbg); + + if (dev->model->asic_type==AsicType::GL847 || + dev->model->asic_type==AsicType::GL845 || + dev->model->asic_type==AsicType::GL846 || + dev->model->asic_type==AsicType::GL124) + { + DBG(DBG_warn, "%s: shouldn't be used for GL846+ ASICs\n", __func__); + return; + } + + DBG(DBG_io, "%s: setting address to 0x%05x\n", __func__, addr & 0xfffffff0); + + addr = addr >> 4; + + dev->interface->write_register(0x2b, (addr & 0xff)); + + addr = addr >> 8; + dev->interface->write_register(0x2a, (addr & 0xff)); +} + +/* ------------------------------------------------------------------------ */ +/* Medium level functions */ +/* ------------------------------------------------------------------------ */ + +Status scanner_read_status(Genesys_Device& dev) +{ + DBG_HELPER(dbg); + std::uint16_t address = 0; + + switch (dev.model->asic_type) { + case AsicType::GL124: address = 0x101; break; + case AsicType::GL646: + case AsicType::GL841: + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: address = 0x41; break; + default: throw SaneException("Unsupported asic type"); + } + + // same for all chips + constexpr std::uint8_t PWRBIT = 0x80; + constexpr std::uint8_t BUFEMPTY = 0x40; + constexpr std::uint8_t FEEDFSH = 0x20; + constexpr std::uint8_t SCANFSH = 0x10; + constexpr std::uint8_t HOMESNR = 0x08; + constexpr std::uint8_t LAMPSTS = 0x04; + constexpr std::uint8_t FEBUSY = 0x02; + constexpr std::uint8_t MOTORENB = 0x01; + + auto value = dev.interface->read_register(address); + Status status; + status.is_replugged = !(value & PWRBIT); + status.is_buffer_empty = value & BUFEMPTY; + status.is_feeding_finished = value & FEEDFSH; + status.is_scanning_finished = value & SCANFSH; + status.is_at_home = value & HOMESNR; + status.is_lamp_on = value & LAMPSTS; + status.is_front_end_busy = value & FEBUSY; + status.is_motor_enabled = value & MOTORENB; + + if (DBG_LEVEL >= DBG_io) { + debug_print_status(dbg, status); + } + + return status; +} + +Status scanner_read_reliable_status(Genesys_Device& dev) +{ + DBG_HELPER(dbg); + + scanner_read_status(dev); + dev.interface->sleep_ms(100); + return scanner_read_status(dev); +} + +void scanner_read_print_status(Genesys_Device& dev) +{ + scanner_read_status(dev); +} + +/** + * decodes and prints content of status register + * @param val value read from status register + */ +void debug_print_status(DebugMessageHelper& dbg, Status val) +{ + std::stringstream str; + str << val; + dbg.vlog(DBG_info, "status=%s\n", str.str().c_str()); +} + +#if 0 +/* returns pixels per line from register set */ +/*candidate for moving into chip specific files?*/ +static int +genesys_pixels_per_line (Genesys_Register_Set * reg) +{ + int pixels_per_line; + + pixels_per_line = reg->get8(0x32) * 256 + reg->get8(0x33); + pixels_per_line -= (reg->get8(0x30) * 256 + reg->get8(0x31)); + + return pixels_per_line; +} + +/* returns dpiset from register set */ +/*candidate for moving into chip specific files?*/ +static int +genesys_dpiset (Genesys_Register_Set * reg) +{ + return reg->get8(0x2c) * 256 + reg->get8(0x2d); +} +#endif + +/** read the number of valid words in scanner's RAM + * ie registers 42-43-44 + */ +// candidate for moving into chip specific files? +void sanei_genesys_read_valid_words(Genesys_Device* dev, unsigned int* words) +{ + DBG_HELPER(dbg); + + switch (dev->model->asic_type) + { + case AsicType::GL124: + *words = dev->interface->read_register(0x102) & 0x03; + *words = *words * 256 + dev->interface->read_register(0x103); + *words = *words * 256 + dev->interface->read_register(0x104); + *words = *words * 256 + dev->interface->read_register(0x105); + break; + + case AsicType::GL845: + case AsicType::GL846: + *words = dev->interface->read_register(0x42) & 0x02; + *words = *words * 256 + dev->interface->read_register(0x43); + *words = *words * 256 + dev->interface->read_register(0x44); + *words = *words * 256 + dev->interface->read_register(0x45); + break; + + case AsicType::GL847: + *words = dev->interface->read_register(0x42) & 0x03; + *words = *words * 256 + dev->interface->read_register(0x43); + *words = *words * 256 + dev->interface->read_register(0x44); + *words = *words * 256 + dev->interface->read_register(0x45); + break; + + default: + *words = dev->interface->read_register(0x44); + *words += dev->interface->read_register(0x43) * 256; + if (dev->model->asic_type == AsicType::GL646) { + *words += ((dev->interface->read_register(0x42) & 0x03) * 256 * 256); + } else { + *words += ((dev->interface->read_register(0x42) & 0x0f) * 256 * 256); + } + } + + DBG(DBG_proc, "%s: %d words\n", __func__, *words); +} + +/** read the number of lines scanned + * ie registers 4b-4c-4d + */ +void sanei_genesys_read_scancnt(Genesys_Device* dev, unsigned int* words) +{ + DBG_HELPER(dbg); + + if (dev->model->asic_type == AsicType::GL124) { + *words = (dev->interface->read_register(0x10b) & 0x0f) << 16; + *words += (dev->interface->read_register(0x10c) << 8); + *words += dev->interface->read_register(0x10d); + } + else + { + *words = dev->interface->read_register(0x4d); + *words += dev->interface->read_register(0x4c) * 256; + if (dev->model->asic_type == AsicType::GL646) { + *words += ((dev->interface->read_register(0x4b) & 0x03) * 256 * 256); + } else { + *words += ((dev->interface->read_register(0x4b) & 0x0f) * 256 * 256); + } + } + + DBG(DBG_proc, "%s: %d lines\n", __func__, *words); +} + +/** @brief Check if the scanner's internal data buffer is empty + * @param *dev device to test for data + * @param *empty return value + * @return empty will be set to true if there is no scanned data. + **/ +bool sanei_genesys_is_buffer_empty(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + + dev->interface->sleep_ms(1); + + auto status = scanner_read_status(*dev); + + if (status.is_buffer_empty) { + /* fix timing issue on USB3 (or just may be too fast) hardware + * spotted by John S. Weber <jweber53@gmail.com> + */ + dev->interface->sleep_ms(1); + DBG(DBG_io2, "%s: buffer is empty\n", __func__); + return true; + } + + + DBG(DBG_io, "%s: buffer is filled\n", __func__); + return false; +} + +void wait_until_buffer_non_empty(Genesys_Device* dev, bool check_status_twice) +{ + // FIXME: reduce MAX_RETRIES once tests are updated + const unsigned MAX_RETRIES = 100000; + for (unsigned i = 0; i < MAX_RETRIES; ++i) { + + if (check_status_twice) { + // FIXME: this only to preserve previous behavior, can be removed + scanner_read_status(*dev); + } + + bool empty = sanei_genesys_is_buffer_empty(dev); + dev->interface->sleep_ms(10); + if (!empty) + return; + } + throw SaneException(SANE_STATUS_IO_ERROR, "failed to read data"); +} + +void wait_until_has_valid_words(Genesys_Device* dev) +{ + unsigned words = 0; + unsigned sleep_time_ms = 10; + + for (unsigned wait_ms = 0; wait_ms < 50000; wait_ms += sleep_time_ms) { + sanei_genesys_read_valid_words(dev, &words); + if (words != 0) + break; + dev->interface->sleep_ms(sleep_time_ms); + } + + if (words == 0) { + throw SaneException(SANE_STATUS_IO_ERROR, "timeout, buffer does not get filled"); + } +} + +// Read data (e.g scanned image) from scan buffer +void sanei_genesys_read_data_from_scanner(Genesys_Device* dev, uint8_t* data, size_t size) +{ + DBG_HELPER_ARGS(dbg, "size = %zu bytes", size); + + if (size & 1) + DBG(DBG_info, "WARNING %s: odd number of bytes\n", __func__); + + wait_until_has_valid_words(dev); + + dev->interface->bulk_read_data(0x45, data, size); +} + +Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& session, + std::size_t total_bytes) +{ + DBG_HELPER(dbg); + + auto format = create_pixel_format(session.params.depth, + dev->model->is_cis ? 1 : session.params.channels, + dev->model->line_mode_color_order); + + auto width = get_pixels_from_row_bytes(format, session.output_line_bytes_raw); + auto height = session.output_line_count * (dev->model->is_cis ? session.params.channels : 1); + + Image image(width, height, format); + + auto max_bytes = image.get_row_bytes() * height; + if (total_bytes > max_bytes) { + throw SaneException("Trying to read too much data %zu (max %zu)", total_bytes, max_bytes); + } + if (total_bytes != max_bytes) { + DBG(DBG_info, "WARNING %s: trying to read not enough data (%zu, full fill %zu\n", __func__, + total_bytes, max_bytes); + } + + sanei_genesys_read_data_from_scanner(dev, image.get_row_ptr(0), total_bytes); + + ImagePipelineStack pipeline; + pipeline.push_first_node<ImagePipelineNodeImageSource>(image); + + if ((dev->model->flags & GENESYS_FLAG_16BIT_DATA_INVERTED) && session.params.depth == 16) { + dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>(); + } + +#ifdef WORDS_BIGENDIAN + if (depth == 16) { + dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>(); + } +#endif + + if (dev->model->is_cis && session.params.channels == 3) { + dev->pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order); + } + + if (dev->pipeline.get_output_format() == PixelFormat::BGR888) { + dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888); + } + + if (dev->pipeline.get_output_format() == PixelFormat::BGR161616) { + dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616); + } + + return pipeline.get_image(); +} + +void sanei_genesys_read_feed_steps(Genesys_Device* dev, unsigned int* steps) +{ + DBG_HELPER(dbg); + + if (dev->model->asic_type == AsicType::GL124) { + *steps = (dev->interface->read_register(0x108) & 0x1f) << 16; + *steps += (dev->interface->read_register(0x109) << 8); + *steps += dev->interface->read_register(0x10a); + } + else + { + *steps = dev->interface->read_register(0x4a); + *steps += dev->interface->read_register(0x49) * 256; + if (dev->model->asic_type == AsicType::GL646) { + *steps += ((dev->interface->read_register(0x48) & 0x03) * 256 * 256); + } else if (dev->model->asic_type == AsicType::GL841) { + *steps += ((dev->interface->read_register(0x48) & 0x0f) * 256 * 256); + } else { + *steps += ((dev->interface->read_register(0x48) & 0x1f) * 256 * 256); + } + } + + DBG(DBG_proc, "%s: %d steps\n", __func__, *steps); +} + +void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, bool set) +{ + static const uint8_t REG_0x03_LAMPPWR = 0x10; + + if (set) { + regs.find_reg(0x03).value |= REG_0x03_LAMPPWR; + + if (dev->model->asic_type == AsicType::GL841) { + regs_set_exposure(dev->model->asic_type, regs, + sanei_genesys_fixup_exposure(sensor.exposure)); + regs.set8(0x19, 0x50); + } + + if (dev->model->asic_type == AsicType::GL843) { + regs_set_exposure(dev->model->asic_type, regs, sensor.exposure); + + // we don't actually turn on lamp on infrared scan + if ((dev->model->model_id == ModelId::CANON_8400F || + dev->model->model_id == ModelId::CANON_8600F || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) && + dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) + { + regs.find_reg(0x03).value &= ~REG_0x03_LAMPPWR; + } + } + } else { + regs.find_reg(0x03).value &= ~REG_0x03_LAMPPWR; + + if (dev->model->asic_type == AsicType::GL841) { + regs_set_exposure(dev->model->asic_type, regs, {0x0101, 0x0101, 0x0101}); + regs.set8(0x19, 0xff); + } + + if (dev->model->asic_type == AsicType::GL843) { + if (dev->model->model_id == ModelId::PANASONIC_KV_SS080 || + dev->model->model_id == ModelId::HP_SCANJET_4850C || + dev->model->model_id == ModelId::HP_SCANJET_G4010 || + dev->model->model_id == ModelId::HP_SCANJET_G4050) + { + // BUG: datasheet says we shouldn't set exposure to zero + regs_set_exposure(dev->model->asic_type, regs, {0, 0, 0}); + } + } + } + regs.state.is_lamp_on = set; +} + +void sanei_genesys_set_motor_power(Genesys_Register_Set& regs, bool set) +{ + static const uint8_t REG_0x02_MTRPWR = 0x10; + + if (set) { + regs.find_reg(0x02).value |= REG_0x02_MTRPWR; + } else { + regs.find_reg(0x02).value &= ~REG_0x02_MTRPWR; + } + regs.state.is_motor_on = set; +} + +bool should_enable_gamma(const ScanSession& session, const Genesys_Sensor& sensor) +{ + if ((session.params.flags & ScanFlag::DISABLE_GAMMA) != ScanFlag::NONE) { + return false; + } + if (sensor.gamma[0] == 1.0f || sensor.gamma[1] == 1.0f || sensor.gamma[2] == 1.0f) { + return false; + } + if (session.params.depth == 16) + return false; + + return true; +} + +std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor, + int color) +{ + if (!dev->gamma_override_tables[color].empty()) { + return dev->gamma_override_tables[color]; + } else { + std::vector<uint16_t> ret; + sanei_genesys_create_default_gamma_table(dev, ret, sensor.gamma[color]); + return ret; + } +} + +/** @brief generates gamma buffer to transfer + * Generates gamma table buffer to send to ASIC. Applies + * contrast and brightness if set. + * @param dev device to set up + * @param bits number of bits used by gamma + * @param max value for gamma + * @param size of the gamma table + * @param gamma allocated gamma buffer to fill + */ +void sanei_genesys_generate_gamma_buffer(Genesys_Device* dev, + const Genesys_Sensor& sensor, + int bits, + int max, + int size, + uint8_t* gamma) +{ + DBG_HELPER(dbg); + std::vector<uint16_t> rgamma = get_gamma_table(dev, sensor, GENESYS_RED); + std::vector<uint16_t> ggamma = get_gamma_table(dev, sensor, GENESYS_GREEN); + std::vector<uint16_t> bgamma = get_gamma_table(dev, sensor, GENESYS_BLUE); + + if(dev->settings.contrast!=0 || dev->settings.brightness!=0) + { + std::vector<uint16_t> lut(65536); + sanei_genesys_load_lut(reinterpret_cast<unsigned char *>(lut.data()), + bits, + bits, + 0, + max, + dev->settings.contrast, + dev->settings.brightness); + for (int i = 0; i < size; i++) + { + uint16_t value=rgamma[i]; + value=lut[value]; + gamma[i * 2 + size * 0 + 0] = value & 0xff; + gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff; + + value=ggamma[i]; + value=lut[value]; + gamma[i * 2 + size * 2 + 0] = value & 0xff; + gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff; + + value=bgamma[i]; + value=lut[value]; + gamma[i * 2 + size * 4 + 0] = value & 0xff; + gamma[i * 2 + size * 4 + 1] = (value >> 8) & 0xff; + } + } + else + { + for (int i = 0; i < size; i++) + { + uint16_t value=rgamma[i]; + gamma[i * 2 + size * 0 + 0] = value & 0xff; + gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff; + + value=ggamma[i]; + gamma[i * 2 + size * 2 + 0] = value & 0xff; + gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff; + + value=bgamma[i]; + gamma[i * 2 + size * 4 + 0] = value & 0xff; + gamma[i * 2 + size * 4 + 1] = (value >> 8) & 0xff; + } + } +} + + +/** @brief send gamma table to scanner + * This function sends generic gamma table (ie ones built with + * provided gamma) or the user defined one if provided by + * fontend. Used by gl846+ ASICs + * @param dev device to write to + */ +void sanei_genesys_send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) +{ + DBG_HELPER(dbg); + int size; + int i; + + size = 256 + 1; + + /* allocate temporary gamma tables: 16 bits words, 3 channels */ + std::vector<uint8_t> gamma(size * 2 * 3, 255); + + sanei_genesys_generate_gamma_buffer(dev, sensor, 16, 65535, size, gamma.data()); + + // loop sending gamma tables NOTE: 0x01000000 not 0x10000000 + for (i = 0; i < 3; i++) { + // clear corresponding GMM_N bit + uint8_t val = dev->interface->read_register(0xbd); + val &= ~(0x01 << i); + dev->interface->write_register(0xbd, val); + + // clear corresponding GMM_F bit + val = dev->interface->read_register(0xbe); + val &= ~(0x01 << i); + dev->interface->write_register(0xbe, val); + + // FIXME: currently the last word of each gamma table is not initialied, so to work around + // unstable data, just set it to 0 which is the most likely value of uninitialized memory + // (proper value is probably 0xff) + gamma[size * 2 * i + size * 2 - 2] = 0; + gamma[size * 2 * i + size * 2 - 1] = 0; + + /* set GMM_Z */ + dev->interface->write_register(0xc5+2*i, gamma[size*2*i+1]); + dev->interface->write_register(0xc6+2*i, gamma[size*2*i]); + + dev->interface->write_ahb(0x01000000 + 0x200 * i, (size-1) * 2, + gamma.data() + i * size * 2+2); + } +} + +static unsigned align_int_up(unsigned num, unsigned alignment) +{ + unsigned mask = alignment - 1; + if (num & mask) + num = (num & ~mask) + alignment; + return num; +} + +void compute_session_buffer_sizes(AsicType asic, ScanSession& s) +{ + size_t line_bytes = s.output_line_bytes; + size_t line_bytes_stagger = s.output_line_bytes; + + if (asic != AsicType::GL646) { + // BUG: this is historical artifact and should be removed. Note that buffer sizes affect + // how often we request the scanner for data and thus change the USB traffic. + line_bytes_stagger = + multiply_by_depth_ceil(s.optical_pixels, s.params.depth) * s.params.channels; + } + + struct BufferConfig { + size_t* result_size = nullptr; + size_t lines = 0; + size_t lines_mult = 0; + size_t max_size = 0; // does not apply if 0 + size_t stagger_lines = 0; + + BufferConfig() = default; + BufferConfig(std::size_t* rs, std::size_t l, std::size_t lm, std::size_t ms, + std::size_t sl) : + result_size{rs}, + lines{l}, + lines_mult{lm}, + max_size{ms}, + stagger_lines{sl} + {} + }; + + std::array<BufferConfig, 4> configs; + if (asic == AsicType::GL124 || asic == AsicType::GL843) { + configs = { { + { &s.buffer_size_read, 32, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_lines, 32, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_shrink, 16, 1, 0, 0 }, + { &s.buffer_size_out, 8, 1, 0, 0 }, + } }; + } else if (asic == AsicType::GL841) { + size_t max_buf = sanei_genesys_get_bulk_max_size(asic); + configs = { { + { &s.buffer_size_read, 8, 2, max_buf, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_lines, 8, 2, max_buf, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_shrink, 8, 1, max_buf, 0 }, + { &s.buffer_size_out, 8, 1, 0, 0 }, + } }; + } else { + configs = { { + { &s.buffer_size_read, 16, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_lines, 16, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_shrink, 8, 1, 0, 0 }, + { &s.buffer_size_out, 8, 1, 0, 0 }, + } }; + } + + for (BufferConfig& config : configs) { + size_t buf_size = line_bytes * config.lines; + if (config.max_size > 0 && buf_size > config.max_size) { + buf_size = (config.max_size / line_bytes) * line_bytes; + } + buf_size *= config.lines_mult; + buf_size += line_bytes_stagger * config.stagger_lines; + *config.result_size = buf_size; + } +} + +void compute_session_pipeline(const Genesys_Device* dev, ScanSession& s) +{ + auto channels = s.params.channels; + auto depth = s.params.depth; + + s.pipeline_needs_reorder = true; + if (channels != 3 && depth != 16) { + s.pipeline_needs_reorder = false; + } +#ifndef WORDS_BIGENDIAN + if (channels != 3 && depth == 16) { + s.pipeline_needs_reorder = false; + } + if (channels == 3 && depth == 16 && !dev->model->is_cis && + dev->model->line_mode_color_order == ColorOrder::RGB) + { + s.pipeline_needs_reorder = false; + } +#endif + if (channels == 3 && depth == 8 && !dev->model->is_cis && + dev->model->line_mode_color_order == ColorOrder::RGB) + { + s.pipeline_needs_reorder = false; + } + s.pipeline_needs_ccd = s.max_color_shift_lines + s.num_staggered_lines > 0; + s.pipeline_needs_shrink = dev->settings.requested_pixels != s.output_pixels; +} + +void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s, + const Genesys_Sensor& sensor) +{ + unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); + + if (dev->model->asic_type == AsicType::GL646) { + + // startx cannot be below dummy pixel value + s.pixel_startx = sensor.dummy_pixel; + if (has_flag(s.params.flags, ScanFlag::USE_XCORRECTION) && sensor.ccd_start_xoffset > 0) { + s.pixel_startx = sensor.ccd_start_xoffset; + } + s.pixel_startx += s.params.startx; + + if (sensor.stagger_config.stagger_at_resolution(s.params.xres, s.params.yres) > 0) { + s.pixel_startx |= 1; + } + + s.pixel_endx = s.pixel_startx + s.optical_pixels; + + s.pixel_startx /= sensor.ccd_pixels_per_system_pixel() * s.ccd_size_divisor; + s.pixel_endx /= sensor.ccd_pixels_per_system_pixel() * s.ccd_size_divisor; + + } else if (dev->model->asic_type == AsicType::GL841) { + s.pixel_startx = ((sensor.ccd_start_xoffset + s.params.startx) * s.optical_resolution) + / sensor.optical_res; + + s.pixel_startx += sensor.dummy_pixel + 1; + + if (s.num_staggered_lines > 0 && (s.pixel_startx & 1) == 0) { + s.pixel_startx++; + } + + /* In case of SHDAREA, we need to align start on pixel average factor, startx is + different than 0 only when calling for function to setup for scan, where shading data + needs to be align. + + NOTE: we can check the value of the register here, because we don't set this bit + anywhere except in initialization. + */ + const uint8_t REG_0x01_SHDAREA = 0x02; + if ((dev->reg.find_reg(0x01).value & REG_0x01_SHDAREA) != 0) { + unsigned average_factor = s.optical_resolution / s.params.xres; + s.pixel_startx = align_multiple_floor(s.pixel_startx, average_factor); + } + + s.pixel_endx = s.pixel_startx + s.optical_pixels; + + } else if (dev->model->asic_type == AsicType::GL843) { + + s.pixel_startx = (s.params.startx + sensor.dummy_pixel) / ccd_pixels_per_system_pixel; + s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel; + + s.pixel_startx /= s.hwdpi_divisor; + s.pixel_endx /= s.hwdpi_divisor; + + // in case of stagger we have to start at an odd coordinate + bool stagger_starts_even = dev->model->model_id == ModelId::CANON_8400F; + if (s.num_staggered_lines > 0) { + if (!stagger_starts_even && (s.pixel_startx & 1) == 0) { + s.pixel_startx++; + s.pixel_endx++; + } else if (stagger_starts_even && (s.pixel_startx & 1) != 0) { + s.pixel_startx++; + s.pixel_endx++; + } + } + + } else if (dev->model->asic_type == AsicType::GL845 || + dev->model->asic_type == AsicType::GL846 || + dev->model->asic_type == AsicType::GL847) + { + s.pixel_startx = s.params.startx; + + if (s.num_staggered_lines > 0) { + s.pixel_startx |= 1; + } + + s.pixel_startx += sensor.ccd_start_xoffset * ccd_pixels_per_system_pixel; + s.pixel_endx = s.pixel_startx + s.optical_pixels_raw; + + s.pixel_startx /= s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel; + s.pixel_endx /= s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel; + + } else if (dev->model->asic_type == AsicType::GL124) { + s.pixel_startx = s.params.startx; + + if (s.num_staggered_lines > 0) { + s.pixel_startx |= 1; + } + + s.pixel_startx /= ccd_pixels_per_system_pixel; + // FIXME: should we add sensor.dummy_pxel to pixel_startx at this point? + s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel; + + s.pixel_startx /= s.hwdpi_divisor * s.segment_count; + s.pixel_endx /= s.hwdpi_divisor * s.segment_count; + + std::uint32_t segcnt = (sensor.custom_regs.get_value(gl124::REG_SEGCNT) << 16) + + (sensor.custom_regs.get_value(gl124::REG_SEGCNT + 1) << 8) + + sensor.custom_regs.get_value(gl124::REG_SEGCNT + 2); + if (s.pixel_endx == segcnt) { + s.pixel_endx = 0; + } + } + + s.pixel_count_multiplier = sensor.pixel_count_multiplier; + + s.pixel_startx *= sensor.pixel_count_multiplier; + s.pixel_endx *= sensor.pixel_count_multiplier; +} + +void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor) +{ + DBG_HELPER(dbg); + + (void) dev; + s.params.assert_valid(); + + if (s.params.depth != 8 && s.params.depth != 16) { + throw SaneException("Unsupported depth setting %d", s.params.depth); + } + + unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); + + // compute optical and output resolutions + + if (dev->model->asic_type == AsicType::GL843) { + // FIXME: this may be incorrect, but need more scanners to test + s.hwdpi_divisor = sensor.get_hwdpi_divisor_for_dpi(s.params.xres); + } else { + s.hwdpi_divisor = sensor.get_hwdpi_divisor_for_dpi(s.params.xres * ccd_pixels_per_system_pixel); + } + + s.ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(s.params.xres); + + if (dev->model->asic_type == AsicType::GL646) { + s.optical_resolution = sensor.optical_res; + } else { + s.optical_resolution = sensor.optical_res / s.ccd_size_divisor; + } + s.output_resolution = s.params.xres; + + if (s.output_resolution > s.optical_resolution) { + throw std::runtime_error("output resolution higher than optical resolution"); + } + + // compute the number of optical pixels that will be acquired by the chip + s.optical_pixels = (s.params.pixels * s.optical_resolution) / s.output_resolution; + if (s.optical_pixels * s.output_resolution < s.params.pixels * s.optical_resolution) { + s.optical_pixels++; + } + + if (dev->model->asic_type == AsicType::GL841) { + if (s.optical_pixels & 1) + s.optical_pixels++; + } + + if (dev->model->asic_type == AsicType::GL646 && s.params.xres == 400) { + s.optical_pixels = (s.optical_pixels / 6) * 6; + } + + if (dev->model->asic_type == AsicType::GL843) { + // ensure the number of optical pixels is divisible by 2. + // In quarter-CCD mode optical_pixels is 4x larger than the actual physical number + s.optical_pixels = align_int_up(s.optical_pixels, 2 * s.ccd_size_divisor); + + if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200I || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7300 || + dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7500I) + { + s.optical_pixels = align_int_up(s.optical_pixels, 16); + } + } + + // after all adjustments on the optical pixels have been made, compute the number of pixels + // to retrieve from the chip + s.output_pixels = (s.optical_pixels * s.output_resolution) / s.optical_resolution; + + // Note: staggering is not applied for calibration. Staggering starts at 2400 dpi + s.num_staggered_lines = 0; + if (!has_flag(s.params.flags, ScanFlag::IGNORE_LINE_DISTANCE)) + { + s.num_staggered_lines = sensor.stagger_config.stagger_at_resolution(s.params.xres, + s.params.yres); + } + + s.color_shift_lines_r = dev->model->ld_shift_r; + s.color_shift_lines_g = dev->model->ld_shift_g; + s.color_shift_lines_b = dev->model->ld_shift_b; + + if (dev->model->motor_id == MotorId::G4050 && s.params.yres > 600) { + // it seems base_dpi of the G4050 motor is changed above 600 dpi + s.color_shift_lines_r = (s.color_shift_lines_r * 3800) / dev->motor.base_ydpi; + s.color_shift_lines_g = (s.color_shift_lines_g * 3800) / dev->motor.base_ydpi; + s.color_shift_lines_b = (s.color_shift_lines_b * 3800) / dev->motor.base_ydpi; + } + + s.color_shift_lines_r = (s.color_shift_lines_r * s.params.yres) / dev->motor.base_ydpi; + s.color_shift_lines_g = (s.color_shift_lines_g * s.params.yres) / dev->motor.base_ydpi; + s.color_shift_lines_b = (s.color_shift_lines_b * s.params.yres) / dev->motor.base_ydpi; + + s.max_color_shift_lines = 0; + if (s.params.channels > 1 && !has_flag(s.params.flags, ScanFlag::IGNORE_LINE_DISTANCE)) { + s.max_color_shift_lines = std::max(s.color_shift_lines_r, std::max(s.color_shift_lines_g, + s.color_shift_lines_b)); + } + + s.output_line_count = s.params.lines + s.max_color_shift_lines + s.num_staggered_lines; + + s.output_channel_bytes = multiply_by_depth_ceil(s.output_pixels, s.params.depth); + s.output_line_bytes = s.output_channel_bytes * s.params.channels; + + s.segment_count = sensor.get_segment_count(); + + s.optical_pixels_raw = s.optical_pixels; + s.output_line_bytes_raw = s.output_line_bytes; + s.conseq_pixel_dist = 0; + + if (dev->model->asic_type == AsicType::GL845 || + dev->model->asic_type == AsicType::GL846 || + dev->model->asic_type == AsicType::GL847) + { + if (s.segment_count > 1) { + s.conseq_pixel_dist = sensor.segment_size; + + // in case of multi-segments sensor, we have to add the width of the sensor crossed by + // the scan area + unsigned extra_segment_scan_area = align_multiple_ceil(s.conseq_pixel_dist, 2); + extra_segment_scan_area *= s.segment_count - 1; + extra_segment_scan_area *= s.hwdpi_divisor * s.segment_count; + extra_segment_scan_area *= ccd_pixels_per_system_pixel; + + s.optical_pixels_raw += extra_segment_scan_area; + } + + s.output_line_bytes_raw = multiply_by_depth_ceil( + (s.optical_pixels_raw * s.output_resolution) / sensor.optical_res / s.segment_count, + s.params.depth); + } + + if (dev->model->asic_type == AsicType::GL841) { + if (dev->model->is_cis) { + s.output_line_bytes_raw = s.output_channel_bytes; + } + } + + if (dev->model->asic_type == AsicType::GL124) { + if (dev->model->is_cis) { + s.output_line_bytes_raw = s.output_channel_bytes; + } + s.conseq_pixel_dist = s.output_pixels / s.ccd_size_divisor / s.segment_count; + } + + if (dev->model->asic_type == AsicType::GL843) { + s.conseq_pixel_dist = s.output_pixels / s.segment_count; + } + + s.output_segment_pixel_group_count = 0; + if (dev->model->asic_type == AsicType::GL124 || + dev->model->asic_type == AsicType::GL843) + { + s.output_segment_pixel_group_count = multiply_by_depth_ceil( + s.output_pixels / s.ccd_size_divisor / s.segment_count, s.params.depth); + } + if (dev->model->asic_type == AsicType::GL845 || + dev->model->asic_type == AsicType::GL846 || + dev->model->asic_type == AsicType::GL847) + { + s.output_segment_pixel_group_count = multiply_by_depth_ceil( + s.optical_pixels / (s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel), + s.params.depth); + } + + s.output_line_bytes_requested = multiply_by_depth_ceil( + s.params.get_requested_pixels() * s.params.channels, s.params.depth); + + s.output_total_bytes_raw = s.output_line_bytes_raw * s.output_line_count; + s.output_total_bytes = s.output_line_bytes * s.output_line_count; + + compute_session_buffer_sizes(dev->model->asic_type, s); + compute_session_pipeline(dev, s); + compute_session_pixel_offsets(dev, s, sensor); + + if (dev->model->asic_type == AsicType::GL124 || + dev->model->asic_type == AsicType::GL845 || + dev->model->asic_type == AsicType::GL846) + { + s.enable_ledadd = (s.params.channels == 1 && dev->model->is_cis && dev->settings.true_gray); + } + + if (dev->model->asic_type == AsicType::GL841 || + dev->model->asic_type == AsicType::GL843) + { + // no 16 bit gamma for this ASIC + if (s.params.depth == 16) { + s.params.flags |= ScanFlag::DISABLE_GAMMA; + } + } + + s.computed = true; + + DBG(DBG_info, "%s ", __func__); + debug_dump(DBG_info, s); +} + +static std::size_t get_usb_buffer_read_size(AsicType asic, const ScanSession& session) +{ + switch (asic) { + case AsicType::GL646: + // buffer not used on this chip set + return 1; + + case AsicType::GL124: + // BUG: we shouldn't multiply by channels here nor divide by ccd_size_divisor + return session.output_line_bytes_raw / session.ccd_size_divisor * session.params.channels; + + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + // BUG: we shouldn't multiply by channels here + return session.output_line_bytes_raw * session.params.channels; + + case AsicType::GL843: + return session.output_line_bytes_raw * 2; + + default: + throw SaneException("Unknown asic type"); + } +} + +static FakeBufferModel get_fake_usb_buffer_model(const ScanSession& session) +{ + FakeBufferModel model; + model.push_step(session.buffer_size_read, 1); + + if (session.pipeline_needs_reorder) { + model.push_step(session.buffer_size_lines, session.output_line_bytes); + } + if (session.pipeline_needs_ccd) { + model.push_step(session.buffer_size_shrink, session.output_line_bytes); + } + if (session.pipeline_needs_shrink) { + model.push_step(session.buffer_size_out, session.output_line_bytes); + } + + return model; +} + +void build_image_pipeline(Genesys_Device* dev, const ScanSession& session) +{ + static unsigned s_pipeline_index = 0; + + s_pipeline_index++; + + auto format = create_pixel_format(session.params.depth, + dev->model->is_cis ? 1 : session.params.channels, + dev->model->line_mode_color_order); + auto depth = get_pixel_format_depth(format); + auto width = get_pixels_from_row_bytes(format, session.output_line_bytes_raw); + + auto read_data_from_usb = [dev](std::size_t size, std::uint8_t* data) + { + dev->interface->bulk_read_data(0x45, data, size); + return true; + }; + + auto lines = session.output_line_count * (dev->model->is_cis ? session.params.channels : 1); + + dev->pipeline.clear(); + + // FIXME: here we are complicating things for the time being to preserve the existing behaviour + // This allows to be sure that the changes to the image pipeline have not introduced + // regressions. + + if (session.segment_count > 1) { + // BUG: we're reading one line too much + dev->pipeline.push_first_node<ImagePipelineNodeBufferedCallableSource>( + width, lines + 1, format, + get_usb_buffer_read_size(dev->model->asic_type, session), read_data_from_usb); + + auto output_width = session.output_segment_pixel_group_count * session.segment_count; + dev->pipeline.push_node<ImagePipelineNodeDesegment>(output_width, dev->segment_order, + session.conseq_pixel_dist, + 1, 1); + } else { + auto read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count; + if (dev->model->asic_type == AsicType::GL646) { + read_bytes_left_after_deseg *= dev->model->is_cis ? session.params.channels : 1; + } + + dev->pipeline.push_first_node<ImagePipelineNodeBufferedGenesysUsb>( + width, lines, format, read_bytes_left_after_deseg, + get_fake_usb_buffer_model(session), read_data_from_usb); + } + + if (DBG_LEVEL >= DBG_io2) { + dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + + std::to_string(s_pipeline_index) + + "_0_before_swap.pnm"); + } + + if ((dev->model->flags & GENESYS_FLAG_16BIT_DATA_INVERTED) && depth == 16) { + dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>(); + } + +#ifdef WORDS_BIGENDIAN + if (depth == 16) { + dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>(); + } +#endif + + if (DBG_LEVEL >= DBG_io2) { + dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + + std::to_string(s_pipeline_index) + + "_1_after_swap.pnm"); + } + + if (dev->model->is_cis && session.params.channels == 3) { + dev->pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order); + } + + if (dev->pipeline.get_output_format() == PixelFormat::BGR888) { + dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888); + } + + if (dev->pipeline.get_output_format() == PixelFormat::BGR161616) { + dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616); + } + + if (session.max_color_shift_lines > 0 && session.params.channels == 3) { + dev->pipeline.push_node<ImagePipelineNodeComponentShiftLines>( + session.color_shift_lines_r, + session.color_shift_lines_g, + session.color_shift_lines_b); + } + + if (DBG_LEVEL >= DBG_io2) { + dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + + std::to_string(s_pipeline_index) + + "_2_after_shift.pnm"); + } + + if (session.num_staggered_lines > 0) { + std::vector<std::size_t> shifts{0, session.num_staggered_lines}; + dev->pipeline.push_node<ImagePipelineNodePixelShiftLines>(shifts); + } + + if (DBG_LEVEL >= DBG_io2) { + dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + + std::to_string(s_pipeline_index) + + "_3_after_stagger.pnm"); + } + + if ((dev->model->flags & GENESYS_FLAG_CALIBRATION_HOST_SIDE) && + !(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) + { + dev->pipeline.push_node<ImagePipelineNodeCalibrate>(dev->dark_average_data, + dev->white_average_data); + + if (DBG_LEVEL >= DBG_io2) { + dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + + std::to_string(s_pipeline_index) + + "_4_after_calibrate.pnm"); + } + } + + if (session.output_pixels != session.params.get_requested_pixels()) { + dev->pipeline.push_node<ImagePipelineNodeScaleRows>(session.params.get_requested_pixels()); + } + + auto read_from_pipeline = [dev](std::size_t size, std::uint8_t* out_data) + { + (void) size; // will be always equal to dev->pipeline.get_output_row_bytes() + return dev->pipeline.get_next_row_data(out_data); + }; + dev->pipeline_buffer = ImageBuffer{dev->pipeline.get_output_row_bytes(), + read_from_pipeline}; +} + +std::uint8_t compute_frontend_gain_wolfson(float value, float target_value) +{ + /* the flow of data through the frontend ADC is as follows (see e.g. WM8192 datasheet) + input + -> apply offset (o = i + 260mV * (DAC[7:0]-127.5)/127.5) -> + -> apply gain (o = i * 208/(283-PGA[7:0]) + -> ADC + + Here we have some input data that was acquired with zero gain (PGA==0). + We want to compute gain such that the output would approach full ADC range (controlled by + target_value). + + We want to solve the following for {PGA}: + + {value} = {input} * 208 / (283 - 0) + {target_value} = {input} * 208 / (283 - {PGA}) + + The solution is the following equation: + + {PGA} = 283 * (1 - {value} / {target_value}) + */ + float gain = value / target_value; + int code = static_cast<int>(283 * (1 - gain)); + return clamp(code, 0, 255); +} + +std::uint8_t compute_frontend_gain_analog_devices(float value, float target_value) +{ + /* The flow of data through the frontend ADC is as follows (see e.g. AD9826 datasheet) + input + -> apply offset (o = i + 300mV * (OFFSET[8] ? 1 : -1) * (OFFSET[7:0] / 127) + -> apply gain (o = i * 6 / (1 + 5 * ( 63 - PGA[5:0] ) / 63 ) ) + -> ADC + + We want to solve the following for {PGA}: + + {value} = {input} * 6 / (1 + 5 * ( 63 - 0) / 63 ) ) + {target_value} = {input} * 6 / (1 + 5 * ( 63 - {PGA}) / 63 ) ) + + The solution is the following equation: + + {PGA} = (378 / 5) * ({target_value} - {value} / {target_value}) + */ + int code = static_cast<int>((378.0f / 5.0f) * ((target_value - value) / target_value)); + return clamp(code, 0, 63); +} + +std::uint8_t compute_frontend_gain(float value, float target_value, + FrontendType frontend_type) +{ + if (frontend_type == FrontendType::WOLFSON) { + return compute_frontend_gain_wolfson(value, target_value); + } + if (frontend_type == FrontendType::ANALOG_DEVICES) { + return compute_frontend_gain_analog_devices(value, target_value); + } + throw SaneException("Unknown frontend to compute gain for"); +} + +/** @brief initialize device + * Initialize backend and ASIC : registers, motor tables, and gamma tables + * then ensure scanner's head is at home. Designed for gl846+ ASICs. + * Detects cold boot (ie first boot since device plugged) in this case + * an extensice setup up is done at hardware level. + * + * @param dev device to initialize + * @param max_regs umber of maximum used registers + */ +void sanei_genesys_asic_init(Genesys_Device* dev, bool /*max_regs*/) +{ + DBG_HELPER(dbg); + + uint8_t val; + bool cold = true; + + // URB 16 control 0xc0 0x0c 0x8e 0x0b len 1 read 0x00 */ + dev->interface->get_usb_device().control_msg(REQUEST_TYPE_IN, REQUEST_REGISTER, + VALUE_GET_REGISTER, 0x00, 1, &val); + + DBG (DBG_io2, "%s: value=0x%02x\n", __func__, val); + DBG (DBG_info, "%s: device is %s\n", __func__, (val & 0x08) ? "USB 1.0" : "USB2.0"); + if (val & 0x08) + { + dev->usb_mode = 1; + } + else + { + dev->usb_mode = 2; + } + + /* Check if the device has already been initialized and powered up. We read register 0x06 and + check PWRBIT, if reset scanner has been freshly powered up. This bit will be set to later + so that following reads can detect power down/up cycle + */ + if (!is_testing_mode()) { + if (dev->interface->read_register(0x06) & 0x10) { + cold = false; + } + } + DBG (DBG_info, "%s: device is %s\n", __func__, cold ? "cold" : "warm"); + + /* don't do anything if backend is initialized and hardware hasn't been + * replug */ + if (dev->already_initialized && !cold) + { + DBG (DBG_info, "%s: already initialized, nothing to do\n", __func__); + return; + } + + // set up hardware and registers + dev->cmd_set->asic_boot(dev, cold); + + /* now hardware part is OK, set up device struct */ + dev->white_average_data.clear(); + dev->dark_average_data.clear(); + + dev->settings.color_filter = ColorFilter::RED; + + /* duplicate initial values into calibration registers */ + dev->calib_reg = dev->reg; + + const auto& sensor = sanei_genesys_find_sensor_any(dev); + + // Set analog frontend + dev->cmd_set->set_fe(dev, sensor, AFE_INIT); + + dev->already_initialized = true; + + // Move to home if needed + dev->cmd_set->move_back_home(dev, true); + dev->set_head_pos_zero(ScanHeadId::PRIMARY); + + // Set powersaving (default = 15 minutes) + dev->cmd_set->set_powersaving(dev, 15); +} + +void scanner_start_action(Genesys_Device& dev, bool start_motor) +{ + DBG_HELPER(dbg); + switch (dev.model->asic_type) { + case AsicType::GL646: + case AsicType::GL841: + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + case AsicType::GL124: + break; + default: + throw SaneException("Unsupported chip"); + } + + if (start_motor) { + dev.interface->write_register(0x0f, 0x01); + } else { + dev.interface->write_register(0x0f, 0); + } +} + +void sanei_genesys_set_dpihw(Genesys_Register_Set& regs, const Genesys_Sensor& sensor, + unsigned dpihw) +{ + // same across GL646, GL841, GL843, GL846, GL847, GL124 + const uint8_t REG_0x05_DPIHW_MASK = 0xc0; + const uint8_t REG_0x05_DPIHW_600 = 0x00; + const uint8_t REG_0x05_DPIHW_1200 = 0x40; + const uint8_t REG_0x05_DPIHW_2400 = 0x80; + const uint8_t REG_0x05_DPIHW_4800 = 0xc0; + + if (sensor.register_dpihw_override != 0) { + dpihw = sensor.register_dpihw_override; + } + + uint8_t dpihw_setting; + switch (dpihw) { + case 600: + dpihw_setting = REG_0x05_DPIHW_600; + break; + case 1200: + dpihw_setting = REG_0x05_DPIHW_1200; + break; + case 2400: + dpihw_setting = REG_0x05_DPIHW_2400; + break; + case 4800: + dpihw_setting = REG_0x05_DPIHW_4800; + break; + default: + throw SaneException("Unknown dpihw value: %d", dpihw); + } + regs.set8_mask(0x05, dpihw_setting, REG_0x05_DPIHW_MASK); +} + +void regs_set_exposure(AsicType asic_type, Genesys_Register_Set& regs, + const SensorExposure& exposure) +{ + switch (asic_type) { + case AsicType::GL124: { + regs.set24(gl124::REG_EXPR, exposure.red); + regs.set24(gl124::REG_EXPG, exposure.green); + regs.set24(gl124::REG_EXPB, exposure.blue); + break; + } + case AsicType::GL646: { + regs.set16(gl646::REG_EXPR, exposure.red); + regs.set16(gl646::REG_EXPG, exposure.green); + regs.set16(gl646::REG_EXPB, exposure.blue); + break; + } + case AsicType::GL841: { + regs.set16(gl841::REG_EXPR, exposure.red); + regs.set16(gl841::REG_EXPG, exposure.green); + regs.set16(gl841::REG_EXPB, exposure.blue); + break; + } + case AsicType::GL843: { + regs.set16(gl843::REG_EXPR, exposure.red); + regs.set16(gl843::REG_EXPG, exposure.green); + regs.set16(gl843::REG_EXPB, exposure.blue); + break; + } + case AsicType::GL845: + case AsicType::GL846: { + regs.set16(gl846::REG_EXPR, exposure.red); + regs.set16(gl846::REG_EXPG, exposure.green); + regs.set16(gl846::REG_EXPB, exposure.blue); + break; + } + case AsicType::GL847: { + regs.set16(gl847::REG_EXPR, exposure.red); + regs.set16(gl847::REG_EXPG, exposure.green); + regs.set16(gl847::REG_EXPB, exposure.blue); + break; + } + default: + throw SaneException("Unsupported asic"); + } +} + +void regs_set_optical_off(AsicType asic_type, Genesys_Register_Set& regs) +{ + DBG_HELPER(dbg); + switch (asic_type) { + case AsicType::GL646: { + regs.find_reg(gl646::REG_0x01).value &= ~gl646::REG_0x01_SCAN; + break; + } + case AsicType::GL841: { + regs.find_reg(gl841::REG_0x01).value &= ~gl841::REG_0x01_SCAN; + break; + } + case AsicType::GL843: { + regs.find_reg(gl843::REG_0x01).value &= ~gl843::REG_0x01_SCAN; + break; + } + case AsicType::GL845: + case AsicType::GL846: { + regs.find_reg(gl846::REG_0x01).value &= ~gl846::REG_0x01_SCAN; + break; + } + case AsicType::GL847: { + regs.find_reg(gl847::REG_0x01).value &= ~gl847::REG_0x01_SCAN; + break; + } + case AsicType::GL124: { + regs.find_reg(gl124::REG_0x01).value &= ~gl124::REG_0x01_SCAN; + break; + } + default: + throw SaneException("Unsupported asic"); + } +} + +bool get_registers_gain4_bit(AsicType asic_type, const Genesys_Register_Set& regs) +{ + switch (asic_type) { + case AsicType::GL646: + return static_cast<bool>(regs.get8(gl646::REG_0x06) & gl646::REG_0x06_GAIN4); + case AsicType::GL841: + return static_cast<bool>(regs.get8(gl841::REG_0x06) & gl841::REG_0x06_GAIN4); + case AsicType::GL843: + return static_cast<bool>(regs.get8(gl843::REG_0x06) & gl843::REG_0x06_GAIN4); + case AsicType::GL845: + case AsicType::GL846: + return static_cast<bool>(regs.get8(gl846::REG_0x06) & gl846::REG_0x06_GAIN4); + case AsicType::GL847: + return static_cast<bool>(regs.get8(gl847::REG_0x06) & gl847::REG_0x06_GAIN4); + case AsicType::GL124: + return static_cast<bool>(regs.get8(gl124::REG_0x06) & gl124::REG_0x06_GAIN4); + default: + throw SaneException("Unsupported chipset"); + } +} + +/** + * Wait for the scanning head to park + */ +void sanei_genesys_wait_for_home(Genesys_Device* dev) +{ + DBG_HELPER(dbg); + + /* clear the parking status whatever the outcome of the function */ + dev->parking = false; + + if (is_testing_mode()) { + return; + } + + // read initial status, if head isn't at home and motor is on we are parking, so we wait. + // gl847/gl124 need 2 reads for reliable results + auto status = scanner_read_status(*dev); + dev->interface->sleep_ms(10); + status = scanner_read_status(*dev); + + if (status.is_at_home) { + DBG (DBG_info, + "%s: already at home\n", __func__); + return; + } + + unsigned timeout_ms = 200000; + unsigned elapsed_ms = 0; + do + { + dev->interface->sleep_ms(100); + elapsed_ms += 100; + + status = scanner_read_status(*dev); + } while (elapsed_ms < timeout_ms && !status.is_at_home); + + /* if after the timeout, head is still not parked, error out */ + if (elapsed_ms >= timeout_ms && !status.is_at_home) { + DBG (DBG_error, "%s: failed to reach park position in %dseconds\n", __func__, + timeout_ms / 1000); + throw SaneException(SANE_STATUS_IO_ERROR, "failed to reach park position"); + } +} + +/** @brief motor profile + * search for the database of motor profiles and get the best one. Each + * profile is at full step and at a reference exposure. Use first entry + * by default. + * @param motors motor profile database + * @param motor_type motor id + * @param exposure exposure time + * @return a pointer to a Motor_Profile struct + */ +const Motor_Profile& sanei_genesys_get_motor_profile(const std::vector<Motor_Profile>& motors, + MotorId motor_id, int exposure) +{ + int idx; + + idx=-1; + for (std::size_t i = 0; i < motors.size(); ++i) { + // exact match + if (motors[i].motor_id == motor_id && motors[i].exposure==exposure) { + return motors[i]; + } + + // closest match + if (motors[i].motor_id == motor_id) { + /* if profile exposure is higher than the required one, + * the entry is a candidate for the closest match */ + if (motors[i].exposure == 0 || motors[i].exposure >= exposure) + { + if(idx<0) + { + /* no match found yet */ + idx=i; + } + else + { + /* test for better match */ + if(motors[i].exposure<motors[idx].exposure) + { + idx=i; + } + } + } + } + } + + /* default fallback */ + if(idx<0) + { + DBG (DBG_warn,"%s: using default motor profile\n",__func__); + idx=0; + } + + return motors[idx]; +} + +MotorSlopeTable sanei_genesys_slope_table(AsicType asic_type, int dpi, int exposure, int base_dpi, + unsigned step_multiplier, + const Motor_Profile& motor_profile) +{ + unsigned target_speed_w = ((exposure * dpi) / base_dpi); + + auto table = create_slope_table(motor_profile.slope, target_speed_w, motor_profile.step_type, + step_multiplier, 2 * step_multiplier, + get_slope_table_max_size(asic_type)); + return table; +} + +MotorSlopeTable create_slope_table_fastest(AsicType asic_type, unsigned step_multiplier, + const Motor_Profile& motor_profile) +{ + return create_slope_table(motor_profile.slope, motor_profile.slope.max_speed_w, + motor_profile.step_type, + step_multiplier, 2 * step_multiplier, + get_slope_table_max_size(asic_type)); +} + +/** @brief returns the lowest possible ydpi for the device + * Parses device entry to find lowest motor dpi. + * @param dev device description + * @return lowest motor resolution + */ +int sanei_genesys_get_lowest_ydpi(Genesys_Device *dev) +{ + const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method); + return resolution_settings.get_min_resolution_y(); +} + +/** @brief returns the lowest possible dpi for the device + * Parses device entry to find lowest motor or sensor dpi. + * @param dev device description + * @return lowest motor resolution + */ +int sanei_genesys_get_lowest_dpi(Genesys_Device *dev) +{ + const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method); + return std::min(resolution_settings.get_min_resolution_x(), + resolution_settings.get_min_resolution_y()); +} + +/** @brief check is a cache entry may be used + * Compares current settings with the cache entry and return + * true if they are compatible. + * A calibration cache is compatible if color mode and x dpi match the user + * requested scan. In the case of CIS scanners, dpi isn't a criteria. + * flatbed cache entries are considred too old and then expires if they + * are older than the expiration time option, forcing calibration at least once + * then given time. */ +bool sanei_genesys_is_compatible_calibration(Genesys_Device* dev, + const ScanSession& session, + const Genesys_Calibration_Cache* cache, + bool for_overwrite) +{ + DBG_HELPER(dbg); +#ifdef HAVE_SYS_TIME_H + struct timeval time; +#endif + + bool compatible = true; + + const auto& dev_params = session.params; + + if (dev_params.scan_method != cache->params.scan_method) { + dbg.vlog(DBG_io, "incompatible: scan_method %d vs. %d\n", + static_cast<unsigned>(dev_params.scan_method), + static_cast<unsigned>(cache->params.scan_method)); + compatible = false; + } + + if (dev_params.xres != cache->params.xres) { + dbg.vlog(DBG_io, "incompatible: params.xres %d vs. %d\n", + dev_params.xres, cache->params.xres); + compatible = false; + } + + if (dev_params.yres != cache->params.yres) { + // exposure depends on selected sensor and we select the sensor according to yres + dbg.vlog(DBG_io, "incompatible: params.yres %d vs. %d\n", + dev_params.yres, cache->params.yres); + compatible = false; + } + + if (dev_params.channels != cache->params.channels) { + // exposure depends on total number of pixels at least on gl841 + dbg.vlog(DBG_io, "incompatible: params.channels %d vs. %d\n", + dev_params.channels, cache->params.channels); + compatible = false; + } + + if (dev_params.startx != cache->params.startx) { + // exposure depends on total number of pixels at least on gl841 + dbg.vlog(DBG_io, "incompatible: params.startx %d vs. %d\n", + dev_params.startx, cache->params.startx); + compatible = false; + } + + if (dev_params.pixels != cache->params.pixels) { + // exposure depends on total number of pixels at least on gl841 + dbg.vlog(DBG_io, "incompatible: params.pixels %d vs. %d\n", + dev_params.pixels, cache->params.pixels); + compatible = false; + } + + if (!compatible) + { + DBG (DBG_proc, "%s: completed, non compatible cache\n", __func__); + return false; + } + + /* a cache entry expires after afetr expiration time for non sheetfed scanners */ + /* this is not taken into account when overwriting cache entries */ +#ifdef HAVE_SYS_TIME_H + if (!for_overwrite && dev->settings.expiration_time >=0) + { + gettimeofday(&time, nullptr); + if ((time.tv_sec - cache->last_calibration > dev->settings.expiration_time*60) + && !dev->model->is_sheetfed + && (dev->settings.scan_method == ScanMethod::FLATBED)) + { + DBG (DBG_proc, "%s: expired entry, non compatible cache\n", __func__); + return false; + } + } +#endif + + return true; +} + +/** @brief build lookup table for digital enhancements + * Function to build a lookup table (LUT), often + used by scanners to implement brightness/contrast/gamma + or by backends to speed binarization/thresholding + + offset and slope inputs are -127 to +127 + + slope rotates line around central input/output val, + 0 makes horizontal line + + pos zero neg + . x . . x + . x . . x + out . x .xxxxxxxxxxx . x + . x . . x + ....x....... ............ .......x.... + in in in + + offset moves line vertically, and clamps to output range + 0 keeps the line crossing the center of the table + + high low + . xxxxxxxx . + . x . + out x . x + . . x + ............ xxxxxxxx.... + in in + + out_min/max provide bounds on output values, + useful when building thresholding lut. + 0 and 255 are good defaults otherwise. + * @param lut pointer where to store the generated lut + * @param in_bits number of bits for in values + * @param out_bits number of bits of out values + * @param out_min minimal out value + * @param out_max maximal out value + * @param slope slope of the generated data + * @param offset offset of the generated data + */ +void sanei_genesys_load_lut(unsigned char* lut, + int in_bits, int out_bits, + int out_min, int out_max, + int slope, int offset) +{ + DBG_HELPER(dbg); + int i, j; + double shift, rise; + int max_in_val = (1 << in_bits) - 1; + int max_out_val = (1 << out_bits) - 1; + uint8_t *lut_p8 = lut; + uint16_t* lut_p16 = reinterpret_cast<std::uint16_t*>(lut); + + /* slope is converted to rise per unit run: + * first [-127,127] to [-.999,.999] + * then to [-PI/4,PI/4] then [0,PI/2] + * then take the tangent (T.O.A) + * then multiply by the normal linear slope + * because the table may not be square, i.e. 1024x256*/ + auto pi_4 = M_PI / 4.0; + rise = std::tan(static_cast<double>(slope) / 128 * pi_4 + pi_4) * max_out_val / max_in_val; + + /* line must stay vertically centered, so figure + * out vertical offset at central input value */ + shift = static_cast<double>(max_out_val) / 2 - (rise * max_in_val / 2); + + /* convert the user offset setting to scale of output + * first [-127,127] to [-1,1] + * then to [-max_out_val/2,max_out_val/2]*/ + shift += static_cast<double>(offset) / 127 * max_out_val / 2; + + for (i = 0; i <= max_in_val; i++) + { + j = static_cast<int>(rise * i + shift); + + /* cap data to required range */ + if (j < out_min) + { + j = out_min; + } + else if (j > out_max) + { + j = out_max; + } + + /* copy result according to bit depth */ + if (out_bits <= 8) + { + *lut_p8 = j; + lut_p8++; + } + else + { + *lut_p16 = j; + lut_p16++; + } + } +} + +} // namespace genesys diff --git a/backend/genesys/low.h b/backend/genesys/low.h new file mode 100644 index 0000000..d7f5dd2 --- /dev/null +++ b/backend/genesys/low.h @@ -0,0 +1,525 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2003 Oliver Rauch + Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de> + Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de> + Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> + Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> + Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com> + Parts of the structs have been taken from the gt68xx backend by + Sergey Vlasov <vsu@altlinux.ru> et al. + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef GENESYS_LOW_H +#define GENESYS_LOW_H + + +#include "../include/sane/config.h" + +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <math.h> +#include <stddef.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_MKDIR +#include <sys/stat.h> +#include <sys/types.h> +#endif + +#include "../include/sane/sane.h" +#include "../include/sane/sanei.h" +#include "../include/sane/saneopts.h" + +#include "../include/sane/sanei_backend.h" +#include "../include/sane/sanei_usb.h" + +#include "../include/_stdint.h" + +#include "device.h" +#include "enums.h" +#include "error.h" +#include "fwd.h" +#include "usb_device.h" +#include "sensor.h" +#include "serialize.h" +#include "settings.h" +#include "static_init.h" +#include "status.h" +#include "register.h" + +#include <algorithm> +#include <array> +#include <cstring> +#include <functional> +#include <iostream> +#include <sstream> +#include <limits> +#include <memory> +#include <stdexcept> +#include <string> +#include <vector> + +#define GENESYS_RED 0 +#define GENESYS_GREEN 1 +#define GENESYS_BLUE 2 + +/* Flags */ +#define GENESYS_FLAG_UNTESTED (1 << 0) /**< Print a warning for these scanners */ +#define GENESYS_FLAG_14BIT_GAMMA (1 << 1) /**< use 14bit Gamma table instead of 12 */ +#define GENESYS_FLAG_XPA (1 << 3) +#define GENESYS_FLAG_SKIP_WARMUP (1 << 4) /**< skip genesys_warmup() */ +/** @brief offset calibration flag + * signals that the scanner does offset calibration. In this case off_calibration() and + * coarse_gain_calibration() functions must be implemented + */ +#define GENESYS_FLAG_OFFSET_CALIBRATION (1 << 5) +#define GENESYS_FLAG_SEARCH_START (1 << 6) /**< do start search before scanning */ +#define GENESYS_FLAG_REPARK (1 << 7) /**< repark head (and check for lock) by + moving without scanning */ +#define GENESYS_FLAG_DARK_CALIBRATION (1 << 8) /**< do dark calibration */ + +#define GENESYS_FLAG_MUST_WAIT (1 << 10) /**< tells wether the scanner must wait for the head when parking */ + + +#define GENESYS_FLAG_HAS_UTA (1 << 11) /**< scanner has a transparency adapter */ + +#define GENESYS_FLAG_DARK_WHITE_CALIBRATION (1 << 12) /**< yet another calibration method. does white and dark shading in one run, depending on a black and a white strip*/ +#define GENESYS_FLAG_CUSTOM_GAMMA (1 << 13) /**< allow custom gamma tables */ +#define GENESYS_FLAG_NO_CALIBRATION (1 << 14) /**< allow scanners to use skip the calibration, needed for sheetfed scanners */ +#define GENESYS_FLAG_SIS_SENSOR (1 << 16) /**< handling of multi-segments sensors in software */ +#define GENESYS_FLAG_SHADING_NO_MOVE (1 << 17) /**< scanner doesn't move sensor during shading calibration */ +#define GENESYS_FLAG_SHADING_REPARK (1 << 18) /**< repark head between shading scans */ +#define GENESYS_FLAG_FULL_HWDPI_MODE (1 << 19) /**< scanner always use maximum hw dpi to setup the sensor */ +// scanner has infrared transparency scanning capability +#define GENESYS_FLAG_HAS_UTA_INFRARED (1 << 20) +// scanner calibration is handled on the host side +#define GENESYS_FLAG_CALIBRATION_HOST_SIDE (1 << 21) +#define GENESYS_FLAG_16BIT_DATA_INVERTED (1 << 22) + +#define GENESYS_HAS_NO_BUTTONS 0 /**< scanner has no supported button */ +#define GENESYS_HAS_SCAN_SW (1 << 0) /**< scanner has SCAN button */ +#define GENESYS_HAS_FILE_SW (1 << 1) /**< scanner has FILE button */ +#define GENESYS_HAS_COPY_SW (1 << 2) /**< scanner has COPY button */ +#define GENESYS_HAS_EMAIL_SW (1 << 3) /**< scanner has EMAIL button */ +#define GENESYS_HAS_PAGE_LOADED_SW (1 << 4) /**< scanner has paper in detection */ +#define GENESYS_HAS_OCR_SW (1 << 5) /**< scanner has OCR button */ +#define GENESYS_HAS_POWER_SW (1 << 6) /**< scanner has power button */ +#define GENESYS_HAS_CALIBRATE (1 << 7) /**< scanner has 'calibrate' software button to start calibration */ +#define GENESYS_HAS_EXTRA_SW (1 << 8) /**< scanner has extra function button */ + +/* USB control message values */ +#define REQUEST_TYPE_IN (USB_TYPE_VENDOR | USB_DIR_IN) +#define REQUEST_TYPE_OUT (USB_TYPE_VENDOR | USB_DIR_OUT) +#define REQUEST_REGISTER 0x0c +#define REQUEST_BUFFER 0x04 +#define VALUE_BUFFER 0x82 +#define VALUE_SET_REGISTER 0x83 +#define VALUE_READ_REGISTER 0x84 +#define VALUE_WRITE_REGISTER 0x85 +#define VALUE_INIT 0x87 +#define GPIO_OUTPUT_ENABLE 0x89 +#define GPIO_READ 0x8a +#define GPIO_WRITE 0x8b +#define VALUE_BUF_ENDACCESS 0x8c +#define VALUE_GET_REGISTER 0x8e +#define INDEX 0x00 + +/* todo: used? +#define VALUE_READ_STATUS 0x86 +*/ + +/* Read/write bulk data/registers */ +#define BULK_OUT 0x01 +#define BULK_IN 0x00 +#define BULK_RAM 0x00 +#define BULK_REGISTER 0x11 + +#define BULKOUT_MAXSIZE 0xF000 + +/* AFE values */ +#define AFE_INIT 1 +#define AFE_SET 2 +#define AFE_POWER_SAVE 4 + +#define LOWORD(x) ((uint16_t)((x) & 0xffff)) +#define HIWORD(x) ((uint16_t)((x) >> 16)) +#define LOBYTE(x) ((uint8_t)((x) & 0xFF)) +#define HIBYTE(x) ((uint8_t)((x) >> 8)) + +/* Global constants */ +/* TODO: emove this leftover of early backend days */ +#define MOTOR_SPEED_MAX 350 +#define DARK_VALUE 0 + +#define MAX_RESOLUTIONS 13 +#define MAX_DPI 4 + +namespace genesys { + +struct Genesys_USB_Device_Entry { + + Genesys_USB_Device_Entry(unsigned v, unsigned p, const Genesys_Model& m) : + vendor(v), product(p), model(m) + {} + + // USB vendor identifier + std::uint16_t vendor; + // USB product identifier + std::uint16_t product; + // Scanner model information + Genesys_Model model; +}; + +/** + * structure for motor database + */ +struct Motor_Profile +{ + MotorId motor_id; + int exposure; // used only to select the wanted motor + StepType step_type; // default step type for given exposure + MotorSlope slope; +}; + +extern StaticInit<std::vector<Motor_Profile>> gl843_motor_profiles; +extern StaticInit<std::vector<Motor_Profile>> gl846_motor_profiles; +extern StaticInit<std::vector<Motor_Profile>> gl847_motor_profiles; +extern StaticInit<std::vector<Motor_Profile>> gl124_motor_profiles; + +/*--------------------------------------------------------------------------*/ +/* common functions needed by low level specific functions */ +/*--------------------------------------------------------------------------*/ + +inline GenesysRegister* sanei_genesys_get_address(Genesys_Register_Set* regs, uint16_t addr) +{ + auto* ret = regs->find_reg_address(addr); + if (ret == nullptr) { + DBG(DBG_error, "%s: failed to find address for register 0x%02x, crash expected !\n", + __func__, addr); + } + return ret; +} + +extern void sanei_genesys_init_cmd_set(Genesys_Device* dev); + +// reads the status of the scanner +Status scanner_read_status(Genesys_Device& dev); + +// reads the status of the scanner reliably. This is done by reading the status twice. The first +// read sometimes returns the home sensor as engaged when this is not true. +Status scanner_read_reliable_status(Genesys_Device& dev); + +// reads and prints the scanner status +void scanner_read_print_status(Genesys_Device& dev); + +void debug_print_status(DebugMessageHelper& dbg, Status status); + +extern void sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t size, + uint8_t* data); + +extern void sanei_genesys_init_structs (Genesys_Device * dev); + +const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev); +const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, unsigned dpi, + unsigned channels, ScanMethod scan_method); +bool sanei_genesys_has_sensor(Genesys_Device* dev, unsigned dpi, unsigned channels, + ScanMethod scan_method); +Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigned dpi, + unsigned channels, ScanMethod scan_method); + +std::vector<std::reference_wrapper<const Genesys_Sensor>> + sanei_genesys_find_sensors_all(Genesys_Device* dev, ScanMethod scan_method); +std::vector<std::reference_wrapper<Genesys_Sensor>> + sanei_genesys_find_sensors_all_for_write(Genesys_Device* dev, ScanMethod scan_method); + +extern void sanei_genesys_init_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, + int pixels_per_line); + +extern void sanei_genesys_read_valid_words(Genesys_Device* dev, unsigned int* steps); + +extern void sanei_genesys_read_scancnt(Genesys_Device* dev, unsigned int* steps); + +extern void sanei_genesys_read_feed_steps(Genesys_Device* dev, unsigned int* steps); + +void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sensor, + Genesys_Register_Set& regs, bool set); + +void sanei_genesys_set_motor_power(Genesys_Register_Set& regs, bool set); + +bool should_enable_gamma(const ScanSession& session, const Genesys_Sensor& sensor); + +/** Calculates the values of the Z{1,2}MOD registers. They are a phase correction to synchronize + with the line clock during acceleration and deceleration. + + two_table is true if moving is done by two tables, false otherwise. + + acceleration_steps is the number of steps for acceleration, i.e. the number written to + REG_STEPNO. + + move_steps number of steps to move, i.e. the number written to REG_FEEDL. + + buffer_acceleration_steps, the number of steps for acceleration when buffer condition is met, + i.e. the number written to REG_FWDSTEP. +*/ +void sanei_genesys_calculate_zmod(bool two_table, + uint32_t exposure_time, + const std::vector<uint16_t>& slope_table, + unsigned acceleration_steps, + unsigned move_steps, + unsigned buffer_acceleration_steps, + uint32_t* out_z1, uint32_t* out_z2); + +extern void sanei_genesys_set_buffer_address(Genesys_Device* dev, uint32_t addr); + +unsigned sanei_genesys_get_bulk_max_size(AsicType asic_type); + +SANE_Int sanei_genesys_exposure_time2(Genesys_Device * dev, float ydpi, StepType step_type, + int endpixel, int led_exposure); + +MotorSlopeTable sanei_genesys_create_slope_table3(AsicType asic_type, const Genesys_Motor& motor, + StepType step_type, int exposure_time, + unsigned yres); + +void sanei_genesys_create_default_gamma_table(Genesys_Device* dev, + std::vector<uint16_t>& gamma_table, float gamma); + +std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor, + int color); + +void sanei_genesys_send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor); + +extern void sanei_genesys_stop_motor(Genesys_Device* dev); + +extern void sanei_genesys_search_reference_point(Genesys_Device* dev, Genesys_Sensor& sensor, + const uint8_t* src_data, int start_pixel, int dpi, + int width, int height); + +// moves the scan head by the specified steps at the motor base dpi +void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, Direction direction); + +void scanner_move_back_home(Genesys_Device& dev, bool wait_until_home); +void scanner_move_back_home_ta(Genesys_Device& dev); + +void scanner_clear_scan_and_feed_counts(Genesys_Device& dev); + +extern void sanei_genesys_write_file(const char* filename, const std::uint8_t* data, + std::size_t length); + +extern void sanei_genesys_write_pnm_file(const char* filename, const std::uint8_t* data, int depth, + int channels, int pixels_per_line, int lines); + +void sanei_genesys_write_pnm_file(const char* filename, const Image& image); + +extern void sanei_genesys_write_pnm_file16(const char* filename, const uint16_t *data, unsigned channels, + unsigned pixels_per_line, unsigned lines); + +void wait_until_buffer_non_empty(Genesys_Device* dev, bool check_status_twice = false); + +extern void sanei_genesys_read_data_from_scanner(Genesys_Device* dev, uint8_t* data, size_t size); + +Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& session, + std::size_t total_bytes); + +void regs_set_exposure(AsicType asic_type, Genesys_Register_Set& regs, + const SensorExposure& exposure); + +void regs_set_optical_off(AsicType asic_type, Genesys_Register_Set& regs); + +void sanei_genesys_set_dpihw(Genesys_Register_Set& regs, const Genesys_Sensor& sensor, + unsigned dpihw); + +inline uint16_t sanei_genesys_fixup_exposure_value(uint16_t value) +{ + if ((value & 0xff00) == 0) { + value |= 0x100; + } + if ((value & 0x00ff) == 0) { + value |= 0x1; + } + return value; +} + +inline SensorExposure sanei_genesys_fixup_exposure(SensorExposure exposure) +{ + exposure.red = sanei_genesys_fixup_exposure_value(exposure.red); + exposure.green = sanei_genesys_fixup_exposure_value(exposure.green); + exposure.blue = sanei_genesys_fixup_exposure_value(exposure.blue); + return exposure; +} + +bool get_registers_gain4_bit(AsicType asic_type, const Genesys_Register_Set& regs); + +extern void sanei_genesys_wait_for_home(Genesys_Device* dev); + +extern void sanei_genesys_asic_init(Genesys_Device* dev, bool cold); + +void scanner_start_action(Genesys_Device& dev, bool start_motor); +void scanner_stop_action(Genesys_Device& dev); +void scanner_stop_action_no_move(Genesys_Device& dev, Genesys_Register_Set& regs); + +bool scanner_is_motor_stopped(Genesys_Device& dev); + +const Motor_Profile& sanei_genesys_get_motor_profile(const std::vector<Motor_Profile>& motors, + MotorId motor_id, int exposure); + +MotorSlopeTable sanei_genesys_slope_table(AsicType asic_type, int dpi, int exposure, int base_dpi, + unsigned step_multiplier, + const Motor_Profile& motor_profile); + +MotorSlopeTable create_slope_table_fastest(AsicType asic_type, unsigned step_multiplier, + const Motor_Profile& motor_profile); + +/** @brief find lowest motor resolution for the device. + * Parses the resolution list for motor and + * returns the lowest value. + * @param dev for which to find the lowest motor resolution + * @return the lowest available motor resolution for the device + */ +extern +int sanei_genesys_get_lowest_ydpi(Genesys_Device *dev); + +/** @brief find lowest resolution for the device. + * Parses the resolution list for motor and sensor and + * returns the lowest value. + * @param dev for which to find the lowest resolution + * @return the lowest available resolution for the device + */ +extern +int sanei_genesys_get_lowest_dpi(Genesys_Device *dev); + +bool sanei_genesys_is_compatible_calibration(Genesys_Device* dev, + const ScanSession& session, + const Genesys_Calibration_Cache* cache, + bool for_overwrite); + +extern void sanei_genesys_load_lut(unsigned char* lut, + int in_bits, int out_bits, + int out_min, int out_max, + int slope, int offset); + +extern void sanei_genesys_generate_gamma_buffer(Genesys_Device* dev, + const Genesys_Sensor& sensor, + int bits, + int max, + int size, + uint8_t* gamma); + +void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor); + +void build_image_pipeline(Genesys_Device* dev, const ScanSession& session); + +std::uint8_t compute_frontend_gain(float value, float target_value, + FrontendType frontend_type); + +template<class T> +inline T abs_diff(T a, T b) +{ + if (a < b) { + return b - a; + } else { + return a - b; + } +} + +inline uint64_t align_multiple_floor(uint64_t x, uint64_t multiple) +{ + return (x / multiple) * multiple; +} + +inline uint64_t align_multiple_ceil(uint64_t x, uint64_t multiple) +{ + return ((x + multiple - 1) / multiple) * multiple; +} + +inline uint64_t multiply_by_depth_ceil(uint64_t pixels, uint64_t depth) +{ + if (depth == 1) { + return (pixels / 8) + ((pixels % 8) ? 1 : 0); + } else { + return pixels * (depth / 8); + } +} + +template<class T> +inline T clamp(const T& value, const T& lo, const T& hi) +{ + if (value < lo) + return lo; + if (value > hi) + return hi; + return value; +} + +/*---------------------------------------------------------------------------*/ +/* ASIC specific functions declarations */ +/*---------------------------------------------------------------------------*/ + +extern StaticInit<std::vector<Genesys_Sensor>> s_sensors; +extern StaticInit<std::vector<Genesys_Frontend>> s_frontends; +extern StaticInit<std::vector<Genesys_Gpo>> s_gpo; +extern StaticInit<std::vector<Genesys_Motor>> s_motors; +extern StaticInit<std::vector<Genesys_USB_Device_Entry>> s_usb_devices; + +void genesys_init_sensor_tables(); +void genesys_init_frontend_tables(); +void genesys_init_gpo_tables(); +void genesys_init_motor_tables(); +void genesys_init_motor_profile_tables(); +void genesys_init_usb_device_tables(); + +template<class T> +void debug_dump(unsigned level, const T& value) +{ + std::stringstream out; + out << value; + DBG(level, "%s\n", out.str().c_str()); +} + +} // namespace genesys + +#endif /* not GENESYS_LOW_H */ diff --git a/backend/genesys/motor.cpp b/backend/genesys/motor.cpp new file mode 100644 index 0000000..910266a --- /dev/null +++ b/backend/genesys/motor.cpp @@ -0,0 +1,180 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "motor.h" +#include "utilities.h" +#include <cmath> + +namespace genesys { + +unsigned MotorSlope::get_table_step_shifted(unsigned step, StepType step_type) const +{ + // first two steps are always equal to the initial speed + if (step < 2) { + return initial_speed_w >> static_cast<unsigned>(step_type); + } + step--; + + float initial_speed_v = 1.0f / initial_speed_w; + float speed_v = std::sqrt(initial_speed_v * initial_speed_v + 2 * acceleration * step); + return static_cast<unsigned>(1.0f / speed_v) >> static_cast<unsigned>(step_type); +} + +float compute_acceleration_for_steps(unsigned initial_w, unsigned max_w, unsigned steps) +{ + float initial_speed_v = 1.0f / static_cast<float>(initial_w); + float max_speed_v = 1.0f / static_cast<float>(max_w); + return (max_speed_v * max_speed_v - initial_speed_v * initial_speed_v) / (2 * steps); +} + + +MotorSlope MotorSlope::create_from_steps(unsigned initial_w, unsigned max_w, + unsigned steps) +{ + MotorSlope slope; + slope.initial_speed_w = initial_w; + slope.max_speed_w = max_w; + slope.acceleration = compute_acceleration_for_steps(initial_w, max_w, steps); + return slope; +} + +void MotorSlopeTable::slice_steps(unsigned count) +{ + if (count >= table.size() || count > steps_count) { + throw SaneException("Excepssive steps count"); + } + steps_count = count; +} + +unsigned get_slope_table_max_size(AsicType asic_type) +{ + switch (asic_type) { + case AsicType::GL646: + case AsicType::GL841: return 255; + case AsicType::GL843: + case AsicType::GL845: + case AsicType::GL846: + case AsicType::GL847: + case AsicType::GL124: return 1024; + default: + throw SaneException("Unknown asic type"); + } +} + +MotorSlopeTable create_slope_table(const MotorSlope& slope, unsigned target_speed_w, + StepType step_type, unsigned steps_alignment, + unsigned min_size, unsigned max_size) +{ + DBG_HELPER_ARGS(dbg, "target_speed_w: %d, step_type: %d, steps_alignment: %d, min_size: %d", + target_speed_w, static_cast<unsigned>(step_type), steps_alignment, min_size); + MotorSlopeTable table; + + unsigned step_shift = static_cast<unsigned>(step_type); + + unsigned target_speed_shifted_w = target_speed_w >> step_shift; + unsigned max_speed_shifted_w = slope.max_speed_w >> step_shift; + + if (target_speed_shifted_w < max_speed_shifted_w) { + dbg.log(DBG_warn, "failed to reach target speed"); + } + + unsigned final_speed = std::max(target_speed_shifted_w, max_speed_shifted_w); + + table.table.reserve(max_size); + + while (table.table.size() < max_size - 1) { + unsigned current = slope.get_table_step_shifted(table.table.size(), step_type); + if (current <= final_speed) { + break; + } + table.table.push_back(current); + table.pixeltime_sum += current; + } + + // make sure the target speed (or the max speed if target speed is too high) is present in + // the table + table.table.push_back(final_speed); + table.pixeltime_sum += table.table.back(); + + // fill the table up to the specified size + while (table.table.size() < max_size - 1 && + (table.table.size() % steps_alignment != 0 || table.table.size() < min_size)) + { + table.table.push_back(table.table.back()); + table.pixeltime_sum += table.table.back(); + } + + table.steps_count = table.table.size(); + + // fill the rest of the table with the final speed + table.table.resize(max_size, final_speed); + + return table; +} + +std::ostream& operator<<(std::ostream& out, const MotorSlope& slope) +{ + out << "MotorSlope{\n" + << " initial_speed_w: " << slope.initial_speed_w << '\n' + << " max_speed_w: " << slope.max_speed_w << '\n' + << " a: " << slope.acceleration << '\n' + << '}'; + return out; +} + +std::ostream& operator<<(std::ostream& out, const Genesys_Motor& motor) +{ + out << "Genesys_Motor{\n" + << " id: " << static_cast<unsigned>(motor.id) << '\n' + << " base_ydpi: " << motor.base_ydpi << '\n' + << " optical_ydpi: " << motor.optical_ydpi << '\n' + << " slopes: " + << format_indent_braced_list(4, format_vector_indent_braced(4, "MotorSlope", + motor.slopes)) + << '}'; + return out; +} + +} // namespace genesys diff --git a/backend/genesys/motor.h b/backend/genesys/motor.h new file mode 100644 index 0000000..d80da6d --- /dev/null +++ b/backend/genesys/motor.h @@ -0,0 +1,177 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_MOTOR_H +#define BACKEND_GENESYS_MOTOR_H + +#include <cstdint> +#include <vector> +#include "enums.h" + +namespace genesys { + +/* Describes a motor acceleration curve. + + Definitions: + v - speed in steps per pixeltime + w - speed in pixel times per step. w = 1 / v + a - acceleration in steps per pixeltime squared + s - distance travelled in steps + t - time in pixeltime + + The physical mode defines the curve in physical quantities. We asssume that the scanner head + accelerates from standstill to the target speed uniformly. Then: + + v(t) = v(0) + a * t (2) + + Where `a` is acceleration, `t` is time. Also we can calculate the travelled distance `s`: + + s(t) = v(0) * t + a * t^2 / 2 (3) + + The actual motor slope is defined as the duration of each motor step. That means we need to + define speed in terms of travelled distance. + + Solving (3) for `t` gives: + + sqrt( v(0)^2 + 2 * a * s ) - v(0) + t(s) = --------------------------------- (4) + a + + Combining (4) and (2) will yield: + + v(s) = sqrt( v(0)^2 + 2 * a * s ) (5) + + The data in the slope struct MotorSlope corresponds to the above in the following way: + + maximum_start_speed is `w(0) = 1/v(0)` + + maximum_speed is defines maximum speed which should not be exceeded + + minimum_steps is not used + + g is `a` + + Given the start and target speeds on a known motor curve, `a` can be computed as follows: + + v(t1)^2 - v(t0)^2 + a = ----------------- (6) + 2 * s + + Here `v(t0)` and `v(t1)` are the start and target speeds and `s` is the number of step required + to reach the target speeds. +*/ +struct MotorSlope +{ + // initial speed in pixeltime per step + unsigned initial_speed_w = 0; + + // max speed in pixeltime per step + unsigned max_speed_w = 0; + + // maximum number of steps in the table + unsigned max_step_count; + + // acceleration in steps per pixeltime squared. + float acceleration = 0; + + unsigned get_table_step_shifted(unsigned step, StepType step_type) const; + + static MotorSlope create_from_steps(unsigned initial_w, unsigned max_w, + unsigned steps); +}; + +struct MotorSlopeTable +{ + std::vector<std::uint16_t> table; + unsigned steps_count = 0; + unsigned pixeltime_sum = 0; + + void slice_steps(unsigned count); +}; + +unsigned get_slope_table_max_size(AsicType asic_type); + +MotorSlopeTable create_slope_table(const MotorSlope& slope, unsigned target_speed_w, + StepType step_type, unsigned steps_alignment, + unsigned min_size, unsigned max_size); + +std::ostream& operator<<(std::ostream& out, const MotorSlope& slope); + + +struct Genesys_Motor +{ + Genesys_Motor() = default; + + // id of the motor description + MotorId id = MotorId::UNKNOWN; + // motor base steps. Unit: 1/inch + int base_ydpi = 0; + // maximum resolution in y-direction. Unit: 1/inch + int optical_ydpi = 0; + // slopes to derive individual slopes from + std::vector<MotorSlope> slopes; + + MotorSlope& get_slope(StepType step_type) + { + return slopes[static_cast<unsigned>(step_type)]; + } + + const MotorSlope& get_slope(StepType step_type) const + { + return slopes[static_cast<unsigned>(step_type)]; + } + + StepType max_step_type() const + { + if (slopes.empty()) { + throw std::runtime_error("Slopes table is empty"); + } + return static_cast<StepType>(slopes.size() - 1); + } +}; + +std::ostream& operator<<(std::ostream& out, const Genesys_Motor& motor); + +} // namespace genesys + +#endif // BACKEND_GENESYS_MOTOR_H diff --git a/backend/genesys/register.h b/backend/genesys/register.h new file mode 100644 index 0000000..bbc7ec8 --- /dev/null +++ b/backend/genesys/register.h @@ -0,0 +1,537 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_REGISTER_H +#define BACKEND_GENESYS_REGISTER_H + +#include "utilities.h" + +#include <algorithm> +#include <climits> +#include <cstdint> +#include <iostream> +#include <iomanip> +#include <stdexcept> +#include <vector> + +namespace genesys { + +template<class Value> +struct Register +{ + std::uint16_t address = 0; + Value value = 0; +}; + +using GenesysRegister = Register<std::uint8_t>; + +template<class Value> +inline bool operator<(const Register<Value>& lhs, const Register<Value>& rhs) +{ + return lhs.address < rhs.address; +} + +struct GenesysRegisterSetState +{ + bool is_lamp_on = false; + bool is_xpa_on = false; + bool is_motor_on = false; + bool is_xpa_motor_on = false; +}; + +template<class Value> +class RegisterContainer +{ +public: + + enum Options { + SEQUENTIAL = 1 + }; + + using RegisterType = Register<Value>; + using ContainerType = std::vector<RegisterType>; + using iterator = typename ContainerType::iterator; + using const_iterator = typename ContainerType::const_iterator; + + RegisterContainer() = default; + + RegisterContainer(Options opts) : RegisterContainer() + { + if ((opts & SEQUENTIAL) == SEQUENTIAL) { + sorted_ = false; + } + } + + void init_reg(std::uint16_t address, Value default_value) + { + if (find_reg_index(address) >= 0) { + set(address, default_value); + return; + } + RegisterType reg; + reg.address = address; + reg.value = default_value; + registers_.push_back(reg); + if (sorted_) + std::sort(registers_.begin(), registers_.end()); + } + + bool has_reg(std::uint16_t address) const + { + return find_reg_index(address) >= 0; + } + + void remove_reg(std::uint16_t address) + { + int i = find_reg_index(address); + if (i < 0) { + throw std::runtime_error("the register does not exist"); + } + registers_.erase(registers_.begin() + i); + } + + RegisterType& find_reg(std::uint16_t address) + { + int i = find_reg_index(address); + if (i < 0) { + throw std::runtime_error("the register does not exist"); + } + return registers_[i]; + } + + const RegisterType& find_reg(std::uint16_t address) const + { + int i = find_reg_index(address); + if (i < 0) { + throw std::runtime_error("the register does not exist"); + } + return registers_[i]; + } + + void set(std::uint16_t address, Value value) + { + find_reg(address).value = value; + } + + Value get(std::uint16_t address) const + { + return find_reg(address).value; + } + + void reserve(std::size_t size) { registers_.reserve(size); } + void clear() { registers_.clear(); } + std::size_t size() const { return registers_.size(); } + + iterator begin() { return registers_.begin(); } + const_iterator begin() const { return registers_.begin(); } + + iterator end() { return registers_.end(); } + const_iterator end() const { return registers_.end(); } + +private: + int find_reg_index(std::uint16_t address) const + { + if (!sorted_) { + for (std::size_t i = 0; i < registers_.size(); i++) { + if (registers_[i].address == address) { + return i; + } + } + return -1; + } + + RegisterType search; + search.address = address; + auto it = std::lower_bound(registers_.begin(), registers_.end(), search); + if (it == registers_.end()) + return -1; + if (it->address != address) + return -1; + return std::distance(registers_.begin(), it); + } + + // registers are stored in a sorted vector + bool sorted_ = true; + std::vector<RegisterType> registers_; +}; + +template<class Value> +std::ostream& operator<<(std::ostream& out, const RegisterContainer<Value>& container) +{ + StreamStateSaver state_saver{out}; + + out << "RegisterContainer{\n"; + out << std::hex; + out.fill('0'); + + for (const auto& reg : container) { + unsigned address_width = sizeof(reg.address) * 2; + unsigned value_width = sizeof(reg.value) * 2; + + out << " 0x" << std::setw(address_width) << static_cast<unsigned>(reg.address) + << " = 0x" << std::setw(value_width) << static_cast<unsigned>(reg.value) << '\n'; + } + out << "}"; + return out; +} + +class Genesys_Register_Set +{ +public: + static constexpr unsigned MAX_REGS = 256; + + using ContainerType = RegisterContainer<std::uint8_t>; + using iterator = typename ContainerType::iterator; + using const_iterator = typename ContainerType::const_iterator; + + // FIXME: this shouldn't live here, but in a separate struct that contains Genesys_Register_Set + GenesysRegisterSetState state; + + enum Options { + SEQUENTIAL = 1 + }; + + Genesys_Register_Set() + { + registers_.reserve(MAX_REGS); + } + + // by default the register set is sorted by address. In certain cases it's importand to send + // the registers in certain order: use the SEQUENTIAL option for that + Genesys_Register_Set(Options opts) : registers_{static_cast<ContainerType::Options>(opts)} + { + registers_.reserve(MAX_REGS); + } + + const ContainerType& registers() const + { + return registers_; + } + + void init_reg(std::uint16_t address, std::uint8_t default_value) + { + registers_.init_reg(address, default_value); + } + + bool has_reg(std::uint16_t address) const { return registers_.has_reg(address); } + + void remove_reg(std::uint16_t address) { registers_.remove_reg(address); } + + GenesysRegister& find_reg(std::uint16_t address) + { + return registers_.find_reg(address); + } + + const GenesysRegister& find_reg(std::uint16_t address) const + { + return registers_.find_reg(address); + } + + GenesysRegister* find_reg_address(std::uint16_t address) + { + return &find_reg(address); + } + + const GenesysRegister* find_reg_address(std::uint16_t address) const + { + return &find_reg(address); + } + + void set8(std::uint16_t address, std::uint8_t value) + { + find_reg(address).value = value; + } + + void set8_mask(std::uint16_t address, std::uint8_t value, std::uint8_t mask) + { + auto& reg = find_reg(address); + reg.value = (reg.value & ~mask) | value; + } + + void set16(std::uint16_t address, std::uint16_t value) + { + find_reg(address).value = (value >> 8) & 0xff; + find_reg(address + 1).value = value & 0xff; + } + + void set24(std::uint16_t address, std::uint32_t value) + { + find_reg(address).value = (value >> 16) & 0xff; + find_reg(address + 1).value = (value >> 8) & 0xff; + find_reg(address + 2).value = value & 0xff; + } + + std::uint8_t get8(std::uint16_t address) const + { + return find_reg(address).value; + } + + std::uint16_t get16(std::uint16_t address) const + { + return (find_reg(address).value << 8) | find_reg(address + 1).value; + } + + std::uint32_t get24(std::uint16_t address) const + { + return (find_reg(address).value << 16) | + (find_reg(address + 1).value << 8) | + find_reg(address + 2).value; + } + + void clear() { registers_.clear(); } + std::size_t size() const { return registers_.size(); } + + iterator begin() { return registers_.begin(); } + const_iterator begin() const { return registers_.begin(); } + + iterator end() { return registers_.end(); } + const_iterator end() const { return registers_.end(); } + +private: + + // registers are stored in a sorted vector + ContainerType registers_; +}; + +inline std::ostream& operator<<(std::ostream& out, const Genesys_Register_Set& regs) +{ + out << regs.registers(); + return out; +} + +template<class Value> +struct RegisterSetting +{ + using ValueType = Value; + using AddressType = std::uint16_t; + + RegisterSetting() = default; + + RegisterSetting(AddressType p_address, ValueType p_value) : + address(p_address), value(p_value) + {} + + RegisterSetting(AddressType p_address, ValueType p_value, ValueType p_mask) : + address(p_address), value(p_value), mask(p_mask) + {} + + AddressType address = 0; + ValueType value = 0; + ValueType mask = 0xff; + + bool operator==(const RegisterSetting& other) const + { + return address == other.address && value == other.value && mask == other.mask; + } +}; + +using GenesysRegisterSetting = RegisterSetting<std::uint8_t>; +using GenesysRegisterSetting16 = RegisterSetting<std::uint16_t>; + +template<class Stream, class Value> +void serialize(Stream& str, RegisterSetting<Value>& reg) +{ + serialize(str, reg.address); + serialize(str, reg.value); + serialize(str, reg.mask); +} + +template<class Value> +class RegisterSettingSet +{ +public: + using ValueType = Value; + using SettingType = RegisterSetting<ValueType>; + using AddressType = typename SettingType::AddressType; + + using container = std::vector<SettingType>; + using iterator = typename container::iterator; + using const_iterator = typename container::const_iterator; + + RegisterSettingSet() = default; + RegisterSettingSet(std::initializer_list<SettingType> ilist) : + registers_(ilist) + {} + + iterator begin() { return registers_.begin(); } + const_iterator begin() const { return registers_.begin(); } + iterator end() { return registers_.end(); } + const_iterator end() const { return registers_.end(); } + + SettingType& operator[](std::size_t i) { return registers_[i]; } + const SettingType& operator[](std::size_t i) const { return registers_[i]; } + + std::size_t size() const { return registers_.size(); } + bool empty() const { return registers_.empty(); } + void clear() { registers_.clear(); } + + void push_back(SettingType reg) { registers_.push_back(reg); } + + void merge(const RegisterSettingSet& other) + { + for (const auto& reg : other) { + set_value(reg.address, reg.value); + } + } + + SettingType& find_reg(AddressType address) + { + int i = find_reg_index(address); + if (i < 0) { + throw std::runtime_error("the register does not exist"); + } + return registers_[i]; + } + + const SettingType& find_reg(AddressType address) const + { + int i = find_reg_index(address); + if (i < 0) { + throw std::runtime_error("the register does not exist"); + } + return registers_[i]; + } + + ValueType get_value(AddressType address) const + { + int index = find_reg_index(address); + if (index >= 0) { + return registers_[index].value; + } + throw std::out_of_range("Unknown register"); + } + + void set_value(AddressType address, ValueType value) + { + int index = find_reg_index(address); + if (index >= 0) { + registers_[index].value = value; + return; + } + push_back(SettingType(address, value)); + } + + template<class V> + friend void serialize(std::istream& str, RegisterSettingSet<V>& reg); + template<class V> + friend void serialize(std::ostream& str, RegisterSettingSet<V>& reg); + + bool operator==(const RegisterSettingSet& other) const + { + return registers_ == other.registers_; + } + +private: + + int find_reg_index(AddressType address) const + { + for (std::size_t i = 0; i < registers_.size(); i++) { + if (registers_[i].address == address) { + return i; + } + } + return -1; + } + + std::vector<SettingType> registers_; +}; + +using GenesysRegisterSettingSet = RegisterSettingSet<std::uint8_t>; +using GenesysRegisterSettingSet16 = RegisterSettingSet<std::uint16_t>; + +template<class Value> +std::ostream& operator<<(std::ostream& out, const RegisterSettingSet<Value>& container) +{ + StreamStateSaver state_saver{out}; + + out << "RegisterSettingSet{\n"; + out << std::hex; + out.fill('0'); + + for (const auto& reg : container) { + unsigned address_width = sizeof(reg.address) * 2; + unsigned value_width = sizeof(reg.value) * 2; + unsigned mask_width = sizeof(reg.mask) * 2; + + out << " 0x" << std::setw(address_width) << static_cast<unsigned>(reg.address) + << " = 0x" << std::setw(value_width) << static_cast<unsigned>(reg.value) + << " & 0x" << std::setw(mask_width) << static_cast<unsigned>(reg.mask) << '\n'; + } + out << "}"; + return out; +} + +template<class Value> +inline void serialize(std::istream& str, RegisterSettingSet<Value>& reg) +{ + using AddressType = typename RegisterSetting<Value>::AddressType; + + reg.clear(); + const std::size_t max_register_address = 1 << (sizeof(AddressType) * CHAR_BIT); + serialize(str, reg.registers_, max_register_address); +} + +template<class Value> +inline void serialize(std::ostream& str, RegisterSettingSet<Value>& reg) +{ + serialize(str, reg.registers_); +} + +template<class F, class Value> +void apply_registers_ordered(const RegisterSettingSet<Value>& set, + std::initializer_list<std::uint16_t> order, F f) +{ + for (std::uint16_t addr : order) { + f(set.find_reg(addr)); + } + for (const auto& reg : set) { + if (std::find(order.begin(), order.end(), reg.address) != order.end()) { + continue; + } + f(reg); + } +} + +} // namespace genesys + +#endif // BACKEND_GENESYS_REGISTER_H diff --git a/backend/genesys/register_cache.h b/backend/genesys/register_cache.h new file mode 100644 index 0000000..dce701a --- /dev/null +++ b/backend/genesys/register_cache.h @@ -0,0 +1,92 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_REGISTER_CACHE_H +#define BACKEND_GENESYS_REGISTER_CACHE_H + +#include "register.h" + +namespace genesys { + +template<class Value> +class RegisterCache +{ +public: + void update(std::uint16_t address, Value value) + { + if (regs_.has_reg(address)) { + regs_.set(address, value); + } else { + regs_.init_reg(address, value); + } + } + + void update(const Genesys_Register_Set& regs) + { + for (const auto& reg : regs) { + update(reg.address, reg.value); + } + } + + Value get(std::uint16_t address) const + { + return regs_.get(address); + } + +private: + RegisterContainer<Value> regs_; + + template<class V> + friend std::ostream& operator<<(std::ostream& out, const RegisterCache<V>& cache); +}; + +template<class Value> +std::ostream& operator<<(std::ostream& out, const RegisterCache<Value>& cache) +{ + out << cache.regs_; + return out; +} + +} // namespace genesys + +#endif // BACKEND_GENESYS_LINE_BUFFER_H diff --git a/backend/genesys/row_buffer.h b/backend/genesys/row_buffer.h new file mode 100644 index 0000000..e1a0c82 --- /dev/null +++ b/backend/genesys/row_buffer.h @@ -0,0 +1,214 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_LINE_BUFFER_H +#define BACKEND_GENESYS_LINE_BUFFER_H + +#include "error.h" + +#include <algorithm> +#include <cstdint> +#include <cstddef> +#include <vector> + +namespace genesys { + +class RowBuffer +{ +public: + RowBuffer(std::size_t line_bytes) : row_bytes_{line_bytes} {} + RowBuffer(const RowBuffer&) = default; + RowBuffer& operator=(const RowBuffer&) = default; + ~RowBuffer() = default; + + const std::uint8_t* get_row_ptr(std::size_t y) const + { + if (y >= height()) { + throw SaneException("y %zu is out of range", y); + } + return data_.data() + row_bytes_ * get_row_index(y); + } + + std::uint8_t* get_row_ptr(std::size_t y) + { + if (y >= height()) { + throw SaneException("y %zu is out of range", y); + } + return data_.data() + row_bytes_ * get_row_index(y); + } + + const std::uint8_t* get_front_row_ptr() const { return get_row_ptr(0); } + std::uint8_t* get_front_row_ptr() { return get_row_ptr(0); } + const std::uint8_t* get_back_row_ptr() const { return get_row_ptr(height() - 1); } + std::uint8_t* get_back_row_ptr() { return get_row_ptr(height() - 1); } + + bool empty() const { return is_linear_ && first_ == last_; } + + bool full() + { + if (is_linear_) { + return last_ == buffer_end_; + } + return first_ == last_; + } + + bool is_linear() const { return is_linear_; } + + void linearize() + { + if (!is_linear_) { + std::rotate(data_.begin(), data_.begin() + row_bytes_ * first_, data_.end()); + last_ = height(); + first_ = 0; + is_linear_ = true; + } + } + + void pop_front() + { + if (empty()) { + throw SaneException("Trying to pop out of empty() line buffer"); + } + + first_++; + if (first_ == last_) { + first_ = 0; + last_ = 0; + is_linear_ = true; + } else if (first_ == buffer_end_) { + first_ = 0; + is_linear_ = true; + } + } + + void push_front() + { + if (height() + 1 >= height_capacity()) { + ensure_capacity(std::max<std::size_t>(1, height() * 2)); + } + + if (first_ == 0) { + is_linear_ = false; + first_ = buffer_end_; + } + first_--; + } + + void pop_back() + { + if (empty()) { + throw SaneException("Trying to pop out of empty() line buffer"); + } + if (last_ == 0) { + last_ = buffer_end_; + is_linear_ = true; + } + last_--; + if (first_ == last_) { + first_ = 0; + last_ = 0; + is_linear_ = true; + } + } + + void push_back() + { + if (height() + 1 >= height_capacity()) { + ensure_capacity(std::max<std::size_t>(1, height() * 2)); + } + + if (last_ == buffer_end_) { + is_linear_ = false; + last_ = 0; + } + last_++; + } + + std::size_t row_bytes() const { return row_bytes_; } + + std::size_t height() const + { + if (!is_linear_) { + return last_ + buffer_end_ - first_; + } + return last_ - first_; + } + + std::size_t height_capacity() const { return buffer_end_; } + + void clear() + { + first_ = 0; + last_ = 0; + } + +private: + std::size_t get_row_index(std::size_t index) const + { + if (index >= buffer_end_ - first_) { + return index - (buffer_end_ - first_); + } + return index + first_; + } + + void ensure_capacity(std::size_t capacity) + { + if (capacity < height_capacity()) + return; + linearize(); + data_.resize(capacity * row_bytes_); + buffer_end_ = capacity; + } + +private: + std::size_t row_bytes_ = 0; + std::size_t first_ = 0; + std::size_t last_ = 0; + std::size_t buffer_end_ = 0; + bool is_linear_ = true; + std::vector<std::uint8_t> data_; +}; + +} // namespace genesys + +#endif // BACKEND_GENESYS_LINE_BUFFER_H diff --git a/backend/genesys/scanner_interface.cpp b/backend/genesys/scanner_interface.cpp new file mode 100644 index 0000000..0b60b66 --- /dev/null +++ b/backend/genesys/scanner_interface.cpp @@ -0,0 +1,52 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "scanner_interface.h" + +namespace genesys { + +ScannerInterface::~ScannerInterface() = default; + +} // namespace genesys diff --git a/backend/genesys/scanner_interface.h b/backend/genesys/scanner_interface.h new file mode 100644 index 0000000..03c7132 --- /dev/null +++ b/backend/genesys/scanner_interface.h @@ -0,0 +1,112 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_SCANNER_INTERFACE_H +#define BACKEND_GENESYS_SCANNER_INTERFACE_H + +#include "fwd.h" +#include <cstddef> +#include <cstdint> +#include <string> +#include <vector> + +namespace genesys { + +// Represents an interface through which all low level operations are performed. +class ScannerInterface +{ +public: + enum Flags { + FLAG_NONE = 0, + FLAG_SWAP_REGISTERS = 1 << 0, + FLAG_SMALL_ADDRESS = 1 << 1 + }; + + virtual ~ScannerInterface(); + + virtual bool is_mock() const = 0; + + virtual std::uint8_t read_register(std::uint16_t address) = 0; + virtual void write_register(std::uint16_t address, std::uint8_t value) = 0; + virtual void write_registers(const Genesys_Register_Set& regs) = 0; + + virtual void write_0x8c(std::uint8_t index, std::uint8_t value) = 0; + virtual void bulk_read_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) = 0; + virtual void bulk_write_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) = 0; + + // GL646, GL841, GL843 have different ways to write to RAM and to gamma tables + // FIXME: remove flags when updating tests + virtual void write_buffer(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags = FLAG_NONE) = 0; + + virtual void write_gamma(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags = FLAG_NONE) = 0; + + // GL845, GL846, GL847 and GL124 have a uniform way to write to RAM tables + virtual void write_ahb(std::uint32_t addr, std::uint32_t size, std::uint8_t* data) = 0; + + virtual std::uint16_t read_fe_register(std::uint8_t address) = 0; + virtual void write_fe_register(std::uint8_t address, std::uint16_t value) = 0; + + virtual IUsbDevice& get_usb_device() = 0; + + // sleeps the specified number of microseconds. Will not sleep if testing mode is enabled. + virtual void sleep_us(unsigned microseconds) = 0; + + void sleep_ms(unsigned milliseconds) + { + sleep_us(milliseconds * 1000); + } + + virtual void record_progress_message(const char* msg) = 0; + + virtual void record_slope_table(unsigned table_nr, const std::vector<std::uint16_t>& steps) = 0; + + virtual void record_key_value(const std::string& key, const std::string& value) = 0; + + virtual void test_checkpoint(const std::string& name) = 0; +}; + +} // namespace genesys + +#endif diff --git a/backend/genesys/scanner_interface_usb.cpp b/backend/genesys/scanner_interface_usb.cpp new file mode 100644 index 0000000..d4d83dd --- /dev/null +++ b/backend/genesys/scanner_interface_usb.cpp @@ -0,0 +1,515 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "scanner_interface_usb.h" +#include "low.h" +#include <thread> + +namespace genesys { + +ScannerInterfaceUsb::~ScannerInterfaceUsb() = default; + +ScannerInterfaceUsb::ScannerInterfaceUsb(Genesys_Device* dev) : dev_{dev} {} + +bool ScannerInterfaceUsb::is_mock() const +{ + return false; +} + +std::uint8_t ScannerInterfaceUsb::read_register(std::uint16_t address) +{ + DBG_HELPER(dbg); + + std::uint8_t value = 0; + + if (dev_->model->asic_type == AsicType::GL847 || + dev_->model->asic_type == AsicType::GL845 || + dev_->model->asic_type == AsicType::GL846 || + dev_->model->asic_type == AsicType::GL124) + { + std::uint8_t value2x8[2]; + std::uint16_t address16 = 0x22 + (address << 8); + + std::uint16_t usb_value = VALUE_GET_REGISTER; + if (address > 0xff) { + usb_value |= 0x100; + } + + usb_dev_.control_msg(REQUEST_TYPE_IN, REQUEST_BUFFER, usb_value, address16, 2, value2x8); + + // check usb link status + if (value2x8[1] != 0x55) { + throw SaneException(SANE_STATUS_IO_ERROR, "invalid read, scanner unplugged?"); + } + + DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, address, value2x8[0]); + + value = value2x8[0]; + + } else { + + if (address > 0xff) { + throw SaneException("Invalid register address 0x%04x", address); + } + + std::uint8_t address8 = address & 0xff; + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, + 1, &address8); + usb_dev_.control_msg(REQUEST_TYPE_IN, REQUEST_REGISTER, VALUE_READ_REGISTER, INDEX, + 1, &value); + } + + DBG(DBG_proc, "%s (0x%02x, 0x%02x) completed\n", __func__, address, value); + return value; +} + +void ScannerInterfaceUsb::write_register(std::uint16_t address, std::uint8_t value) +{ + DBG_HELPER_ARGS(dbg, "address: 0x%04x, value: 0x%02x", static_cast<unsigned>(address), + static_cast<unsigned>(value)); + + if (dev_->model->asic_type == AsicType::GL847 || + dev_->model->asic_type == AsicType::GL845 || + dev_->model->asic_type == AsicType::GL846 || + dev_->model->asic_type == AsicType::GL124) + { + std::uint8_t buffer[2]; + + buffer[0] = address & 0xff; + buffer[1] = value; + + std::uint16_t usb_value = VALUE_SET_REGISTER; + if (address > 0xff) { + usb_value |= 0x100; + } + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, usb_value, INDEX, + 2, buffer); + + } else { + if (address > 0xff) { + throw SaneException("Invalid register address 0x%04x", address); + } + + std::uint8_t address8 = address & 0xff; + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, + 1, &address8); + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_WRITE_REGISTER, INDEX, + 1, &value); + + } + DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, address, value); +} + +void ScannerInterfaceUsb::write_registers(const Genesys_Register_Set& regs) +{ + DBG_HELPER(dbg); + if (dev_->model->asic_type == AsicType::GL646 || + dev_->model->asic_type == AsicType::GL841) + { + uint8_t outdata[8]; + std::vector<uint8_t> buffer; + buffer.reserve(regs.size() * 2); + + /* copy registers and values in data buffer */ + for (const auto& r : regs) { + buffer.push_back(r.address); + buffer.push_back(r.value); + } + + DBG(DBG_io, "%s (elems= %zu, size = %zu)\n", __func__, regs.size(), buffer.size()); + + if (dev_->model->asic_type == AsicType::GL646) { + outdata[0] = BULK_OUT; + outdata[1] = BULK_REGISTER; + outdata[2] = 0x00; + outdata[3] = 0x00; + outdata[4] = (buffer.size() & 0xff); + outdata[5] = ((buffer.size() >> 8) & 0xff); + outdata[6] = ((buffer.size() >> 16) & 0xff); + outdata[7] = ((buffer.size() >> 24) & 0xff); + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, INDEX, + sizeof(outdata), outdata); + + size_t write_size = buffer.size(); + + usb_dev_.bulk_write(buffer.data(), &write_size); + } else { + for (std::size_t i = 0; i < regs.size();) { + std::size_t c = regs.size() - i; + if (c > 32) /*32 is max on GL841. checked that.*/ + c = 32; + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_SET_REGISTER, + INDEX, c * 2, buffer.data() + i * 2); + + i += c; + } + } + } else { + for (const auto& r : regs) { + write_register(r.address, r.value); + } + } + + DBG(DBG_io, "%s: wrote %zu registers\n", __func__, regs.size()); +} + +void ScannerInterfaceUsb::write_0x8c(std::uint8_t index, std::uint8_t value) +{ + DBG_HELPER_ARGS(dbg, "0x%02x,0x%02x", index, value); + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_BUF_ENDACCESS, index, 1, &value); +} + +static void bulk_read_data_send_header(UsbDevice& usb_dev, AsicType asic_type, size_t size) +{ + DBG_HELPER(dbg); + + uint8_t outdata[8]; + if (asic_type == AsicType::GL124 || + asic_type == AsicType::GL846 || + asic_type == AsicType::GL847) + { + // hard coded 0x10000000 address + outdata[0] = 0; + outdata[1] = 0; + outdata[2] = 0; + outdata[3] = 0x10; + } else if (asic_type == AsicType::GL841 || + asic_type == AsicType::GL843) { + outdata[0] = BULK_IN; + outdata[1] = BULK_RAM; + outdata[2] = 0x82; // + outdata[3] = 0x00; + } else { + outdata[0] = BULK_IN; + outdata[1] = BULK_RAM; + outdata[2] = 0x00; + outdata[3] = 0x00; + } + + /* data size to transfer */ + outdata[4] = (size & 0xff); + outdata[5] = ((size >> 8) & 0xff); + outdata[6] = ((size >> 16) & 0xff); + outdata[7] = ((size >> 24) & 0xff); + + usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x00, + sizeof(outdata), outdata); +} + +void ScannerInterfaceUsb::bulk_read_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) +{ + // currently supported: GL646, GL841, GL843, GL846, GL847, GL124 + DBG_HELPER(dbg); + + unsigned is_addr_used = 1; + unsigned has_header_before_each_chunk = 0; + if (dev_->model->asic_type == AsicType::GL124 || + dev_->model->asic_type == AsicType::GL846 || + dev_->model->asic_type == AsicType::GL847) + { + is_addr_used = 0; + has_header_before_each_chunk = 1; + } + + if (is_addr_used) { + DBG(DBG_io, "%s: requesting %zu bytes from 0x%02x addr\n", __func__, size, addr); + } else { + DBG(DBG_io, "%s: requesting %zu bytes\n", __func__, size); + } + + if (size == 0) + return; + + if (is_addr_used) { + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, 0x00, + 1, &addr); + } + + std::size_t target_size = size; + + std::size_t max_in_size = sanei_genesys_get_bulk_max_size(dev_->model->asic_type); + + if (!has_header_before_each_chunk) { + bulk_read_data_send_header(usb_dev_, dev_->model->asic_type, size); + } + + // loop until computed data size is read + while (target_size > 0) { + std::size_t block_size = std::min(target_size, max_in_size); + + if (has_header_before_each_chunk) { + bulk_read_data_send_header(usb_dev_, dev_->model->asic_type, block_size); + } + + DBG(DBG_io2, "%s: trying to read %zu bytes of data\n", __func__, block_size); + + usb_dev_.bulk_read(data, &block_size); + + DBG(DBG_io2, "%s: read %zu bytes, %zu remaining\n", __func__, block_size, target_size - block_size); + + target_size -= block_size; + data += block_size; + } +} + +void ScannerInterfaceUsb::bulk_write_data(std::uint8_t addr, std::uint8_t* data, std::size_t len) +{ + DBG_HELPER_ARGS(dbg, "writing %zu bytes", len); + + // supported: GL646, GL841, GL843 + std::size_t size; + std::uint8_t outdata[8]; + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, + 1, &addr); + + std::size_t max_out_size = sanei_genesys_get_bulk_max_size(dev_->model->asic_type); + + while (len) { + if (len > max_out_size) + size = max_out_size; + else + size = len; + + if (dev_->model->asic_type == AsicType::GL841) { + outdata[0] = BULK_OUT; + outdata[1] = BULK_RAM; + // both 0x82 and 0x00 works on GL841. + outdata[2] = 0x82; + outdata[3] = 0x00; + } else { + outdata[0] = BULK_OUT; + outdata[1] = BULK_RAM; + // 8600F uses 0x82, but 0x00 works too. 8400F uses 0x02 for certain transactions. + outdata[2] = 0x00; + outdata[3] = 0x00; + } + + outdata[4] = (size & 0xff); + outdata[5] = ((size >> 8) & 0xff); + outdata[6] = ((size >> 16) & 0xff); + outdata[7] = ((size >> 24) & 0xff); + + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x00, + sizeof(outdata), outdata); + + usb_dev_.bulk_write(data, &size); + + DBG(DBG_io2, "%s: wrote %zu bytes, %zu remaining\n", __func__, size, len - size); + + len -= size; + data += size; + } +} + +void ScannerInterfaceUsb::write_buffer(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) +{ + DBG_HELPER_ARGS(dbg, "type: 0x%02x, addr: 0x%08x, size: 0x%08zx", type, addr, size); + if (dev_->model->asic_type != AsicType::GL646 && + dev_->model->asic_type != AsicType::GL841 && + dev_->model->asic_type != AsicType::GL843) + { + throw SaneException("Unsupported transfer mode"); + } + + if (dev_->model->asic_type == AsicType::GL843) { + if (flags & FLAG_SWAP_REGISTERS) { + if (!(flags & FLAG_SMALL_ADDRESS)) { + write_register(0x29, ((addr >> 20) & 0xff)); + } + write_register(0x2a, ((addr >> 12) & 0xff)); + write_register(0x2b, ((addr >> 4) & 0xff)); + } else { + write_register(0x2b, ((addr >> 4) & 0xff)); + write_register(0x2a, ((addr >> 12) & 0xff)); + if (!(flags & FLAG_SMALL_ADDRESS)) { + write_register(0x29, ((addr >> 20) & 0xff)); + } + } + } else { + write_register(0x2b, ((addr >> 4) & 0xff)); + write_register(0x2a, ((addr >> 12) & 0xff)); + } + bulk_write_data(type, data, size); +} + +void ScannerInterfaceUsb::write_gamma(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) +{ + DBG_HELPER_ARGS(dbg, "type: 0x%02x, addr: 0x%08x, size: 0x%08zx", type, addr, size); + if (dev_->model->asic_type != AsicType::GL646 && + dev_->model->asic_type != AsicType::GL841 && + dev_->model->asic_type != AsicType::GL843) + { + throw SaneException("Unsupported transfer mode"); + } + + if (flags & FLAG_SWAP_REGISTERS) { + write_register(0x5b, ((addr >> 12) & 0xff)); + write_register(0x5c, ((addr >> 4) & 0xff)); + } else { + write_register(0x5c, ((addr >> 4) & 0xff)); + write_register(0x5b, ((addr >> 12) & 0xff)); + } + bulk_write_data(type, data, size); +} + +void ScannerInterfaceUsb::write_ahb(std::uint32_t addr, std::uint32_t size, std::uint8_t* data) +{ + DBG_HELPER_ARGS(dbg, "address: 0x%08x, size: %d", static_cast<unsigned>(addr), + static_cast<unsigned>(size)); + + if (dev_->model->asic_type != AsicType::GL845 && + dev_->model->asic_type != AsicType::GL846 && + dev_->model->asic_type != AsicType::GL847 && + dev_->model->asic_type != AsicType::GL124) + { + throw SaneException("Unsupported transfer type"); + } + std::uint8_t outdata[8]; + outdata[0] = addr & 0xff; + outdata[1] = ((addr >> 8) & 0xff); + outdata[2] = ((addr >> 16) & 0xff); + outdata[3] = ((addr >> 24) & 0xff); + outdata[4] = (size & 0xff); + outdata[5] = ((size >> 8) & 0xff); + outdata[6] = ((size >> 16) & 0xff); + outdata[7] = ((size >> 24) & 0xff); + + // write addr and size for AHB + usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x01, 8, outdata); + + std::size_t max_out_size = sanei_genesys_get_bulk_max_size(dev_->model->asic_type); + + // write actual data + std::size_t written = 0; + do { + std::size_t block_size = std::min(size - written, max_out_size); + + usb_dev_.bulk_write(data + written, &block_size); + + written += block_size; + } while (written < size); +} + +std::uint16_t ScannerInterfaceUsb::read_fe_register(std::uint8_t address) +{ + DBG_HELPER(dbg); + Genesys_Register_Set reg; + + reg.init_reg(0x50, address); + + // set up read address + write_registers(reg); + + // read data + std::uint16_t value = read_register(0x46) << 8; + value |= read_register(0x47); + + DBG(DBG_io, "%s (0x%02x, 0x%04x)\n", __func__, address, value); + return value; +} + +void ScannerInterfaceUsb::write_fe_register(std::uint8_t address, std::uint16_t value) +{ + DBG_HELPER_ARGS(dbg, "0x%02x, 0x%04x", address, value); + Genesys_Register_Set reg(Genesys_Register_Set::SEQUENTIAL); + + reg.init_reg(0x51, address); + if (dev_->model->asic_type == AsicType::GL124) { + reg.init_reg(0x5d, (value / 256) & 0xff); + reg.init_reg(0x5e, value & 0xff); + } else { + reg.init_reg(0x3a, (value / 256) & 0xff); + reg.init_reg(0x3b, value & 0xff); + } + + write_registers(reg); +} + +IUsbDevice& ScannerInterfaceUsb::get_usb_device() +{ + return usb_dev_; +} + +void ScannerInterfaceUsb::sleep_us(unsigned microseconds) +{ + if (sanei_usb_is_replay_mode_enabled()) { + return; + } + std::this_thread::sleep_for(std::chrono::microseconds{microseconds}); +} + +void ScannerInterfaceUsb::record_progress_message(const char* msg) +{ + sanei_usb_testing_record_message(msg); +} + +void ScannerInterfaceUsb::record_slope_table(unsigned table_nr, + const std::vector<std::uint16_t>& steps) +{ + (void) table_nr; + (void) steps; +} + +void ScannerInterfaceUsb::record_key_value(const std::string& key, const std::string& value) +{ + (void) key; + (void) value; +} + +void ScannerInterfaceUsb::test_checkpoint(const std::string& name) +{ + (void) name; +} + +} // namespace genesys diff --git a/backend/genesys/scanner_interface_usb.h b/backend/genesys/scanner_interface_usb.h new file mode 100644 index 0000000..06b51ff --- /dev/null +++ b/backend/genesys/scanner_interface_usb.h @@ -0,0 +1,98 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_SCANNER_INTERFACE_USB_H +#define BACKEND_GENESYS_SCANNER_INTERFACE_USB_H + +#include "scanner_interface.h" +#include "usb_device.h" + +namespace genesys { + +class ScannerInterfaceUsb : public ScannerInterface +{ +public: + ScannerInterfaceUsb(Genesys_Device* dev); + + ~ScannerInterfaceUsb() override; + + bool is_mock() const override; + + std::uint8_t read_register(std::uint16_t address) override; + void write_register(std::uint16_t address, std::uint8_t value) override; + void write_registers(const Genesys_Register_Set& regs) override; + + void write_0x8c(std::uint8_t index, std::uint8_t value) override; + void bulk_read_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) override; + void bulk_write_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) override; + + void write_buffer(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) override; + void write_gamma(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) override; + + void write_ahb(std::uint32_t addr, std::uint32_t size, std::uint8_t* data) override; + + std::uint16_t read_fe_register(std::uint8_t address) override; + void write_fe_register(std::uint8_t address, std::uint16_t value) override; + + IUsbDevice& get_usb_device() override; + + void sleep_us(unsigned microseconds) override; + + void record_progress_message(const char* msg) override; + + void record_slope_table(unsigned table_nr, const std::vector<std::uint16_t>& steps) override; + + void record_key_value(const std::string& key, const std::string& value) override; + + void test_checkpoint(const std::string& name) override; + +private: + Genesys_Device* dev_; + UsbDevice usb_dev_; +}; + +} // namespace genesys + +#endif diff --git a/backend/genesys/sensor.cpp b/backend/genesys/sensor.cpp new file mode 100644 index 0000000..e54af65 --- /dev/null +++ b/backend/genesys/sensor.cpp @@ -0,0 +1,160 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "sensor.h" +#include "utilities.h" +#include <iomanip> + +namespace genesys { + +std::ostream& operator<<(std::ostream& out, const StaggerConfig& config) +{ + out << "StaggerConfig{\n" + << " min_resolution: " << config.min_resolution() << '\n' + << " lines_at_min: " << config.lines_at_min() << '\n' + << "}"; + return out; +} + +std::ostream& operator<<(std::ostream& out, const FrontendType& type) +{ + switch (type) { + case FrontendType::UNKNOWN: out << "UNKNOWN"; break; + case FrontendType::WOLFSON: out << "WOLFSON"; break; + case FrontendType::ANALOG_DEVICES: out << "ANALOG_DEVICES"; break; + default: out << "(unknown value)"; + } + return out; +} + +std::ostream& operator<<(std::ostream& out, const GenesysFrontendLayout& layout) +{ + StreamStateSaver state_saver{out}; + + out << "GenesysFrontendLayout{\n" + << " type: " << layout.type << '\n' + << std::hex + << " offset_addr[0]: " << layout.offset_addr[0] << '\n' + << " offset_addr[1]: " << layout.offset_addr[1] << '\n' + << " offset_addr[2]: " << layout.offset_addr[2] << '\n' + << " gain_addr[0]: " << layout.gain_addr[0] << '\n' + << " gain_addr[1]: " << layout.gain_addr[1] << '\n' + << " gain_addr[2]: " << layout.gain_addr[2] << '\n' + << '}'; + return out; +} + +std::ostream& operator<<(std::ostream& out, const Genesys_Frontend& frontend) +{ + StreamStateSaver state_saver{out}; + + out << "Genesys_Frontend{\n" + << " id: " << static_cast<unsigned>(frontend.id) << '\n' + << " regs: " << format_indent_braced_list(4, frontend.regs) << '\n' + << std::hex + << " reg2[0]: " << frontend.reg2[0] << '\n' + << " reg2[1]: " << frontend.reg2[1] << '\n' + << " reg2[2]: " << frontend.reg2[2] << '\n' + << " layout: " << format_indent_braced_list(4, frontend.layout) << '\n' + << '}'; + return out; +} + +std::ostream& operator<<(std::ostream& out, const SensorExposure& exposure) +{ + out << "SensorExposure{\n" + << " red: " << exposure.red << '\n' + << " green: " << exposure.green << '\n' + << " blue: " << exposure.blue << '\n' + << '}'; + return out; +} + +std::ostream& operator<<(std::ostream& out, const ResolutionFilter& resolutions) +{ + if (resolutions.matches_any()) { + out << "ANY"; + return out; + } + out << format_vector_unsigned(4, resolutions.resolutions()); + return out; +} + +std::ostream& operator<<(std::ostream& out, const Genesys_Sensor& sensor) +{ + out << "Genesys_Sensor{\n" + << " sensor_id: " << static_cast<unsigned>(sensor.sensor_id) << '\n' + << " optical_res: " << sensor.optical_res << '\n' + << " resolutions: " << format_indent_braced_list(4, sensor.resolutions) << '\n' + << " channels: " << format_vector_unsigned(4, sensor.channels) << '\n' + << " method: " << sensor.method << '\n' + << " register_dpihw_override: " << sensor.register_dpihw_override << '\n' + << " logical_dpihw_override: " << sensor.logical_dpihw_override << '\n' + << " dpiset_override: " << sensor.dpiset_override << '\n' + << " ccd_size_divisor: " << sensor.ccd_size_divisor << '\n' + << " pixel_count_multiplier: " << sensor.pixel_count_multiplier << '\n' + << " black_pixels: " << sensor.black_pixels << '\n' + << " dummy_pixel: " << sensor.dummy_pixel << '\n' + << " ccd_start_xoffset: " << sensor.ccd_start_xoffset << '\n' + << " sensor_pixels: " << sensor.sensor_pixels << '\n' + << " fau_gain_white_ref: " << sensor.fau_gain_white_ref << '\n' + << " gain_white_ref: " << sensor.gain_white_ref << '\n' + << " exposure: " << format_indent_braced_list(4, sensor.exposure) << '\n' + << " exposure_lperiod: " << sensor.exposure_lperiod << '\n' + << " segment_size: " << sensor.segment_size << '\n' + << " segment_order: " + << format_indent_braced_list(4, format_vector_unsigned(4, sensor.segment_order)) << '\n' + << " stagger_config: " << format_indent_braced_list(4, sensor.stagger_config) << '\n' + << " custom_base_regs: " << format_indent_braced_list(4, sensor.custom_base_regs) << '\n' + << " custom_regs: " << format_indent_braced_list(4, sensor.custom_regs) << '\n' + << " custom_fe_regs: " << format_indent_braced_list(4, sensor.custom_fe_regs) << '\n' + << " gamma.red: " << sensor.gamma[0] << '\n' + << " gamma.green: " << sensor.gamma[1] << '\n' + << " gamma.blue: " << sensor.gamma[2] << '\n' + << "}"; + return out; +} + +} // namespace genesys diff --git a/backend/genesys/sensor.h b/backend/genesys/sensor.h new file mode 100644 index 0000000..e70728e --- /dev/null +++ b/backend/genesys/sensor.h @@ -0,0 +1,470 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_SENSOR_H +#define BACKEND_GENESYS_SENSOR_H + +#include "enums.h" +#include "register.h" +#include "serialize.h" +#include <array> +#include <functional> + +namespace genesys { + +template<class T, size_t Size> +struct AssignableArray : public std::array<T, Size> { + AssignableArray() = default; + AssignableArray(const AssignableArray&) = default; + AssignableArray& operator=(const AssignableArray&) = default; + + AssignableArray& operator=(std::initializer_list<T> init) + { + if (init.size() != std::array<T, Size>::size()) + throw std::runtime_error("An array of incorrect size assigned"); + std::copy(init.begin(), init.end(), std::array<T, Size>::begin()); + return *this; + } +}; + + +class StaggerConfig +{ +public: + StaggerConfig() = default; + StaggerConfig(unsigned min_resolution, unsigned lines_at_min) : + min_resolution_{min_resolution}, + lines_at_min_{lines_at_min} + { + } + + unsigned stagger_at_resolution(unsigned xresolution, unsigned yresolution) const + { + if (min_resolution_ == 0 || xresolution < min_resolution_) + return 0; + return yresolution / min_resolution_ * lines_at_min_; + } + + unsigned min_resolution() const { return min_resolution_; } + unsigned lines_at_min() const { return lines_at_min_; } + + bool operator==(const StaggerConfig& other) const + { + return min_resolution_ == other.min_resolution_ && + lines_at_min_ == other.lines_at_min_; + } + +private: + unsigned min_resolution_ = 0; + unsigned lines_at_min_ = 0; + + template<class Stream> + friend void serialize(Stream& str, StaggerConfig& x); +}; + +template<class Stream> +void serialize(Stream& str, StaggerConfig& x) +{ + serialize(str, x.min_resolution_); + serialize(str, x.lines_at_min_); +} + +std::ostream& operator<<(std::ostream& out, const StaggerConfig& config); + + +enum class FrontendType : unsigned +{ + UNKNOWN, + WOLFSON, + ANALOG_DEVICES +}; + +inline void serialize(std::istream& str, FrontendType& x) +{ + unsigned value; + serialize(str, value); + x = static_cast<FrontendType>(value); +} + +inline void serialize(std::ostream& str, FrontendType& x) +{ + unsigned value = static_cast<unsigned>(x); + serialize(str, value); +} + +std::ostream& operator<<(std::ostream& out, const FrontendType& type); + +struct GenesysFrontendLayout +{ + FrontendType type = FrontendType::UNKNOWN; + std::array<std::uint16_t, 3> offset_addr = {}; + std::array<std::uint16_t, 3> gain_addr = {}; + + bool operator==(const GenesysFrontendLayout& other) const + { + return type == other.type && + offset_addr == other.offset_addr && + gain_addr == other.gain_addr; + } +}; + +template<class Stream> +void serialize(Stream& str, GenesysFrontendLayout& x) +{ + serialize(str, x.type); + serialize_newline(str); + serialize(str, x.offset_addr); + serialize_newline(str); + serialize(str, x.gain_addr); +} + +std::ostream& operator<<(std::ostream& out, const GenesysFrontendLayout& layout); + +/** @brief Data structure to set up analog frontend. + The analog frontend converts analog value from image sensor to digital value. It has its own + control registers which are set up with this structure. The values are written using + fe_write_data. + */ +struct Genesys_Frontend +{ + Genesys_Frontend() = default; + + // id of the frontend description + AdcId id = AdcId::UNKNOWN; + + // all registers of the frontend. Note that the registers can hold 9-bit values + RegisterSettingSet<std::uint16_t> regs; + + // extra control registers + std::array<std::uint16_t, 3> reg2 = {}; + + GenesysFrontendLayout layout; + + void set_offset(unsigned which, std::uint16_t value) + { + regs.set_value(layout.offset_addr[which], value); + } + + void set_gain(unsigned which, std::uint16_t value) + { + regs.set_value(layout.gain_addr[which], value); + } + + std::uint16_t get_offset(unsigned which) const + { + return regs.get_value(layout.offset_addr[which]); + } + + std::uint16_t get_gain(unsigned which) const + { + return regs.get_value(layout.gain_addr[which]); + } + + bool operator==(const Genesys_Frontend& other) const + { + return id == other.id && + regs == other.regs && + reg2 == other.reg2 && + layout == other.layout; + } +}; + +std::ostream& operator<<(std::ostream& out, const Genesys_Frontend& frontend); + +template<class Stream> +void serialize(Stream& str, Genesys_Frontend& x) +{ + serialize(str, x.id); + serialize_newline(str); + serialize(str, x.regs); + serialize_newline(str); + serialize(str, x.reg2); + serialize_newline(str); + serialize(str, x.layout); +} + +struct SensorExposure { + std::uint16_t red = 0; + std::uint16_t green = 0; + std::uint16_t blue = 0; + + SensorExposure() = default; + SensorExposure(std::uint16_t r, std::uint16_t g, std::uint16_t b) : + red{r}, green{g}, blue{b} + {} + + bool operator==(const SensorExposure& other) const + { + return red == other.red && green == other.green && blue == other.blue; + } +}; + +std::ostream& operator<<(std::ostream& out, const SensorExposure& exposure); + + +class ResolutionFilter +{ +public: + struct Any {}; + static constexpr Any ANY{}; + + ResolutionFilter() : matches_any_{false} {} + ResolutionFilter(Any) : matches_any_{true} {} + ResolutionFilter(std::initializer_list<unsigned> resolutions) : + matches_any_{false}, + resolutions_{resolutions} + {} + + bool matches(unsigned resolution) const + { + if (matches_any_) + return true; + auto it = std::find(resolutions_.begin(), resolutions_.end(), resolution); + return it != resolutions_.end(); + } + + bool operator==(const ResolutionFilter& other) const + { + return matches_any_ == other.matches_any_ && resolutions_ == other.resolutions_; + } + + bool matches_any() const { return matches_any_; } + const std::vector<unsigned>& resolutions() const { return resolutions_; } + +private: + bool matches_any_ = false; + std::vector<unsigned> resolutions_; + + template<class Stream> + friend void serialize(Stream& str, ResolutionFilter& x); +}; + +std::ostream& operator<<(std::ostream& out, const ResolutionFilter& resolutions); + +template<class Stream> +void serialize(Stream& str, ResolutionFilter& x) +{ + serialize(str, x.matches_any_); + serialize_newline(str); + serialize(str, x.resolutions_); +} + + +struct Genesys_Sensor { + + Genesys_Sensor() = default; + ~Genesys_Sensor() = default; + + // id of the sensor description + SensorId sensor_id = SensorId::UNKNOWN; + + // sensor resolution in CCD pixels. Note that we may read more than one CCD pixel per logical + // pixel, see ccd_pixels_per_system_pixel() + unsigned optical_res = 0; + + // the resolution list that the sensor is usable at. + ResolutionFilter resolutions = ResolutionFilter::ANY; + + // the channel list that the sensor is usable at + std::vector<unsigned> channels = { 1, 3 }; + + // the scan method used with the sensor + ScanMethod method = ScanMethod::FLATBED; + + // The scanner may be setup to use a custom dpihw that does not correspond to any actual + // resolution. The value zero does not set the override. + unsigned register_dpihw_override = 0; + + // The scanner may be setup to use a custom logical dpihw that does not correspond to any actual + // resolution. The value zero does not set the override. + unsigned logical_dpihw_override = 0; + + // The scanner may be setup to use a custom dpiset value that does not correspond to any actual + // resolution. The value zero does not set the override. + unsigned dpiset_override = 0; + + // CCD may present itself as half or quarter-size CCD on certain resolutions + int ccd_size_divisor = 1; + + // Some scanners need an additional multiplier over the scan coordinates + int pixel_count_multiplier = 1; + + int black_pixels = 0; + // value of the dummy register + int dummy_pixel = 0; + // last pixel of CCD margin at optical resolution + int ccd_start_xoffset = 0; + // total pixels used by the sensor + int sensor_pixels = 0; + // TA CCD target code (reference gain) + int fau_gain_white_ref = 0; + // CCD target code (reference gain) + int gain_white_ref = 0; + + // red, green and blue initial exposure values + SensorExposure exposure; + + int exposure_lperiod = -1; + + // the number of pixels in a single segment. + // only on gl843 + unsigned segment_size = 0; + + // the order of the segments, if any, for the sensor. If the sensor is not segmented or uses + // only single segment, this array can be empty + // only on gl843 + std::vector<unsigned> segment_order; + + // some CCDs use two arrays of pixels for double resolution. On such CCDs when scanning at + // high-enough resolution, every other pixel column is shifted + StaggerConfig stagger_config; + + GenesysRegisterSettingSet custom_base_regs; // gl646-specific + GenesysRegisterSettingSet custom_regs; + GenesysRegisterSettingSet custom_fe_regs; + + // red, green and blue gamma coefficient for default gamma tables + AssignableArray<float, 3> gamma; + + std::function<unsigned(const Genesys_Sensor&, unsigned)> get_logical_hwdpi_fun; + std::function<unsigned(const Genesys_Sensor&, unsigned)> get_register_hwdpi_fun; + std::function<unsigned(const Genesys_Sensor&, unsigned)> get_ccd_size_divisor_fun; + std::function<unsigned(const Genesys_Sensor&, unsigned)> get_hwdpi_divisor_fun; + + unsigned get_logical_hwdpi(unsigned xres) const { return get_logical_hwdpi_fun(*this, xres); } + unsigned get_register_hwdpi(unsigned xres) const { return get_register_hwdpi_fun(*this, xres); } + unsigned get_ccd_size_divisor_for_dpi(unsigned xres) const + { + return get_ccd_size_divisor_fun(*this, xres); + } + unsigned get_hwdpi_divisor_for_dpi(unsigned xres) const + { + return get_hwdpi_divisor_fun(*this, xres); + } + + // how many CCD pixels are processed per system pixel time. This corresponds to CKSEL + 1 + unsigned ccd_pixels_per_system_pixel() const + { + // same on GL646, GL841, GL843, GL846, GL847, GL124 + constexpr unsigned REG_CKSEL = 0x03; + return (custom_regs.get_value(0x18) & REG_CKSEL) + 1; + } + + bool matches_channel_count(unsigned count) const + { + return std::find(channels.begin(), channels.end(), count) != channels.end(); + } + + unsigned get_segment_count() const + { + if (segment_order.size() < 2) + return 1; + return segment_order.size(); + } + + bool operator==(const Genesys_Sensor& other) const + { + return sensor_id == other.sensor_id && + optical_res == other.optical_res && + resolutions == other.resolutions && + method == other.method && + ccd_size_divisor == other.ccd_size_divisor && + black_pixels == other.black_pixels && + dummy_pixel == other.dummy_pixel && + ccd_start_xoffset == other.ccd_start_xoffset && + sensor_pixels == other.sensor_pixels && + fau_gain_white_ref == other.fau_gain_white_ref && + gain_white_ref == other.gain_white_ref && + exposure == other.exposure && + exposure_lperiod == other.exposure_lperiod && + segment_size == other.segment_size && + segment_order == other.segment_order && + stagger_config == other.stagger_config && + custom_base_regs == other.custom_base_regs && + custom_regs == other.custom_regs && + custom_fe_regs == other.custom_fe_regs && + gamma == other.gamma; + } +}; + +template<class Stream> +void serialize(Stream& str, Genesys_Sensor& x) +{ + serialize(str, x.sensor_id); + serialize(str, x.optical_res); + serialize(str, x.resolutions); + serialize(str, x.method); + serialize(str, x.ccd_size_divisor); + serialize(str, x.black_pixels); + serialize(str, x.dummy_pixel); + serialize(str, x.ccd_start_xoffset); + serialize(str, x.sensor_pixels); + serialize(str, x.fau_gain_white_ref); + serialize(str, x.gain_white_ref); + serialize_newline(str); + serialize(str, x.exposure.blue); + serialize(str, x.exposure.green); + serialize(str, x.exposure.red); + serialize(str, x.exposure_lperiod); + serialize_newline(str); + serialize(str, x.segment_size); + serialize_newline(str); + serialize(str, x.segment_order); + serialize_newline(str); + serialize(str, x.stagger_config); + serialize_newline(str); + serialize(str, x.custom_base_regs); + serialize_newline(str); + serialize(str, x.custom_regs); + serialize_newline(str); + serialize(str, x.custom_fe_regs); + serialize_newline(str); + serialize(str, x.gamma); + serialize_newline(str); +} + +std::ostream& operator<<(std::ostream& out, const Genesys_Sensor& sensor); + +} // namespace genesys + +#endif // BACKEND_GENESYS_SENSOR_H diff --git a/backend/genesys_serialize.cc b/backend/genesys/serialize.cpp index e69de29..e69de29 100644 --- a/backend/genesys_serialize.cc +++ b/backend/genesys/serialize.cpp diff --git a/backend/genesys_serialize.h b/backend/genesys/serialize.h index 481e872..ed40a4e 100644 --- a/backend/genesys_serialize.h +++ b/backend/genesys/serialize.h @@ -44,18 +44,22 @@ #ifndef BACKEND_GENESYS_SERIALIZE_H #define BACKEND_GENESYS_SERIALIZE_H -#include "genesys_error.h" +#include "error.h" #include <array> #include <iostream> #include <limits> #include <string> #include <vector> +namespace genesys { + // it would be best to use something like boost.serialization inline void serialize_newline(std::ostream& str) { str << '\n'; } inline void serialize_newline(std::istream& str) { (void) str; } +inline void serialize(std::ostream& str, bool x) { str << static_cast<unsigned>(x) << " "; } +inline void serialize(std::istream& str, bool& x) { unsigned v; str >> v; x = v; } inline void serialize(std::ostream& str, char x) { str << static_cast<int>(x) << " "; } inline void serialize(std::istream& str, char& x) { int v; str >> v; x = v; } inline void serialize(std::ostream& str, unsigned char x) { str << static_cast<unsigned>(x) << " "; } @@ -141,4 +145,6 @@ void serialize(std::istream& str, std::array<T, Size>& x) } } +} // namespace genesys + #endif diff --git a/backend/genesys/settings.cpp b/backend/genesys/settings.cpp new file mode 100644 index 0000000..41c66de --- /dev/null +++ b/backend/genesys/settings.cpp @@ -0,0 +1,142 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "settings.h" +#include "utilities.h" +#include <iomanip> + +namespace genesys { + +std::ostream& operator<<(std::ostream& out, const Genesys_Settings& settings) +{ + StreamStateSaver state_saver{out}; + + out << "Genesys_Settings{\n" + << " xres: " << settings.xres << " yres: " << settings.yres << '\n' + << " lines: " << settings.lines << '\n' + << " pixels per line (actual): " << settings.pixels << '\n' + << " pixels per line (requested): " << settings.requested_pixels << '\n' + << " depth: " << settings.depth << '\n'; + auto prec = out.precision(); + out.precision(3); + out << " tl_x: " << settings.tl_x << " tl_y: " << settings.tl_y << '\n'; + out.precision(prec); + out << " scan_mode: " << settings.scan_mode << '\n' + << '}'; + return out; +} + +std::ostream& operator<<(std::ostream& out, const SetupParams& params) +{ + StreamStateSaver state_saver{out}; + + out << "SetupParams{\n" + << " xres: " << params.xres << " yres: " << params.yres << '\n' + << " lines: " << params.lines << '\n' + << " pixels per line (actual): " << params.pixels << '\n' + << " pixels per line (requested): " << params.requested_pixels << '\n' + << " depth: " << params.depth << '\n' + << " channels: " << params.channels << '\n' + << " startx: " << params.startx << " starty: " << params.starty << '\n' + << " scan_mode: " << params.scan_mode << '\n' + << " color_filter: " << params.color_filter << '\n' + << " flags: " << params.flags << '\n' + << "}"; + return out; +} + +std::ostream& operator<<(std::ostream& out, const ScanSession& session) +{ + out << "ScanSession{\n" + << " computed: " << session.computed << '\n' + << " hwdpi_divisor: " << session.hwdpi_divisor << '\n' + << " ccd_size_divisor: " << session.ccd_size_divisor << '\n' + << " optical_resolution: " << session.optical_resolution << '\n' + << " optical_pixels: " << session.optical_pixels << '\n' + << " optical_pixels_raw: " << session.optical_pixels_raw << '\n' + << " output_resolution: " << session.output_resolution << '\n' + << " output_pixels: " << session.output_pixels << '\n' + << " output_line_bytes: " << session.output_line_bytes << '\n' + << " output_line_bytes_raw: " << session.output_line_bytes_raw << '\n' + << " output_line_count: " << session.output_line_count << '\n' + << " num_staggered_lines: " << session.num_staggered_lines << '\n' + << " color_shift_lines_r: " << session.color_shift_lines_r << '\n' + << " color_shift_lines_g: " << session.color_shift_lines_g << '\n' + << " color_shift_lines_b: " << session.color_shift_lines_b << '\n' + << " max_color_shift_lines: " << session.max_color_shift_lines << '\n' + << " enable_ledadd: " << session.enable_ledadd << '\n' + << " segment_count: " << session.segment_count << '\n' + << " pixel_startx: " << session.pixel_startx << '\n' + << " pixel_endx: " << session.pixel_endx << '\n' + << " conseq_pixel_dist: " << session.conseq_pixel_dist << '\n' + << " output_segment_pixel_group_count: " + << session.output_segment_pixel_group_count << '\n' + << " buffer_size_read: " << session.buffer_size_read << '\n' + << " buffer_size_read: " << session.buffer_size_lines << '\n' + << " buffer_size_shrink: " << session.buffer_size_shrink << '\n' + << " buffer_size_out: " << session.buffer_size_out << '\n' + << " filters: " + << (session.pipeline_needs_reorder ? " reorder": "") + << (session.pipeline_needs_ccd ? " ccd": "") + << (session.pipeline_needs_shrink ? " shrink": "") << '\n' + << " params: " << format_indent_braced_list(4, session.params) << '\n' + << "}"; + return out; +} + +std::ostream& operator<<(std::ostream& out, const SANE_Parameters& params) +{ + out << "SANE_Parameters{\n" + << " format: " << static_cast<unsigned>(params.format) << '\n' + << " last_frame: " << params.last_frame << '\n' + << " bytes_per_line: " << params.bytes_per_line << '\n' + << " pixels_per_line: " << params.pixels_per_line << '\n' + << " lines: " << params.lines << '\n' + << " depth: " << params.depth << '\n' + << '}'; + return out; +} + +} // namespace genesys diff --git a/backend/genesys/settings.h b/backend/genesys/settings.h new file mode 100644 index 0000000..a697e60 --- /dev/null +++ b/backend/genesys/settings.h @@ -0,0 +1,328 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_SETTINGS_H +#define BACKEND_GENESYS_SETTINGS_H + +#include "enums.h" +#include "serialize.h" + +namespace genesys { + +struct Genesys_Settings +{ + ScanMethod scan_method = ScanMethod::FLATBED; + ScanColorMode scan_mode = ScanColorMode::LINEART; + + // horizontal dpi + unsigned xres = 0; + // vertical dpi + unsigned yres = 0; + + //x start on scan table in mm + double tl_x = 0; + // y start on scan table in mm + double tl_y = 0; + + // number of lines at scan resolution + unsigned int lines = 0; + // number of pixels expected from the scanner + unsigned int pixels = 0; + // number of pixels expected by the frontend + unsigned requested_pixels = 0; + + // bit depth of the scan + unsigned int depth = 0; + + ColorFilter color_filter = ColorFilter::NONE; + + // true if scan is true gray, false if monochrome scan + int true_gray = 0; + + // lineart threshold + int threshold = 0; + + // lineart threshold curve for dynamic rasterization + int threshold_curve = 0; + + // Disable interpolation for xres<yres + int disable_interpolation = 0; + + // value for contrast enhancement in the [-100..100] range + int contrast = 0; + + // value for brightness enhancement in the [-100..100] range + int brightness = 0; + + // cache entries expiration time + int expiration_time = 0; + + unsigned get_channels() const + { + if (scan_mode == ScanColorMode::COLOR_SINGLE_PASS) + return 3; + return 1; + } +}; + +std::ostream& operator<<(std::ostream& out, const Genesys_Settings& settings); + + +struct SetupParams { + + static constexpr unsigned NOT_SET = std::numeric_limits<unsigned>::max(); + + // resolution in x direction + unsigned xres = NOT_SET; + // resolution in y direction + unsigned yres = NOT_SET; + // start pixel in X direction, from dummy_pixel + 1 + unsigned startx = NOT_SET; + // start pixel in Y direction, counted according to base_ydpi + unsigned starty = NOT_SET; + // the number of pixels in X direction. Note that each logical pixel may correspond to more + // than one CCD pixel, see CKSEL and GenesysSensor::ccd_pixels_per_system_pixel() + unsigned pixels = NOT_SET; + + // the number of pixels in the X direction as requested by the frontend. This will be different + // from `pixels` if the X resolution requested by the frontend is different than the actual + // resolution. This is only needed to compute dev->total_bytes_to_read. If 0, then the value + // is the same as pixels. + // TODO: move the computation of total_bytes_to_read to a higher layer. + unsigned requested_pixels = 0; + + // the number of pixels in Y direction + unsigned lines = NOT_SET; + // the depth of the scan in bits. Allowed are 1, 8, 16 + unsigned depth = NOT_SET; + // the number of channels + unsigned channels = NOT_SET; + + ScanMethod scan_method = static_cast<ScanMethod>(NOT_SET); + + ScanColorMode scan_mode = static_cast<ScanColorMode>(NOT_SET); + + ColorFilter color_filter = static_cast<ColorFilter>(NOT_SET); + + ScanFlag flags; + + unsigned get_requested_pixels() const + { + if (requested_pixels != 0) { + return requested_pixels; + } + return pixels; + } + + void assert_valid() const + { + if (xres == NOT_SET || yres == NOT_SET || startx == NOT_SET || starty == NOT_SET || + pixels == NOT_SET || lines == NOT_SET ||depth == NOT_SET || channels == NOT_SET || + scan_method == static_cast<ScanMethod>(NOT_SET) || + scan_mode == static_cast<ScanColorMode>(NOT_SET) || + color_filter == static_cast<ColorFilter>(NOT_SET)) + { + throw std::runtime_error("SetupParams are not valid"); + } + } + + bool operator==(const SetupParams& other) const + { + return xres == other.xres && + yres == other.yres && + startx == other.startx && + starty == other.starty && + pixels == other.pixels && + requested_pixels == other.requested_pixels && + lines == other.lines && + depth == other.depth && + channels == other.channels && + scan_method == other.scan_method && + scan_mode == other.scan_mode && + color_filter == other.color_filter && + flags == other.flags; + } +}; + +std::ostream& operator<<(std::ostream& out, const SetupParams& params); + +template<class Stream> +void serialize(Stream& str, SetupParams& x) +{ + serialize(str, x.xres); + serialize(str, x.yres); + serialize(str, x.startx); + serialize(str, x.starty); + serialize(str, x.pixels); + serialize(str, x.requested_pixels); + serialize(str, x.lines); + serialize(str, x.depth); + serialize(str, x.channels); + serialize(str, x.scan_method); + serialize(str, x.scan_mode); + serialize(str, x.color_filter); + serialize(str, x.flags); +} + +struct ScanSession { + SetupParams params; + + // whether the session setup has been computed via compute_session() + bool computed = false; + + // specifies the reduction (if any) of hardware dpi on the Genesys chip side. + // except gl646 + unsigned hwdpi_divisor = 1; + + // specifies the reduction (if any) of CCD effective dpi which is performed by latching the + // data coming from CCD in such a way that 1/2 or 3/4 of pixel data is ignored. + unsigned ccd_size_divisor = 1; + + // the optical resolution of the scanner. + unsigned optical_resolution = 0; + + // the number of pixels at the optical resolution, not including segmentation overhead. + unsigned optical_pixels = 0; + + // the number of pixels at the optical resolution, including segmentation overhead. + // only on gl846, g847 + unsigned optical_pixels_raw = 0; + + // the resolution of the output data. + // gl843-only + unsigned output_resolution = 0; + + // the number of pixels in output data (after desegmentation) + unsigned output_pixels = 0; + + // the number of bytes in the output of a channel of a single line (after desegmentation) + unsigned output_channel_bytes = 0; + + // the number of bytes in the output of a single line (after desegmentation) + unsigned output_line_bytes = 0; + + // the number of bytes per line in the output data from the scanner (before desegmentation) + // Equal to output_line_bytes if sensor does not have segments + unsigned output_line_bytes_raw = 0; + + // the number of bytes per line as requested by the frontend + unsigned output_line_bytes_requested = 0; + + // the number of lines in the output of the scanner. This must be larger than the user + // requested number due to line staggering and color channel shifting. + unsigned output_line_count = 0; + + // the total number of bytes to read from the scanner (before desegmentation) + unsigned output_total_bytes_raw = 0; + + // the total number of bytes to read from the scanner (after desegmentation) + unsigned output_total_bytes = 0; + + // the number of staggered lines (i.e. lines that overlap during scanning due to line being + // thinner than the CCD element) + unsigned num_staggered_lines = 0; + + // the number of lines that color channels shift due to different physical positions of + // different color channels. + unsigned max_color_shift_lines = 0; + + // actual line shift of the red color + unsigned color_shift_lines_r = 0; + // actual line shift of the green color + unsigned color_shift_lines_g = 0; + // actual line shift of the blue color + unsigned color_shift_lines_b = 0; + + // the number of scanner segments used in the current scan + unsigned segment_count = 1; + + // the physical pixel positions that are sent to the registers + unsigned pixel_startx = 0; + unsigned pixel_endx = 0; + + // certain scanners require the logical pixel count to be multiplied on certain resolutions + unsigned pixel_count_multiplier = 1; + + // Distance in pixels between consecutive pixels, e.g. between odd and even pixels. Note that + // the number of segments can be large. + // only on gl124, gl846, gl847 + unsigned conseq_pixel_dist = 0; + + // The number of "even" pixels to scan. This corresponds to the number of pixels that will be + // scanned from a single segment + // only on gl124, gl846, gl847 + unsigned output_segment_pixel_group_count = 0; + + // The number of bytes to skip at start of line during desegmentation. + // Currently it's always zero. + unsigned output_segment_start_offset = 0; + + // the sizes of the corresponding buffers + size_t buffer_size_read = 0; + size_t buffer_size_lines = 0; + size_t buffer_size_shrink = 0; + size_t buffer_size_out = 0; + + // whether to enable ledadd functionality + bool enable_ledadd = false; + + // what pipeline modifications are needed + bool pipeline_needs_reorder = false; + bool pipeline_needs_ccd = false; + bool pipeline_needs_shrink = false; + + void assert_computed() const + { + if (!computed) { + throw std::runtime_error("ScanSession is not computed"); + } + } +}; + +std::ostream& operator<<(std::ostream& out, const ScanSession& session); + +std::ostream& operator<<(std::ostream& out, const SANE_Parameters& params); + +} // namespace genesys + +#endif // BACKEND_GENESYS_SETTINGS_H diff --git a/backend/genesys/static_init.cpp b/backend/genesys/static_init.cpp new file mode 100644 index 0000000..c0f3748 --- /dev/null +++ b/backend/genesys/static_init.cpp @@ -0,0 +1,70 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "static_init.h" +#include <vector> + +namespace genesys { + +static std::unique_ptr<std::vector<std::function<void()>>> s_functions_run_at_backend_exit; + +void add_function_to_run_at_backend_exit(const std::function<void()>& function) +{ + if (!s_functions_run_at_backend_exit) + s_functions_run_at_backend_exit.reset(new std::vector<std::function<void()>>()); + s_functions_run_at_backend_exit->push_back(std::move(function)); +} + +void run_functions_at_backend_exit() +{ + for (auto it = s_functions_run_at_backend_exit->rbegin(); + it != s_functions_run_at_backend_exit->rend(); ++it) + { + (*it)(); + } + s_functions_run_at_backend_exit.reset(); +} + +} // namespace genesys diff --git a/backend/genesys/static_init.h b/backend/genesys/static_init.h new file mode 100644 index 0000000..3ffa62c --- /dev/null +++ b/backend/genesys/static_init.h @@ -0,0 +1,88 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_STATIC_INIT_H +#define BACKEND_GENESYS_STATIC_INIT_H + +#include <functional> +#include <memory> + +namespace genesys { + +void add_function_to_run_at_backend_exit(const std::function<void()>& function); + +// calls functions added via add_function_to_run_at_backend_exit() in reverse order of being +// added. +void run_functions_at_backend_exit(); + +template<class T> +class StaticInit { +public: + StaticInit() = default; + StaticInit(const StaticInit&) = delete; + StaticInit& operator=(const StaticInit&) = delete; + + template<class... Args> + void init(Args&& ... args) + { + ptr_ = std::unique_ptr<T>(new T(std::forward<Args>(args)...)); + add_function_to_run_at_backend_exit([this](){ deinit(); }); + } + + void deinit() + { + ptr_.reset(); + } + + const T* operator->() const { return ptr_.get(); } + T* operator->() { return ptr_.get(); } + const T& operator*() const { return *ptr_.get(); } + T& operator*() { return *ptr_.get(); } + +private: + std::unique_ptr<T> ptr_; +}; + +} // namespace genesys + +#endif // BACKEND_GENESYS_STATIC_INIT_H diff --git a/backend/genesys/status.cpp b/backend/genesys/status.cpp new file mode 100644 index 0000000..7f883b0 --- /dev/null +++ b/backend/genesys/status.cpp @@ -0,0 +1,66 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "status.h" +#include <iostream> + +namespace genesys { + +std::ostream& operator<<(std::ostream& out, Status status) +{ + out << "Status{\n" + << " replugged: " << (status.is_replugged ? "yes" : "no") << '\n' + << " is_buffer_empty: " << (status.is_buffer_empty ? "yes" : "no") << '\n' + << " is_feeding_finished: " << (status.is_feeding_finished ? "yes" : "no") << '\n' + << " is_scanning_finished: " << (status.is_scanning_finished ? "yes" : "no") << '\n' + << " is_at_home: " << (status.is_at_home ? "yes" : "no") << '\n' + << " is_lamp_on: " << (status.is_lamp_on ? "yes" : "no") << '\n' + << " is_front_end_busy: " << (status.is_front_end_busy ? "yes" : "no") << '\n' + << " is_motor_enabled: " << (status.is_motor_enabled ? "yes" : "no") << '\n' + << "}\n"; + return out; +} + +} // namespace genesys diff --git a/backend/genesys/status.h b/backend/genesys/status.h new file mode 100644 index 0000000..91f4692 --- /dev/null +++ b/backend/genesys/status.h @@ -0,0 +1,68 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_STATUS_H +#define BACKEND_GENESYS_STATUS_H + +#include <iosfwd> + +namespace genesys { + +/// Represents the scanner status register +struct Status +{ + bool is_replugged = false; + bool is_buffer_empty = false; + bool is_feeding_finished = false; + bool is_scanning_finished = false; + bool is_at_home = false; + bool is_lamp_on = false; + bool is_front_end_busy = false; + bool is_motor_enabled = false; +}; + +std::ostream& operator<<(std::ostream& out, Status status); + +} // namespace genesys + +#endif // BACKEND_GENESYS_STATUS_H diff --git a/backend/genesys/tables_frontend.cpp b/backend/genesys/tables_frontend.cpp new file mode 100644 index 0000000..1edf32f --- /dev/null +++ b/backend/genesys/tables_frontend.cpp @@ -0,0 +1,653 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "low.h" + +namespace genesys { + +StaticInit<std::vector<Genesys_Frontend>> s_frontends; + +void genesys_init_frontend_tables() +{ + s_frontends.init(); + + GenesysFrontendLayout wolfson_layout; + wolfson_layout.type = FrontendType::WOLFSON; + wolfson_layout.offset_addr = { 0x20, 0x21, 0x22 }; + wolfson_layout.gain_addr = { 0x28, 0x29, 0x2a }; + + GenesysFrontendLayout analog_devices; + analog_devices.type = FrontendType::ANALOG_DEVICES; + + + Genesys_Frontend fe; + fe.id = AdcId::WOLFSON_UMAX; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x03 }, + { 0x02, 0x05 }, + { 0x03, 0x11 }, + { 0x20, 0x80 }, + { 0x21, 0x80 }, + { 0x22, 0x80 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x02 }, + { 0x29, 0x02 }, + { 0x2a, 0x02 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_ST12; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x03 }, + { 0x02, 0x05 }, + { 0x03, 0x03 }, + { 0x20, 0xc8 }, + { 0x21, 0xc8 }, + { 0x22, 0xc8 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x04 }, + { 0x29, 0x04 }, + { 0x2a, 0x04 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_ST24; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x03 }, + { 0x02, 0x05 }, + { 0x03, 0x21 }, + { 0x20, 0xc8 }, + { 0x21, 0xc8 }, + { 0x22, 0xc8 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x06 }, + { 0x29, 0x06 }, + { 0x2a, 0x06 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_5345; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x03 }, + { 0x02, 0x05 }, + { 0x03, 0x12 }, + { 0x20, 0xb8 }, + { 0x21, 0xb8 }, + { 0x22, 0xb8 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x04 }, + { 0x29, 0x04 }, + { 0x2a, 0x04 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + // reg3=0x02 for 50-600 dpi, 0x32 (0x12 also works well) at 1200 + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_HP2400; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x03 }, + { 0x02, 0x05 }, + { 0x03, 0x02 }, + { 0x20, 0xb4 }, + { 0x21, 0xb6 }, + { 0x22, 0xbc }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x06 }, + { 0x29, 0x09 }, + { 0x2a, 0x08 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_HP2300; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x03 }, + { 0x02, 0x04 }, + { 0x03, 0x02 }, + { 0x20, 0xbe }, + { 0x21, 0xbe }, + { 0x22, 0xbe }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x04 }, + { 0x29, 0x04 }, + { 0x2a, 0x04 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_LIDE_35; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x3d }, + { 0x02, 0x08 }, + { 0x03, 0x00 }, + { 0x20, 0xe1 }, + { 0x21, 0xe1 }, + { 0x22, 0xe1 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x93 }, + { 0x29, 0x93 }, + { 0x2a, 0x93 }, + }; + fe.reg2 = {0x00, 0x19, 0x06}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::AD_XP200; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x58 }, + { 0x01, 0x80 }, + { 0x02, 0x00 }, + { 0x03, 0x00 }, + { 0x20, 0x09 }, + { 0x21, 0x09 }, + { 0x22, 0x09 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x09 }, + { 0x29, 0x09 }, + { 0x2a, 0x09 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_XP300; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x35 }, + { 0x02, 0x20 }, + { 0x03, 0x14 }, + { 0x20, 0xe1 }, + { 0x21, 0xe1 }, + { 0x22, 0xe1 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x93 }, + { 0x29, 0x93 }, + { 0x2a, 0x93 }, + }; + fe.reg2 = {0x07, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_HP3670; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x03 }, + { 0x02, 0x05 }, + { 0x03, 0x32 }, + { 0x20, 0xba }, + { 0x21, 0xb8 }, + { 0x22, 0xb8 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x06 }, + { 0x29, 0x05 }, + { 0x2a, 0x04 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::WOLFSON_DSM600; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x35 }, + { 0x02, 0x20 }, + { 0x03, 0x14 }, + { 0x20, 0x85 }, + { 0x21, 0x85 }, + { 0x22, 0x85 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0xa0 }, + { 0x29, 0xa0 }, + { 0x2a, 0xa0 }, + }; + fe.reg2 = {0x07, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_LIDE_200; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x9d }, + { 0x01, 0x91 }, + { 0x02, 0x00 }, + { 0x03, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x3f }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x32 }, + { 0x29, 0x04 }, + { 0x2a, 0x00 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_LIDE_700F; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x9d }, + { 0x01, 0x9e }, + { 0x02, 0x00 }, + { 0x03, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x3f }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x2f }, + { 0x29, 0x04 }, + { 0x2a, 0x00 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::KVSS080; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x23 }, + { 0x02, 0x24 }, + { 0x03, 0x0f }, + { 0x20, 0x80 }, + { 0x21, 0x80 }, + { 0x22, 0x80 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x4b }, + { 0x29, 0x4b }, + { 0x2a, 0x4b }, + }; + fe.reg2 = {0x00,0x00,0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::G4050; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x23 }, + { 0x02, 0x24 }, + { 0x03, 0x1f }, + { 0x20, 0x45 }, + { 0x21, 0x45 }, + { 0x22, 0x45 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x4b }, + { 0x29, 0x4b }, + { 0x2a, 0x4b }, + }; + fe.reg2 = {0x00,0x00,0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_LIDE_110; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x80 }, + { 0x01, 0x8a }, + { 0x02, 0x23 }, + { 0x03, 0x4c }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0xca }, + { 0x26, 0x94 }, + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x00 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + /** @brief GL124 special case + * for GL124 based scanners, this struct is "abused" + * in fact the fields are map like below to AFE registers + * (from Texas Instrument or alike ?) + */ + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_LIDE_120; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x80 }, + { 0x01, 0xa3 }, + { 0x02, 0x2b }, + { 0x03, 0x4c }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, // actual address 0x05 + { 0x25, 0xca }, // actual address 0x06 + { 0x26, 0x95 }, // actual address 0x07 + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x00 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::PLUSTEK_OPTICPRO_3600; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x70 }, + { 0x01, 0x80 }, + { 0x02, 0x00 }, + { 0x03, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x3f }, + { 0x29, 0x3d }, + { 0x2a, 0x3d }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::PLUSTEK_OPTICFILM_7200I; + fe.layout = analog_devices; + fe.regs = { + { 0x00, 0xf8 }, + { 0x01, 0x80 }, + { 0x02, 0x0a }, + { 0x03, 0x06 }, + { 0x04, 0x0f }, + { 0x05, 0x56 }, + { 0x06, 0x64 }, + { 0x07, 0x56 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::PLUSTEK_OPTICFILM_7300; + fe.layout = analog_devices; + fe.regs = { + { 0x00, 0xf8 }, + { 0x01, 0x80 }, + { 0x02, 0x10 }, + { 0x03, 0x06 }, + { 0x04, 0x06 }, + { 0x05, 0x09 }, + { 0x06, 0x0a }, + { 0x07, 0x0102 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::PLUSTEK_OPTICFILM_7500I; + fe.layout = analog_devices; + fe.regs = { + { 0x00, 0xf8 }, + { 0x01, 0x80 }, + { 0x02, 0x1d }, + { 0x03, 0x17 }, + { 0x04, 0x13 }, + { 0x05, 0x00 }, + { 0x06, 0x00 }, + { 0x07, 0x0111 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_4400F; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x23 }, + { 0x02, 0x24 }, + { 0x03, 0x2f }, + { 0x20, 0x6d }, + { 0x21, 0x67 }, + { 0x22, 0x5b }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0xd8 }, + { 0x29, 0xd1 }, + { 0x2a, 0xb9 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_8400F; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x23 }, + { 0x02, 0x24 }, + { 0x03, 0x0f }, + { 0x20, 0x60 }, + { 0x21, 0x5c }, + { 0x22, 0x6c }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x8a }, + { 0x29, 0x9f }, + { 0x2a, 0xc2 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_8600F; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x00 }, + { 0x01, 0x23 }, + { 0x02, 0x24 }, + { 0x03, 0x2f }, + { 0x20, 0x67 }, + { 0x21, 0x69 }, + { 0x22, 0x68 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0xdb }, + { 0x29, 0xda }, + { 0x2a, 0xd7 }, + }; + fe.reg2 = { 0x00, 0x00, 0x00 }; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::IMG101; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x78 }, + { 0x01, 0xf0 }, + { 0x02, 0x00 }, + { 0x03, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x00 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + fe = Genesys_Frontend(); + fe.id = AdcId::PLUSTEK_OPTICBOOK_3800; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x78 }, + { 0x01, 0xf0 }, + { 0x02, 0x00 }, + { 0x03, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x00 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + + /* reg0: control 74 data, 70 no data + * reg3: offset + * reg6: gain + * reg0 , reg3, reg6 */ + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_LIDE_80; + fe.layout = wolfson_layout; + fe.regs = { + { 0x00, 0x70 }, + { 0x01, 0x16 }, + { 0x02, 0x60 }, + { 0x03, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x00 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); +} + +} // namespace genesys diff --git a/backend/genesys/tables_gpo.cpp b/backend/genesys/tables_gpo.cpp new file mode 100644 index 0000000..2c9ad5e --- /dev/null +++ b/backend/genesys/tables_gpo.cpp @@ -0,0 +1,415 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "low.h" + +namespace genesys { + +StaticInit<std::vector<Genesys_Gpo>> s_gpo; + +void genesys_init_gpo_tables() +{ + s_gpo.init(); + + Genesys_Gpo gpo; + gpo.id = GpioId::UMAX; + gpo.regs = { + { 0x66, 0x11 }, + { 0x67, 0x00 }, + { 0x68, 0x51 }, + { 0x69, 0x20 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::ST12; + gpo.regs = { + { 0x66, 0x11 }, + { 0x67, 0x00 }, + { 0x68, 0x51 }, + { 0x69, 0x20 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::ST24; + gpo.regs = { + { 0x66, 0x00 }, + { 0x67, 0x00 }, + { 0x68, 0x51 }, + { 0x69, 0x20 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::MD_5345; // bits 11-12 are for bipolar V-ref input voltage + gpo.regs = { + { 0x66, 0x30 }, + { 0x67, 0x18 }, + { 0x68, 0xa0 }, + { 0x69, 0x18 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::HP2400; + gpo.regs = { + { 0x66, 0x30 }, + { 0x67, 0x00 }, + { 0x68, 0x31 }, + { 0x69, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::HP2300; + gpo.regs = { + { 0x66, 0x00 }, + { 0x67, 0x00 }, + { 0x68, 0x00 }, + { 0x69, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_35; + gpo.regs = { + { 0x6c, 0x02 }, + { 0x6d, 0x80 }, + { 0x6e, 0xef }, + { 0x6f, 0x80 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::XP200; + gpo.regs = { + { 0x66, 0x30 }, + { 0x67, 0x00 }, + { 0x68, 0xb0 }, + { 0x69, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::HP3670; + gpo.regs = { + { 0x66, 0x00 }, + { 0x67, 0x00 }, + { 0x68, 0x00 }, + { 0x69, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::XP300; + gpo.regs = { + { 0x6c, 0x09 }, + { 0x6d, 0xc6 }, + { 0x6e, 0xbb }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::DP665; + gpo.regs = { + { 0x6c, 0x18 }, + { 0x6d, 0x00 }, + { 0x6e, 0xbb }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::DP685; + gpo.regs = { + { 0x6c, 0x3f }, + { 0x6d, 0x46 }, + { 0x6e, 0xfb }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_200; + gpo.regs = { + { 0x6c, 0xfb }, // 0xfb when idle , 0xf9/0xe9 (1200) when scanning + { 0x6d, 0x20 }, + { 0x6e, 0xff }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_700F; + gpo.regs = { + { 0x6c, 0xdb }, + { 0x6d, 0xff }, + { 0x6e, 0xff }, + { 0x6f, 0x80 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::KVSS080; + gpo.regs = { + { 0x6c, 0xf5 }, + { 0x6d, 0x20 }, + { 0x6e, 0x7e }, + { 0x6f, 0xa1 }, + { 0xa6, 0x06 }, + { 0xa7, 0x0f }, + { 0xa8, 0x00 }, + { 0xa9, 0x08 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::G4050; + gpo.regs = { + { 0x6c, 0x20 }, + { 0x6d, 0x00 }, + { 0x6e, 0xfc }, + { 0x6f, 0x00 }, + { 0xa6, 0x08 }, + { 0xa7, 0x1e }, + { 0xa8, 0x3e }, + { 0xa9, 0x06 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::HP_N6310; + gpo.regs = { + { 0x6c, 0xa3 }, + { 0x6d, 0x00 }, + { 0x6e, 0x7f }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_110; + gpo.regs = { + { 0x6c, 0xfb }, + { 0x6d, 0x20 }, + { 0x6e, 0xff }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_120; + gpo.regs = { + { 0x6c, 0xfb }, + { 0x6d, 0x20 }, + { 0x6e, 0xff }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_210; + gpo.regs = { + { 0x6c, 0xfb }, + { 0x6d, 0x20 }, + { 0x6e, 0xff }, + { 0x6f, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::PLUSTEK_OPTICPRO_3600; + gpo.regs = { + { 0x6c, 0x02 }, + { 0x6d, 0x00 }, + { 0x6e, 0x1e }, + { 0x6f, 0x80 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::PLUSTEK_OPTICFILM_7200I; + gpo.regs = { + { 0x6c, 0x4c }, + { 0x6d, 0x80 }, + { 0x6e, 0x4c }, + { 0x6f, 0x80 }, + { 0xa6, 0x00 }, + { 0xa7, 0x07 }, + { 0xa8, 0x20 }, + { 0xa9, 0x01 }, + }; + s_gpo->push_back(gpo); + + gpo = Genesys_Gpo(); + gpo.id = GpioId::PLUSTEK_OPTICFILM_7300; + gpo.regs = { + { 0x6c, 0x4c }, + { 0x6d, 0x00 }, + { 0x6e, 0x4c }, + { 0x6f, 0x80 }, + { 0xa6, 0x00 }, + { 0xa7, 0x07 }, + { 0xa8, 0x20 }, + { 0xa9, 0x01 }, + }; + s_gpo->push_back(gpo); + + gpo = Genesys_Gpo(); + gpo.id = GpioId::PLUSTEK_OPTICFILM_7500I; + gpo.regs = { + { 0x6c, 0x4c }, + { 0x6d, 0x00 }, + { 0x6e, 0x4c }, + { 0x6f, 0x80 }, + { 0xa6, 0x00 }, + { 0xa7, 0x07 }, + { 0xa8, 0x20 }, + { 0xa9, 0x01 }, + }; + s_gpo->push_back(gpo); + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_4400F; + gpo.regs = { + { 0x6c, 0x01 }, + { 0x6d, 0x7f }, + { 0x6e, 0xff }, + { 0x6f, 0x00 }, + { 0xa6, 0x00 }, + { 0xa7, 0xff }, + { 0xa8, 0x07 }, + { 0xa9, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_8400F; + gpo.regs = { + { 0x6c, 0x9a }, + { 0x6d, 0xdf }, + { 0x6e, 0xfe }, + { 0x6f, 0x60 }, + { 0xa6, 0x00 }, + { 0xa7, 0x03 }, + { 0xa8, 0x00 }, + { 0xa9, 0x02 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_8600F; + gpo.regs = { + { 0x6c, 0x20 }, + { 0x6d, 0x7c }, + { 0x6e, 0xff }, + { 0x6f, 0x00 }, + { 0xa6, 0x00 }, + { 0xa7, 0xff }, + { 0xa8, 0x00 }, + { 0xa9, 0x00 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::IMG101; + gpo.regs = { + { 0x6c, 0x41 }, + { 0x6d, 0xa4 }, + { 0x6e, 0x13 }, + { 0x6f, 0xa7 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::PLUSTEK_OPTICBOOK_3800; + gpo.regs = { + { 0x6c, 0x41 }, + { 0x6d, 0xa4 }, + { 0x6e, 0x13 }, + { 0x6f, 0xa7 }, + }; + s_gpo->push_back(gpo); + + + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_80; + gpo.regs = { + { 0x6c, 0x28 }, + { 0x6d, 0x90 }, + { 0x6e, 0x75 }, + { 0x6f, 0x80 }, + }; + s_gpo->push_back(gpo); +} + +} // namespace genesys diff --git a/backend/genesys/tables_model.cpp b/backend/genesys/tables_model.cpp new file mode 100644 index 0000000..0b3a0af --- /dev/null +++ b/backend/genesys/tables_model.cpp @@ -0,0 +1,2958 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2003 Oliver Rauch + Copyright (C) 2003-2005 Henning Meier-Geinitz <henning@meier-geinitz.de> + Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de> + Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> + Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> + Copyright (C) 2007 Luke <iceyfor@gmail.com> + Copyright (C) 2010 Jack McGill <jmcgill85258@yahoo.com> + Copyright (C) 2010 Andrey Loginov <avloginov@gmail.com>, + xerox travelscan device entry + Copyright (C) 2010 Chris Berry <s0457957@sms.ed.ac.uk> and Michael Rickmann <mrickma@gwdg.de> + for Plustek Opticbook 3600 support + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "low.h" + +namespace genesys { + +StaticInit<std::vector<Genesys_USB_Device_Entry>> s_usb_devices; + +void genesys_init_usb_device_tables() +{ + s_usb_devices.init(); + + Genesys_Model model; + model.name = "umax-astra-4500"; + model.vendor = "UMAX"; + model.model = "Astra 4500"; + model.model_id = ModelId::UMAX_ASTRA_4500; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 75 }, + { 2400, 1200, 600, 300, 150, 75 } + } + }; + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 3.5; + model.y_offset = 7.5; + model.x_size = 218.0; + model.y_size = 299.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 1.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 8; + model.ld_shift_b = 16; + + model.line_mode_color_order = ColorOrder::BGR; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_UMAX; + model.adc_id = AdcId::WOLFSON_UMAX; + model.gpio_id = GpioId::UMAX; + model.motor_id = MotorId::UMAX; + model.flags = GENESYS_FLAG_UNTESTED; + model.buttons = GENESYS_HAS_NO_BUTTONS; + model.shading_lines = 20; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x0638, 0x0a10, model); + + + model = Genesys_Model(); + model.name = "canon-lide-50"; + model.vendor = "Canon"; + model.model = "LiDE 35/40/50"; + model.model_id = ModelId::CANON_LIDE_50; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 200, 150, 75 }, + { 2400, 1200, 600, 300, 200, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.42; + model.y_offset = 7.9; + model.x_size = 218.0; + model.y_size = 299.0; + + model.y_offset_calib_white = 6.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_35; + model.adc_id = AdcId::CANON_LIDE_35; + model.gpio_id = GpioId::CANON_LIDE_35; + model.motor_id = MotorId::CANON_LIDE_35; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_WHITE_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_FILE_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_COPY_SW; + model.shading_lines = 280; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x2213, model); + + + model = Genesys_Model(); + model.name = "panasonic-kv-ss080"; + model.vendor = "Panasonic"; + model.model = "KV-SS080"; + model.model_id = ModelId::PANASONIC_KV_SS080; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, /* 500, 400,*/ 300, 200, 150, 100, 75 }, + { 1200, 600, /* 500, 400, */ 300, 200, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 7.2; + model.y_offset = 14.7; + model.x_size = 217.7; + model.y_size = 300.0; + + model.y_offset_calib_white = 9.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 0.0; + model.y_size_ta = 0.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 8; + model.ld_shift_b = 16; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_KVSS080; + model.adc_id = AdcId::KVSS080; + model.gpio_id = GpioId::KVSS080; + model.motor_id = MotorId::KVSS080; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x04da, 0x100f, model); + + + model = Genesys_Model(); + model.name = "hewlett-packard-scanjet-4850c"; + model.vendor = "Hewlett Packard"; + model.model = "ScanJet 4850C"; + model.model_id = ModelId::HP_SCANJET_4850C; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, 400, 300, 200, 150, 100 }, + { 2400, 1200, 600, 400, 300, 200, 150, 100 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 7.9; + model.y_offset = 10.0; + model.x_size = 219.6; + model.y_size = 314.5; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_HP_4850C; + model.adc_id = AdcId::G4050; + model.gpio_id = GpioId::G4050; + model.motor_id = MotorId::G4050; + model.flags = GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + s_usb_devices->emplace_back(0x03f0, 0x1b05, model); + + + model = Genesys_Model(); + model.name = "hewlett-packard-scanjet-g4010"; + model.vendor = "Hewlett Packard"; + model.model = "ScanJet G4010"; + model.model_id = ModelId::HP_SCANJET_G4010; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, 400, 300, 200, 150, 100 }, + { 2400, 1200, 600, 400, 300, 200, 150, 100 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 8.0; + model.y_offset = 13.00; + model.x_size = 217.9; + model.y_size = 315.0; + + model.y_offset_calib_white = 3.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_G4050; + model.adc_id = AdcId::G4050; + model.gpio_id = GpioId::G4050; + model.motor_id = MotorId::G4050; + model.flags = GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x03f0, 0x4505, model); + + + model = Genesys_Model(); + model.name = "hewlett-packard-scanjet-g4050"; + model.vendor = "Hewlett Packard"; + model.model = "ScanJet G4050"; + model.model_id = ModelId::HP_SCANJET_G4050; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, 400, 300, 200, 150, 100 }, + { 2400, 1200, 600, 400, 300, 200, 150, 100 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 8.0; + model.y_offset = 10.00; + model.x_size = 217.9; + model.y_size = 315.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 8.0; + model.y_offset_ta = 13.00; + model.x_size_ta = 217.9; + model.y_size_ta = 250.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 40.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_G4050; + model.adc_id = AdcId::G4050; + model.gpio_id = GpioId::G4050; + model.motor_id = MotorId::G4050; + model.flags = GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x03f0, 0x4605, model); + + + model = Genesys_Model(); + model.name = "canon-canoscan-4400f"; + model.vendor = "Canon"; + model.model = "Canoscan 4400f"; + model.model_id = ModelId::CANON_4400F; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300 }, + { 1200, 600, 300 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 6.0; + model.y_offset = 12.00; + model.x_size = 215.9; + model.y_size = 297.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 8.0; + model.y_offset_ta = 13.00; + model.x_size_ta = 217.9; + model.y_size_ta = 250.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 40.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 96; + model.ld_shift_g = 48; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_CANON_4400F; + model.adc_id = AdcId::CANON_4400F; + model.gpio_id = GpioId::CANON_4400F; + model.motor_id = MotorId::CANON_4400F; + model.flags = GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_FULL_HWDPI_MODE | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SHADING_REPARK; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x04a9, 0x2228, model); + + + model = Genesys_Model(); + model.name = "canon-canoscan-8400f"; + model.vendor = "Canon"; + model.model = "Canoscan 8400f"; + model.model_id = ModelId::CANON_8400F; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 3200, 1600, 800, 400 }, + { 3200, 1600, 800, 400 }, + }, { + { ScanMethod::TRANSPARENCY }, + { 3200, 1600, 800, 400 }, + { 3200, 1600, 800, 400 }, + }, { + { ScanMethod::TRANSPARENCY_INFRARED }, + { 3200, 1600, 800, 400 }, + { 3200, 1600, 800, 400 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 3.5; + model.y_offset = 17.00; + model.x_size = 219.9; + model.y_size = 300.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 10.0; + + model.x_offset_ta = 75.0; + model.y_offset_ta = 45.00; + model.x_size_ta = 75.0; + model.y_size_ta = 230.0; + + model.y_offset_sensor_to_ta = 22.0; + model.y_offset_calib_white_ta = 25.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_CANON_8400F; + model.adc_id = AdcId::CANON_8400F; + model.gpio_id = GpioId::CANON_8400F; + model.motor_id = MotorId::CANON_8400F; + model.flags = GENESYS_FLAG_HAS_UTA | + GENESYS_FLAG_HAS_UTA_INFRARED | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_FULL_HWDPI_MODE | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SHADING_REPARK; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW; + model.shading_lines = 100; + model.shading_ta_lines = 50; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x04a9, 0x221e, model); + + + model = Genesys_Model(); + model.name = "canon-canoscan-8600f"; + model.vendor = "Canon"; + model.model = "Canoscan 8600f"; + model.model_id = ModelId::CANON_8600F; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300 }, + { 1200, 600, 300 }, + }, { + { ScanMethod::TRANSPARENCY, ScanMethod::TRANSPARENCY_INFRARED }, + { 4800, 2400, 1200, 600, 300 }, + { 4800, 2400, 1200, 600, 300 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 24.0; + model.y_offset = 10.0; + model.x_size = 216.0; + model.y_size = 297.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 8.0; + + model.x_offset_ta = 85.0; + model.y_offset_ta = 26.0; + model.x_size_ta = 70.0; + model.y_size_ta = 230.0; + + model.y_offset_sensor_to_ta = 11.5; + model.y_offset_calib_white_ta = 14.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 48; + model.ld_shift_b = 96; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_CANON_8600F; + model.adc_id = AdcId::CANON_8600F; + model.gpio_id = GpioId::CANON_8600F; + model.motor_id = MotorId::CANON_8600F; + model.flags = GENESYS_FLAG_HAS_UTA | + GENESYS_FLAG_HAS_UTA_INFRARED | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_FULL_HWDPI_MODE | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SHADING_REPARK; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW; + model.shading_lines = 50; + model.shading_ta_lines = 50; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x04a9, 0x2229, model); + + + model = Genesys_Model(); + model.name = "canon-lide-100"; + model.vendor = "Canon"; + model.model = "LiDE 100"; + model.model_id = ModelId::CANON_LIDE_100; + model.asic_type = AsicType::GL847; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, 300, 200, 150, 100, 75 }, + { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 1.1; + model.y_offset = 8.3; + model.x_size = 216.07; + model.y_size = 299.0; + + model.y_offset_calib_white = 1.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_100; + model.adc_id = AdcId::CANON_LIDE_200; + model.gpio_id = GpioId::CANON_LIDE_200; + model.motor_id = MotorId::CANON_LIDE_100; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_SIS_SENSOR | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW; + model.shading_lines = 50; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x1904, model); + + + model = Genesys_Model(); + model.name = "canon-lide-110"; + model.vendor = "Canon"; + model.model = "LiDE 110"; + model.model_id = ModelId::CANON_LIDE_110; + model.asic_type = AsicType::GL124; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 }, + { 4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 2.2; + model.y_offset = 9.0; + model.x_size = 216.70; + model.y_size = 300.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_110; + model.adc_id = AdcId::CANON_LIDE_110; + model.gpio_id = GpioId::CANON_LIDE_110; + model.motor_id = MotorId::CANON_LIDE_110; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW; + model.shading_lines = 25; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x1909, model); + + + model = Genesys_Model(); + model.name = "canon-lide-120"; + model.vendor = "Canon"; + model.model = "LiDE 120"; + model.model_id = ModelId::CANON_LIDE_120; + model.asic_type = AsicType::GL124; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, 300, 150, 100, 75 }, + { 4800, 2400, 1200, 600, 300, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 8.0; + model.x_size = 216.0; + model.y_size = 300.0; + + model.y_offset_calib_white = 1.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + model.line_mode_color_order = ColorOrder::RGB; + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_120; + model.adc_id = AdcId::CANON_LIDE_120; + model.gpio_id = GpioId::CANON_LIDE_120; + model.motor_id = MotorId::CANON_LIDE_120; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW; + model.shading_lines = 50; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x190e, model); + + + model = Genesys_Model(); + model.name = "canon-lide-210"; + model.vendor = "Canon"; + model.model = "LiDE 210"; + model.model_id = ModelId::CANON_LIDE_210; + model.asic_type = AsicType::GL124; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + // BUG: 4800 resolution crashes + { /*4800,*/ 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 }, + { /*4800,*/ 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 2.2; + model.y_offset = 8.7; + model.x_size = 216.70; + model.y_size = 297.5; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_210; + model.adc_id = AdcId::CANON_LIDE_110; + model.gpio_id = GpioId::CANON_LIDE_210; + model.motor_id = MotorId::CANON_LIDE_210; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW | + GENESYS_HAS_EXTRA_SW; + model.shading_lines = 60; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x190a, model); + + + model = Genesys_Model(); + model.name = "canon-lide-220"; + model.vendor = "Canon"; + model.model = "LiDE 220"; + model.model_id = ModelId::CANON_LIDE_220; + model.asic_type = AsicType::GL124; // or a compatible one + + model.resolutions = { + { + { ScanMethod::FLATBED }, + // BUG: 4800 resolution crashes + { /*4800,*/ 2400, 1200, 600, 300, 150, 100, 75 }, + { /*4800,*/ 2400, 1200, 600, 300, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 2.2; + model.y_offset = 8.7; + model.x_size = 216.70; + model.y_size = 297.5; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_220; + model.adc_id = AdcId::CANON_LIDE_110; + model.gpio_id = GpioId::CANON_LIDE_210; + model.motor_id = MotorId::CANON_LIDE_210; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW | + GENESYS_HAS_EXTRA_SW; + model.shading_lines = 60; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x190f, model); + + + model = Genesys_Model(); + model.name = "canon-5600f"; + model.vendor = "Canon"; + model.model = "5600F"; + model.model_id = ModelId::CANON_5600F; + model.asic_type = AsicType::GL847; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 75 }, + { 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 1.1; + model.y_offset = 8.3; + model.x_size = 216.07; + model.y_size = 299.0; + + model.y_offset_calib_white = 3.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_200; + model.adc_id = AdcId::CANON_LIDE_200; + model.gpio_id = GpioId::CANON_LIDE_200; + model.motor_id = MotorId::CANON_LIDE_200; + model.flags = GENESYS_FLAG_UNTESTED | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_SIS_SENSOR | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW; + model.shading_lines = 50; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x1906, model); + + + model = Genesys_Model(); + model.name = "canon-lide-700f"; + model.vendor = "Canon"; + model.model = "LiDE 700F"; + model.model_id = ModelId::CANON_LIDE_700F; + model.asic_type = AsicType::GL847; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 }, + { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 3.1; + model.y_offset = 8.1; + model.x_size = 216.07; + model.y_size = 297.0; + + model.y_offset_calib_white = 1.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_700F; + model.adc_id = AdcId::CANON_LIDE_700F; + model.gpio_id = GpioId::CANON_LIDE_700F; + model.motor_id = MotorId::CANON_LIDE_700; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_SIS_SENSOR | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW; + model.shading_lines = 70; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x1907, model); + + + model = Genesys_Model(); + model.name = "canon-lide-200"; + model.vendor = "Canon"; + model.model = "LiDE 200"; + model.model_id = ModelId::CANON_LIDE_200; + model.asic_type = AsicType::GL847; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 }, + { 4800, 2400, 1200, 600, 300, 200, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 1.1; + model.y_offset = 8.3; + model.x_size = 216.07; + model.y_size = 299.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_200; + model.adc_id = AdcId::CANON_LIDE_200; + model.gpio_id = GpioId::CANON_LIDE_200; + model.motor_id = MotorId::CANON_LIDE_200; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_SIS_SENSOR | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_FILE_SW; + model.shading_lines = 50; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x1905, model); + + + model = Genesys_Model(); + model.name = "canon-lide-60"; + model.vendor = "Canon"; + model.model = "LiDE 60"; + model.model_id = ModelId::CANON_LIDE_60; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 75 }, + { 2400, 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.42; + model.y_offset = 7.9; + model.x_size = 218.0; + model.y_size = 299.0; + + model.y_offset_calib_white = 6.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_35; + model.adc_id = AdcId::CANON_LIDE_35; + model.gpio_id = GpioId::CANON_LIDE_35; + model.motor_id = MotorId::CANON_LIDE_35; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_WHITE_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + + model.buttons = GENESYS_HAS_COPY_SW | + GENESYS_HAS_SCAN_SW | + GENESYS_HAS_FILE_SW | + GENESYS_HAS_EMAIL_SW; + model.shading_lines = 300; + model.shading_ta_lines = 0; + model.search_lines = 400; + // this is completely untested + s_usb_devices->emplace_back(0x04a9, 0x221c, model); + + + model = Genesys_Model(); + model.name = "canon-lide-80"; + model.vendor = "Canon"; + model.model = "LiDE 80"; + model.model_id = ModelId::CANON_LIDE_80; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 100, 75 }, + { 2400, 1200, 600, 300, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + model.x_offset = 0.42; + model.y_offset = 7.90; + model.x_size = 216.07; + model.y_size = 299.0; + + model.y_offset_calib_white = 4.5; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_80; + model.adc_id = AdcId::CANON_LIDE_80; + model.gpio_id = GpioId::CANON_LIDE_80; + model.motor_id = MotorId::CANON_LIDE_80; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_WHITE_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_FILE_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_COPY_SW; + model.shading_lines = 160; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x2214, model); + + + model = Genesys_Model(); + model.name = "hewlett-packard-scanjet-2300c"; + model.vendor = "Hewlett Packard"; + model.model = "ScanJet 2300c"; + model.model_id = ModelId::HP_SCANJET_2300C; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 2.0; + model.y_offset = 7.5; + model.x_size = 215.9; + model.y_size = 295.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 1.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 16; + model.ld_shift_g = 8; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_HP2300; + model.adc_id = AdcId::WOLFSON_HP2300; + model.gpio_id = GpioId::HP2300; + model.motor_id = MotorId::HP2300; + model.flags = GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_SEARCH_START | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW; + model.shading_lines = 40; + model.shading_ta_lines = 0; + model.search_lines = 132; + + s_usb_devices->emplace_back(0x03f0, 0x0901, model); + + + model = Genesys_Model(); + model.name = "hewlett-packard-scanjet-2400c"; + model.vendor = "Hewlett Packard"; + model.model = "ScanJet 2400c"; + model.model_id = ModelId::HP_SCANJET_2400C; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 100, 50 }, + { 1200, 600, 300, 150, 100, 50 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 6.5; + model.y_offset = 2.5; + model.x_size = 220.0; + model.y_size = 297.2; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 1.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_HP2400; + model.adc_id = AdcId::WOLFSON_HP2400; + model.gpio_id = GpioId::HP2400; + model.motor_id = MotorId::HP2400; + model.flags = GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW; + model.shading_lines = 20; + model.shading_ta_lines = 0; + model.search_lines = 132; + + s_usb_devices->emplace_back(0x03f0, 0x0a01, model); + + + model = Genesys_Model(); + model.name = "visioneer-strobe-xp200"; + model.vendor = "Visioneer"; + model.model = "Strobe XP200"; + model.model_id = ModelId::VISIONEER_STROBE_XP200; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 200, 100, 75 }, + { 600, 300, 200, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.5; + model.y_offset = 16.0; + model.x_size = 215.9; + model.y_size = 297.2; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CIS_XP200; + model.adc_id = AdcId::AD_XP200; + model.gpio_id = GpioId::XP200; + model.motor_id = MotorId::XP200; + model.flags = GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 120; + model.shading_ta_lines = 0; + model.search_lines = 132; + + s_usb_devices->emplace_back(0x04a7, 0x0426, model); + + + model = Genesys_Model(); + model.name = "hewlett-packard-scanjet-3670"; + model.vendor = "Hewlett Packard"; + model.model = "ScanJet 3670"; + model.model_id = ModelId::HP_SCANJET_3670; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 100, 75, 50 }, + { 1200, 600, 300, 150, 100, 75, 50 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 8.5; + model.y_offset = 11.0; + model.x_size = 215.9; + model.y_size = 300.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 1.0; + + model.x_offset_ta = 104.0; + model.y_offset_ta = 55.6; + model.x_size_ta = 25.6; + model.y_size_ta = 78.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 76.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_HP3670; + model.adc_id = AdcId::WOLFSON_HP3670; + model.gpio_id = GpioId::HP3670; + model.motor_id = MotorId::HP3670; + model.flags = GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_XPA | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW; + model.shading_lines = 20; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x03f0, 0x1405, model); + + + model = Genesys_Model(); + model.name = "plustek-opticpro-st12"; + model.vendor = "Plustek"; + model.model = "OpticPro ST12"; + model.model_id = ModelId::PLUSTEK_OPTICPRO_ST12; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 3.5; + model.y_offset = 7.5; + model.x_size = 218.0; + model.y_size = 299.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 1.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 8; + model.ld_shift_b = 16; + + model.line_mode_color_order = ColorOrder::BGR; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_ST12; + model.adc_id = AdcId::WOLFSON_ST12; + model.gpio_id = GpioId::ST12; + model.motor_id = MotorId::UMAX; + model.flags = GENESYS_FLAG_UNTESTED | GENESYS_FLAG_14BIT_GAMMA; + model.buttons = GENESYS_HAS_NO_BUTTONS; + model.shading_lines = 20; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x07b3, 0x0600, model); + + model = Genesys_Model(); + model.name = "plustek-opticpro-st24"; + model.vendor = "Plustek"; + model.model = "OpticPro ST24"; + model.model_id = ModelId::PLUSTEK_OPTICPRO_ST24; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 75 }, + { 2400, 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 3.5; + model.y_offset = 7.5; + model.x_size = 218.0; + model.y_size = 299.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 1.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 8; + model.ld_shift_b = 16; + + model.line_mode_color_order = ColorOrder::BGR; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_ST24; + model.adc_id = AdcId::WOLFSON_ST24; + model.gpio_id = GpioId::ST24; + model.motor_id = MotorId::ST24; + model.flags = GENESYS_FLAG_UNTESTED | + GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SEARCH_START | + GENESYS_FLAG_OFFSET_CALIBRATION; + model.buttons = GENESYS_HAS_NO_BUTTONS; + model.shading_lines = 20; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x07b3, 0x0601, model); + + model = Genesys_Model(); + model.name = "medion-md5345-model"; + model.vendor = "Medion"; + model.model = "MD5345/MD6228/MD6471"; + model.model_id = ModelId::MEDION_MD5345; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 400, 300, 200, 150, 100, 75, 50 }, + { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.30; + model.y_offset = 0.80; + model.x_size = 220.0; + model.y_size = 296.4; + + model.y_offset_calib_white = 0.00; + model.x_offset_calib_black = 0.00; + + model.x_offset_ta = 0.00; + model.y_offset_ta = 0.00; + model.x_size_ta = 0.00; + model.y_size_ta = 0.00; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.00; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 48; + model.ld_shift_g = 24; + model.ld_shift_b = 0; + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_5345; + model.adc_id = AdcId::WOLFSON_5345; + model.gpio_id = GpioId::MD_5345; + model.motor_id = MotorId::MD_5345; + model.flags = GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_SEARCH_START | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_SHADING_NO_MOVE | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_POWER_SW | + GENESYS_HAS_OCR_SW | + GENESYS_HAS_SCAN_SW; + model.shading_lines = 40; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x0461, 0x0377, model); + + model = Genesys_Model(); + model.name = "visioneer-strobe-xp300"; + model.vendor = "Visioneer"; + model.model = "Strobe XP300"; + model.model_id = ModelId::VISIONEER_STROBE_XP300; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 1.0; + model.x_size = 435.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 26.5; + // this is larger than needed -- accounts for second sensor head, which is a calibration item + model.eject_feed = 0.0; + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_XP300; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::XP300; + model.motor_id = MotorId::XP300; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a7, 0x0474, model); + + model = Genesys_Model(); + model.name = "syscan-docketport-665"; + model.vendor = "Syscan/Ambir"; + model.model = "DocketPORT 665"; + model.model_id = ModelId::SYSCAN_DOCKETPORT_665; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 108.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 17.5; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_DP665; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::DP665; + model.motor_id = MotorId::DP665; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x0a82, 0x4803, model); + + model = Genesys_Model(); + model.name = "visioneer-roadwarrior"; + model.vendor = "Visioneer"; + model.model = "Readwarrior"; + model.model_id = ModelId::VISIONEER_ROADWARRIOR; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 220.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 16.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_ROADWARRIOR; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::DP665; + model.motor_id = MotorId::ROADWARRIOR; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a7, 0x0494, model); + + model = Genesys_Model(); + model.name = "syscan-docketport-465"; + model.vendor = "Syscan"; + model.model = "DocketPORT 465"; + model.model_id = ModelId::SYSCAN_DOCKETPORT_465; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 220.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 16.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_ROADWARRIOR; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::DP665; + model.motor_id = MotorId::ROADWARRIOR; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_NO_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_UNTESTED; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW; + model.shading_lines = 300; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x0a82, 0x4802, model); + + + model = Genesys_Model(); + model.name = "visioneer-xp100-revision3"; + model.vendor = "Visioneer"; + model.model = "XP100 Revision 3"; + model.model_id = ModelId::VISIONEER_STROBE_XP100_REVISION3; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 220.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 16.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_ROADWARRIOR; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::DP665; + model.motor_id = MotorId::ROADWARRIOR; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a7, 0x049b, model); + + model = Genesys_Model(); + model.name = "pentax-dsmobile-600"; + model.vendor = "Pentax"; + model.model = "DSmobile 600"; + model.model_id = ModelId::PENTAX_DSMOBILE_600; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 220.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 16.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_DSMOBILE600; + model.adc_id = AdcId::WOLFSON_DSM600; + model.gpio_id = GpioId::DP665; + model.motor_id = MotorId::DSMOBILE_600; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x0a17, 0x3210, model); + // clone, only usb id is different + s_usb_devices->emplace_back(0x04f9, 0x2038, model); + + model = Genesys_Model(); + model.name = "syscan-docketport-467"; + model.vendor = "Syscan"; + model.model = "DocketPORT 467"; + model.model_id = ModelId::SYSCAN_DOCKETPORT_467; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 220.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 16.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_DSMOBILE600; + model.adc_id = AdcId::WOLFSON_DSM600; + model.gpio_id = GpioId::DP665; + model.motor_id = MotorId::DSMOBILE_600; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x1dcc, 0x4812, model); + + model = Genesys_Model(); + model.name = "syscan-docketport-685"; + model.vendor = "Syscan/Ambir"; + model.model = "DocketPORT 685"; + model.model_id = ModelId::SYSCAN_DOCKETPORT_685; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 1.0; + model.x_size = 212.0; + model.y_size = 500; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 26.5; + // this is larger than needed -- accounts for second sensor head, which is a calibration item + model.eject_feed = 0.0; + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_DP685; + model.adc_id = AdcId::WOLFSON_DSM600; + model.gpio_id = GpioId::DP685; + model.motor_id = MotorId::XP300; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + + s_usb_devices->emplace_back(0x0a82, 0x480c, model); + + + model = Genesys_Model(); + model.name = "syscan-docketport-485"; + model.vendor = "Syscan/Ambir"; + model.model = "DocketPORT 485"; + model.model_id = ModelId::SYSCAN_DOCKETPORT_485; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 1.0; + model.x_size = 435.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 26.5; + // this is larger than needed -- accounts for second sensor head, which is a calibration item + model.eject_feed = 0.0; + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_XP300; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::XP300; + model.motor_id = MotorId::XP300; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x0a82, 0x4800, model); + + + model = Genesys_Model(); + model.name = "dct-docketport-487"; + model.vendor = "DCT"; + model.model = "DocketPORT 487"; + model.model_id = ModelId::DCT_DOCKETPORT_487; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.0; + model.y_offset = 1.0; + model.x_size = 435.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 26.5; + // this is larger than needed -- accounts for second sensor head, which is a calibration item + model.eject_feed = 0.0; + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_XP300; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::XP300; + model.motor_id = MotorId::XP300; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_UNTESTED; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x1dcc, 0x4810, model); + + + model = Genesys_Model(); + model.name = "visioneer-7100-model"; + model.vendor = "Visioneer"; + model.model = "OneTouch 7100"; + model.model_id = ModelId::VISIONEER_7100; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 400, 300, 200, 150, 100, 75, 50 }, + { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 4.00; + model.y_offset = 0.80; + model.x_size = 215.9; + model.y_size = 296.4; + + model.y_offset_calib_white = 0.00; + model.x_offset_calib_black = 0.00; + + model.x_offset_ta = 0.00; + model.y_offset_ta = 0.00; + model.x_size_ta = 0.00; + model.y_size_ta = 0.00; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.00; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 48; + model.ld_shift_g = 24; + model.ld_shift_b = 0; + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_5345; + model.adc_id = AdcId::WOLFSON_5345; + model.gpio_id = GpioId::MD_5345; + model.motor_id = MotorId::MD_5345; + model.flags = GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_SEARCH_START | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_POWER_SW | + GENESYS_HAS_OCR_SW | + GENESYS_HAS_SCAN_SW; + model.shading_lines = 40; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x04a7, 0x0229, model); + + + model = Genesys_Model(); + model.name = "xerox-2400-model"; + model.vendor = "Xerox"; + model.model = "OneTouch 2400"; + model.model_id = ModelId::XEROX_2400; + model.asic_type = AsicType::GL646; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 400, 300, 200, 150, 100, 75, 50 }, + { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 4.00; + model.y_offset = 0.80; + model.x_size = 215.9; + model.y_size = 296.4; + + model.y_offset_calib_white = 0.00; + model.x_offset_calib_black = 0.00; + + model.x_offset_ta = 0.00; + model.y_offset_ta = 0.00; + model.x_size_ta = 0.00; + model.y_size_ta = 0.00; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.00; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 48; + model.ld_shift_g = 24; + model.ld_shift_b = 0; + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_5345; + model.adc_id = AdcId::WOLFSON_5345; + model.gpio_id = GpioId::MD_5345; + model.motor_id = MotorId::MD_5345; + model.flags = GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_SEARCH_START | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_COPY_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_POWER_SW | + GENESYS_HAS_OCR_SW | + GENESYS_HAS_SCAN_SW; + model.shading_lines = 40; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x0461, 0x038b, model); + + + model = Genesys_Model(); + model.name = "xerox-travelscanner"; + model.vendor = "Xerox"; + model.model = "Travelscanner 100"; + model.model_id = ModelId::XEROX_TRAVELSCANNER_100; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 600, 300, 150, 75 }, + { 1200, 600, 300, 150, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 4.0; + model.y_offset = 0.0; + model.x_size = 220.0; + model.y_size = 511; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 16.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = true; + model.sensor_id = SensorId::CCD_ROADWARRIOR; + model.adc_id = AdcId::WOLFSON_XP300; + model.gpio_id = GpioId::DP665; + model.motor_id = MotorId::ROADWARRIOR; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION; + model.buttons = GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a7, 0x04ac, model); + + + model = Genesys_Model(); + model.name = "plustek-opticbook-3600"; + model.vendor = "PLUSTEK"; + model.model = "OpticBook 3600"; + model.model_id = ModelId::PLUSTEK_OPTICPRO_3600; + model.asic_type = AsicType::GL841; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { /*1200,*/ 600, 400, 300, 200, 150, 100, 75 }, + { /*2400,*/ 1200, 600, 400, 300, 200, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 0.42; + model.y_offset = 6.75; + model.x_size = 216.0; + model.y_size = 297.0; + + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 0.0; + model.y_size_ta = 0.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_PLUSTEK_OPTICPRO_3600; + model.adc_id = AdcId::PLUSTEK_OPTICPRO_3600; + model.gpio_id = GpioId::PLUSTEK_OPTICPRO_3600; + model.motor_id = MotorId::PLUSTEK_OPTICPRO_3600; + model.flags = GENESYS_FLAG_UNTESTED | // not fully working yet + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION; + model.buttons = GENESYS_HAS_NO_BUTTONS; + model.shading_lines = 7; + model.shading_ta_lines = 0; + model.search_lines = 200; + + s_usb_devices->emplace_back(0x07b3, 0x0900, model); + + + model = Genesys_Model(); + model.name = "plustek-opticfilm-7200i"; + model.vendor = "PLUSTEK"; + model.model = "OpticFilm 7200i"; + model.model_id = ModelId::PLUSTEK_OPTICFILM_7200I; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::TRANSPARENCY, ScanMethod::TRANSPARENCY_INFRARED }, + { 7200, 3600, 1800, 900 }, + { 7200, 3600, 1800, 900 }, + } + }; + + model.bpp_gray_values = { 16 }; + model.bpp_color_values = { 16 }; + model.default_method = ScanMethod::TRANSPARENCY; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 36.0; + model.y_size = 44.0; + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 6.5; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 29.0; + model.x_size_ta = 36.0; + model.y_size_ta = 24.0; + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_black_ta = 6.5; + model.y_offset_calib_white_ta = 0.0; + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 12; + model.ld_shift_b = 24; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + + model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7200I; + model.adc_id = AdcId::PLUSTEK_OPTICFILM_7200I; + model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7200I; + model.motor_id = MotorId::PLUSTEK_OPTICFILM_7200I; + + model.flags = GENESYS_FLAG_HAS_UTA | + GENESYS_FLAG_HAS_UTA_INFRARED | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_HAS_NO_BUTTONS | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CALIBRATION_HOST_SIDE | + GENESYS_FLAG_16BIT_DATA_INVERTED; + + model.shading_lines = 7; + model.shading_ta_lines = 50; + model.search_lines = 200; + s_usb_devices->emplace_back(0x07b3, 0x0c04, model); + + + model = Genesys_Model(); + model.name = "plustek-opticfilm-7300"; + model.vendor = "PLUSTEK"; + model.model = "OpticFilm 7300"; + model.model_id = ModelId::PLUSTEK_OPTICFILM_7300; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::TRANSPARENCY }, + { 7200, 3600, 1800, 900 }, + { 7200, 3600, 1800, 900 }, + } + }; + + model.bpp_gray_values = { 16 }; + model.bpp_color_values = { 16 }; + model.default_method = ScanMethod::TRANSPARENCY; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 36.0; + model.y_size = 44.0; + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 6.5; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 29.0; + model.x_size_ta = 36.0; + model.y_size_ta = 24.0; + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_black_ta = 6.5; + model.y_offset_calib_white_ta = 0.0; + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 12; + model.ld_shift_b = 24; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + + model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7300; + model.adc_id = AdcId::PLUSTEK_OPTICFILM_7300; + model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7300; + model.motor_id = MotorId::PLUSTEK_OPTICFILM_7300; + + model.flags = GENESYS_FLAG_HAS_UTA | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_HAS_NO_BUTTONS | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CALIBRATION_HOST_SIDE; + + model.shading_lines = 7; + model.shading_ta_lines = 50; + model.search_lines = 200; + s_usb_devices->emplace_back(0x07b3, 0x0c12, model); + + + model = Genesys_Model(); + model.name = "plustek-opticfilm-7500i"; + model.vendor = "PLUSTEK"; + model.model = "OpticFilm 7500i"; + model.model_id = ModelId::PLUSTEK_OPTICFILM_7500I; + model.asic_type = AsicType::GL843; + + model.resolutions = { + { + { ScanMethod::TRANSPARENCY, ScanMethod::TRANSPARENCY_INFRARED }, + { 7200, 3600, 1800, 900 }, + { 7200, 3600, 1800, 900 }, + } + }; + + model.bpp_gray_values = { 16 }; + model.bpp_color_values = { 16 }; + model.default_method = ScanMethod::TRANSPARENCY; + + model.x_offset = 0.0; + model.y_offset = 0.0; + model.x_size = 36.0; + model.y_size = 44.0; + model.y_offset_calib_white = 0.0; + model.x_offset_calib_black = 6.5; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 29.0; + model.x_size_ta = 36.0; + model.y_size_ta = 24.0; + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_black_ta = 6.5; + model.y_offset_calib_white_ta = 0.0; + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 12; + model.ld_shift_b = 24; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + + model.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7500I; + model.adc_id = AdcId::PLUSTEK_OPTICFILM_7500I; + model.gpio_id = GpioId::PLUSTEK_OPTICFILM_7500I; + model.motor_id = MotorId::PLUSTEK_OPTICFILM_7500I; + + model.flags = GENESYS_FLAG_HAS_UTA | + GENESYS_FLAG_HAS_UTA_INFRARED | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_HAS_NO_BUTTONS | + GENESYS_FLAG_SHADING_REPARK | + GENESYS_FLAG_CALIBRATION_HOST_SIDE; + + model.shading_lines = 7; + model.shading_ta_lines = 50; + model.search_lines = 200; + s_usb_devices->emplace_back(0x07b3, 0x0c13, model); + + + model = Genesys_Model(); + model.name = "hewlett-packard-scanjet-N6310"; + model.vendor = "Hewlett Packard"; + model.model = "ScanJet N6310"; + model.model_id = ModelId::HP_SCANJET_N6310; + model.asic_type = AsicType::GL847; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, 400, 300, 200, 150, 100, 75 }, + { 2400, 1200, 600, 400, 300, 200, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 6; + model.y_offset = 2; + model.x_size = 216; + model.y_size = 511; + + model.y_offset_calib_white = 3.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 100.0; + model.y_size_ta = 100.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0; + + model.post_scan = 0; + model.eject_feed = 0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_HP_N6310; + model.adc_id = AdcId::CANON_LIDE_200; // Not defined yet for N6310 + model.gpio_id = GpioId::HP_N6310; + model.motor_id = MotorId::CANON_LIDE_200; // Not defined yet for N6310 + model.flags = GENESYS_FLAG_UNTESTED | + GENESYS_FLAG_14BIT_GAMMA | + GENESYS_FLAG_DARK_CALIBRATION | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_NO_CALIBRATION; + + model.buttons = GENESYS_HAS_NO_BUTTONS; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x03f0, 0x4705, model); + + + model = Genesys_Model(); + model.name = "plustek-opticbook-3800"; + model.vendor = "PLUSTEK"; + model.model = "OpticBook 3800"; + model.model_id = ModelId::PLUSTEK_OPTICBOOK_3800; + model.asic_type = AsicType::GL845; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 100, 75 }, + { 1200, 600, 300, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 7.2; + model.y_offset = 14.7; + model.x_size = 217.7; + model.y_size = 300.0; + + model.y_offset_calib_white = 9.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 0.0; + model.y_size_ta = 0.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_PLUSTEK_OPTICBOOK_3800; + model.adc_id = AdcId::PLUSTEK_OPTICBOOK_3800; + model.gpio_id = GpioId::PLUSTEK_OPTICBOOK_3800; + model.motor_id = MotorId::PLUSTEK_OPTICBOOK_3800; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_NO_BUTTONS; // TODO there are 4 buttons to support + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x07b3, 0x1300, model); + + + model = Genesys_Model(); + model.name = "canon-image-formula-101"; + model.vendor = "Canon"; + model.model = "Image Formula 101"; + model.model_id = ModelId::CANON_IMAGE_FORMULA_101; + model.asic_type = AsicType::GL846; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 1200, 600, 300, 150, 100, 75 }, + { 1200, 600, 300, 150, 100, 75 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + + model.x_offset = 7.2; + model.y_offset = 14.7; + model.x_size = 217.7; + model.y_size = 300.0; + + model.y_offset_calib_white = 9.0; + model.x_offset_calib_black = 0.0; + + model.x_offset_ta = 0.0; + model.y_offset_ta = 0.0; + model.x_size_ta = 0.0; + model.y_size_ta = 0.0; + + model.y_offset_sensor_to_ta = 0.0; + model.y_offset_calib_white_ta = 0.0; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 24; + model.ld_shift_b = 48; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = false; + model.is_sheetfed = false; + model.sensor_id = SensorId::CCD_IMG101; + model.adc_id = AdcId::IMG101; + model.gpio_id = GpioId::IMG101; + model.motor_id = MotorId::IMG101; + model.flags = GENESYS_FLAG_SKIP_WARMUP | + GENESYS_FLAG_OFFSET_CALIBRATION | + GENESYS_FLAG_CUSTOM_GAMMA | + GENESYS_FLAG_UNTESTED; + model.buttons = GENESYS_HAS_NO_BUTTONS ; + model.shading_lines = 100; + model.shading_ta_lines = 0; + model.search_lines = 100; + + s_usb_devices->emplace_back(0x1083, 0x162e, model); + } + +} // namespace genesys diff --git a/backend/genesys/tables_motor.cpp b/backend/genesys/tables_motor.cpp new file mode 100644 index 0000000..2484d2d --- /dev/null +++ b/backend/genesys/tables_motor.cpp @@ -0,0 +1,325 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "low.h" + +namespace genesys { + +StaticInit<std::vector<Genesys_Motor>> s_motors; + +void genesys_init_motor_tables() +{ + s_motors.init(); + + Genesys_Motor motor; + motor.id = MotorId::UMAX; + motor.base_ydpi = 1200; + motor.optical_ydpi = 2400; + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 3000, 128)); + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 3000, 128)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::MD_5345; // MD5345/6228/6471 + motor.base_ydpi = 1200; + motor.optical_ydpi = 2400; + motor.slopes.push_back(MotorSlope::create_from_steps(2000, 1375, 128)); + motor.slopes.push_back(MotorSlope::create_from_steps(2000, 1375, 128)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::ST24; + motor.base_ydpi = 2400; + motor.optical_ydpi = 2400; + motor.slopes.push_back(MotorSlope::create_from_steps(2289, 2100, 128)); + motor.slopes.push_back(MotorSlope::create_from_steps(2289, 2100, 128)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::HP3670; + motor.base_ydpi = 1200; + motor.optical_ydpi = 1200; + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 3000, 128)); + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 3000, 128)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::HP2400; + motor.base_ydpi = 1200; + motor.optical_ydpi = 1200; + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 3000, 128)); + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 3000, 128)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::HP2300; + motor.base_ydpi = 600; + motor.optical_ydpi = 1200; + motor.slopes.push_back(MotorSlope::create_from_steps(3200, 1200, 128)); + motor.slopes.push_back(MotorSlope::create_from_steps(3200, 1200, 128)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_35; + motor.base_ydpi = 1200; + motor.optical_ydpi = 2400; + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 1300, 60)); + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 1400, 60)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::XP200; + motor.base_ydpi = 600; + motor.optical_ydpi = 600; + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 1300, 60)); + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 1300, 60)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::XP300; + motor.base_ydpi = 300; + motor.optical_ydpi = 600; + // works best with GPIO10, GPIO14 off + motor.slopes.push_back(MotorSlope::create_from_steps(3700, 3700, 2)); + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 11000, 2)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::DP665; + motor.base_ydpi = 750; + motor.optical_ydpi = 1500; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 2500, 10)); + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 11000, 2)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::ROADWARRIOR; + motor.base_ydpi = 750; + motor.optical_ydpi = 1500; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 2600, 10)); + motor.slopes.push_back(MotorSlope::create_from_steps(11000, 11000, 2)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::DSMOBILE_600; + motor.base_ydpi = 750; + motor.optical_ydpi = 1500; + motor.slopes.push_back(MotorSlope::create_from_steps(6666, 3700, 8)); + motor.slopes.push_back(MotorSlope::create_from_steps(6666, 3700, 8)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_100; + motor.base_ydpi = 1200; + motor.optical_ydpi = 6400; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1000, 127)); + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1500, 127)); + motor.slopes.push_back(MotorSlope::create_from_steps(3 * 2712, 3 * 2712, 16)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_200; + motor.base_ydpi = 1200; + motor.optical_ydpi = 6400; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1000, 127)); + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1500, 127)); + motor.slopes.push_back(MotorSlope::create_from_steps(3 * 2712, 3 * 2712, 16)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_700; + motor.base_ydpi = 1200; + motor.optical_ydpi = 6400; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1000, 127)); + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1500, 127)); + motor.slopes.push_back(MotorSlope::create_from_steps(3 * 2712, 3 * 2712, 16)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::KVSS080; + motor.base_ydpi = 1200; + motor.optical_ydpi = 1200; + motor.slopes.push_back(MotorSlope::create_from_steps(22222, 500, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(22222, 500, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(22222, 500, 246)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::G4050; + motor.base_ydpi = 2400; + motor.optical_ydpi = 9600; + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_4400F; + motor.base_ydpi = 2400; + motor.optical_ydpi = 9600; + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_8400F; + motor.base_ydpi = 1600; + motor.optical_ydpi = 6400; + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_8600F; + motor.base_ydpi = 2400; + motor.optical_ydpi = 9600; + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + motor.slopes.push_back(MotorSlope::create_from_steps(3961, 240, 246)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_110; + motor.base_ydpi = 4800; + motor.optical_ydpi = 9600; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1000, 256)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_120; + motor.base_ydpi = 4800; + motor.optical_ydpi = 9600; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1000, 256)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_210; + motor.base_ydpi = 4800; + motor.optical_ydpi = 9600; + motor.slopes.push_back(MotorSlope::create_from_steps(3000, 1000, 256)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::PLUSTEK_OPTICPRO_3600; + motor.base_ydpi = 1200; + motor.optical_ydpi = 2400; + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 1300, 60)); + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 3250, 60)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::PLUSTEK_OPTICFILM_7200I; + motor.base_ydpi = 3600; + motor.optical_ydpi = 3600; + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::PLUSTEK_OPTICFILM_7300; + motor.base_ydpi = 3600; + motor.optical_ydpi = 3600; + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::PLUSTEK_OPTICFILM_7500I; + motor.base_ydpi = 3600; + motor.optical_ydpi = 3600; + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::IMG101; + motor.base_ydpi = 600; + motor.optical_ydpi = 1200; + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 1300, 60)); + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 3250, 60)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::PLUSTEK_OPTICBOOK_3800; + motor.base_ydpi = 600; + motor.optical_ydpi = 1200; + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 1300, 60)); + motor.slopes.push_back(MotorSlope::create_from_steps(3500, 3250, 60)); + s_motors->push_back(std::move(motor)); + + + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_80; + motor.base_ydpi = 2400; + motor.optical_ydpi = 4800; // 9600 + motor.slopes.push_back(MotorSlope::create_from_steps(9560, 1912, 31)); + s_motors->push_back(std::move(motor)); +} + +} // namespace genesys diff --git a/backend/genesys/tables_motor_profile.cpp b/backend/genesys/tables_motor_profile.cpp new file mode 100644 index 0000000..18f7271 --- /dev/null +++ b/backend/genesys/tables_motor_profile.cpp @@ -0,0 +1,380 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "low.h" + +namespace genesys { + +StaticInit<std::vector<Motor_Profile>> gl843_motor_profiles; + +void genesys_init_motor_profile_tables_gl843() +{ + gl843_motor_profiles.init(); + + auto profile = Motor_Profile(); + profile.motor_id = MotorId::KVSS080; + profile.exposure = 8000; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(44444, 500, 489); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 8016; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(7842, 320, 602); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 15624; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(9422, 254, 1004); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 42752; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(42752, 1706, 610); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::G4050; + profile.exposure = 56064; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(28032, 2238, 604); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_4400F; + profile.exposure = 11640; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(49152, 484, 1014); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_8400F; + profile.exposure = 50000; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(8743, 300, 794); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_8600F; + profile.exposure = 0x59d8; + profile.step_type = StepType::QUARTER; + // FIXME: if the exposure is lower then we'll select another motor + profile.slope = MotorSlope::create_from_steps(54612, 1500, 219); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7200I; + profile.exposure = 0; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(39682, 1191, 15); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7300; + profile.exposure = 0x2f44; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(31250, 1512, 6); + gl843_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICFILM_7500I; + profile.exposure = 0; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(31250, 1375, 7); + gl843_motor_profiles->push_back(profile); +} + +StaticInit<std::vector<Motor_Profile>> gl846_motor_profiles; + +void genesys_init_motor_profile_tables_gl846() +{ + gl846_motor_profiles.init(); + + auto profile = Motor_Profile(); + profile.motor_id = MotorId::IMG101; + profile.exposure = 11000; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(22000, 1000, 1017); + + gl846_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::PLUSTEK_OPTICBOOK_3800; + profile.exposure = 11000; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(22000, 1000, 1017); + gl846_motor_profiles->push_back(profile); +} + +/** + * database of motor profiles + */ + +StaticInit<std::vector<Motor_Profile>> gl847_motor_profiles; + +void genesys_init_motor_profile_tables_gl847() +{ + gl847_motor_profiles.init(); + + auto profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 2848; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 1424; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 1432; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 2712; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(46876, 534, 279); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_100; + profile.exposure = 5280; + profile.step_type = StepType::EIGHTH; + profile.slope = MotorSlope::create_from_steps(31680, 534, 247); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 2848; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 1424; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 1432; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 2712; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(46876, 534, 279); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 5280; + profile.step_type = StepType::EIGHTH; + profile.slope = MotorSlope::create_from_steps(31680, 534, 247); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_200; + profile.exposure = 10416; + profile.step_type = StepType::EIGHTH; + profile.slope = MotorSlope::create_from_steps(31680, 534, 247); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 2848; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 1424; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 1504; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 534, 255); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 2696; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(46876, 2022, 127); + gl847_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_700; + profile.exposure = 10576; + profile.step_type = StepType::EIGHTH; + profile.slope = MotorSlope::create_from_steps(46876, 15864, 2); + gl847_motor_profiles->push_back(profile); +} + +StaticInit<std::vector<Motor_Profile>> gl124_motor_profiles; + +void genesys_init_motor_profile_tables_gl124() +{ + gl124_motor_profiles.init(); + + // NEXT LPERIOD=PREVIOUS*2-192 + Motor_Profile profile; + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 2768; + profile.step_type = StepType::FULL; + profile.slope = MotorSlope::create_from_steps(62496, 335, 255); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 5360; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(62496, 335, 469); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 10528; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(62496, 2632, 3); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_110; + profile.exposure = 20864; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(62496, 10432, 3); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 4608; + profile.step_type = StepType::FULL; + profile.slope = MotorSlope::create_from_steps(62496, 864, 127); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 5360; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(62496, 2010, 63); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 10528; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(62464, 2632, 3); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_120; + profile.exposure = 20864; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(62592, 10432, 5); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 2768; + profile.step_type = StepType::FULL; + profile.slope = MotorSlope::create_from_steps(62496, 335, 255); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 5360; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(62496, 335, 469); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 10528; + profile.step_type = StepType::HALF; + profile.slope = MotorSlope::create_from_steps(62496, 2632, 3); + gl124_motor_profiles->push_back(profile); + + profile = Motor_Profile(); + profile.motor_id = MotorId::CANON_LIDE_210; + profile.exposure = 20864; + profile.step_type = StepType::QUARTER; + profile.slope = MotorSlope::create_from_steps(62496, 10432, 4); + gl124_motor_profiles->push_back(profile); +} + +void genesys_init_motor_profile_tables() +{ + genesys_init_motor_profile_tables_gl843(); + genesys_init_motor_profile_tables_gl846(); + genesys_init_motor_profile_tables_gl847(); + genesys_init_motor_profile_tables_gl124(); +} + +} // namespace genesys diff --git a/backend/genesys/tables_sensor.cpp b/backend/genesys/tables_sensor.cpp new file mode 100644 index 0000000..bbbe441 --- /dev/null +++ b/backend/genesys/tables_sensor.cpp @@ -0,0 +1,3668 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "low.h" + +namespace genesys { + +inline unsigned default_get_logical_hwdpi(const Genesys_Sensor& sensor, unsigned xres) +{ + if (sensor.logical_dpihw_override) + return sensor.logical_dpihw_override; + + // can't be below 600 dpi + if (xres <= 600) { + return 600; + } + if (xres <= static_cast<unsigned>(sensor.optical_res) / 4) { + return sensor.optical_res / 4; + } + if (xres <= static_cast<unsigned>(sensor.optical_res) / 2) { + return sensor.optical_res / 2; + } + return sensor.optical_res; +} + +inline unsigned get_sensor_optical_with_ccd_divisor(const Genesys_Sensor& sensor, unsigned xres) +{ + unsigned hwres = sensor.optical_res / sensor.get_ccd_size_divisor_for_dpi(xres); + + if (xres <= hwres / 4) { + return hwres / 4; + } + if (xres <= hwres / 2) { + return hwres / 2; + } + return hwres; +} + +inline unsigned default_get_ccd_size_divisor_for_dpi(const Genesys_Sensor& sensor, unsigned xres) +{ + if (sensor.ccd_size_divisor >= 4 && xres * 4 <= static_cast<unsigned>(sensor.optical_res)) { + return 4; + } + if (sensor.ccd_size_divisor >= 2 && xres * 2 <= static_cast<unsigned>(sensor.optical_res)) { + return 2; + } + return 1; +} + +inline unsigned get_ccd_size_divisor_exact(const Genesys_Sensor& sensor, unsigned xres) +{ + (void) xres; + return sensor.ccd_size_divisor; +} + +inline unsigned get_ccd_size_divisor_gl124(const Genesys_Sensor& sensor, unsigned xres) +{ + // we have 2 domains for ccd: xres below or above half ccd max dpi + if (xres <= 300 && sensor.ccd_size_divisor > 1) { + return 2; + } + return 1; +} + +inline unsigned default_get_hwdpi_divisor_for_dpi(const Genesys_Sensor& sensor, unsigned xres) +{ + return sensor.optical_res / default_get_logical_hwdpi(sensor, xres); +} + +StaticInit<std::vector<Genesys_Sensor>> s_sensors; + +void genesys_init_sensor_tables() +{ + s_sensors.init(); + + Genesys_Sensor sensor; + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_UMAX; + sensor.optical_res = 1200; + sensor.black_pixels = 48; + sensor.dummy_pixel = 64; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10800; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.custom_regs = { + { 0x08, 0x01 }, + { 0x09, 0x03 }, + { 0x0a, 0x05 }, + { 0x0b, 0x07 }, + { 0x16, 0x33 }, + { 0x17, 0x05 }, + { 0x18, 0x31 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x13 }, + { 0x53, 0x17 }, + { 0x54, 0x03 }, + { 0x55, 0x07 }, + { 0x56, 0x0b }, + { 0x57, 0x0f }, + { 0x58, 0x23 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_ST12; + sensor.optical_res = 600; + sensor.black_pixels = 48; + sensor.dummy_pixel = 85; + sensor.ccd_start_xoffset = 152; + sensor.sensor_pixels = 5416; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.custom_regs = { + { 0x08, 0x02 }, + { 0x09, 0x00 }, + { 0x0a, 0x06 }, + { 0x0b, 0x04 }, + { 0x16, 0x2b }, + { 0x17, 0x08 }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x0c }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_ST24; + sensor.optical_res = 1200; + sensor.black_pixels = 48; + sensor.dummy_pixel = 64; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10800; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.custom_regs = { + { 0x08, 0x0e }, + { 0x09, 0x0c }, + { 0x0a, 0x00 }, + { 0x0b, 0x0c }, + { 0x16, 0x33 }, + { 0x17, 0x08 }, + { 0x18, 0x31 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x17 }, + { 0x53, 0x03 }, + { 0x54, 0x07 }, + { 0x55, 0x0b }, + { 0x56, 0x0f }, + { 0x57, 0x13 }, + { 0x58, 0x03 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_5345; + sensor.optical_res = 1200; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 48; + sensor.dummy_pixel = 16; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10872; + sensor.fau_gain_white_ref = 190; + sensor.gain_white_ref = 190; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.stagger_config = StaggerConfig{ 1200, 4 }; // FIXME: may be incorrect + sensor.custom_base_regs = { + { 0x08, 0x0d }, + { 0x09, 0x0f }, + { 0x0a, 0x11 }, + { 0x0b, 0x13 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x30 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x23 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 }, + }; + sensor.gamma = { 2.38f, 2.35f, 2.34f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + unsigned exposure_lperiod; + unsigned ccd_size_divisor; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 50 }, 12000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 75 }, 11000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 100 }, 11000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 150 }, 11000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 200 }, 11000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 300 }, 11000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 400 }, 11000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 600 }, 11000, 2, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x28 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 1200 }, 11000, 1, { + { 0x08, 0x0d }, + { 0x09, 0x0f }, + { 0x0a, 0x11 }, + { 0x0b, 0x13 }, + { 0x16, 0x0b }, + { 0x17, 0x0a }, + { 0x18, 0x30 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x03 }, + { 0x52, 0x03 }, + { 0x53, 0x07 }, + { 0x54, 0x0b }, + { 0x55, 0x0f }, + { 0x56, 0x13 }, + { 0x57, 0x17 }, + { 0x58, 0x23 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + }; + + for (const CustomSensorSettings& setting : custom_settings) + { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.ccd_size_divisor = setting.ccd_size_divisor; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_HP2400; + sensor.optical_res = 1200; + sensor.black_pixels = 48; + sensor.dummy_pixel = 15; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10872; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.stagger_config = StaggerConfig{1200, 4}; // FIXME: may be incorrect + sensor.custom_base_regs = { + { 0x08, 0x14 }, + { 0x09, 0x15 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0xbf }, + { 0x17, 0x08 }, + { 0x18, 0x3f }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x0b }, + { 0x53, 0x0f }, + { 0x54, 0x13 }, + { 0x55, 0x17 }, + { 0x56, 0x03 }, + { 0x57, 0x07 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x0e }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 }, + }; + sensor.gamma = { 2.1f, 2.1f, 2.1f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + unsigned exposure_lperiod; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 50 }, 7211, { + { 0x08, 0x14 }, + { 0x09, 0x15 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0xbf }, + { 0x17, 0x08 }, + { 0x18, 0x3f }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x0b }, + { 0x53, 0x0f }, + { 0x54, 0x13 }, + { 0x55, 0x17 }, + { 0x56, 0x03 }, + { 0x57, 0x07 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 100 }, 7211, { + { 0x08, 0x14 }, + { 0x09, 0x15 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0xbf }, + { 0x17, 0x08 }, + { 0x18, 0x3f }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x0b }, + { 0x53, 0x0f }, + { 0x54, 0x13 }, + { 0x55, 0x17 }, + { 0x56, 0x03 }, + { 0x57, 0x07 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 150 }, 7211, { + { 0x08, 0x14 }, + { 0x09, 0x15 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0xbf }, + { 0x17, 0x08 }, + { 0x18, 0x3f }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x0b }, + { 0x53, 0x0f }, + { 0x54, 0x13 }, + { 0x55, 0x17 }, + { 0x56, 0x03 }, + { 0x57, 0x07 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 300 }, 8751, { + { 0x08, 0x14 }, + { 0x09, 0x15 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0xbf }, + { 0x17, 0x08 }, + { 0x18, 0x3f }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x0b }, + { 0x53, 0x0f }, + { 0x54, 0x13 }, + { 0x55, 0x17 }, + { 0x56, 0x03 }, + { 0x57, 0x07 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 600 }, 18760, { + { 0x08, 0x0e }, + { 0x09, 0x0f }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0xbf }, + { 0x17, 0x08 }, + { 0x18, 0x31 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x03 }, + { 0x53, 0x07 }, + { 0x54, 0x0b }, + { 0x55, 0x0f }, + { 0x56, 0x13 }, + { 0x57, 0x17 }, + { 0x58, 0x23 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 1200 }, 21749, { + { 0x08, 0x02 }, + { 0x09, 0x04 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0xbf }, + { 0x17, 0x08 }, + { 0x18, 0x30 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x42 }, + { 0x52, 0x0b }, + { 0x53, 0x0f }, + { 0x54, 0x13 }, + { 0x55, 0x17 }, + { 0x56, 0x03 }, + { 0x57, 0x07 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x0e }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + }; + + for (const CustomSensorSettings& setting : custom_settings) + { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_HP2300; + sensor.optical_res = 600; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 48; + sensor.dummy_pixel = 20; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 5368; + sensor.fau_gain_white_ref = 180; + sensor.gain_white_ref = 180; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.custom_base_regs = { + { 0x08, 0x16 }, + { 0x09, 0x00 }, + { 0x0a, 0x01 }, + { 0x0b, 0x03 }, + { 0x16, 0xb7 }, + { 0x17, 0x0a }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x6a }, + { 0x1b, 0x8a }, + { 0x1c, 0x00 }, + { 0x1d, 0x05 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x06 }, + { 0x5c, 0x0b }, + { 0x5d, 0x10 }, + { 0x5e, 0x16 }, + }; + sensor.gamma = { 2.1f, 2.1f, 2.1f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + unsigned exposure_lperiod; + unsigned ccd_size_divisor; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 75 }, 4480, 2, { + { 0x08, 0x16 }, + { 0x09, 0x00 }, + { 0x0a, 0x01 }, + { 0x0b, 0x03 }, + { 0x16, 0xb7 }, + { 0x17, 0x0a }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x6a }, + { 0x1b, 0x8a }, + { 0x1c, 0x00 }, + { 0x1d, 0x85 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x06 }, + { 0x5c, 0x0b }, + { 0x5d, 0x10 }, + { 0x5e, 0x16 } + } + }, + { { 150 }, 4350, 2, { + { 0x08, 0x16 }, + { 0x09, 0x00 }, + { 0x0a, 0x01 }, + { 0x0b, 0x03 }, + { 0x16, 0xb7 }, + { 0x17, 0x0a }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x6a }, + { 0x1b, 0x8a }, + { 0x1c, 0x00 }, + { 0x1d, 0x85 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x06 }, + { 0x5c, 0x0b }, + { 0x5d, 0x10 }, + { 0x5e, 0x16 } + } + }, + { { 300 }, 4350, 2, { + { 0x08, 0x16 }, + { 0x09, 0x00 }, + { 0x0a, 0x01 }, + { 0x0b, 0x03 }, + { 0x16, 0xb7 }, + { 0x17, 0x0a }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x6a }, + { 0x1b, 0x8a }, + { 0x1c, 0x00 }, + { 0x1d, 0x85 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x06 }, + { 0x5c, 0x0b }, + { 0x5d, 0x10 }, + { 0x5e, 0x16 } + } + }, + { { 600 }, 8700, 1, { + { 0x08, 0x01 }, + { 0x09, 0x03 }, + { 0x0a, 0x04 }, + { 0x0b, 0x06 }, + { 0x16, 0xb7 }, + { 0x17, 0x0a }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x6a }, + { 0x1b, 0x8a }, + { 0x1c, 0x00 }, + { 0x1d, 0x05 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x06 }, + { 0x5c, 0x0b }, + { 0x5d, 0x10 }, + { 0x5e, 0x16 } + } + }, + }; + + for (const CustomSensorSettings& setting : custom_settings) + { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.ccd_size_divisor = setting.ccd_size_divisor; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_35; + sensor.optical_res = 1200; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 87; + sensor.dummy_pixel = 87; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10400; + sensor.fau_gain_white_ref = 0; + sensor.gain_white_ref = 0; + sensor.exposure = { 0x0400, 0x0400, 0x0400 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0x00 }, + { 0x17, 0x02 }, + { 0x18, 0x00 }, + { 0x19, 0x50 }, + { 0x1a, 0x00 }, // TODO: 1a-1d: these do no harm, but may be neccessery for CCD + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x02 }, + { 0x52, 0x05 }, // [GB](HI|LOW) not needed for cis + { 0x53, 0x07 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x3a }, + { 0x59, 0x03 }, + { 0x5a, 0x40 }, + { 0x5b, 0x00 }, // TODO: 5b-5e + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_XP200; + sensor.optical_res = 600; + sensor.black_pixels = 5; + sensor.dummy_pixel = 38; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 5200; + sensor.fau_gain_white_ref = 200; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x1450, 0x0c80, 0x0a28 }; + sensor.custom_base_regs = { + { 0x08, 0x16 }, + { 0x09, 0x00 }, + { 0x0a, 0x01 }, + { 0x0b, 0x03 }, + { 0x16, 0xb7 }, + { 0x17, 0x0a }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x6a }, + { 0x1b, 0x8a }, + { 0x1c, 0x00 }, + { 0x1d, 0x05 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x06 }, + { 0x5c, 0x0b }, + { 0x5d, 0x10 }, + { 0x5e, 0x16 }, + }; + sensor.custom_regs = { + { 0x08, 0x06 }, + { 0x09, 0x07 }, + { 0x0a, 0x0a }, + { 0x0b, 0x04 }, + { 0x16, 0x24 }, + { 0x17, 0x04 }, + { 0x18, 0x00 }, + { 0x19, 0x2a }, + { 0x1a, 0x0a }, + { 0x1b, 0x0a }, + { 0x1c, 0x00 }, + { 0x1d, 0x11 }, + { 0x52, 0x08 }, + { 0x53, 0x02 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x1a }, + { 0x59, 0x51 }, + { 0x5a, 0x00 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + }; + sensor.gamma = { 2.1f, 2.1f, 2.1f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + std::vector<unsigned> channels; + unsigned exposure_lperiod; + SensorExposure exposure; + }; + + CustomSensorSettings custom_settings[] = { + { { 75 }, { 3 }, 5700, { 0x1644, 0x0c80, 0x092e } }, + { { 100 }, { 3 }, 5700, { 0x1644, 0x0c80, 0x092e } }, + { { 200 }, { 3 }, 5700, { 0x1644, 0x0c80, 0x092e } }, + { { 300 }, { 3 }, 9000, { 0x1644, 0x0c80, 0x092e } }, + { { 600 }, { 3 }, 16000, { 0x1644, 0x0c80, 0x092e } }, + { { 75 }, { 1 }, 16000, { 0x050a, 0x0fa0, 0x1010 } }, + { { 100 }, { 1 }, 7800, { 0x050a, 0x0fa0, 0x1010 } }, + { { 200 }, { 1 }, 11000, { 0x050a, 0x0fa0, 0x1010 } }, + { { 300 }, { 1 }, 13000, { 0x050a, 0x0fa0, 0x1010 } }, + { { 600 }, { 1 }, 24000, { 0x050a, 0x0fa0, 0x1010 } }, + }; + + for (const CustomSensorSettings& setting : custom_settings) + { + sensor.resolutions = setting.resolutions; + sensor.channels = setting.channels; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_HP3670; + sensor.optical_res = 1200; + sensor.black_pixels = 48; + sensor.dummy_pixel = 16; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10872; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0, 0, 0 }; + sensor.stagger_config = StaggerConfig{1200, 4}; // FIXME: may be incorrect + sensor.custom_base_regs = { + { 0x08, 0x00 }, + { 0x09, 0x0a }, + { 0x0a, 0x0b }, + { 0x0b, 0x0d }, + { 0x16, 0x33 }, + { 0x17, 0x07 }, + { 0x18, 0x20 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x00 }, + { 0x5a, 0x15 }, + { 0x5b, 0x05 }, + { 0x5c, 0x0a }, + { 0x5d, 0x0f }, + { 0x5e, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + unsigned exposure_lperiod; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 50 }, 5758, { + { 0x08, 0x00 }, + { 0x09, 0x0a }, + { 0x0a, 0x0b }, + { 0x0b, 0x0d }, + { 0x16, 0x33 }, + { 0x17, 0x07 }, + { 0x18, 0x33 }, + { 0x19, 0x2a }, + { 0x1a, 0x02 }, + { 0x1b, 0x13 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x15 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x05 }, + { 0x5c, 0x0a }, + { 0x5d, 0x0f }, + { 0x5e, 0x00 } + } + }, + { { 75 }, 4879, { + { 0x08, 0x00 }, + { 0x09, 0x0a }, + { 0x0a, 0x0b }, + { 0x0b, 0x0d }, + { 0x16, 0x33 }, + { 0x17, 0x07 }, + { 0x18, 0x33 }, + { 0x19, 0x2a }, + { 0x1a, 0x02 }, + { 0x1b, 0x13 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x15 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x05 }, + { 0x5c, 0x0a }, + { 0x5d, 0x0f }, + { 0x5e, 0x00 } + } + }, + { { 100 }, 4487, { + { 0x08, 0x00 }, + { 0x09, 0x0a }, + { 0x0a, 0x0b }, + { 0x0b, 0x0d }, + { 0x16, 0x33 }, + { 0x17, 0x07 }, + { 0x18, 0x33 }, + { 0x19, 0x2a }, + { 0x1a, 0x02 }, + { 0x1b, 0x13 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x15 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x05 }, + { 0x5c, 0x0a }, + { 0x5d, 0x0f }, + { 0x5e, 0x00 } + } + }, + { { 150 }, 4879, { + { 0x08, 0x00 }, + { 0x09, 0x0a }, + { 0x0a, 0x0b }, + { 0x0b, 0x0d }, + { 0x16, 0x33 }, + { 0x17, 0x07 }, + { 0x18, 0x33 }, + { 0x19, 0x2a }, + { 0x1a, 0x02 }, + { 0x1b, 0x13 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x15 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x05 }, + { 0x5c, 0x0a }, + { 0x5d, 0x0f }, + { 0x5e, 0x00 } + } + }, + { { 300 }, 4503, { + { 0x08, 0x00 }, + { 0x09, 0x0a }, + { 0x0a, 0x0b }, + { 0x0b, 0x0d }, + { 0x16, 0x33 }, + { 0x17, 0x07 }, + { 0x18, 0x33 }, + { 0x19, 0x2a }, + { 0x1a, 0x02 }, + { 0x1b, 0x13 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x0f }, + { 0x53, 0x13 }, + { 0x54, 0x17 }, + { 0x55, 0x03 }, + { 0x56, 0x07 }, + { 0x57, 0x0b }, + { 0x58, 0x83 }, + { 0x59, 0x15 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x05 }, + { 0x5c, 0x0a }, + { 0x5d, 0x0f }, + { 0x5e, 0x00 } + } + }, + { { 600 }, 10251, { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x06 }, + { 0x0b, 0x08 }, + { 0x16, 0x33 }, + { 0x17, 0x07 }, + { 0x18, 0x31 }, + { 0x19, 0x2a }, + { 0x1a, 0x02 }, + { 0x1b, 0x0e }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x0b }, + { 0x53, 0x0f }, + { 0x54, 0x13 }, + { 0x55, 0x17 }, + { 0x56, 0x03 }, + { 0x57, 0x07 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x02 }, + { 0x5c, 0x0e }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + { { 1200 }, 12750, { + { 0x08, 0x0d }, + { 0x09, 0x0f }, + { 0x0a, 0x11 }, + { 0x0b, 0x13 }, + { 0x16, 0x2b }, + { 0x17, 0x07 }, + { 0x18, 0x30 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x43 }, + { 0x52, 0x03 }, + { 0x53, 0x07 }, + { 0x54, 0x0b }, + { 0x55, 0x0f }, + { 0x56, 0x13 }, + { 0x57, 0x17 }, + { 0x58, 0x23 }, + { 0x59, 0x00 }, + { 0x5a, 0xc1 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x00 } + } + }, + }; + + for (const CustomSensorSettings& setting : custom_settings) + { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_DP665; + sensor.optical_res = 600; + sensor.black_pixels = 27; + sensor.dummy_pixel = 27; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 2496; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x1100, 0x1100, 0x1100 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0x00 }, + { 0x17, 0x02 }, + { 0x18, 0x04 }, + { 0x19, 0x50 }, + { 0x1a, 0x10 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x02 }, + { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis + { 0x53, 0x05 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x54 }, + { 0x59, 0x03 }, + { 0x5a, 0x00 }, + { 0x5b, 0x00 }, // TODO: 5b-5e + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x01 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_ROADWARRIOR; + sensor.optical_res = 600; + sensor.black_pixels = 27; + sensor.dummy_pixel = 27; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 5200; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x1100, 0x1100, 0x1100 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0x00 }, + { 0x17, 0x02 }, + { 0x18, 0x04 }, + { 0x19, 0x50 }, + { 0x1a, 0x10 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x02 }, + { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis + { 0x53, 0x05 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x54 }, + { 0x59, 0x03 }, + { 0x5a, 0x00 }, + { 0x5b, 0x00 }, // TODO: 5b-5e + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x01 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_DSMOBILE600; + sensor.optical_res = 600; + sensor.black_pixels = 28; + sensor.dummy_pixel = 28; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 5200; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x1544, 0x1544, 0x1544 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0x00 }, + { 0x17, 0x02 }, + { 0x18, 0x04 }, + { 0x19, 0x50 }, + { 0x1a, 0x10 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x02 }, + { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis + { 0x53, 0x05 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x54 }, + { 0x59, 0x03 }, + { 0x5a, 0x00 }, + { 0x5b, 0x00 }, // TODO: 5b-5e + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x01 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_XP300; + sensor.optical_res = 600; + sensor.black_pixels = 27; + sensor.dummy_pixel = 27; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10240; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x1100, 0x1100, 0x1100 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0x00 }, + { 0x17, 0x02 }, + { 0x18, 0x04 }, + { 0x19, 0x50 }, + { 0x1a, 0x10 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x02 }, + { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis + { 0x53, 0x05 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x54 }, + { 0x59, 0x03 }, + { 0x5a, 0x00 }, + { 0x5b, 0x00 }, // TODO: 5b-5e + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x01 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_DP685; + sensor.optical_res = 600; + sensor.black_pixels = 27; + sensor.dummy_pixel = 27; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 5020; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x1100, 0x1100, 0x1100 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0x00 }, + { 0x17, 0x02 }, + { 0x18, 0x04 }, + { 0x19, 0x50 }, + { 0x1a, 0x10 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x02 }, + { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis + { 0x53, 0x05 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x54 }, + { 0x59, 0x03 }, + { 0x5a, 0x00 }, + { 0x5b, 0x00 }, // TODO: 5b-5e + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x01 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_200; + sensor.optical_res = 4800; + sensor.black_pixels = 87*4; + sensor.dummy_pixel = 16*4; + sensor.ccd_start_xoffset = 320*8; + sensor.sensor_pixels = 5136*8; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.gamma = { 2.2f, 2.2f, 2.2f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + SensorExposure exposure; + unsigned segment_size; + std::vector<unsigned> segment_order; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + // Note: Windows driver uses 1424 lperiod and enables dummy line (0x17) + { { 75, 100, 150, 200 }, 2848, { 304, 203, 180 }, 5136, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + // Note: Windows driver uses 788 lperiod and enables dummy line (0x17) + { { 300, 400 }, 1424, { 304, 203, 180 }, 5136, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 600 }, 1432, { 492, 326, 296 }, 5136, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 1200 }, 2712, { 935, 592, 538 }, 5136, { 0, 1 }, { + { 0x16, 0x10 }, { 0x17, 0x08 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 2400 }, 5280, { 1777, 1125, 979 }, 5136, { 0, 2, 1, 3 }, { + { 0x16, 0x10 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 4800 }, 10416, { 3377, 2138, 1780 }, 5136, { 0, 2, 4, 6, 1, 3, 5, 7 }, { + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + } + }; + + for (const auto& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + sensor.segment_size = setting.segment_size; + sensor.segment_order = setting.segment_order; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_700F; + sensor.optical_res = 4800; + sensor.black_pixels = 73*8; // black pixels 73 at 600 dpi + sensor.dummy_pixel = 16*8; + // 384 at 600 dpi + sensor.ccd_start_xoffset = 384*8; + // 8x5570 segments, 5187+1 for rounding + sensor.sensor_pixels = 5188*8; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + SensorExposure exposure; + unsigned segment_size; + std::vector<unsigned> segment_order; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 75, 100, 150, 200 }, 2848, { 465, 310, 239 }, 5187, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 300 }, 1424, { 465, 310, 239 }, 5187, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 600 }, 1504, { 465, 310, 239 }, 5187, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 1200 }, 2696, { 1464, 844, 555 }, 5187, { 0, 1 }, { + { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 2400 }, 10576, { 2798, 1558, 972 }, 5187, { 0, 1, 2, 3 }, { + { 0x16, 0x10 }, { 0x17, 0x08 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 4800 }, 10576, { 2798, 1558, 972 }, 5187, { 0, 1, 4, 5, 2, 3, 6, 7 }, { + { 0x16, 0x10 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x07 }, { 0x53, 0x03 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x87 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0xf9 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + } + }; + + for (const auto& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + sensor.segment_size = setting.segment_size; + sensor.segment_order = setting.segment_order; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_100; + sensor.optical_res = 2400; + sensor.black_pixels = 87*4; + sensor.dummy_pixel = 16*4; + sensor.ccd_start_xoffset = 320*4; + sensor.sensor_pixels = 5136*4; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x01c1, 0x0126, 0x00e5 }; + sensor.gamma = { 2.2f, 2.2f, 2.2f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + SensorExposure exposure; + unsigned segment_size; + std::vector<unsigned> segment_order; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 75, 100, 150, 200 }, 2304, { 423, 294, 242 }, 5136, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 300 }, 1728, { 423, 294, 242 }, 5136, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 600 }, 1432, { 423, 294, 242 }, 5136, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x0a }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + }, + }, + { { 1200 }, 2712, { 791, 542, 403 }, 5136, {0, 1}, { + { 0x16, 0x10 }, { 0x17, 0x08 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + }, + { { 2400 }, 5280, { 1504, 1030, 766 }, 5136, {0, 2, 1, 3}, { + { 0x16, 0x10 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x04 }, + { 0x52, 0x03 }, { 0x53, 0x07 }, { 0x54, 0x00 }, { 0x55, 0x00 }, + { 0x56, 0x00 }, { 0x57, 0x00 }, { 0x58, 0x2a }, { 0x59, 0xe1 }, { 0x5a, 0x55 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + } + } + }; + + for (const auto& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + sensor.segment_size = setting.segment_size; + sensor.segment_order = setting.segment_order; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_KVSS080; + sensor.optical_res = 600; + sensor.black_pixels = 38; + sensor.dummy_pixel = 38; + sensor.ccd_start_xoffset = 152; + sensor.sensor_pixels = 5376; + sensor.fau_gain_white_ref = 160; + sensor.gain_white_ref = 160; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.exposure_lperiod = 8000; + sensor.custom_regs = { + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 }, + { 0x77, 0x00 }, { 0x78, 0xff }, { 0x79, 0xff }, + { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, + { 0x0c, 0x00 }, + { 0x70, 0x01 }, + { 0x71, 0x03 }, + { 0x9e, 0x00 }, + { 0xaa, 0x00 }, + { 0x16, 0x33 }, + { 0x17, 0x1c }, + { 0x18, 0x00 }, + { 0x19, 0x2a }, + { 0x1a, 0x2c }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x04 }, + { 0x52, 0x0c }, + { 0x53, 0x0f }, + { 0x54, 0x00 }, + { 0x55, 0x03 }, + { 0x56, 0x06 }, + { 0x57, 0x09 }, + { 0x58, 0x6b }, + { 0x59, 0x00 }, + { 0x5a, 0xc0 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_G4050; + sensor.optical_res = 4800; + sensor.black_pixels = 50*8; + // 31 at 600 dpi dummy_pixels 58 at 1200 + sensor.dummy_pixel = 58; + sensor.ccd_start_xoffset = 152; + sensor.sensor_pixels = 5360*8; + sensor.fau_gain_white_ref = 160; + sensor.gain_white_ref = 160; + sensor.exposure = { 0x2c09, 0x22b8, 0x10f0 }; + sensor.stagger_config = StaggerConfig{ 2400, 4 }; // FIXME: may be incorrect + sensor.custom_regs = {}; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + ScanMethod method; + GenesysRegisterSettingSet extra_custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 100, 150, 200, 300, 400, 600 }, 8016, ScanMethod::FLATBED, { + { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, + { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, + { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, + { 0x0c, 0x00 }, + { 0x70, 0x00 }, + { 0x71, 0x02 }, + { 0x9e, 0x00 }, + { 0xaa, 0x00 }, + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x00 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x08 }, + { 0x52, 0x0b }, + { 0x53, 0x0e }, + { 0x54, 0x11 }, + { 0x55, 0x02 }, + { 0x56, 0x05 }, + { 0x57, 0x08 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + } + }, + { { 1200 }, 56064, ScanMethod::FLATBED, { + { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x01 }, { 0x79, 0xff }, + { 0x7a, 0x00 }, { 0x7b, 0x01 }, { 0x7c, 0xff }, + { 0x0c, 0x20 }, + { 0x70, 0x08 }, + { 0x71, 0x0c }, + { 0x9e, 0xc0 }, + { 0xaa, 0x05 }, + { 0x16, 0x3b }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x38 }, + { 0x1b, 0x10 }, + { 0x1c, 0x00 }, + { 0x1d, 0x08 }, + { 0x52, 0x02 }, + { 0x53, 0x05 }, + { 0x54, 0x08 }, + { 0x55, 0x0b }, + { 0x56, 0x0e }, + { 0x57, 0x11 }, + { 0x58, 0x1b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + } + }, + { { 2400 }, 56064, ScanMethod::FLATBED, { + { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, + { 0x0c, 0x20 }, + { 0x70, 0x08 }, + { 0x71, 0x0a }, + { 0x9e, 0xc0 }, + { 0xaa, 0x05 }, + { 0x16, 0x3b }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x38 }, + { 0x1b, 0x10 }, + { 0x1c, 0xc0 }, + { 0x1d, 0x08 }, + { 0x52, 0x02 }, + { 0x53, 0x05 }, + { 0x54, 0x08 }, + { 0x55, 0x0b }, + { 0x56, 0x0e }, + { 0x57, 0x11 }, + { 0x58, 0x1b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + } + }, + { { 4800 }, 42752, ScanMethod::FLATBED, { + { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, + { 0x0c, 0x21 }, + { 0x70, 0x08 }, + { 0x71, 0x0a }, + { 0x9e, 0xc0 }, + { 0xaa, 0x07 }, + { 0x16, 0x3b }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x38 }, + { 0x1b, 0x10 }, + { 0x1c, 0xc1 }, + { 0x1d, 0x08 }, + { 0x52, 0x02 }, + { 0x53, 0x05 }, + { 0x54, 0x08 }, + { 0x55, 0x0b }, + { 0x56, 0x0e }, + { 0x57, 0x11 }, + { 0x58, 0x1b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + } + }, + { ResolutionFilter::ANY, 15624, ScanMethod::TRANSPARENCY, { + { 0x74, 0x00 }, { 0x75, 0x1c }, { 0x76, 0x7f }, + { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, + { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, + { 0x0c, 0x00 }, + { 0x70, 0x00 }, + { 0x71, 0x02 }, + { 0x9e, 0x00 }, + { 0xaa, 0x00 }, + { 0x16, 0x33 }, + { 0x17, 0x4c }, + { 0x18, 0x01 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x08 }, + { 0x52, 0x0e }, + { 0x53, 0x11 }, + { 0x54, 0x02 }, + { 0x55, 0x05 }, + { 0x56, 0x08 }, + { 0x57, 0x0b }, + { 0x58, 0x6b }, + { 0x59, 0x00 }, + { 0x5a, 0xc0 }, + } + } + }; + + auto base_custom_regs = sensor.custom_regs; + for (const CustomSensorSettings& setting : custom_settings) + { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.method = setting.method; + sensor.custom_regs = base_custom_regs; + sensor.custom_regs.merge(setting.extra_custom_regs); + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_HP_4850C; + sensor.optical_res = 4800; + sensor.black_pixels = 100; + sensor.dummy_pixel = 58; + sensor.ccd_start_xoffset = 152; + sensor.sensor_pixels = 5360*8; + sensor.fau_gain_white_ref = 160; + sensor.gain_white_ref = 160; + sensor.exposure = { 0x2c09, 0x22b8, 0x10f0 }; + sensor.stagger_config = StaggerConfig{ 2400, 4 }; // FIXME: may be incorrect + sensor.custom_regs = {}; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + ScanMethod method; + GenesysRegisterSettingSet extra_custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 100, 150, 200, 300, 400, 600 }, 8016, ScanMethod::FLATBED, { + { 0x0c, 0x00 }, + { 0x16, 0x33 }, { 0x17, 0x0c }, { 0x18, 0x00 }, { 0x19, 0x2a }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x08 }, + { 0x52, 0x0b }, { 0x53, 0x0e }, { 0x54, 0x11 }, { 0x55, 0x02 }, + { 0x56, 0x05 }, { 0x57, 0x08 }, { 0x58, 0x63 }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, + { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, + { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, + { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, + { 0x9e, 0x00 }, + { 0xaa, 0x00 }, + } + }, + { { 1200 }, 56064, ScanMethod::FLATBED, { + { 0x0c, 0x20 }, + { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a }, + { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0x00 }, { 0x1d, 0x08 }, + { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b }, + { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x70, 0x08 }, { 0x71, 0x0c }, + { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x01 }, { 0x79, 0xff }, + { 0x7a, 0x00 }, { 0x7b, 0x01 }, { 0x7c, 0xff }, + { 0x9e, 0xc0 }, + { 0xaa, 0x05 }, + } + }, + { { 2400 }, 56064, ScanMethod::FLATBED, { + { 0x0c, 0x20 }, + { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a }, + { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0xc0 }, { 0x1d, 0x08 }, + { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b }, + { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x70, 0x08 }, { 0x71, 0x0a }, + { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, + { 0x9e, 0xc0 }, + { 0xaa, 0x05 }, + } + }, + { { 4800 }, 42752, ScanMethod::FLATBED, { + { 0x0c, 0x21 }, + { 0x16, 0x3b }, { 0x17, 0x0c }, { 0x18, 0x10 }, { 0x19, 0x2a }, + { 0x1a, 0x38 }, { 0x1b, 0x10 }, { 0x1c, 0xc1 }, { 0x1d, 0x08 }, + { 0x52, 0x02 }, { 0x53, 0x05 }, { 0x54, 0x08 }, { 0x55, 0x0b }, + { 0x56, 0x0e }, { 0x57, 0x11 }, { 0x58, 0x1b }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x70, 0x08 }, { 0x71, 0x0a }, + { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, + { 0x9e, 0xc0 }, + { 0xaa, 0x07 }, + } + }, + { ResolutionFilter::ANY, 15624, ScanMethod::TRANSPARENCY, { + { 0x0c, 0x00 }, + { 0x16, 0x33 }, { 0x17, 0x4c }, { 0x18, 0x01 }, { 0x19, 0x2a }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x08 }, + { 0x52, 0x0e }, { 0x53, 0x11 }, { 0x54, 0x02 }, { 0x55, 0x05 }, + { 0x56, 0x08 }, { 0x57, 0x0b }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0xc0 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, + { 0x74, 0x00 }, { 0x75, 0x1c }, { 0x76, 0x7f }, + { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, + { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, + { 0x9e, 0x00 }, + { 0xaa, 0x00 }, + } + } + }; + + auto base_custom_regs = sensor.custom_regs; + for (const CustomSensorSettings& setting : custom_settings) + { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.method = setting.method; + sensor.custom_regs = base_custom_regs; + sensor.custom_regs.merge(setting.extra_custom_regs); + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_CANON_4400F; + sensor.optical_res = 4800; + sensor.ccd_size_divisor = 4; + sensor.black_pixels = 50*8; + // 31 at 600 dpi, 58 at 1200 dpi + sensor.dummy_pixel = 20; + sensor.ccd_start_xoffset = 152; + // 5360 max at 600 dpi + sensor.sensor_pixels = 5700 * 8; + sensor.fau_gain_white_ref = 160; + sensor.gain_white_ref = 160; + sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = get_sensor_optical_with_ccd_divisor; + sensor.get_register_hwdpi_fun = [](const Genesys_Sensor&, unsigned) { return 4800; }; + sensor.get_hwdpi_divisor_fun = [](const Genesys_Sensor&, unsigned) { return 1; }; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + std::vector<ScanMethod> methods; + GenesysRegisterSettingSet extra_custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 300, 600, 1200 }, 11640, { ScanMethod::FLATBED }, { + { 0x16, 0x13 }, + { 0x17, 0x0a }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x6b }, + { 0x52, 0x0a }, + { 0x53, 0x0d }, + { 0x54, 0x00 }, + { 0x55, 0x03 }, + { 0x56, 0x06 }, + { 0x57, 0x08 }, + { 0x58, 0x5b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x01 }, { 0x73, 0x03 }, + { 0x74, 0x00 }, { 0x75, 0xf8 }, { 0x76, 0x38 }, + { 0x77, 0x00 }, { 0x78, 0xfc }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0xa4 }, + { 0x9e, 0x2d }, + } + }, + { { 300, 600, 1200 }, 33300, { ScanMethod::TRANSPARENCY }, { + { 0x16, 0x13 }, + { 0x17, 0x0a }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x6b }, + { 0x52, 0x0a }, + { 0x53, 0x0d }, + { 0x54, 0x00 }, + { 0x55, 0x03 }, + { 0x56, 0x06 }, + { 0x57, 0x08 }, + { 0x58, 0x5b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x00 }, { 0x73, 0x02 }, + { 0x74, 0x00 }, { 0x75, 0xf8 }, { 0x76, 0x38 }, + { 0x77, 0x00 }, { 0x78, 0xfc }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0xa4 }, + { 0x9e, 0x2d }, + } + }, + { { 2400 }, 33300, { ScanMethod::TRANSPARENCY }, { + { 0x16, 0x13 }, + { 0x17, 0x0a }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x01 }, + { 0x1d, 0x75 }, + { 0x52, 0x0b }, + { 0x53, 0x0d }, + { 0x54, 0x00 }, + { 0x55, 0x03 }, + { 0x56, 0x06 }, + { 0x57, 0x09 }, + { 0x58, 0x53 }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 }, + { 0x74, 0x00 }, { 0x75, 0xff }, { 0x76, 0x00 }, + { 0x77, 0x00 }, { 0x78, 0xff }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x54 }, { 0x7c, 0x92 }, + { 0x9e, 0x2d }, + } + }, + { { 4800 }, 33300, { ScanMethod::TRANSPARENCY }, { + { 0x16, 0x13 }, + { 0x17, 0x0a }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x61 }, + { 0x1d, 0x75 }, + { 0x52, 0x02 }, + { 0x53, 0x05 }, + { 0x54, 0x08 }, + { 0x55, 0x0b }, + { 0x56, 0x0d }, + { 0x57, 0x0f }, + { 0x58, 0x1b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x08 }, { 0x71, 0x0a }, { 0x72, 0x0a }, { 0x73, 0x0c }, + { 0x74, 0x00 }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0xff }, { 0x79, 0xff }, + { 0x7a, 0x00 }, { 0x7b, 0x54 }, { 0x7c, 0x92 }, + { 0x9e, 0x2d }, + } + } + }; + + for (const CustomSensorSettings& setting : custom_settings) + { + for (auto method : setting.methods) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.method = method; + sensor.custom_regs = setting.extra_custom_regs; + s_sensors->push_back(sensor); + } + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_CANON_8400F; + sensor.optical_res = 3200; + sensor.register_dpihw_override = 4800; + sensor.ccd_size_divisor = 1; + sensor.black_pixels = 50*8; + // 31 at 600 dpi, 58 at 1200 dpi + sensor.dummy_pixel = 20; + sensor.ccd_start_xoffset = 152; + sensor.sensor_pixels = 27200; + sensor.fau_gain_white_ref = 160; + sensor.gain_white_ref = 160; + sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 }; + sensor.stagger_config = StaggerConfig{ 3200, 6 }; + sensor.custom_regs = {}; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = get_sensor_optical_with_ccd_divisor; + sensor.get_register_hwdpi_fun = [](const Genesys_Sensor&, unsigned) { return 4800; }; + sensor.get_hwdpi_divisor_fun = [](const Genesys_Sensor&, unsigned) { return 1; }; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + unsigned dpiset_override; + unsigned pixel_count_multiplier; + int exposure_lperiod; + std::vector<ScanMethod> methods; + GenesysRegisterSettingSet extra_custom_regs; + GenesysRegisterSettingSet custom_fe_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 400 }, 2400, 1, 7200, { ScanMethod::FLATBED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x13 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa0 }, + { 0x52, 0x0d }, + { 0x53, 0x10 }, + { 0x54, 0x01 }, + { 0x55, 0x04 }, + { 0x56, 0x07 }, + { 0x57, 0x0a }, + { 0x58, 0x6b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 }, + { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb }, + { 0x80, 0x2a }, + }, {} + }, + { { 800 }, 4800, 1, 7200, { ScanMethod::FLATBED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x13 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa0 }, + { 0x52, 0x0d }, + { 0x53, 0x10 }, + { 0x54, 0x01 }, + { 0x55, 0x04 }, + { 0x56, 0x07 }, + { 0x57, 0x0a }, + { 0x58, 0x6b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 }, + { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb }, + { 0x80, 0x20 }, + }, {} + }, + { { 1600 }, 4800, 1, 14400, { ScanMethod::FLATBED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x11 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa1 }, + { 0x52, 0x0b }, + { 0x53, 0x0e }, + { 0x54, 0x11 }, + { 0x55, 0x02 }, + { 0x56, 0x05 }, + { 0x57, 0x08 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x03 }, + { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 }, + { 0x80, 0x28 }, + }, { + { 0x03, 0x1f }, + } + }, + { { 3200 }, 4800, 1, 28800, { ScanMethod::FLATBED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa1 }, + { 0x52, 0x02 }, + { 0x53, 0x05 }, + { 0x54, 0x08 }, + { 0x55, 0x0b }, + { 0x56, 0x0e }, + { 0x57, 0x11 }, + { 0x58, 0x1b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x09 }, { 0x71, 0x0a }, { 0x72, 0x0b }, { 0x73, 0x0c }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 }, + { 0x80, 0x2b }, + }, { + { 0x03, 0x1f }, + }, + }, + { { 400 }, 2400, 1, 14400, { ScanMethod::TRANSPARENCY, + ScanMethod::TRANSPARENCY_INFRARED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x13 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa0 }, + { 0x52, 0x0d }, + { 0x53, 0x10 }, + { 0x54, 0x01 }, + { 0x55, 0x04 }, + { 0x56, 0x07 }, + { 0x57, 0x0a }, + { 0x58, 0x6b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 }, + { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb }, + { 0x80, 0x20 }, + }, {} + }, + { { 800 }, 4800, 1, 14400, { ScanMethod::TRANSPARENCY, + ScanMethod::TRANSPARENCY_INFRARED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x13 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa0 }, + { 0x52, 0x0d }, + { 0x53, 0x10 }, + { 0x54, 0x01 }, + { 0x55, 0x04 }, + { 0x56, 0x07 }, + { 0x57, 0x0a }, + { 0x58, 0x6b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 }, + { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb }, + { 0x80, 0x20 }, + }, {} + }, + { { 1600 }, 4800, 1, 28800, { ScanMethod::TRANSPARENCY, + ScanMethod::TRANSPARENCY_INFRARED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x11 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa0 }, + { 0x52, 0x0b }, + { 0x53, 0x0e }, + { 0x54, 0x11 }, + { 0x55, 0x02 }, + { 0x56, 0x05 }, + { 0x57, 0x08 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x01 }, { 0x72, 0x02 }, { 0x73, 0x03 }, + { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 }, + { 0x80, 0x29 }, + }, { + { 0x03, 0x1f }, + }, + }, + { { 3200 }, 4800, 1, 28800, { ScanMethod::TRANSPARENCY, + ScanMethod::TRANSPARENCY_INFRARED }, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa0 }, + { 0x52, 0x02 }, + { 0x53, 0x05 }, + { 0x54, 0x08 }, + { 0x55, 0x0b }, + { 0x56, 0x0e }, + { 0x57, 0x11 }, + { 0x58, 0x1b }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x09 }, { 0x71, 0x0a }, { 0x72, 0x0b }, { 0x73, 0x0c }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 }, + { 0x80, 0x2b }, + }, { + { 0x03, 0x1f }, + }, + }, + }; + + for (const CustomSensorSettings& setting : custom_settings) + { + for (auto method : setting.methods) { + sensor.resolutions = setting.resolutions; + sensor.dpiset_override = setting.dpiset_override; + sensor.pixel_count_multiplier = setting.pixel_count_multiplier; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.method = method; + sensor.custom_regs = setting.extra_custom_regs; + sensor.custom_fe_regs = setting.custom_fe_regs; + s_sensors->push_back(sensor); + } + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_CANON_8600F; + sensor.optical_res = 4800; + sensor.ccd_size_divisor = 4; + sensor.black_pixels = 31; + sensor.dummy_pixel = 20; + sensor.ccd_start_xoffset = 0; // not used at the moment + // 11372 pixels at 1200 dpi + sensor.sensor_pixels = 11372*4; + sensor.fau_gain_white_ref = 160; + sensor.gain_white_ref = 160; + sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 }; + sensor.stagger_config = StaggerConfig{4800, 8}; + sensor.custom_regs = {}; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = get_sensor_optical_with_ccd_divisor; + sensor.get_register_hwdpi_fun = [](const Genesys_Sensor&, unsigned) { return 4800; }; + sensor.get_hwdpi_divisor_fun = [](const Genesys_Sensor&, unsigned) { return 1; }; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + std::vector<ScanMethod> methods; + GenesysRegisterSettingSet extra_custom_regs; + GenesysRegisterSettingSet custom_fe_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 300, 600, 1200 }, 24000, { ScanMethod::FLATBED }, { + { 0x0c, 0x00 }, + { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b }, + { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 }, + { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 }, + { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, + { 0x9e, 0x2d }, + { 0xaa, 0x00 }, + }, + {}, + }, + { { 300, 600, 1200 }, 45000, { ScanMethod::TRANSPARENCY, + ScanMethod::TRANSPARENCY_INFRARED }, { + { 0x0c, 0x00 }, + { 0x16, 0x13 }, { 0x17, 0x0a }, { 0x18, 0x10 }, { 0x19, 0x2a }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x00 }, { 0x1d, 0x6b }, + { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 }, + { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 }, + { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 }, + { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, + { 0x9e, 0x2d }, + { 0xaa, 0x00 }, + }, + {}, + }, + { { 2400 }, 45000, { ScanMethod::TRANSPARENCY, + ScanMethod::TRANSPARENCY_INFRARED }, { + { 0x0c, 0x00 }, + { 0x16, 0x13 }, { 0x17, 0x15 }, { 0x18, 0x10 }, { 0x19, 0x2a }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x01 }, { 0x1d, 0x75 }, + { 0x52, 0x0c }, { 0x53, 0x0f }, { 0x54, 0x00 }, { 0x55, 0x03 }, + { 0x56, 0x06 }, { 0x57, 0x09 }, { 0x58, 0x6b }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x02 }, { 0x72, 0x02 }, { 0x73, 0x04 }, + { 0x74, 0x03 }, { 0x75, 0xfe }, { 0x76, 0x00 }, + { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, + { 0x9e, 0x2d }, + { 0xaa, 0x00 }, + }, + {}, + }, + { { 4800 }, 45000, { ScanMethod::TRANSPARENCY, + ScanMethod::TRANSPARENCY_INFRARED }, { + { 0x0c, 0x00 }, + { 0x16, 0x13 }, { 0x17, 0x15 }, { 0x18, 0x10 }, { 0x19, 0x2a }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x61 }, { 0x1d, 0x75 }, + { 0x52, 0x03 }, { 0x53, 0x06 }, { 0x54, 0x09 }, { 0x55, 0x0c }, + { 0x56, 0x0f }, { 0x57, 0x00 }, { 0x58, 0x23 }, { 0x59, 0x00 }, { 0x5a, 0x40 }, + { 0x70, 0x0a }, { 0x71, 0x0c }, { 0x72, 0x0c }, { 0x73, 0x0e }, + { 0x74, 0x03 }, { 0x75, 0xff }, { 0x76, 0xff }, + { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, + { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, + { 0x9e, 0x2d }, + { 0xaa, 0x00 }, + }, + { { 0x03, 0x1f }, + }, + }, + }; + + for (const CustomSensorSettings& setting : custom_settings) { + for (auto method : setting.methods) { + sensor.resolutions = setting.resolutions; + sensor.method = method; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.custom_regs = setting.extra_custom_regs; + sensor.custom_fe_regs = setting.custom_fe_regs; + s_sensors->push_back(sensor); + } + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_HP_N6310; + sensor.optical_res = 2400; + // sensor.ccd_size_divisor = 2; Possibly half CCD, needs checking + sensor.black_pixels = 96; + sensor.dummy_pixel = 26; + sensor.ccd_start_xoffset = 128; + sensor.sensor_pixels = 42720; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.custom_regs = { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x02 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x08 }, + { 0x52, 0x0b }, + { 0x53, 0x0e }, + { 0x54, 0x11 }, + { 0x55, 0x02 }, + { 0x56, 0x05 }, + { 0x57, 0x08 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_110; + sensor.optical_res = 2400; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 87; + sensor.dummy_pixel = 16; + sensor.ccd_start_xoffset = 303; + sensor.sensor_pixels = 5168*4; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.gamma = { 2.2f, 2.2f, 2.2f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + SensorExposure exposure; + std::vector<unsigned> segment_order; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 75, 100, 150 }, 4608, { 462, 609, 453 }, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 }, + { 0x96, 0x00 }, { 0x97, 0x9a }, + { 0x98, 0x21 }, + } + }, + { { 300 }, 4608, { 462, 609, 453 }, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x0c }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 }, + { 0x96, 0x00 }, { 0x97, 0x9a }, + { 0x98, 0x21 }, + } + }, + { { 600 }, 5360, { 823, 1117, 805 }, std::vector<unsigned>{}, { + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x0a }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x21 }, + }, + }, + { { 1200 }, 10528, { 6071, 6670, 6042 }, { 0, 1 }, { + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 },{ 0x20, 0x08 }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x12 }, { 0x89, 0x47 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x22 }, + } + }, + { { 2400 }, 20864, { 7451, 8661, 7405 }, { 0, 2, 1, 3 }, { + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x06 }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + { 0x70, 0x06 }, { 0x71, 0x08 }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x12 }, { 0x89, 0x47 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x24 }, + } + } + }; + + for (const auto& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + sensor.segment_order = setting.segment_order; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_120; + sensor.optical_res = 2400; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 87; + sensor.dummy_pixel = 16; + sensor.ccd_start_xoffset = 303; + // SEGCNT at 600 DPI by number of segments + sensor.sensor_pixels = 5104*4; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.gamma = { 2.2f, 2.2f, 2.2f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + SensorExposure exposure; + std::vector<unsigned> segment_order; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 75, 100, 150, 300 }, 4608, { 1244, 1294, 1144 }, std::vector<unsigned>{}, { + { 0x16, 0x15 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 }, + { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 }, + { 0x61, 0x20 }, + { 0x70, 0x00 }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x5e }, + { 0x93, 0x00 }, { 0x94, 0x09 }, { 0x95, 0xf8 }, + { 0x96, 0x00 }, { 0x97, 0x70 }, + { 0x98, 0x21 }, + }, + }, + { { 600 }, 5360, { 2394, 2444, 2144 }, std::vector<unsigned>{}, { + { 0x16, 0x11 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 }, + { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 }, + { 0x61, 0x20 }, + { 0x70, 0x1f }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x5e }, + { 0x93, 0x00 }, { 0x94, 0x13 }, { 0x95, 0xf0 }, + { 0x96, 0x00 }, { 0x97, 0x8b }, + { 0x98, 0x21 }, + }, + }, + { { 1200 }, 10528, { 4694, 4644, 4094 }, std::vector<unsigned>{}, { + { 0x16, 0x15 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 }, + { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 }, + { 0x61, 0x20 }, + { 0x70, 0x1f }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x5e }, + { 0x93, 0x00 }, { 0x94, 0x27 }, { 0x95, 0xe0 }, + { 0x96, 0x00 }, { 0x97, 0xc0 }, + { 0x98, 0x21 }, + }, + }, + { { 2400 }, 20864, { 8944, 8144, 7994 }, std::vector<unsigned>{}, { + { 0x16, 0x11 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x20, 0x02 }, + { 0x52, 0x04 }, { 0x53, 0x06 }, { 0x54, 0x00 }, { 0x55, 0x02 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x3a }, { 0x5b, 0x00 }, { 0x5c, 0x00 }, + { 0x61, 0x20 }, + { 0x70, 0x00 }, { 0x71, 0x1f }, { 0x72, 0x08 }, { 0x73, 0x0a }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x5e }, + { 0x93, 0x00 }, { 0x94, 0x4f }, { 0x95, 0xc0 }, + { 0x96, 0x01 }, { 0x97, 0x2a }, + { 0x98, 0x21 }, + } + }, + }; + + for (const auto& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + sensor.segment_order = setting.segment_order; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_210; + sensor.optical_res = 2400; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 87; + sensor.dummy_pixel = 16; + sensor.ccd_start_xoffset = 303; + sensor.sensor_pixels = 5168*4; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.gamma = { 2.2f, 2.2f, 2.2f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + SensorExposure exposure; + std::vector<unsigned> segment_order; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 75, 100, 150, 300 }, 2768, { 388, 574, 393 }, std::vector<unsigned>{}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 }, + { 0x96, 0x00 }, { 0x97, 0x9a }, + { 0x98, 0x21 }, + } + }, + { { 600 }, 5360, { 388, 574, 393 }, std::vector<unsigned>{}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0a }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x21 }, + } + }, + { { 1200 }, 10528, { 388, 574, 393 }, {0, 1}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x08 }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x22 }, + }, + }, + { { 2400 }, 20864, { 6839, 8401, 6859 }, {0, 2, 1, 3}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x06 }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x1e }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x12 }, { 0x89, 0x47 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x24 }, + }, + } + }; + + for (const auto& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + sensor.segment_order = setting.segment_order; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_220; + sensor.optical_res = 2400; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 87; + sensor.dummy_pixel = 16; + sensor.ccd_start_xoffset = 303; + sensor.sensor_pixels = 5168*4; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.gamma = { 2.2f, 2.2f, 2.2f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124; + + { + struct CustomSensorSettings { + ResolutionFilter resolutions; + int exposure_lperiod; + SensorExposure exposure; + std::vector<unsigned> segment_order; + GenesysRegisterSettingSet custom_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 75, 100, 150, 300 }, 2768, { 388, 574, 393 }, std::vector<unsigned>{}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0c }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x0a }, { 0x95, 0x18 }, + { 0x96, 0x00 }, { 0x97, 0x9a }, + { 0x98, 0x21 }, + } + }, + { { 600 }, 5360, { 388, 574, 393 }, std::vector<unsigned>{}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x0a }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x21 }, + } + }, + { { 1200 }, 10528, { 388, 574, 393 }, {0, 1}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x08 }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x00 }, { 0x89, 0x65 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x22 }, + } + }, + { { 2400 }, 20864, { 6839, 8401, 6859 }, {0, 2, 1, 3}, { + // { 0x16, 0x00 }, // FIXME: check if default value is different + { 0x16, 0x10 }, { 0x17, 0x04 }, { 0x18, 0x00 }, { 0x19, 0x01 }, + { 0x1a, 0x30 }, { 0x1b, 0x00 }, { 0x1c, 0x02 }, { 0x1d, 0x01 }, { 0x20, 0x06 }, + { 0x52, 0x00 }, { 0x53, 0x02 }, { 0x54, 0x04 }, { 0x55, 0x06 }, + { 0x56, 0x04 }, { 0x57, 0x04 }, { 0x58, 0x04 }, { 0x59, 0x04 }, + { 0x5a, 0x1a }, { 0x5b, 0x00 }, { 0x5c, 0xc0 }, + { 0x61, 0x20 }, + // { 0x70, 0x00 }, // FIXME: check if default value is different + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x0f }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + { 0x88, 0x12 }, { 0x89, 0x47 }, + { 0x93, 0x00 }, { 0x94, 0x14 }, { 0x95, 0x30 }, + { 0x96, 0x00 }, { 0x97, 0xa3 }, + { 0x98, 0x24 }, + }, + } + }; + + for (const auto& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.exposure = setting.exposure; + sensor.segment_order = setting.segment_order; + sensor.custom_regs = setting.custom_regs; + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICPRO_3600; + sensor.optical_res = 1200; + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 87; + sensor.dummy_pixel = 87; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10100; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x0b, 0x00 }, + { 0x16, 0x33 }, + { 0x17, 0x0b }, + { 0x18, 0x11 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0xc4 }, + { 0x52, 0x07 }, // [GB](HI|LOW) not needed for cis + { 0x53, 0x0a }, + { 0x54, 0x0c }, + { 0x55, 0x00 }, + { 0x56, 0x02 }, + { 0x57, 0x06 }, + { 0x58, 0x22 }, + { 0x59, 0x69 }, + { 0x5a, 0x40 }, + { 0x5b, 0x00 }, // TODO: 5b-5e + { 0x5c, 0x00 }, + { 0x5d, 0x00 }, + { 0x5e, 0x02 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7200I; + sensor.optical_res = 7200; + sensor.register_dpihw_override = 1200; + sensor.black_pixels = 88; // TODO + sensor.dummy_pixel = 20; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10200; // TODO + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.stagger_config = StaggerConfig{7200, 4}; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x16, 0x23 }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x21 }, + { 0x1d, 0x84 }, + { 0x52, 0x0a }, + { 0x53, 0x0d }, + { 0x54, 0x10 }, + { 0x55, 0x01 }, + { 0x56, 0x04 }, + { 0x57, 0x07 }, + { 0x58, 0x3a }, + { 0x59, 0x81 }, + { 0x5a, 0xc0 }, + { 0x70, 0x0a }, + { 0x71, 0x0b }, + { 0x72, 0x0c }, + { 0x73, 0x0d }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + { + struct CustomSensorSettings + { + ResolutionFilter resolutions; + ScanMethod method; + unsigned ccd_size_divisor; + unsigned logical_dpihw_override; + unsigned pixel_count_multiplier; + unsigned exposure_lperiod; + unsigned dpiset_override; + GenesysRegisterSettingSet custom_fe_regs; + }; + + CustomSensorSettings custom_settings[] = { + { { 900 }, ScanMethod::TRANSPARENCY, 1, 900, 8, 0x2538, 150, {} }, + { { 1800 }, ScanMethod::TRANSPARENCY, 1, 1800, 4, 0x2538, 300, {} }, + { { 3600 }, ScanMethod::TRANSPARENCY, 1, 3600, 2, 0x2538, 600, {} }, + { { 7200 }, ScanMethod::TRANSPARENCY, 1, 7200, 1, 0x19c8, 1200, { + { 0x02, 0x1b }, + { 0x03, 0x14 }, + { 0x04, 0x20 }, + } + }, + { { 900 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 900, 8, 0x1f54, 150, {} }, + { { 1800 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 1800, 4, 0x1f54, 300, {} }, + { { 3600 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 3600, 2, 0x1f54, 600, {} }, + { { 7200 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 7200, 1, 0x1f54, 1200, {} }, + }; + + for (const CustomSensorSettings& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.method = setting.method; + sensor.ccd_size_divisor = setting.ccd_size_divisor; + sensor.logical_dpihw_override = setting.logical_dpihw_override; + sensor.pixel_count_multiplier = setting.pixel_count_multiplier; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.dpiset_override = setting.dpiset_override; + sensor.custom_fe_regs = setting.custom_fe_regs; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7300; + sensor.optical_res = 7200; + sensor.method = ScanMethod::TRANSPARENCY; + sensor.register_dpihw_override = 1200; + sensor.black_pixels = 88; // TODO + sensor.dummy_pixel = 20; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10200; // TODO + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.exposure_lperiod = 0x2f44; + sensor.stagger_config = StaggerConfig{7200, 4}; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x16, 0x27 }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x84 }, + { 0x52, 0x0a }, + { 0x53, 0x0d }, + { 0x54, 0x0f }, + { 0x55, 0x01 }, + { 0x56, 0x04 }, + { 0x57, 0x07 }, + { 0x58, 0x31 }, + { 0x59, 0x79 }, + { 0x5a, 0xc0 }, + { 0x70, 0x0c }, + { 0x71, 0x0d }, + { 0x72, 0x0e }, + { 0x73, 0x0f }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + { + struct CustomSensorSettings + { + ResolutionFilter resolutions; + unsigned ccd_size_divisor; + unsigned logical_dpihw_override; + unsigned pixel_count_multiplier; + unsigned dpiset_override; + }; + + CustomSensorSettings custom_settings[] = { + { { 900 }, 1, 900, 8, 150 }, + { { 1800 }, 1, 1800, 4, 300 }, + { { 3600 }, 1, 3600, 2, 600 }, + { { 7200 }, 1, 7200, 1, 1200 }, + }; + + for (const CustomSensorSettings& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.ccd_size_divisor = setting.ccd_size_divisor; + sensor.logical_dpihw_override = setting.logical_dpihw_override; + sensor.pixel_count_multiplier = setting.pixel_count_multiplier; + sensor.dpiset_override = setting.dpiset_override; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICFILM_7500I; + sensor.optical_res = 7200; + sensor.register_dpihw_override = 1200; + sensor.black_pixels = 88; // TODO + sensor.dummy_pixel = 20; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10200; // TODO + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 230; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.stagger_config = StaggerConfig{7200, 4}; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x00 }, + { 0x0a, 0x00 }, + { 0x16, 0x27 }, + { 0x17, 0x0c }, + { 0x18, 0x10 }, + { 0x19, 0x2a }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x20 }, + { 0x1d, 0x84 }, + { 0x52, 0x0a }, + { 0x53, 0x0d }, + { 0x54, 0x0f }, + { 0x55, 0x01 }, + { 0x56, 0x04 }, + { 0x57, 0x07 }, + { 0x58, 0x31 }, + { 0x59, 0x79 }, + { 0x5a, 0xc0 }, + { 0x70, 0x0c }, + { 0x71, 0x0d }, + { 0x72, 0x0e }, + { 0x73, 0x0f }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact; + { + struct CustomSensorSettings + { + ResolutionFilter resolutions; + ScanMethod method; + unsigned ccd_size_divisor; + unsigned logical_dpihw_override; + unsigned pixel_count_multiplier; + unsigned exposure_lperiod; + unsigned dpiset_override; + }; + + CustomSensorSettings custom_settings[] = { + { { 900 }, ScanMethod::TRANSPARENCY, 1, 900, 8, 0x2f44, 150 }, + { { 1800 }, ScanMethod::TRANSPARENCY, 1, 1800, 4, 0x2f44, 300 }, + { { 3600 }, ScanMethod::TRANSPARENCY, 1, 3600, 2, 0x2f44, 600 }, + { { 7200 }, ScanMethod::TRANSPARENCY, 1, 7200, 1, 0x2f44, 1200 }, + { { 900 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 900, 8, 0x2af8, 150 }, + { { 1800 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 1800, 4, 0x2af8, 300 }, + { { 3600 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 3600, 2, 0x2af8, 600 }, + { { 7200 }, ScanMethod::TRANSPARENCY_INFRARED, 1, 7200, 1, 0x2af8, 1200 }, + }; + + for (const CustomSensorSettings& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.method = setting.method; + sensor.ccd_size_divisor = setting.ccd_size_divisor; + sensor.logical_dpihw_override = setting.logical_dpihw_override; + sensor.pixel_count_multiplier = setting.pixel_count_multiplier; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.dpiset_override = setting.dpiset_override; + s_sensors->push_back(sensor); + } + } + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_IMG101; + sensor.resolutions = { 75, 100, 150, 300, 600, 1200 }; + sensor.exposure_lperiod = 11000; + sensor.segment_size = 5136; + sensor.segment_order = {0, 1}; + sensor.optical_res = 1200; + sensor.black_pixels = 31; + sensor.dummy_pixel = 31; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10800; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0x0000, 0x0000, 0x0000 }; + sensor.custom_regs = { + { 0x16, 0xbb }, { 0x17, 0x13 }, { 0x18, 0x10 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x06 }, + { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 }, + { 0x56, 0x0a }, { 0x57, 0x00 }, { 0x58, 0x59 }, { 0x59, 0x31 }, { 0x5a, 0x40 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + }; + sensor.gamma = { 1.7f, 1.7f, 1.7f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CCD_PLUSTEK_OPTICBOOK_3800; + sensor.resolutions = { 75, 100, 150, 300, 600, 1200 }; + sensor.exposure_lperiod = 11000; + sensor.optical_res = 1200; + sensor.black_pixels = 31; + sensor.dummy_pixel = 31; + sensor.ccd_start_xoffset = 0; + sensor.sensor_pixels = 10200; + sensor.fau_gain_white_ref = 210; + sensor.gain_white_ref = 200; + sensor.exposure = { 0, 0, 0 }; + sensor.custom_regs = { + { 0x16, 0xbb }, { 0x17, 0x13 }, { 0x18, 0x10 }, { 0x19, 0xff }, + { 0x1a, 0x34 }, { 0x1b, 0x00 }, { 0x1c, 0x20 }, { 0x1d, 0x06 }, + { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x06 }, { 0x55, 0x08 }, + { 0x56, 0x0a }, { 0x57, 0x00 }, { 0x58, 0x59 }, { 0x59, 0x31 }, { 0x5a, 0x40 }, + { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x3c }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x9f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 }, + }; + sensor.gamma = { 1.7f, 1.7f, 1.7f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); + + + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_80; + sensor.optical_res = 1200; // real hardware limit is 2400 + sensor.ccd_size_divisor = 2; + sensor.black_pixels = 20; + sensor.dummy_pixel = 6; + // tuned to give 3*8 multiple startx coordinate during shading calibration + sensor.ccd_start_xoffset = 34; // 14=>3, 20=>2 + // 10400, too wide=>10288 in shading data 10240~ + // 10208 too short for shading, max shading data = 10240 pixels, endpix-startpix=10208 + sensor.sensor_pixels = 10240; + sensor.fau_gain_white_ref = 150; + sensor.gain_white_ref = 150; + // maps to 0x70-0x73 for GL841 + sensor.exposure = { 0x1000, 0x1000, 0x0500 }; + sensor.custom_regs = { + { 0x08, 0x00 }, + { 0x09, 0x05 }, + { 0x0a, 0x07 }, + { 0x0b, 0x09 }, + { 0x16, 0x00 }, + { 0x17, 0x01 }, + { 0x18, 0x00 }, + { 0x19, 0x06 }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x04 }, + { 0x52, 0x03 }, + { 0x53, 0x07 }, + { 0x54, 0x00 }, + { 0x55, 0x00 }, + { 0x56, 0x00 }, + { 0x57, 0x00 }, + { 0x58, 0x29 }, + { 0x59, 0x69 }, + { 0x5a, 0x55 }, + { 0x5b, 0x00 }, + { 0x5c, 0x00 }, + { 0x5d, 0x20 }, + { 0x5e, 0x41 }, + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_register_hwdpi_fun = default_get_logical_hwdpi; + sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi; + sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi; + s_sensors->push_back(sensor); +} + +} // namespace genesys diff --git a/backend/genesys/test_scanner_interface.cpp b/backend/genesys/test_scanner_interface.cpp new file mode 100644 index 0000000..12f726f --- /dev/null +++ b/backend/genesys/test_scanner_interface.cpp @@ -0,0 +1,229 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "test_scanner_interface.h" +#include "device.h" +#include <cstring> + +namespace genesys { + +TestScannerInterface::TestScannerInterface(Genesys_Device* dev) : dev_{dev} +{ + // initialize status registers + if (dev_->model->asic_type == AsicType::GL124) { + write_register(0x101, 0x00); + } else { + write_register(0x41, 0x00); + } + if (dev_->model->asic_type == AsicType::GL841 || + dev_->model->asic_type == AsicType::GL843 || + dev_->model->asic_type == AsicType::GL845 || + dev_->model->asic_type == AsicType::GL846 || + dev_->model->asic_type == AsicType::GL847) + { + write_register(0x40, 0x00); + } + + // initialize other registers that we read on init + if (dev_->model->asic_type == AsicType::GL124) { + write_register(0x33, 0x00); + write_register(0xbd, 0x00); + write_register(0xbe, 0x00); + write_register(0x100, 0x00); + } + + if (dev_->model->asic_type == AsicType::GL845 || + dev_->model->asic_type == AsicType::GL846 || + dev_->model->asic_type == AsicType::GL847) + { + write_register(0xbd, 0x00); + write_register(0xbe, 0x00); + + write_register(0xd0, 0x00); + write_register(0xd1, 0x01); + write_register(0xd2, 0x02); + write_register(0xd3, 0x03); + write_register(0xd4, 0x04); + write_register(0xd5, 0x05); + write_register(0xd6, 0x06); + write_register(0xd7, 0x07); + write_register(0xd8, 0x08); + write_register(0xd9, 0x09); + } +} + +TestScannerInterface::~TestScannerInterface() = default; + +bool TestScannerInterface::is_mock() const +{ + return true; +} + +std::uint8_t TestScannerInterface::read_register(std::uint16_t address) +{ + return cached_regs_.get(address); +} + +void TestScannerInterface::write_register(std::uint16_t address, std::uint8_t value) +{ + cached_regs_.update(address, value); +} + +void TestScannerInterface::write_registers(const Genesys_Register_Set& regs) +{ + cached_regs_.update(regs); +} + + +void TestScannerInterface::write_0x8c(std::uint8_t index, std::uint8_t value) +{ + (void) index; + (void) value; +} + +void TestScannerInterface::bulk_read_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) +{ + (void) addr; + std::memset(data, 0, size); +} + +void TestScannerInterface::bulk_write_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) +{ + (void) addr; + (void) data; + (void) size; +} + +void TestScannerInterface::write_buffer(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) +{ + (void) type; + (void) addr; + (void) data; + (void) size; + (void) flags; +} + +void TestScannerInterface::write_gamma(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) +{ + (void) type; + (void) addr; + (void) data; + (void) size; + (void) flags; +} + +void TestScannerInterface::write_ahb(std::uint32_t addr, std::uint32_t size, std::uint8_t* data) +{ + (void) addr; + (void) size; + (void) data; +} + +std::uint16_t TestScannerInterface::read_fe_register(std::uint8_t address) +{ + return cached_fe_regs_.get(address); +} + +void TestScannerInterface::write_fe_register(std::uint8_t address, std::uint16_t value) +{ + cached_fe_regs_.update(address, value); +} + +IUsbDevice& TestScannerInterface::get_usb_device() +{ + return usb_dev_; +} + +void TestScannerInterface::sleep_us(unsigned microseconds) +{ + (void) microseconds; +} + +void TestScannerInterface::record_slope_table(unsigned table_nr, + const std::vector<std::uint16_t>& steps) +{ + slope_tables_[table_nr] = steps; +} + +std::map<unsigned, std::vector<std::uint16_t>>& TestScannerInterface::recorded_slope_tables() +{ + return slope_tables_; +} + +void TestScannerInterface::record_progress_message(const char* msg) +{ + last_progress_message_ = msg; +} + +const std::string& TestScannerInterface::last_progress_message() const +{ + return last_progress_message_; +} + +void TestScannerInterface::record_key_value(const std::string& key, const std::string& value) +{ + key_values_[key] = value; +} + +std::map<std::string, std::string>& TestScannerInterface::recorded_key_values() +{ + return key_values_; +} + +void TestScannerInterface::test_checkpoint(const std::string& name) +{ + if (checkpoint_callback_) { + checkpoint_callback_(*dev_, *this, name); + } +} + +void TestScannerInterface::set_checkpoint_callback(TestCheckpointCallback callback) +{ + checkpoint_callback_ = callback; +} + +} // namespace genesys diff --git a/backend/genesys/test_scanner_interface.h b/backend/genesys/test_scanner_interface.h new file mode 100644 index 0000000..acf0f6d --- /dev/null +++ b/backend/genesys/test_scanner_interface.h @@ -0,0 +1,122 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_TEST_SCANNER_INTERFACE_H +#define BACKEND_GENESYS_TEST_SCANNER_INTERFACE_H + +#include "scanner_interface.h" +#include "register_cache.h" +#include "test_usb_device.h" +#include "test_settings.h" + +#include <map> + +namespace genesys { + +class TestScannerInterface : public ScannerInterface +{ +public: + TestScannerInterface(Genesys_Device* dev); + + ~TestScannerInterface() override; + + bool is_mock() const override; + + const RegisterCache<std::uint8_t>& cached_regs() const { return cached_regs_; } + const RegisterCache<std::uint16_t>& cached_fe_regs() const { return cached_fe_regs_; } + + std::uint8_t read_register(std::uint16_t address) override; + void write_register(std::uint16_t address, std::uint8_t value) override; + void write_registers(const Genesys_Register_Set& regs) override; + + void write_0x8c(std::uint8_t index, std::uint8_t value) override; + void bulk_read_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) override; + void bulk_write_data(std::uint8_t addr, std::uint8_t* data, std::size_t size) override; + + void write_buffer(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) override; + void write_gamma(std::uint8_t type, std::uint32_t addr, std::uint8_t* data, + std::size_t size, Flags flags) override; + void write_ahb(std::uint32_t addr, std::uint32_t size, std::uint8_t* data) override; + + std::uint16_t read_fe_register(std::uint8_t address) override; + void write_fe_register(std::uint8_t address, std::uint16_t value) override; + + IUsbDevice& get_usb_device() override; + + void sleep_us(unsigned microseconds) override; + + void record_progress_message(const char* msg) override; + + const std::string& last_progress_message() const; + + void record_slope_table(unsigned table_nr, const std::vector<std::uint16_t>& steps) override; + + std::map<unsigned, std::vector<std::uint16_t>>& recorded_slope_tables(); + + void record_key_value(const std::string& key, const std::string& value) override; + + std::map<std::string, std::string>& recorded_key_values(); + + void test_checkpoint(const std::string& name) override; + + void set_checkpoint_callback(TestCheckpointCallback callback); + +private: + Genesys_Device* dev_; + + RegisterCache<std::uint8_t> cached_regs_; + RegisterCache<std::uint16_t> cached_fe_regs_; + TestUsbDevice usb_dev_; + + TestCheckpointCallback checkpoint_callback_; + + std::map<unsigned, std::vector<std::uint16_t>> slope_tables_; + + std::string last_progress_message_; + std::map<std::string, std::string> key_values_; +}; + +} // namespace genesys + +#endif diff --git a/backend/genesys/test_settings.cpp b/backend/genesys/test_settings.cpp new file mode 100644 index 0000000..425f09c --- /dev/null +++ b/backend/genesys/test_settings.cpp @@ -0,0 +1,106 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "test_settings.h" + +namespace genesys { + +namespace { + +bool s_testing_mode = false; +std::uint16_t s_vendor_id = 0; +std::uint16_t s_product_id = 0; +TestCheckpointCallback s_checkpoint_callback; + +} // namespace + +bool is_testing_mode() +{ + return s_testing_mode; +} + +void disable_testing_mode() +{ + s_testing_mode = false; + s_vendor_id = 0; + s_product_id = 0; + +} + +void enable_testing_mode(std::uint16_t vendor_id, std::uint16_t product_id, + TestCheckpointCallback checkpoint_callback) +{ + s_testing_mode = true; + s_vendor_id = vendor_id; + s_product_id = product_id; + s_checkpoint_callback = checkpoint_callback; +} + +std::uint16_t get_testing_vendor_id() +{ + return s_vendor_id; +} + +std::uint16_t get_testing_product_id() +{ + return s_product_id; +} + +std::string get_testing_device_name() +{ + std::string name; + unsigned max_size = 50; + name.resize(max_size); + name.resize(std::snprintf(&name.front(), max_size, "test device:0x%04x:0x%04x", + s_vendor_id, s_product_id)); + return name; +} + +TestCheckpointCallback get_testing_checkpoint_callback() +{ + return s_checkpoint_callback; +} + +} // namespace genesys diff --git a/backend/genesys/test_settings.h b/backend/genesys/test_settings.h new file mode 100644 index 0000000..8ac03e0 --- /dev/null +++ b/backend/genesys/test_settings.h @@ -0,0 +1,70 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_TEST_SETTINGS_H +#define BACKEND_GENESYS_TEST_SETTINGS_H + +#include "scanner_interface.h" +#include "register_cache.h" +#include "test_usb_device.h" +#include <functional> + +namespace genesys { + +using TestCheckpointCallback = std::function<void(const Genesys_Device&, + TestScannerInterface&, + const std::string&)>; + +bool is_testing_mode(); +void disable_testing_mode(); +void enable_testing_mode(std::uint16_t vendor_id, std::uint16_t product_id, + TestCheckpointCallback checkpoint_callback); +std::uint16_t get_testing_vendor_id(); +std::uint16_t get_testing_product_id(); +std::string get_testing_device_name(); +TestCheckpointCallback get_testing_checkpoint_callback(); + + +} // namespace genesys + +#endif // BACKEND_GENESYS_TEST_SETTINGS_H diff --git a/backend/genesys/test_usb_device.cpp b/backend/genesys/test_usb_device.cpp new file mode 100644 index 0000000..de2399e --- /dev/null +++ b/backend/genesys/test_usb_device.cpp @@ -0,0 +1,141 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "test_usb_device.h" +#include "low.h" + +namespace genesys { + +TestUsbDevice::TestUsbDevice(std::uint16_t vendor, std::uint16_t product) : + vendor_{vendor}, + product_{product} +{ +} + +TestUsbDevice::~TestUsbDevice() +{ + if (is_open()) { + DBG(DBG_error, "TestUsbDevice not closed; closing automatically"); + close(); + } +} + +void TestUsbDevice::open(const char* dev_name) +{ + DBG_HELPER(dbg); + + if (is_open()) { + throw SaneException("device already open"); + } + name_ = dev_name; + is_open_ = true; +} + +void TestUsbDevice::clear_halt() +{ + DBG_HELPER(dbg); + assert_is_open(); +} + +void TestUsbDevice::reset() +{ + DBG_HELPER(dbg); + assert_is_open(); +} + +void TestUsbDevice::close() +{ + DBG_HELPER(dbg); + assert_is_open(); + + is_open_ = false; + name_ = ""; +} + +void TestUsbDevice::get_vendor_product(int& vendor, int& product) +{ + DBG_HELPER(dbg); + assert_is_open(); + vendor = vendor_; + product = product_; +} + +void TestUsbDevice::control_msg(int rtype, int reg, int value, int index, int length, + std::uint8_t* data) +{ + (void) reg; + (void) value; + (void) index; + DBG_HELPER(dbg); + assert_is_open(); + if (rtype == REQUEST_TYPE_IN) { + std::memset(data, 0, length); + } +} + +void TestUsbDevice::bulk_read(std::uint8_t* buffer, std::size_t* size) +{ + + DBG_HELPER(dbg); + assert_is_open(); + std::memset(buffer, 0, *size); +} + +void TestUsbDevice::bulk_write(const std::uint8_t* buffer, std::size_t* size) +{ + (void) buffer; + (void) size; + DBG_HELPER(dbg); + assert_is_open(); +} + +void TestUsbDevice::assert_is_open() const +{ + if (!is_open()) { + throw SaneException("device not open"); + } +} + +} // namespace genesys diff --git a/backend/genesys_sanei.h b/backend/genesys/test_usb_device.h index 0e41600..abbd78a 100644 --- a/backend/genesys_sanei.h +++ b/backend/genesys/test_usb_device.h @@ -41,57 +41,45 @@ If you do not wish that, delete this exception notice. */ -#ifndef BACKEND_GENESYS_SANEI_H -#define BACKEND_GENESYS_SANEI_H +#ifndef BACKEND_GENESYS_TEST_USB_DEVICE_H +#define BACKEND_GENESYS_TEST_USB_DEVICE_H -#include "genesys_error.h" -#include "../include/sane/sanei_usb.h" +#include "usb_device.h" -#include <cstdint> -#include <string> +namespace genesys { -class UsbDevice { +class TestUsbDevice : public IUsbDevice { public: - UsbDevice() = default; - UsbDevice(const UsbDevice& other) = delete; - UsbDevice& operator=(const UsbDevice&) = delete; + TestUsbDevice(std::uint16_t vendor, std::uint16_t product); + TestUsbDevice() = default; - UsbDevice(UsbDevice&& other) : - name_(other.name_), - is_open_(other.is_open_), - device_num_(other.device_num_) - { - other.set_not_open(); - } + ~TestUsbDevice() override; - ~UsbDevice(); + bool is_open() const override { return is_open_; } - bool is_open() const { return is_open_; } + const std::string& name() const override { return name_; } - int device_number() const { return device_num_; } + void open(const char* dev_name) override; - const std::string& name() const { return name_; } + void clear_halt() override; + void reset() override; + void close() override; - void open(const char* dev_name); - - void clear_halt(); - void reset(); - void close(); - - void get_vendor_product(int& vendor, int& product); - - void control_msg(int rtype, int reg, int value, int index, int length, uint8_t* data); - void bulk_read(uint8_t* buffer, size_t* size); - void bulk_write(const uint8_t* buffer, size_t* size); + void get_vendor_product(int& vendor, int& product) override; + void control_msg(int rtype, int reg, int value, int index, int length, + std::uint8_t* data) override; + void bulk_read(std::uint8_t* buffer, std::size_t* size) override; + void bulk_write(const std::uint8_t* buffer, std::size_t* size) override; private: - void assert_is_open() const; - void set_not_open(); std::string name_; bool is_open_ = false; - int device_num_ = 0; + std::uint16_t vendor_ = 0; + std::uint16_t product_ = 0; }; -#endif // BACKEND_GENESYS_SANEI_H +} // namespace genesys + +#endif // BACKEND_GENESYS_TEST_USB_DEVICE_H diff --git a/backend/genesys_sanei.cc b/backend/genesys/usb_device.cpp index 5b5b40a..2d02219 100644 --- a/backend/genesys_sanei.cc +++ b/backend/genesys/usb_device.cpp @@ -43,7 +43,11 @@ #define DEBUG_DECLARE_ONLY -#include "genesys_sanei.h" +#include "usb_device.h" + +namespace genesys { + +IUsbDevice::~IUsbDevice() = default; UsbDevice::~UsbDevice() { @@ -104,21 +108,22 @@ void UsbDevice::get_vendor_product(int& vendor, int& product) TIE(sanei_usb_get_vendor_product(device_num_, &vendor, &product)); } -void UsbDevice::control_msg(int rtype, int reg, int value, int index, int length, uint8_t* data) +void UsbDevice::control_msg(int rtype, int reg, int value, int index, int length, + std::uint8_t* data) { DBG_HELPER(dbg); assert_is_open(); TIE(sanei_usb_control_msg(device_num_, rtype, reg, value, index, length, data)); } -void UsbDevice::bulk_read(uint8_t* buffer, size_t* size) +void UsbDevice::bulk_read(std::uint8_t* buffer, std::size_t* size) { DBG_HELPER(dbg); assert_is_open(); TIE(sanei_usb_read_bulk(device_num_, buffer, size)); } -void UsbDevice::bulk_write(const uint8_t* buffer, size_t* size) +void UsbDevice::bulk_write(const std::uint8_t* buffer, std::size_t* size) { DBG_HELPER(dbg); assert_is_open(); @@ -138,3 +143,5 @@ void UsbDevice::set_not_open() is_open_ = false; name_ = ""; } + +} // namespace genesys diff --git a/backend/genesys/usb_device.h b/backend/genesys/usb_device.h new file mode 100644 index 0000000..265c57c --- /dev/null +++ b/backend/genesys/usb_device.h @@ -0,0 +1,118 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_USB_DEVICE_H +#define BACKEND_GENESYS_USB_DEVICE_H + +#include "error.h" +#include "../include/sane/sanei_usb.h" + +#include <cstdint> +#include <string> + +namespace genesys { + +class IUsbDevice { +public: + IUsbDevice() = default; + + IUsbDevice(const IUsbDevice& other) = delete; + IUsbDevice& operator=(const IUsbDevice&) = delete; + + virtual ~IUsbDevice(); + + virtual bool is_open() const = 0; + + virtual const std::string& name() const = 0; + + virtual void open(const char* dev_name) = 0; + + virtual void clear_halt() = 0; + virtual void reset() = 0; + virtual void close() = 0; + + virtual void get_vendor_product(int& vendor, int& product) = 0; + + virtual void control_msg(int rtype, int reg, int value, int index, int length, + std::uint8_t* data) = 0; + virtual void bulk_read(std::uint8_t* buffer, std::size_t* size) = 0; + virtual void bulk_write(const std::uint8_t* buffer, std::size_t* size) = 0; + +}; + +class UsbDevice : public IUsbDevice { +public: + UsbDevice() = default; + + ~UsbDevice() override; + + bool is_open() const override { return is_open_; } + + const std::string& name() const override { return name_; } + + void open(const char* dev_name) override; + + void clear_halt() override; + void reset() override; + void close() override; + + void get_vendor_product(int& vendor, int& product) override; + + void control_msg(int rtype, int reg, int value, int index, int length, + std::uint8_t* data) override; + void bulk_read(std::uint8_t* buffer, std::size_t* size) override; + void bulk_write(const std::uint8_t* buffer, std::size_t* size) override; + +private: + + void assert_is_open() const; + void set_not_open(); + + std::string name_; + bool is_open_ = false; + int device_num_ = 0; +}; + +} // namespace genesys + +#endif // BACKEND_GENESYS_USB_DEVICE_H diff --git a/backend/genesys/utilities.h b/backend/genesys/utilities.h new file mode 100644 index 0000000..1e268b5 --- /dev/null +++ b/backend/genesys/utilities.h @@ -0,0 +1,180 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. +*/ + +#ifndef BACKEND_GENESYS_UTILITIES_H +#define BACKEND_GENESYS_UTILITIES_H + +#include "error.h" +#include <algorithm> +#include <iostream> +#include <sstream> +#include <vector> + +namespace genesys { + +template<class T> +void compute_array_percentile_approx(T* result, const T* data, + std::size_t line_count, std::size_t elements_per_line, + float percentile) +{ + if (line_count == 0) { + throw SaneException("invalid line count"); + } + + if (line_count == 1) { + std::copy(data, data + elements_per_line, result); + return; + } + + std::vector<T> column_elems; + column_elems.resize(line_count, 0); + + std::size_t select_elem = std::min(static_cast<std::size_t>(line_count * percentile), + line_count - 1); + + auto select_it = column_elems.begin() + select_elem; + + for (std::size_t ix = 0; ix < elements_per_line; ++ix) { + for (std::size_t iy = 0; iy < line_count; ++iy) { + column_elems[iy] = data[iy * elements_per_line + ix]; + } + + std::nth_element(column_elems.begin(), select_it, column_elems.end()); + + *result++ = *select_it; + } +} + +template<class Char, class Traits> +class BasicStreamStateSaver +{ +public: + explicit BasicStreamStateSaver(std::basic_ios<Char, Traits>& stream) : + stream_{stream} + { + flags_ = stream_.flags(); + width_ = stream_.width(); + precision_ = stream_.precision(); + fill_ = stream_.fill(); + } + + ~BasicStreamStateSaver() + { + stream_.flags(flags_); + stream_.width(width_); + stream_.precision(precision_); + stream_.fill(fill_); + } + + BasicStreamStateSaver(const BasicStreamStateSaver&) = delete; + BasicStreamStateSaver& operator=(const BasicStreamStateSaver&) = delete; + +private: + std::basic_ios<Char, Traits>& stream_; + std::ios_base::fmtflags flags_; + std::streamsize width_ = 0; + std::streamsize precision_ = 0; + Char fill_ = ' '; +}; + +using StreamStateSaver = BasicStreamStateSaver<char, std::char_traits<char>>; + +template<class T> +std::string format_indent_braced_list(unsigned indent, const T& x) +{ + std::string indent_str(indent, ' '); + std::ostringstream out; + out << x; + auto formatted_str = out.str(); + if (formatted_str.empty()) { + return formatted_str; + } + + std::string out_str; + for (std::size_t i = 0; i < formatted_str.size(); ++i) { + out_str += formatted_str[i]; + + if (formatted_str[i] == '\n' && + i < formatted_str.size() - 1 && + formatted_str[i + 1] != '\n') + { + out_str += indent_str; + } + } + return out_str; +} + +template<class T> +std::string format_vector_unsigned(unsigned indent, const std::vector<T>& arg) +{ + std::ostringstream out; + std::string indent_str(indent, ' '); + + out << "std::vector<T>{ "; + for (const auto& el : arg) { + out << indent_str << static_cast<unsigned>(el) << "\n"; + } + out << "}"; + return out.str(); +} + +template<class T> +std::string format_vector_indent_braced(unsigned indent, const char* type, + const std::vector<T>& arg) +{ + if (arg.empty()) { + return "{}"; + } + std::string indent_str(indent, ' '); + std::stringstream out; + out << "std::vector<" << type << ">{\n"; + for (const auto& item : arg) { + out << indent_str << format_indent_braced_list(indent, item) << '\n'; + } + out << "}"; + return out.str(); +} + +} // namespace genesys + +#endif // BACKEND_GENESYS_UTILITIES_H diff --git a/backend/genesys_conv.cc b/backend/genesys_conv.cc deleted file mode 100644 index 06fd4e0..0000000 --- a/backend/genesys_conv.cc +++ /dev/null @@ -1,474 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2005, 2006 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -/* - * Conversion filters for genesys backend - */ - - -/*8 bit*/ -#define SINGLE_BYTE -#define BYTES_PER_COMPONENT 1 -#define COMPONENT_TYPE uint8_t - -#define FUNC_NAME(f) f ## _8 - -#include "genesys_conv_hlp.cc" - -#undef FUNC_NAME - -#undef COMPONENT_TYPE -#undef BYTES_PER_COMPONENT -#undef SINGLE_BYTE - -/*16 bit*/ -#define DOUBLE_BYTE -#define BYTES_PER_COMPONENT 2 -#define COMPONENT_TYPE uint16_t - -#define FUNC_NAME(f) f ## _16 - -#include "genesys_conv_hlp.cc" - -#undef FUNC_NAME - -#undef COMPONENT_TYPE -#undef BYTES_PER_COMPONENT -#undef DOUBLE_BYTE - -static SANE_Status -genesys_reverse_bits( - uint8_t *src_data, - uint8_t *dst_data, - size_t bytes) -{ - size_t i; - for(i = 0; i < bytes; i++) { - *dst_data++ = ~ *src_data++; - } - return SANE_STATUS_GOOD; -} - -/** - * uses the threshold/threshold_curve to control software binarization - * This code was taken from the epjistsu backend by m. allan noah - * @param dev device set up for the scan - * @param src pointer to raw data - * @param dst pointer where to store result - * @param width width of the processed line - * */ -static SANE_Status -binarize_line(Genesys_Device * dev, uint8_t *src, uint8_t *dst, int width) -{ - int j, windowX, sum = 0; - int thresh; - int offset, addCol, dropCol; - unsigned char mask; - - int x; - uint8_t min, max; - - /* normalize line */ - min = 255; - max = 0; - for (x = 0; x < width; x++) - { - if (src[x] > max) - { - max = src[x]; - } - if (src[x] < min) - { - min = src[x]; - } - } - - /* safeguard against dark or white areas */ - if(min>80) - min=0; - if(max<80) - max=255; - for (x = 0; x < width; x++) - { - src[x] = ((src[x] - min) * 255) / (max - min); - } - - /* ~1mm works best, but the window needs to have odd # of pixels */ - windowX = (6 * dev->settings.xres) / 150; - if (!(windowX % 2)) - windowX++; - - /* second, prefill the sliding sum */ - for (j = 0; j < windowX; j++) - sum += src[j]; - - /* third, walk the input buffer, update the sliding sum, */ - /* determine threshold, output bits */ - for (j = 0; j < width; j++) - { - /* output image location */ - offset = j % 8; - mask = 0x80 >> offset; - thresh = dev->settings.threshold; - - /* move sum/update threshold only if there is a curve */ - if (dev->settings.threshold_curve) - { - addCol = j + windowX / 2; - dropCol = addCol - windowX; - - if (dropCol >= 0 && addCol < width) - { - sum -= src[dropCol]; - sum += src[addCol]; - } - thresh = dev->lineart_lut[sum / windowX]; - } - - /* use average to lookup threshold */ - if (src[j] > thresh) - *dst &= ~mask; /* white */ - else - *dst |= mask; /* black */ - - if (offset == 7) - dst++; - } - - return SANE_STATUS_GOOD; -} - -/** - * software lineart using data from a 8 bit gray scan. We assume true gray - * or monochrome scan as input. - */ -static SANE_Status -genesys_gray_lineart( - Genesys_Device *dev, - uint8_t *src_data, - uint8_t *dst_data, - size_t pixels, - size_t lines, - uint8_t threshold) -{ - size_t y; - - DBG(DBG_io2, "%s: converting %lu lines of %lu pixels\n", __func__, (unsigned long)lines, - (unsigned long)pixels); - DBG(DBG_io2, "%s: threshold=%d\n", __func__, threshold); - - for (y = 0; y < lines; y++) - { - binarize_line (dev, src_data + y * pixels, dst_data, pixels); - dst_data += pixels / 8; - } - return SANE_STATUS_GOOD; -} - -/** @brief shrink or grow scanned data to fit the final scan size - * This function shrinks the scanned data it the required resolution is lower than the hardware one, - * or grows it in case it is the opposite like when motor resolution is higher than - * sensor's one. - */ -static SANE_Status -genesys_shrink_lines_1 ( - uint8_t *src_data, - uint8_t *dst_data, - unsigned int lines, - unsigned int src_pixels, - unsigned int dst_pixels, - unsigned int channels) -{ - unsigned int dst_x, src_x, y, c, cnt; - unsigned int avg[3], val; - uint8_t *src = (uint8_t *) src_data; - uint8_t *dst = (uint8_t *) dst_data; - - /* choose between case where me must reduce or grow the scanned data */ - if (src_pixels > dst_pixels) - { - /* shrink data */ - /* TODO action must be taken at bit level, no bytes */ - src_pixels /= 8; - dst_pixels /= 8; - /*take first _byte_ */ - for (y = 0; y < lines; y++) - { - cnt = src_pixels / 2; - src_x = 0; - for (dst_x = 0; dst_x < dst_pixels; dst_x++) - { - while (cnt < src_pixels && src_x < src_pixels) - { - cnt += dst_pixels; - - for (c = 0; c < channels; c++) - avg[c] = *src++; - src_x++; - } - cnt -= src_pixels; - - for (c = 0; c < channels; c++) - *dst++ = avg[c]; - } - } - } - else - { - /* common case where y res is double x res */ - for (y = 0; y < lines; y++) - { - if (2 * src_pixels == dst_pixels) - { - /* double and interleave on line */ - for (c = 0; c < src_pixels/8; c++) - { - /* first 4 bits */ - val = 0; - val |= (*src & 0x80) >> 0; /* X___ ____ --> X___ ____ */ - val |= (*src & 0x80) >> 1; /* X___ ____ --> _X__ ____ */ - val |= (*src & 0x40) >> 1; /* _X__ ____ --> __X_ ____ */ - val |= (*src & 0x40) >> 2; /* _X__ ____ --> ___X ____ */ - val |= (*src & 0x20) >> 2; /* __X_ ____ --> ____ X___ */ - val |= (*src & 0x20) >> 3; /* __X_ ____ --> ____ _X__ */ - val |= (*src & 0x10) >> 3; /* ___X ____ --> ____ __X_ */ - val |= (*src & 0x10) >> 4; /* ___X ____ --> ____ ___X */ - *dst = val; - dst++; - - /* last for bits */ - val = 0; - val |= (*src & 0x08) << 4; /* ____ X___ --> X___ ____ */ - val |= (*src & 0x08) << 3; /* ____ X___ --> _X__ ____ */ - val |= (*src & 0x04) << 3; /* ____ _X__ --> __X_ ____ */ - val |= (*src & 0x04) << 2; /* ____ _X__ --> ___X ____ */ - val |= (*src & 0x02) << 2; /* ____ __X_ --> ____ X___ */ - val |= (*src & 0x02) << 1; /* ____ __X_ --> ____ _X__ */ - val |= (*src & 0x01) << 1; /* ____ ___X --> ____ __X_ */ - val |= (*src & 0x01) << 0; /* ____ ___X --> ____ ___X */ - *dst = val; - dst++; - src++; - } - } - else - { - /* TODO: since depth is 1, we must interpolate bit within bytes */ - DBG (DBG_warn, "%s: inaccurate bit expansion!\n", __func__); - cnt = dst_pixels / 2; - dst_x = 0; - for (src_x = 0; src_x < src_pixels; src_x++) - { - for (c = 0; c < channels; c++) - avg[c] = *src++; - while (cnt < dst_pixels && dst_x < dst_pixels) - { - cnt += src_pixels; - for (c = 0; c < channels; c++) - *dst++ = avg[c]; - dst_x++; - } - cnt -= dst_pixels; - } - } - } - } - - return SANE_STATUS_GOOD; -} - - -/** Look in image for likely left/right/bottom paper edges, then crop image. - * Since failing to crop isn't fatal, we always return SANE_STATUS_GOOD . - */ -static SANE_Status -genesys_crop(Genesys_Scanner *s) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Device *dev = s->dev; - int top = 0; - int bottom = 0; - int left = 0; - int right = 0; - - DBG (DBG_proc, "%s: start\n", __func__); - - /* first find edges if any */ - status = sanei_magic_findEdges (&s->params, - dev->img_buffer.data(), - dev->settings.xres, - dev->settings.yres, - &top, - &bottom, - &left, - &right); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_info, "%s: bad or no edges, bailing\n", __func__); - return SANE_STATUS_GOOD; - } - DBG (DBG_io, "%s: t:%d b:%d l:%d r:%d\n", __func__, top, bottom, left, - right); - - /* now crop the image */ - status = - sanei_magic_crop (&(s->params), dev->img_buffer.data(), top, bottom, left, right); - if (status) - { - DBG (DBG_warn, "%s: failed to crop\n", __func__); - return SANE_STATUS_GOOD; - } - - /* update counters to new image size */ - dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines; - - DBG (DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; -} - -/** Look in image for likely upper and left paper edges, then rotate - * image so that upper left corner of paper is upper left of image. - * @return since failure doens't prevent scanning, we always return - * SANE_STATUS_GOOD - */ -static SANE_Status -genesys_deskew(Genesys_Scanner *s, const Genesys_Sensor& sensor) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Device *dev = s->dev; - - int x = 0, y = 0, bg; - double slope = 0; - - DBG (DBG_proc, "%s: start\n", __func__); - - bg=0; - if(s->params.format==SANE_FRAME_GRAY && s->params.depth == 1) - { - bg=0xff; - } - status = sanei_magic_findSkew (&s->params, - dev->img_buffer.data(), - sensor.optical_res, - sensor.optical_res, - &x, - &y, - &slope); - if (status!=SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: bad findSkew, bailing\n", __func__); - return SANE_STATUS_GOOD; - } - DBG(DBG_info, "%s: slope=%f => %f\n",__func__,slope, (slope/M_PI_2)*90); - /* rotate image slope is in [-PI/2,PI/2] - * positive values rotate trigonometric direction wise */ - status = sanei_magic_rotate (&s->params, - dev->img_buffer.data(), - x, - y, - slope, - bg); - if (status!=SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: rotate error: %s", __func__, sane_strstatus(status)); - } - - DBG (DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; -} - -/** remove lone dots - * @return since failure doens't prevent scanning, we always return - * SANE_STATUS_GOOD - */ -static SANE_Status -genesys_despeck(Genesys_Scanner *s) -{ - if(sanei_magic_despeck(&s->params, - s->dev->img_buffer.data(), - s->despeck)!=SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: bad despeck, bailing\n",__func__); - } - - return SANE_STATUS_GOOD; -} - -/** Look if image needs rotation and apply it - * */ -static SANE_Status -genesys_derotate (Genesys_Scanner * s) -{ - SANE_Status status = SANE_STATUS_GOOD; - int angle = 0; - - DBGSTART; - status = sanei_magic_findTurn (&s->params, - s->dev->img_buffer.data(), - s->resolution, - s->resolution, - &angle); - - if (status) - { - DBG (DBG_warn, "%s: failed : %d\n", __func__, status); - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - /* apply rotation angle found */ - status = sanei_magic_turn (&s->params, s->dev->img_buffer.data(), angle); - if (status) - { - DBG (DBG_warn, "%s: failed : %d\n", __func__, status); - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - /* update counters to new image size */ - s->dev->total_bytes_to_read = s->params.bytes_per_line * s->params.lines; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_conv_hlp.cc b/backend/genesys_conv_hlp.cc deleted file mode 100644 index 7663a87..0000000 --- a/backend/genesys_conv_hlp.cc +++ /dev/null @@ -1,345 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2005 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -/* - * Conversion filters for genesys backend - */ - -static SANE_Status -FUNC_NAME(genesys_reorder_components_cis) ( - uint8_t *src_data, - uint8_t *dst_data, - unsigned int lines, - unsigned int pixels) -{ - unsigned int x, y; - uint8_t *src[3]; - uint8_t *dst = dst_data; - unsigned int rest = pixels * 2 * BYTES_PER_COMPONENT; - - src[0] = src_data + pixels * BYTES_PER_COMPONENT * 0; - src[1] = src_data + pixels * BYTES_PER_COMPONENT * 1; - src[2] = src_data + pixels * BYTES_PER_COMPONENT * 2; - - for(y = 0; y < lines; y++) { - for(x = 0; x < pixels; x++) { - -#ifndef DOUBLE_BYTE - *dst++ = *src[0]++; - *dst++ = *src[1]++; - *dst++ = *src[2]++; -#else -# ifndef WORDS_BIGENDIAN - *dst++ = *src[0]++; - *dst++ = *src[0]++; - *dst++ = *src[1]++; - *dst++ = *src[1]++; - *dst++ = *src[2]++; - *dst++ = *src[2]++; -# else - *dst++ = src[0][1]; - *dst++ = src[0][0]; - *dst++ = src[1][1]; - *dst++ = src[1][0]; - *dst++ = src[2][1]; - *dst++ = src[2][0]; - src[0] += 2; - src[1] += 2; - src[2] += 2; -# endif -#endif - } - - src[0] += rest; - src[1] += rest; - src[2] += rest; - } - return SANE_STATUS_GOOD; -} - -static SANE_Status -FUNC_NAME(genesys_reorder_components_cis_bgr) ( - uint8_t *src_data, - uint8_t *dst_data, - unsigned int lines, - unsigned int pixels) -{ - unsigned int x, y; - uint8_t *src[3]; - uint8_t *dst = dst_data; - unsigned int rest = pixels * 2 * BYTES_PER_COMPONENT; - - src[0] = src_data + pixels * BYTES_PER_COMPONENT * 0; - src[1] = src_data + pixels * BYTES_PER_COMPONENT * 1; - src[2] = src_data + pixels * BYTES_PER_COMPONENT * 2; - - for(y = 0; y < lines; y++) { - for(x = 0; x < pixels; x++) { -#ifndef DOUBLE_BYTE - *dst++ = *src[2]++; - *dst++ = *src[1]++; - *dst++ = *src[0]++; -#else -# ifndef WORDS_BIGENDIAN - *dst++ = *src[2]++; - *dst++ = *src[2]++; - *dst++ = *src[1]++; - *dst++ = *src[1]++; - *dst++ = *src[0]++; - *dst++ = *src[0]++; -# else - *dst++ = src[2][1]; - *dst++ = src[2][0]; - *dst++ = src[1][1]; - *dst++ = src[1][0]; - *dst++ = src[0][1]; - *dst++ = src[0][0]; - src[0] += 2; - src[1] += 2; - src[2] += 2; -# endif -#endif - } - - src[0] += rest; - src[1] += rest; - src[2] += rest; - } - return SANE_STATUS_GOOD; -} - -static SANE_Status -FUNC_NAME(genesys_reorder_components_bgr) ( - uint8_t *src_data, - uint8_t *dst_data, - unsigned int lines, - unsigned int pixels) -{ - unsigned int c; - uint8_t *src = src_data; - uint8_t *dst = dst_data; - - for(c = 0; c < lines * pixels; c++) { - -#ifndef DOUBLE_BYTE - *dst++ = src[2]; - *dst++ = src[1]; - *dst++ = src[0]; - src += 3; -#else -# ifndef WORDS_BIGENDIAN - *dst++ = src[2 * 2 + 0]; - *dst++ = src[2 * 2 + 1]; - *dst++ = src[1 * 2 + 0]; - *dst++ = src[1 * 2 + 1]; - *dst++ = src[0 * 2 + 0]; - *dst++ = src[0 * 2 + 1]; -# else - *dst++ = src[2 * 2 + 1]; - *dst++ = src[2 * 2 + 0]; - *dst++ = src[1 * 2 + 1]; - *dst++ = src[1 * 2 + 0]; - *dst++ = src[0 * 2 + 1]; - *dst++ = src[0 * 2 + 0]; -# endif - src += 3 * 2; -#endif - - } - return SANE_STATUS_GOOD; -} - -#if defined(DOUBLE_BYTE) && defined(WORDS_BIGENDIAN) -static SANE_Status -FUNC_NAME(genesys_reorder_components_endian) ( - uint8_t *src_data, - uint8_t *dst_data, - unsigned int lines, - unsigned int pixels, - unsigned int channels) -{ - unsigned int c; - uint8_t *src = src_data; - uint8_t *dst = dst_data; - - for(c = 0; c < lines * pixels * channels; c++) { - *dst++ = src[1]; - *dst++ = src[0]; - src += 2; - } -return SANE_STATUS_GOOD; -} -#endif /*defined(DOUBLE_BYTE) && defined(WORDS_BIGENDIAN)*/ - - -static SANE_Status -FUNC_NAME(genesys_reverse_ccd) ( - uint8_t *src_data, - uint8_t *dst_data, - unsigned int lines, - unsigned int components_per_line, - unsigned int *ccd_shift, - unsigned int component_count) -{ - unsigned int x, y, c; - COMPONENT_TYPE *src = (COMPONENT_TYPE *)src_data; - COMPONENT_TYPE *dst = (COMPONENT_TYPE *)dst_data; - COMPONENT_TYPE *srcp; - COMPONENT_TYPE *dstp; - unsigned int pitch = components_per_line; - unsigned int ccd_shift_pitch[12]; - unsigned int *csp; - - for (c = 0; c < component_count; c++) - ccd_shift_pitch[c] = ccd_shift[c] * pitch; - -/* - * cache efficiency: - we are processing a single line component_count times, so it should fit - into the cpu cache for maximum efficiency. our lines take - maximum 252kb(3 channels, 16bit, 2400dpi, full gl841 shading range) - * instruction efficiency: - the innermost loop runs long and consists of 3 adds, one compare, - 2 derefences. - */ -/* - for (y = 0; y < lines; y++) { - csp = ccd_shift_pitch; - for (c = 0; c < component_count; c++) { - srcp = src + c + *csp++; - dstp = dst + c; - for (x = 0; x < pitch; x += component_count) { - *dstp = *srcp; - srcp += component_count; - dstp += component_count; - } - } - dst += pitch; - src += pitch; - } - */ -/* - * cache efficency: - here only line_dist_pitch needs to stay in cache. 12*4 = 48 bytes - * instruction efficiency: - we have a short running inner loop, consisting of 4 incs, 2 compare, 1 add, - 2 dereference and 1 indexed dereference. - the enclosing loop is long running, consisting of 1 add, 1 compare. - */ - srcp = src; - dstp = dst; - for (y = 0; y < lines; y++) { - for (x = 0; x < pitch; x += component_count) { - csp = ccd_shift_pitch; - for (c = 0; c < component_count && c + x < pitch; c++) { - *dstp = srcp[*csp++]; - dstp++; - srcp++; - } - } - } - return SANE_STATUS_GOOD; -} - -static SANE_Status -FUNC_NAME(genesys_shrink_lines) ( - uint8_t *src_data, - uint8_t *dst_data, - unsigned int lines, - unsigned int src_pixels, - unsigned int dst_pixels, - unsigned int channels) -{ - unsigned int dst_x, src_x, y, c, cnt; - unsigned int avg[3]; - unsigned int count; - COMPONENT_TYPE *src = (COMPONENT_TYPE *)src_data; - COMPONENT_TYPE *dst = (COMPONENT_TYPE *)dst_data; - - if (src_pixels > dst_pixels) { -/*average*/ - for (c = 0; c < channels; c++) - avg[c] = 0; - for(y = 0; y < lines; y++) { - cnt = src_pixels / 2; - src_x = 0; - for (dst_x = 0; dst_x < dst_pixels; dst_x++) { - count = 0; - while (cnt < src_pixels && src_x < src_pixels) { - cnt += dst_pixels; - - for (c = 0; c < channels; c++) - avg[c] += *src++; - src_x++; - count++; - } - cnt -= src_pixels; - - for (c = 0; c < channels; c++) { - *dst++ = avg[c] / count; - avg[c] = 0; - } - } - } - } else { -/*interpolate. copy pixels*/ - for(y = 0; y < lines; y++) { - cnt = dst_pixels / 2; - dst_x = 0; - for (src_x = 0; src_x < src_pixels; src_x++) { - for (c = 0; c < channels; c++) - avg[c] = *src++; - while ((cnt < dst_pixels || src_x + 1 == src_pixels) && - dst_x < dst_pixels) { - cnt += src_pixels; - - for (c = 0; c < channels; c++) - *dst++ = avg[c]; - dst_x++; - } - cnt -= dst_pixels; - } - } - } - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_devices.cc b/backend/genesys_devices.cc deleted file mode 100644 index b4ae5ca..0000000 --- a/backend/genesys_devices.cc +++ /dev/null @@ -1,5165 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2003 Oliver Rauch - Copyright (C) 2003-2005 Henning Meier-Geinitz <henning@meier-geinitz.de> - Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de> - Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> - Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - Copyright (C) 2007 Luke <iceyfor@gmail.com> - Copyright (C) 2010 Jack McGill <jmcgill85258@yahoo.com> - Copyright (C) 2010 Andrey Loginov <avloginov@gmail.com>, - xerox travelscan device entry - Copyright (C) 2010 Chris Berry <s0457957@sms.ed.ac.uk> and Michael Rickmann <mrickma@gwdg.de> - for Plustek Opticbook 3600 support - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -/* ------------------------------------------------------------------------ */ -/* Some setup DAC and CCD tables */ -/* ------------------------------------------------------------------------ */ - -#include "genesys_low.h" - -StaticInit<std::vector<Genesys_Frontend>> s_frontends; - -void genesys_init_frontend_tables() -{ - s_frontends.init(); - - GenesysFrontendLayout wolfson_layout; - wolfson_layout.offset_addr = { 0x20, 0x21, 0x22 }; - wolfson_layout.gain_addr = { 0x28, 0x29, 0x2a }; - - Genesys_Frontend fe; - fe.fe_id = DAC_WOLFSON_UMAX; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x03 }, - { 0x02, 0x05 }, - { 0x03, 0x11 }, - { 0x20, 0x80 }, - { 0x21, 0x80 }, - { 0x22, 0x80 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x02 }, - { 0x29, 0x02 }, - { 0x2a, 0x02 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_ST12; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x03 }, - { 0x02, 0x05 }, - { 0x03, 0x03 }, - { 0x20, 0xc8 }, - { 0x21, 0xc8 }, - { 0x22, 0xc8 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x04 }, - { 0x29, 0x04 }, - { 0x2a, 0x04 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_ST24; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x03 }, - { 0x02, 0x05 }, - { 0x03, 0x21 }, - { 0x20, 0xc8 }, - { 0x21, 0xc8 }, - { 0x22, 0xc8 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x06 }, - { 0x29, 0x06 }, - { 0x2a, 0x06 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_5345; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x03 }, - { 0x02, 0x05 }, - { 0x03, 0x12 }, - { 0x20, 0xb8 }, - { 0x21, 0xb8 }, - { 0x22, 0xb8 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x04 }, - { 0x29, 0x04 }, - { 0x2a, 0x04 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - // reg3=0x02 for 50-600 dpi, 0x32 (0x12 also works well) at 1200 - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_HP2400; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x03 }, - { 0x02, 0x05 }, - { 0x03, 0x02 }, - { 0x20, 0xb4 }, - { 0x21, 0xb6 }, - { 0x22, 0xbc }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x06 }, - { 0x29, 0x09 }, - { 0x2a, 0x08 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_HP2300; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x03 }, - { 0x02, 0x04 }, - { 0x03, 0x02 }, - { 0x20, 0xbe }, - { 0x21, 0xbe }, - { 0x22, 0xbe }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x04 }, - { 0x29, 0x04 }, - { 0x2a, 0x04 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_CANONLIDE35; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x3d }, - { 0x02, 0x08 }, - { 0x03, 0x00 }, - { 0x20, 0xe1 }, - { 0x21, 0xe1 }, - { 0x22, 0xe1 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x93 }, - { 0x29, 0x93 }, - { 0x2a, 0x93 }, - }; - fe.reg2 = {0x00, 0x19, 0x06}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_AD_XP200; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x58 }, - { 0x01, 0x80 }, - { 0x02, 0x00 }, - { 0x03, 0x00 }, - { 0x20, 0x09 }, - { 0x21, 0x09 }, - { 0x22, 0x09 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x09 }, - { 0x29, 0x09 }, - { 0x2a, 0x09 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_XP300; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x35 }, - { 0x02, 0x20 }, - { 0x03, 0x14 }, - { 0x20, 0xe1 }, - { 0x21, 0xe1 }, - { 0x22, 0xe1 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x93 }, - { 0x29, 0x93 }, - { 0x2a, 0x93 }, - }; - fe.reg2 = {0x07, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_HP3670; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x03 }, - { 0x02, 0x05 }, - { 0x03, 0x32 }, - { 0x20, 0xba }, - { 0x21, 0xb8 }, - { 0x22, 0xb8 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x06 }, - { 0x29, 0x05 }, - { 0x2a, 0x04 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_WOLFSON_DSM600; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x35 }, - { 0x02, 0x20 }, - { 0x03, 0x14 }, - { 0x20, 0x85 }, - { 0x21, 0x85 }, - { 0x22, 0x85 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0xa0 }, - { 0x29, 0xa0 }, - { 0x2a, 0xa0 }, - }; - fe.reg2 = {0x07, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_CANONLIDE200; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x9d }, - { 0x01, 0x91 }, - { 0x02, 0x00 }, - { 0x03, 0x00 }, - { 0x20, 0x00 }, - { 0x21, 0x3f }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x32 }, - { 0x29, 0x04 }, - { 0x2a, 0x00 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_CANONLIDE700; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x9d }, - { 0x01, 0x9e }, - { 0x02, 0x00 }, - { 0x03, 0x00 }, - { 0x20, 0x00 }, - { 0x21, 0x3f }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x2f }, - { 0x29, 0x04 }, - { 0x2a, 0x00 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_KVSS080; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x23 }, - { 0x02, 0x24 }, - { 0x03, 0x0f }, - { 0x20, 0x80 }, - { 0x21, 0x80 }, - { 0x22, 0x80 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x4b }, - { 0x29, 0x4b }, - { 0x2a, 0x4b }, - }; - fe.reg2 = {0x00,0x00,0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_G4050; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x23 }, - { 0x02, 0x24 }, - { 0x03, 0x1f }, - { 0x20, 0x45 }, - { 0x21, 0x45 }, - { 0x22, 0x45 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x4b }, - { 0x29, 0x4b }, - { 0x2a, 0x4b }, - }; - fe.reg2 = {0x00,0x00,0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_CANONLIDE110; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x80 }, - { 0x01, 0x8a }, - { 0x02, 0x23 }, - { 0x03, 0x4c }, - { 0x20, 0x00 }, - { 0x21, 0x00 }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, - { 0x25, 0xca }, - { 0x26, 0x94 }, - { 0x28, 0x00 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - /** @brief GL124 special case - * for GL124 based scanners, this struct is "abused" - * in fact the fields are map like below to AFE registers - * (from Texas Instrument or alike ?) - */ - fe = Genesys_Frontend(); - fe.fe_id = DAC_CANONLIDE120; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x80 }, - { 0x01, 0xa3 }, - { 0x02, 0x2b }, - { 0x03, 0x4c }, - { 0x20, 0x00 }, - { 0x21, 0x00 }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, // actual address 0x05 - { 0x25, 0xca }, // actual address 0x06 - { 0x26, 0x95 }, // actual address 0x07 - { 0x28, 0x00 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_PLUSTEK_3600; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x70 }, - { 0x01, 0x80 }, - { 0x02, 0x00 }, - { 0x03, 0x00 }, - { 0x20, 0x00 }, - { 0x21, 0x00 }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x3f }, - { 0x29, 0x3d }, - { 0x2a, 0x3d }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_CS8400F; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x23 }, - { 0x02, 0x24 }, - { 0x03, 0x0f }, - { 0x20, 0x60 }, - { 0x21, 0x5c }, - { 0x22, 0x6c }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x8a }, - { 0x29, 0x9f }, - { 0x2a, 0xc2 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_CS8600F; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x00 }, - { 0x01, 0x23 }, - { 0x02, 0x24 }, - { 0x03, 0x2f }, - { 0x20, 0x67 }, - { 0x21, 0x69 }, - { 0x22, 0x68 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0xdb }, - { 0x29, 0xda }, - { 0x2a, 0xd7 }, - }; - fe.reg2 = { 0x00, 0x00, 0x00 }; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_IMG101; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x78 }, - { 0x01, 0xf0 }, - { 0x02, 0x00 }, - { 0x03, 0x00 }, - { 0x20, 0x00 }, - { 0x21, 0x00 }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x00 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - fe = Genesys_Frontend(); - fe.fe_id = DAC_PLUSTEK3800; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x78 }, - { 0x01, 0xf0 }, - { 0x02, 0x00 }, - { 0x03, 0x00 }, - { 0x20, 0x00 }, - { 0x21, 0x00 }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x00 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); - - - /* reg0: control 74 data, 70 no data - * reg3: offset - * reg6: gain - * reg0 , reg3, reg6 */ - fe = Genesys_Frontend(); - fe.fe_id = DAC_CANONLIDE80; - fe.layout = wolfson_layout; - fe.regs = { - { 0x00, 0x70 }, - { 0x01, 0x16 }, - { 0x02, 0x60 }, - { 0x03, 0x00 }, - { 0x20, 0x00 }, - { 0x21, 0x00 }, - { 0x22, 0x00 }, - { 0x24, 0x00 }, - { 0x25, 0x00 }, - { 0x26, 0x00 }, - { 0x28, 0x00 }, - { 0x29, 0x00 }, - { 0x2a, 0x00 }, - }; - fe.reg2 = {0x00, 0x00, 0x00}; - s_frontends->push_back(fe); -} - - -/** for setting up the sensor-specific settings: - * Optical Resolution, number of black pixels, number of dummy pixels, - * CCD_start_xoffset, and overall number of sensor pixels - * registers 0x08-0x0b, 0x10-0x1d and 0x52-0x5e - */ -StaticInit<std::vector<Genesys_Sensor>> s_sensors; - -void genesys_init_sensor_tables() -{ - s_sensors.init(); - - Genesys_Sensor sensor; - sensor.sensor_id = CCD_UMAX; - sensor.optical_res = 1200; - sensor.black_pixels = 48; - sensor.dummy_pixel = 64; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10800; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 230; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x01 }, - { 0x09, 0x03 }, - { 0x0a, 0x05 }, - { 0x0b, 0x07 }, - { 0x16, 0x33 }, - { 0x17, 0x05 }, - { 0x18, 0x31 }, - { 0x19, 0x2a }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x02 }, - { 0x52, 0x13 }, - { 0x53, 0x17 }, - { 0x54, 0x03 }, - { 0x55, 0x07 }, - { 0x56, 0x0b }, - { 0x57, 0x0f }, - { 0x58, 0x23 }, - { 0x59, 0x00 }, - { 0x5a, 0xc1 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_ST12; - sensor.optical_res = 600; - sensor.black_pixels = 48; - sensor.dummy_pixel = 85; - sensor.CCD_start_xoffset = 152; - sensor.sensor_pixels = 5416; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 230; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x02 }, - { 0x09, 0x00 }, - { 0x0a, 0x06 }, - { 0x0b, 0x04 }, - { 0x16, 0x2b }, - { 0x17, 0x08 }, - { 0x18, 0x20 }, - { 0x19, 0x2a }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0x0c }, - { 0x1d, 0x03 }, - { 0x52, 0x0f }, - { 0x53, 0x13 }, - { 0x54, 0x17 }, - { 0x55, 0x03 }, - { 0x56, 0x07 }, - { 0x57, 0x0b }, - { 0x58, 0x83 }, - { 0x59, 0x00 }, - { 0x5a, 0xc1 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_ST24; - sensor.optical_res = 1200; - sensor.black_pixels = 48; - sensor.dummy_pixel = 64; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10800; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 230; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x0e }, - { 0x09, 0x0c }, - { 0x0a, 0x00 }, - { 0x0b, 0x0c }, - { 0x16, 0x33 }, - { 0x17, 0x08 }, - { 0x18, 0x31 }, - { 0x19, 0x2a }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x02 }, - { 0x52, 0x17 }, - { 0x53, 0x03 }, - { 0x54, 0x07 }, - { 0x55, 0x0b }, - { 0x56, 0x0f }, - { 0x57, 0x13 }, - { 0x58, 0x03 }, - { 0x59, 0x00 }, - { 0x5a, 0xc1 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_5345; - sensor.optical_res = 1200; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 48; - sensor.dummy_pixel = 16; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10872; - sensor.fau_gain_white_ref = 190; - sensor.gain_white_ref = 190; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x0d }, - { 0x09, 0x0f }, - { 0x0a, 0x11 }, - { 0x0b, 0x13 }, - { 0x16, 0x0b }, - { 0x17, 0x0a }, - { 0x18, 0x30 }, - { 0x19, 0x2a }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x03 }, - { 0x52, 0x0f }, - { 0x53, 0x13 }, - { 0x54, 0x17 }, - { 0x55, 0x03 }, - { 0x56, 0x07 }, - { 0x57, 0x0b }, - { 0x58, 0x23 }, - { 0x59, 0x00 }, - { 0x5a, 0xc1 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {2.38, 2.35, 2.34}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_HP2400; - sensor.optical_res = 1200, - sensor.black_pixels = 48; - sensor.dummy_pixel = 15; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10872; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x14 }, - { 0x09, 0x15 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0xbf }, - { 0x17, 0x08 }, - { 0x18, 0x3f }, - { 0x19, 0x2a }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x02 }, - { 0x52, 0x0b }, - { 0x53, 0x0f }, - { 0x54, 0x13 }, - { 0x55, 0x17 }, - { 0x56, 0x03 }, - { 0x57, 0x07 }, - { 0x58, 0x63 }, - { 0x59, 0x00 }, - { 0x5a, 0xc1 }, - { 0x5b, 0x00 }, - { 0x5c, 0x0e }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {2.1, 2.1, 2.1}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_HP2300; - sensor.optical_res = 600; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 48; - sensor.dummy_pixel = 20; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 5368; - sensor.fau_gain_white_ref = 180; - sensor.gain_white_ref = 180; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x16 }, - { 0x09, 0x00 }, - { 0x0a, 0x01 }, - { 0x0b, 0x03 }, - { 0x16, 0xb7 }, - { 0x17, 0x0a }, - { 0x18, 0x20 }, - { 0x19, 0x2a }, - { 0x1a, 0x6a }, - { 0x1b, 0x8a }, - { 0x1c, 0x00 }, - { 0x1d, 0x05 }, - { 0x52, 0x0f }, - { 0x53, 0x13 }, - { 0x54, 0x17 }, - { 0x55, 0x03 }, - { 0x56, 0x07 }, - { 0x57, 0x0b }, - { 0x58, 0x83 }, - { 0x59, 0x00 }, - { 0x5a, 0xc1 }, - { 0x5b, 0x06 }, - { 0x5c, 0x0b }, - { 0x5d, 0x10 }, - { 0x5e, 0x16 }, - }; - sensor.gamma = {2.1, 2.1, 2.1}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_CANONLIDE35; - sensor.optical_res = 1200; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 87; - sensor.dummy_pixel = 87; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10400; - sensor.fau_gain_white_ref = 0; - sensor.gain_white_ref = 0; - sensor.exposure = { 0x0400, 0x0400, 0x0400 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x00 }, - { 0x17, 0x02 }, - { 0x18, 0x00 }, - { 0x19, 0x50 }, - { 0x1a, 0x00 }, // TODO: 1a-1d: these do no harm, but may be neccessery for CCD - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x02 }, - { 0x52, 0x05 }, // [GB](HI|LOW) not needed for cis - { 0x53, 0x07 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x3a }, - { 0x59, 0x03 }, - { 0x5a, 0x40 }, - { 0x5b, 0x00 }, // TODO: 5b-5e - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_XP200; - sensor.optical_res = 600; - sensor.black_pixels = 5; - sensor.dummy_pixel = 38; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 5200; - sensor.fau_gain_white_ref = 200; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x1450, 0x0c80, 0x0a28 }; - sensor.custom_regs = { - { 0x08, 0x16 }, - { 0x09, 0x00 }, - { 0x0a, 0x01 }, - { 0x0b, 0x03 }, - { 0x16, 0xb7 }, - { 0x17, 0x0a }, - { 0x18, 0x20 }, - { 0x19, 0x2a }, - { 0x1a, 0x6a }, - { 0x1b, 0x8a }, - { 0x1c, 0x00 }, - { 0x1d, 0x05 }, - { 0x52, 0x0f }, - { 0x53, 0x13 }, - { 0x54, 0x17 }, - { 0x55, 0x03 }, - { 0x56, 0x07 }, - { 0x57, 0x0b }, - { 0x58, 0x83 }, - { 0x59, 0x00 }, - { 0x5a, 0xc1 }, - { 0x5b, 0x06 }, - { 0x5c, 0x0b }, - { 0x5d, 0x10 }, - { 0x5e, 0x16 }, - }; - sensor.gamma = {2.1, 2.1, 2.1}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_HP3670; - sensor.optical_res = 1200; - sensor.black_pixels = 48; - sensor.dummy_pixel = 16; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10872; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x0a }, - { 0x0a, 0x0b }, - { 0x0b, 0x0d }, - { 0x16, 0x33 }, - { 0x17, 0x07 }, - { 0x18, 0x20 }, - { 0x19, 0x2a }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0xc0 }, - { 0x1d, 0x43 }, - { 0x52, 0x0f }, - { 0x53, 0x13 }, - { 0x54, 0x17 }, - { 0x55, 0x03 }, - { 0x56, 0x07 }, - { 0x57, 0x0b }, - { 0x58, 0x83 }, - { 0x59, 0x00 }, - { 0x5a, 0x15 }, - { 0x5b, 0x05 }, - { 0x5c, 0x0a }, - { 0x5d, 0x0f }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_DP665; - sensor.optical_res = 600; - sensor.black_pixels = 27; - sensor.dummy_pixel = 27; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 2496; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x1100, 0x1100, 0x1100 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x00 }, - { 0x17, 0x02 }, - { 0x18, 0x04 }, - { 0x19, 0x50 }, - { 0x1a, 0x10 }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x02 }, - { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis - { 0x53, 0x05 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x54 }, - { 0x59, 0x03 }, - { 0x5a, 0x00 }, - { 0x5b, 0x00 }, // TODO: 5b-5e - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x01 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_ROADWARRIOR; - sensor.optical_res = 600; - sensor.black_pixels = 27; - sensor.dummy_pixel = 27; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 5200; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x1100, 0x1100, 0x1100 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x00 }, - { 0x17, 0x02 }, - { 0x18, 0x04 }, - { 0x19, 0x50 }, - { 0x1a, 0x10 }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x02 }, - { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis - { 0x53, 0x05 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x54 }, - { 0x59, 0x03 }, - { 0x5a, 0x00 }, - { 0x5b, 0x00 }, // TODO: 5b-5e - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x01 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_DSMOBILE600; - sensor.optical_res = 600; - sensor.black_pixels = 28; - sensor.dummy_pixel = 28; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 5200; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x1544, 0x1544, 0x1544 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x00 }, - { 0x17, 0x02 }, - { 0x18, 0x04 }, - { 0x19, 0x50 }, - { 0x1a, 0x10 }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x02 }, - { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis - { 0x53, 0x05 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x54 }, - { 0x59, 0x03 }, - { 0x5a, 0x00 }, - { 0x5b, 0x00 }, // TODO: 5b-5e - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x01 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_XP300; - sensor.optical_res = 600; - sensor.black_pixels = 27; - sensor.dummy_pixel = 27; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10240; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x1100, 0x1100, 0x1100 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x00 }, - { 0x17, 0x02 }, - { 0x18, 0x04 }, - { 0x19, 0x50 }, - { 0x1a, 0x10 }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x02 }, - { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis - { 0x53, 0x05 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x54 }, - { 0x59, 0x03 }, - { 0x5a, 0x00 }, - { 0x5b, 0x00 }, // TODO: 5b-5e - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x01 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_DP685; - sensor.optical_res = 600; - sensor.black_pixels = 27; - sensor.dummy_pixel = 27; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 5020; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x1100, 0x1100, 0x1100 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x00 }, - { 0x17, 0x02 }, - { 0x18, 0x04 }, - { 0x19, 0x50 }, - { 0x1a, 0x10 }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x02 }, - { 0x52, 0x04 }, // [GB](HI|LOW) not needed for cis - { 0x53, 0x05 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x54 }, - { 0x59, 0x03 }, - { 0x5a, 0x00 }, - { 0x5b, 0x00 }, // TODO: 5b-5e - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x01 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE200; - sensor.optical_res = 4800; - sensor.black_pixels = 87*4; - sensor.dummy_pixel = 16*4; - sensor.CCD_start_xoffset = 320*8; - sensor.sensor_pixels = 5136*8; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x10 }, - { 0x17, 0x08 }, - { 0x18, 0x00 }, - { 0x19, 0xff }, - { 0x1a, 0x34 }, - { 0x1b, 0x00 }, - { 0x1c, 0x02 }, - { 0x1d, 0x04 }, - { 0x52, 0x03 }, - { 0x53, 0x07 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x2a }, - { 0x59, 0xe1 }, - { 0x5a, 0x55 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x41 }, - }; - sensor.gamma = {1.7, 1.7, 1.7}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE700; - sensor.optical_res = 4800; - sensor.black_pixels = 73*8; // black pixels 73 at 600 dpi - sensor.dummy_pixel = 16*8; - // 384 at 600 dpi - sensor.CCD_start_xoffset = 384*8; - // 8x5570 segments, 5187+1 for rounding - sensor.sensor_pixels = 5188*8; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x10 }, - { 0x17, 0x08 }, - { 0x18, 0x00 }, - { 0x19, 0xff }, - { 0x1a, 0x34 }, - { 0x1b, 0x00 }, - { 0x1c, 0x02 }, - { 0x1d, 0x04 }, - { 0x52, 0x07 }, - { 0x53, 0x03 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x2a }, - { 0x59, 0xe1 }, - { 0x5a, 0x55 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x41 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE100; - sensor.optical_res = 2400; - sensor.black_pixels = 87*4, /* black pixels */ - sensor.dummy_pixel = 16*4; - sensor.CCD_start_xoffset = 320*4; - sensor.sensor_pixels = 5136*4; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x01c1, 0x0126, 0x00e5 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x10 }, - { 0x17, 0x08 }, - { 0x18, 0x00 }, - { 0x19, 0x50 }, - { 0x1a, 0x34 }, - { 0x1b, 0x00 }, - { 0x1c, 0x02 }, - { 0x1d, 0x04 }, - { 0x52, 0x03 }, - { 0x53, 0x07 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x2a }, - { 0x59, 0xe1 }, - { 0x5a, 0x55 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x41 }, - }; - sensor.gamma = {1.7, 1.7, 1.7}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_KVSS080; - sensor.optical_res = 600; - sensor.black_pixels = 38; - sensor.dummy_pixel = 38; - sensor.CCD_start_xoffset = 152; - sensor.sensor_pixels = 5376; - sensor.fau_gain_white_ref = 160; - sensor.gain_white_ref = 160; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.exposure_lperiod = 8000; - sensor.custom_regs = { - { 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 }, - { 0x77, 0x00 }, { 0x78, 0xff }, { 0x79, 0xff }, - { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, - { 0x0c, 0x00 }, - { 0x70, 0x01 }, - { 0x71, 0x03 }, - { 0x9e, 0x00 }, - { 0xaa, 0x00 }, - { 0x16, 0x33 }, - { 0x17, 0x1c }, - { 0x18, 0x00 }, - { 0x19, 0x2a }, - { 0x1a, 0x2c }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x04 }, - { 0x52, 0x0c }, - { 0x53, 0x0f }, - { 0x54, 0x00 }, - { 0x55, 0x03 }, - { 0x56, 0x06 }, - { 0x57, 0x09 }, - { 0x58, 0x6b }, - { 0x59, 0x00 }, - { 0x5a, 0xc0 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_G4050; - sensor.optical_res = 4800; - sensor.black_pixels = 50*8; - // 31 at 600 dpi dummy_pixels 58 at 1200 - sensor.dummy_pixel = 58; - sensor.CCD_start_xoffset = 152; - sensor.sensor_pixels = 5360*8; - sensor.fau_gain_white_ref = 160; - sensor.gain_white_ref = 160; - sensor.exposure = { 0x2c09, 0x22b8, 0x10f0 }; - sensor.custom_regs = {}; - sensor.gamma = {1.0, 1.0, 1.0}; - - { - struct CustomSensorSettings { - int min_resolution; - int max_resolution; - int exposure_lperiod; - ScanMethod method; - GenesysRegisterSettingSet extra_custom_regs; - }; - - CustomSensorSettings custom_settings[] = { - { -1, 600, 8016, ScanMethod::FLATBED, { - { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, - { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, - { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, - { 0x0c, 0x00 }, - { 0x70, 0x00 }, - { 0x71, 0x02 }, - { 0x9e, 0x00 }, - { 0xaa, 0x00 }, - { 0x16, 0x33 }, - { 0x17, 0x0c }, - { 0x18, 0x00 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x08 }, - { 0x52, 0x0b }, - { 0x53, 0x0e }, - { 0x54, 0x11 }, - { 0x55, 0x02 }, - { 0x56, 0x05 }, - { 0x57, 0x08 }, - { 0x58, 0x63 }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - } - }, - { 1200, 1200, 56064, ScanMethod::FLATBED, { - { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, - { 0x77, 0x00 }, { 0x78, 0x01 }, { 0x79, 0xff }, - { 0x7a, 0x00 }, { 0x7b, 0x01 }, { 0x7c, 0xff }, - { 0x0c, 0x20 }, - { 0x70, 0x08 }, - { 0x71, 0x0c }, - { 0x9e, 0xc0 }, - { 0xaa, 0x05 }, - { 0x16, 0x3b }, - { 0x17, 0x0c }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x38 }, - { 0x1b, 0x10 }, - { 0x1c, 0x00 }, - { 0x1d, 0x08 }, - { 0x52, 0x02 }, - { 0x53, 0x05 }, - { 0x54, 0x08 }, - { 0x55, 0x0b }, - { 0x56, 0x0e }, - { 0x57, 0x11 }, - { 0x58, 0x1b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - } - }, - { 2400, 2400, 56064, ScanMethod::FLATBED, { - { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, - { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, - { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, - { 0x0c, 0x20 }, - { 0x70, 0x08 }, - { 0x71, 0x0a }, - { 0x9e, 0xc0 }, - { 0xaa, 0x05 }, - { 0x16, 0x3b }, - { 0x17, 0x0c }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x38 }, - { 0x1b, 0x10 }, - { 0x1c, 0xc0 }, - { 0x1d, 0x08 }, - { 0x52, 0x02 }, - { 0x53, 0x05 }, - { 0x54, 0x08 }, - { 0x55, 0x0b }, - { 0x56, 0x0e }, - { 0x57, 0x11 }, - { 0x58, 0x1b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - } - }, - { 4800, 4800, 42752, ScanMethod::FLATBED, { - { 0x74, 0x0f }, { 0x75, 0xff }, { 0x76, 0xff }, - { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, - { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 }, - { 0x0c, 0x21 }, - { 0x70, 0x08 }, - { 0x71, 0x0a }, - { 0x9e, 0xc0 }, - { 0xaa, 0x07 }, - { 0x16, 0x3b }, - { 0x17, 0x0c }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x38 }, - { 0x1b, 0x10 }, - { 0x1c, 0xc1 }, - { 0x1d, 0x08 }, - { 0x52, 0x02 }, - { 0x53, 0x05 }, - { 0x54, 0x08 }, - { 0x55, 0x0b }, - { 0x56, 0x0e }, - { 0x57, 0x11 }, - { 0x58, 0x1b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - } - }, - { -1, -1, 15624, ScanMethod::TRANSPARENCY, { - { 0x74, 0x00 }, { 0x75, 0x1c }, { 0x76, 0x7f }, - { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, - { 0x7a, 0x03 }, { 0x7b, 0xff }, { 0x7c, 0xff }, - { 0x0c, 0x00 }, - { 0x70, 0x00 }, - { 0x71, 0x02 }, - { 0x9e, 0x00 }, - { 0xaa, 0x00 }, - { 0x16, 0x33 }, - { 0x17, 0x4c }, - { 0x18, 0x01 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x08 }, - { 0x52, 0x0e }, - { 0x53, 0x11 }, - { 0x54, 0x02 }, - { 0x55, 0x05 }, - { 0x56, 0x08 }, - { 0x57, 0x0b }, - { 0x58, 0x6b }, - { 0x59, 0x00 }, - { 0x5a, 0xc0 }, - } - } - }; - - auto base_custom_regs = sensor.custom_regs; - for (const CustomSensorSettings& setting : custom_settings) - { - sensor.min_resolution = setting.min_resolution; - sensor.max_resolution = setting.max_resolution; - sensor.exposure_lperiod = setting.exposure_lperiod; - sensor.method = setting.method; - sensor.custom_regs = base_custom_regs; - sensor.custom_regs.merge(setting.extra_custom_regs); - s_sensors->push_back(sensor); - } - } - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_CS4400F; - sensor.optical_res = 4800; - sensor.ccd_size_divisor = 4; - sensor.black_pixels = 50*8; - // 31 at 600 dpi, 58 at 1200 dpi - sensor.dummy_pixel = 20; - sensor.CCD_start_xoffset = 152; - // 5360 max at 600 dpi - sensor.sensor_pixels = 5360*8; - sensor.fau_gain_white_ref = 160; - sensor.gain_white_ref = 160; - sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 }; - sensor.exposure_lperiod = 11640; - sensor.custom_regs = { - { 0x74, 0x00 }, { 0x75, 0xf8 }, { 0x76, 0x38 }, - { 0x77, 0x00 }, { 0x78, 0xfc }, { 0x79, 0x00 }, - { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0xa4 }, - { 0x0c, 0x00 }, - { 0x70, 0x00 }, - { 0x71, 0x02 }, - { 0x9e, 0x2d }, - { 0xaa, 0x00 }, - { 0x16, 0x13 }, - { 0x17, 0x0a }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x6b }, - { 0x52, 0x0a }, - { 0x53, 0x0d }, - { 0x54, 0x00 }, - { 0x55, 0x03 }, - { 0x56, 0x06 }, - { 0x57, 0x08 }, - { 0x58, 0x5b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_CS8400F; - sensor.optical_res = 4800; - sensor.black_pixels = 50*8; - // 31 at 600 dpi, 58 at 1200 dpi - sensor.dummy_pixel = 20; - sensor.CCD_start_xoffset = 152; - // 5360 max at 600 dpi - sensor.sensor_pixels = 5360*8; - sensor.fau_gain_white_ref = 160; - sensor.gain_white_ref = 160; - sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 }; - sensor.exposure_lperiod = 7200; - sensor.custom_regs = { - { 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f }, - { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, - { 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb }, - { 0x0c, 0x00 }, - { 0x70, 0x01 }, - { 0x71, 0x02 }, - { 0x9e, 0x00 }, - { 0xaa, 0x00 }, - { 0x16, 0x33 }, - { 0x17, 0x0c }, - { 0x18, 0x13 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x84 }, - { 0x52, 0x0d }, - { 0x53, 0x10 }, - { 0x54, 0x01 }, - { 0x55, 0x04 }, - { 0x56, 0x07 }, - { 0x57, 0x0a }, - { 0x58, 0x6b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_CS8600F; - sensor.optical_res = 4800; - sensor.ccd_size_divisor = 4; - sensor.black_pixels = 31; - sensor.dummy_pixel = 20; - sensor.CCD_start_xoffset = 0; // not used at the moment - // 11372 pixels at 1200 dpi - sensor.sensor_pixels = 11372*4; - sensor.fau_gain_white_ref = 160; - sensor.gain_white_ref = 160; - sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 }; - sensor.custom_regs = {}; - sensor.gamma = {1.0, 1.0, 1.0}; - - { - struct CustomSensorSettings { - int min_resolution; - int max_resolution; - int exposure_lperiod; - ScanMethod method; - GenesysRegisterSettingSet extra_custom_regs; - GenesysRegisterSettingSet custom_fe_regs; - }; - - CustomSensorSettings custom_settings[] = { - { -1, 1200, 24000, ScanMethod::FLATBED, { - { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 }, - { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, - { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, - { 0x0c, 0x00 }, - { 0x70, 0x00 }, - { 0x71, 0x02 }, - { 0x9e, 0x2d }, - { 0xaa, 0x00 }, - { 0x16, 0x13 }, - { 0x17, 0x0a }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x6b }, - { 0x52, 0x0c }, - { 0x53, 0x0f }, - { 0x54, 0x00 }, - { 0x55, 0x03 }, - { 0x56, 0x06 }, - { 0x57, 0x09 }, - { 0x58, 0x6b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - }, - {}, - }, - { -1, 1200, 24000, ScanMethod::TRANSPARENCY, { - { 0x74, 0x03 }, { 0x75, 0xf0 }, { 0x76, 0xf0 }, - { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, - { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, - { 0x0c, 0x00 }, - { 0x70, 0x00 }, - { 0x71, 0x02 }, - { 0x9e, 0x2d }, - { 0xaa, 0x00 }, - { 0x16, 0x13 }, - { 0x17, 0x0a }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x6b }, - { 0x52, 0x0c }, - { 0x53, 0x0f }, - { 0x54, 0x00 }, - { 0x55, 0x03 }, - { 0x56, 0x06 }, - { 0x57, 0x09 }, - { 0x58, 0x6b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - }, - {}, - }, - { 2400, 2400, 24000, ScanMethod::TRANSPARENCY, { - { 0x74, 0x03 }, { 0x75, 0xfe }, { 0x76, 0x00 }, - { 0x77, 0x03 }, { 0x78, 0xfe }, { 0x79, 0x00 }, - { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, - { 0x0c, 0x00 }, - { 0x70, 0x00 }, - { 0x71, 0x02 }, - { 0x9e, 0x2d }, - { 0xaa, 0x00 }, - { 0x16, 0x13 }, - { 0x17, 0x15 }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x01 }, - { 0x1d, 0x75 }, - { 0x52, 0x0c }, - { 0x53, 0x0f }, - { 0x54, 0x00 }, - { 0x55, 0x03 }, - { 0x56, 0x06 }, - { 0x57, 0x09 }, - { 0x58, 0x6b }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - }, - {}, - }, - { 4800, 4800, 24000, ScanMethod::TRANSPARENCY, { - { 0x74, 0x03 }, { 0x75, 0xff }, { 0x76, 0xff }, - { 0x77, 0x03 }, { 0x78, 0xff }, { 0x79, 0xff }, - { 0x7a, 0x00 }, { 0x7b, 0x92 }, { 0x7c, 0x49 }, - { 0x0c, 0x00 }, - { 0x70, 0x0a }, - { 0x71, 0x0c }, - { 0x72, 0x0c }, - { 0x73, 0x0e }, - { 0x9e, 0x2d }, - { 0xaa, 0x00 }, - { 0x16, 0x13 }, - { 0x17, 0x15 }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x61 }, - { 0x1d, 0x75 }, - { 0x52, 0x03 }, - { 0x53, 0x06 }, - { 0x54, 0x09 }, - { 0x55, 0x0c }, - { 0x56, 0x0f }, - { 0x57, 0x00 }, - { 0x58, 0x23 }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - }, - { { 0x03, 0x1f }, - }, - }, - }; - - auto base_custom_regs = sensor.custom_regs; - for (const CustomSensorSettings& setting : custom_settings) - { - sensor.min_resolution = setting.min_resolution; - sensor.max_resolution = setting.max_resolution; - sensor.method = setting.method; - sensor.exposure_lperiod = setting.exposure_lperiod; - sensor.custom_regs = base_custom_regs; - sensor.custom_regs.merge(setting.extra_custom_regs); - sensor.custom_fe_regs = setting.custom_fe_regs; - s_sensors->push_back(sensor); - } - } - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_HP_N6310; - sensor.optical_res = 2400; - // sensor.ccd_size_divisor = 2; Possibly half CCD, needs checking - sensor.black_pixels = 96; - sensor.dummy_pixel = 26; - sensor.CCD_start_xoffset = 128; - sensor.sensor_pixels = 42720; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 230; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x10 }, - { 0x0a, 0x10 }, - { 0x0b, 0x0c }, - { 0x16, 0x33 }, - { 0x17, 0x0c }, - { 0x18, 0x02 }, - { 0x19, 0x2a }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x08 }, - { 0x52, 0x0b }, - { 0x53, 0x0e }, - { 0x54, 0x11 }, - { 0x55, 0x02 }, - { 0x56, 0x05 }, - { 0x57, 0x08 }, - { 0x58, 0x63 }, - { 0x59, 0x00 }, - { 0x5a, 0x40 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x06 }, - { 0x5e, 0x6f }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE110; - sensor.optical_res = 2400; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 87; - sensor.dummy_pixel = 16; - sensor.CCD_start_xoffset = 303; - sensor.sensor_pixels = 5168*4; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x10 }, - { 0x17, 0x04 }, - { 0x18, 0x00 }, - { 0x19, 0x01 }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x02 }, - { 0x1d, 0x01 }, - { 0x52, 0x00 }, - { 0x53, 0x02 }, - { 0x54, 0x04 }, - { 0x55, 0x06 }, - { 0x56, 0x04 }, - { 0x57, 0x04 }, - { 0x58, 0x04 }, - { 0x59, 0x04 }, - { 0x5a, 0x1a }, - { 0x5b, 0x00 }, - { 0x5c, 0xc0 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {2.1, 2.1, 2.1}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE120; - sensor.optical_res = 2400; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 87; - sensor.dummy_pixel = 16; - sensor.CCD_start_xoffset = 303; - // SEGCNT at 600 DPI by number of segments - sensor.sensor_pixels = 5104*4; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x15 }, - { 0x17, 0x04 }, - { 0x18, 0x00 }, - { 0x19, 0x01 }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x02 }, - { 0x1d, 0x01 }, - { 0x52, 0x04 }, - { 0x53, 0x06 }, - { 0x54, 0x00 }, - { 0x55, 0x02 }, - { 0x56, 0x04 }, - { 0x57, 0x04 }, - { 0x58, 0x04 }, - { 0x59, 0x04 }, - { 0x5a, 0x3a }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x1f }, - }; - sensor.gamma = {2.1, 2.1, 2.1}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE210; - sensor.optical_res = 2400; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 87; - sensor.dummy_pixel = 16; - sensor.CCD_start_xoffset = 303; - sensor.sensor_pixels = 5168*4; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x10 }, - { 0x17, 0x04 }, - { 0x18, 0x00 }, - { 0x19, 0x01 }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x02 }, - { 0x1d, 0x01 }, - { 0x52, 0x00 }, - { 0x53, 0x02 }, - { 0x54, 0x04 }, - { 0x55, 0x06 }, - { 0x56, 0x04 }, - { 0x57, 0x04 }, - { 0x58, 0x04 }, - { 0x59, 0x04 }, - { 0x5a, 0x1a }, - { 0x5b, 0x00 }, - { 0x5c, 0xc0 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {2.1, 2.1, 2.1}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE220; - sensor.optical_res = 2400; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 87; - sensor.dummy_pixel = 16; - sensor.CCD_start_xoffset = 303; - sensor.sensor_pixels = 5168*4; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x10 }, - { 0x17, 0x04 }, - { 0x18, 0x00 }, - { 0x19, 0x01 }, - { 0x1a, 0x30 }, - { 0x1b, 0x00 }, - { 0x1c, 0x02 }, - { 0x1d, 0x01 }, - { 0x52, 0x00 }, - { 0x53, 0x02 }, - { 0x54, 0x04 }, - { 0x55, 0x06 }, - { 0x56, 0x04 }, - { 0x57, 0x04 }, - { 0x58, 0x04 }, - { 0x59, 0x04 }, - { 0x5a, 0x1a }, - { 0x5b, 0x00 }, - { 0x5c, 0xc0 }, - { 0x5d, 0x00 }, - { 0x5e, 0x00 }, - }; - sensor.gamma = {2.1, 2.1, 2.1}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_PLUSTEK_3600; - sensor.optical_res = 1200; - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 87; - sensor.dummy_pixel = 87; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10100; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 230; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x00 }, - { 0x16, 0x33 }, - { 0x17, 0x0b }, - { 0x18, 0x11 }, - { 0x19, 0x2a }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0xc4 }, - { 0x52, 0x07 }, // [GB](HI|LOW) not needed for cis - { 0x53, 0x0a }, - { 0x54, 0x0c }, - { 0x55, 0x00 }, - { 0x56, 0x02 }, - { 0x57, 0x06 }, - { 0x58, 0x22 }, - { 0x59, 0x69 }, - { 0x5a, 0x40 }, - { 0x5b, 0x00 }, // TODO: 5b-5e - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x02 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_IMG101; - sensor.optical_res = 1200; - sensor.black_pixels = 31; - sensor.dummy_pixel = 31; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10800; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x60 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x8b }, - { 0x16, 0xbb }, - { 0x17, 0x13 }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x34 }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x06 }, - { 0x52, 0x02 }, - { 0x53, 0x04 }, - { 0x54, 0x06 }, - { 0x55, 0x08 }, - { 0x56, 0x0a }, - { 0x57, 0x00 }, - { 0x58, 0x59 }, - { 0x59, 0x31 }, - { 0x5a, 0x40 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x1f }, - }; - sensor.gamma = {1.7, 1.7, 1.7}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CCD_PLUSTEK3800; - sensor.optical_res = 1200; - sensor.black_pixels = 31; - sensor.dummy_pixel = 31; - sensor.CCD_start_xoffset = 0; - sensor.sensor_pixels = 10200; - sensor.fau_gain_white_ref = 210; - sensor.gain_white_ref = 200; - sensor.exposure = { 0x0000, 0x0000, 0x0000 }; - sensor.custom_regs = { - { 0x08, 0x60 }, - { 0x09, 0x00 }, - { 0x0a, 0x00 }, - { 0x0b, 0x8b }, - { 0x16, 0xbb }, - { 0x17, 0x13 }, - { 0x18, 0x10 }, - { 0x19, 0x2a }, - { 0x1a, 0x34 }, - { 0x1b, 0x00 }, - { 0x1c, 0x20 }, - { 0x1d, 0x06 }, - { 0x52, 0x02 }, - { 0x53, 0x04 }, - { 0x54, 0x06 }, - { 0x55, 0x08 }, - { 0x56, 0x0a }, - { 0x57, 0x00 }, - { 0x58, 0x59 }, - { 0x59, 0x31 }, - { 0x5a, 0x40 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x00 }, - { 0x5e, 0x1f }, - }; - sensor.gamma = {1.7, 1.7, 1.7}; - s_sensors->push_back(sensor); - - - sensor = Genesys_Sensor(); - sensor.sensor_id = CIS_CANONLIDE80, - sensor.optical_res = 1200; // real hardware limit is 2400 - sensor.ccd_size_divisor = 2; - sensor.black_pixels = 20; - sensor.dummy_pixel = 6; - // tuned to give 3*8 multiple startx coordinate during shading calibration - sensor.CCD_start_xoffset = 34; // 14=>3, 20=>2 - // 10400, too wide=>10288 in shading data 10240~ - // 10208 too short for shading, max shading data = 10240 pixels, endpix-startpix=10208 - sensor.sensor_pixels = 10240; - sensor.fau_gain_white_ref = 150; - sensor.gain_white_ref = 150; - // maps to 0x70-0x73 for GL841 - sensor.exposure = { 0x1000, 0x1000, 0x0500 }; - sensor.custom_regs = { - { 0x08, 0x00 }, - { 0x09, 0x05 }, - { 0x0a, 0x07 }, - { 0x0b, 0x09 }, - { 0x16, 0x00 }, - { 0x17, 0x01 }, - { 0x18, 0x00 }, - { 0x19, 0x06 }, - { 0x1a, 0x00 }, - { 0x1b, 0x00 }, - { 0x1c, 0x00 }, - { 0x1d, 0x04 }, - { 0x52, 0x03 }, - { 0x53, 0x07 }, - { 0x54, 0x00 }, - { 0x55, 0x00 }, - { 0x56, 0x00 }, - { 0x57, 0x00 }, - { 0x58, 0x29 }, - { 0x59, 0x69 }, - { 0x5a, 0x55 }, - { 0x5b, 0x00 }, - { 0x5c, 0x00 }, - { 0x5d, 0x20 }, - { 0x5e, 0x41 }, - }; - sensor.gamma = {1.0, 1.0, 1.0}; - s_sensors->push_back(sensor); -} - -/** for General Purpose Output specific settings: - * initial GPO value (registers 0x66-0x67/0x6c-0x6d) - * GPO enable mask (registers 0x68-0x69/0x6e-0x6f) - * The first register is for GPIO9-GPIO16, the second for GPIO1-GPIO8 - */ -static Genesys_Gpo Gpo[] = { - /* UMAX */ - {GPO_UMAX, - {0x11, 0x00} - , - {0x51, 0x20} - , - } - , - /* Plustek OpticPro S12/ST12 */ - {GPO_ST12, - {0x11, 0x00} - , - {0x51, 0x20} - , - } - , - /* Plustek OpticPro S24/ST24 */ - {GPO_ST24, - {0x00, 0x00} - , - {0x51, 0x20} - , - } - , - /* MD5345/MD6471 */ - {GPO_5345, - {0x30, 0x18} - , /* bits 11-12 are for bipolar V-ref input voltage */ - {0xa0, 0x18} - , - } - , - /* HP2400C */ - {GPO_HP2400, - {0x30, 0x00} - , - {0x31, 0x00} - , - } - , - /* HP2300C */ - {GPO_HP2300, - {0x00, 0x00} - , - {0x00, 0x00} - , - } - , - /* CANONLIDE35 */ - {GPO_CANONLIDE35, - {0x02, 0x80} - , - {0xef, 0x80} - , - } - , - /* 7: XP200 */ - {GPO_XP200, - {0x30, 0x00} - , - {0xb0, 0x00} - , - }, - /* HP3670 */ - {GPO_HP3670, - {0x00, 0x00} - , - {0x00, 0x00} - } - , - /* 8: XP300 */ - {GPO_XP300, - {0x09, 0xc6}, - {0xbb, 0x00}, - } - , - /* Syscan DP 665 */ - { - GPO_DP665, - {0x18, 0x00},/*0x19,0x00*/ - {0xbb, 0x00}, - } - , - /* Syscan DP 685 */ - { - GPO_DP685, - {0x3f, 0x46}, /* 6c, 6d */ - {0xfb, 0x00}, /* 6e, 6f */ - }, - /* CANONLIDE200 */ - {GPO_CANONLIDE200, - {0xfb, 0x20}, /* 0xfb when idle , 0xf9/0xe9 (1200) when scanning */ - {0xff, 0x00}, - }, - /* CANONLIDE700 */ - {GPO_CANONLIDE700, - {0xdb, 0xff}, - {0xff, 0x80}, - }, - {GPO_KVSS080, - {0xf5, 0x20}, - {0x7e, 0xa1}, - } - , - {GPO_G4050, - {0x20, 0x00}, - {0xfc, 0x00}, - } - , - /* HP N6310 */ - {GPO_HP_N6310, - {0xa3, 0x00}, - {0x7f, 0x00}, - } - , - /* CANONLIDE110 */ - {GPO_CANONLIDE110, - {0xfb, 0x20}, - {0xff, 0x00}, - } - , - /* CANONLIDE120 */ - {GPO_CANONLIDE120, - {0xfb, 0x20}, - {0xff, 0x00}, - } - , - /* CANONLIDE210 */ - {GPO_CANONLIDE210, - {0xfb, 0x20}, - {0xff, 0x00}, - } - , - /* Plustek 3600 */ - {GPO_PLUSTEK_3600, - {0x02, 0x00}, - {0x1e, 0x80}, - } - /* CanoScan 4400f */ - , - {GPO_CS4400F, - {0x01, 0x7f}, - {0xff, 0x00}, - } - /* CanoScan 8400f */ - , - {GPO_CS8400F, - {0x9a, 0xdf}, - {0xfe, 0x60}, - } - /* CanoScan 8600F */ - , - { GPO_CS8600F, - { 0x20, 0x7c }, - { 0xff, 0x00 }, - } - /* Canon Image formula 101 */ - , - {GPO_IMG101, - {0x41, 0xa4}, - {0x13, 0xa7} - } - /* Plustek OpticBook 3800 */ - , - {GPO_PLUSTEK3800, - {0x41, 0xa4}, - {0x13, 0xa7} - }, - /* Canon LiDE 80 */ - { - GPO_CANONLIDE80, - {0x28, 0x90}, - {0x75, 0x80}, - } -}; - -static Genesys_Motor Motor[] = { - /* UMAX */ - {MOTOR_UMAX, - 1200, /* motor base steps */ - 2400, /* maximum motor resolution */ - 1, /* maximum step mode */ - 1, /* number of power modes*/ - {{{ - 11000, /* maximum start speed */ - 3000, /* maximum end speed */ - 128, /* step count */ - 1.0, /* nonlinearity */ - }, - { - 11000, - 3000, - 128, - 1.0, - },},}, - }, - {MOTOR_5345, /* MD5345/6228/6471 */ - 1200, - 2400, - 1, - 1, - {{{ - 2000, - 1375, - 128, - 0.5, - }, - { - 2000, - 1375, - 128, - 0.5, - },},}, - }, - {MOTOR_ST24, /* ST24 */ - 2400, - 2400, - 1, - 1, - {{{ - 2289, - 2100, - 128, - 0.3, - }, - { - 2289, - 2100, - 128, - 0.3, - },},}, - }, - {MOTOR_HP3670, /* HP 3670 */ - 1200, - 2400, - 1, - 1, - {{{ - 11000, /* start speed */ - 3000, /* max speed */ - 128, /* min steps */ - 0.25, - }, - { - 11000, - 3000, - 128, - 0.5, - },},}, - }, - {MOTOR_HP2400, /* HP 2400c */ - 1200, - 1200, - 1, - 1, - {{{ - 11000, /* start speed */ - 3000, /* max speed */ - 128, /* min steps */ - 0.25, - }, - { - 11000, - 3000, - 128, - 0.5, - },},}, - }, - {MOTOR_HP2300, /* HP 2300c */ - 600, /* 600/1200 */ - 1200, - 1, - 1, - {{{ - 3200, - 1200, - 128, - 0.5, - }, - { - 3200, - 1200, - 128, - 0.5, - },},}, - }, - {MOTOR_CANONLIDE35, /* Canon LiDE 35 */ - 1200, - 2400, - 1, - 1, - {{{ 3500, 1300, 60, 0.8, }, - { 3500, 1400, 60, 0.8, },},}, - }, - {MOTOR_XP200, /* Strobe XP200 */ - 600, - 600, - 1, - 1, - {{{ - 3500, - 1300, - 60, - 0.25, - }, - { - 3500, - 1400, - 60, - 0.5, - },},}, - }, - {MOTOR_XP300, /* 7: Visioneer Strobe XP300 */ - 300, - 600, - 1, - 1, - {{{ /* works best with GPIO10, GPIO14 off */ - 3700, - 3700, - 2, - 0.8, - }, - { - 11000, - 11000, - 2, - 0.8, - },},}, - }, - {MOTOR_DP665, /* Syscan DP 665 */ - 750, - 1500, - 1, - 1, - {{{ - 3000, - 2500, - 10, - 0.8, - }, - { - 11000, - 11000, - 2, - 0.8, - },},}, - }, - {MOTOR_ROADWARRIOR, /* Visioneer Roadwarrior */ - 750, - 1500, - 1, - 1, - {{{ - 3000, - 2600, - 10, - 0.8, - }, - { - 11000, - 11000, - 2, - 0.8, - },},}, - }, - {MOTOR_DSMOBILE_600, /* Pentax DSmobile 600 */ - 750, - 1500, - 2, - 1, - {{{ - 6666, - 3700, - 8, - 0.8, - }, - { - 6666, - 3700, - 8, - 0.8, - },},}, - }, - {MOTOR_CANONLIDE100, /* Canon LiDE 100 */ - 1200, - 6400, - 2, /* maximum step type count */ - 1, /* maximum power modes count */ - { /* motor slopes */ - { /* power mode 0 */ - { 3000, 1000, 127, 0.50}, /* full step */ - { 3000, 1500, 127, 0.50}, /* half step */ - { 3*2712, 3*2712, 16, 0.80}, /* quarter step 0.75*2712 */ - }, - }, - }, - {MOTOR_CANONLIDE200, /* Canon LiDE 200 */ - 1200, - 6400, - 2, - 1, - { /* motor slopes */ - { /* power mode 0 */ - { 3000, 1000, 127, 0.50}, /* full step */ - { 3000, 1500, 127, 0.50}, /* half step */ - { 3*2712, 3*2712, 16, 0.80}, /* quarter step 0.75*2712 */ - }, - }, - }, - {MOTOR_CANONLIDE700, /* Canon LiDE 700 */ - 1200, - 6400, - 2, - 1, - { /* motor slopes */ - { /* power mode 0 */ - { 3000, 1000, 127, 0.50}, /* full step */ - { 3000, 1500, 127, 0.50}, /* half step */ - { 3*2712, 3*2712, 16, 0.80}, /* quarter step 0.75*2712 */ - }, - }, - }, - {MOTOR_KVSS080, - 1200, - 1200, - 2, - 1, - { /* motor slopes */ - { /* power mode 0 */ - { 22222, 500, 246, 0.5 }, /* max speed / dpi * base dpi => exposure */ - { 22222, 500, 246, 0.5 }, - { 22222, 500, 246, 0.5 }, - }, - }, - }, - {MOTOR_G4050, - 2400, - 9600, - 2, - 1, - { /* motor slopes */ - { /* power mode 0 */ - { 3961, 240, 246, 0.8 }, /* full step */ - { 3961, 240, 246, 0.8 }, /* half step */ - { 3961, 240, 246, 0.8 }, /* quarter step */ - }, - }, - }, - {MOTOR_CS8400F, - 2400, - 9600, - 2, - 1, - { /* motor slopes */ - { /* power mode 0 */ - { 3961, 240, 246, 0.8 }, /* full step */ - { 3961, 240, 246, 0.8 }, /* half step */ - { 3961, 240, 246, 0.8 }, /* quarter step */ - }, - }, - }, - { - MOTOR_CS8600F, - 2400, - 9600, - 2, - 1, - { /* motor slopes */ - { /* power mode 0 */ - { 3961, 240, 246, 0.8 }, /* full step */ - { 3961, 240, 246, 0.8 }, /* half step */ - { 3961, 240, 246, 0.8 }, /* quarter step */ - }, - }, - }, - {MOTOR_CANONLIDE110, /* Canon LiDE 110 */ - 4800, - 9600, - 1, /* maximum step type count */ - 1, /* maximum power modes count */ - { /* motor slopes */ - { /* power mode 0 */ - { 3000, 1000, 256, 0.50}, /* full step */ - }, - }, - }, - {MOTOR_CANONLIDE120, /* Canon LiDE 120 */ - 4800, - 9600, - 1, /* maximum step type count */ - 1, /* maximum power modes count */ - { /* motor slopes */ - { /* power mode 0 */ - { 3000, 1000, 256, 0.50}, /* full step */ - }, - }, - }, - {MOTOR_CANONLIDE210, /* Canon LiDE 210 */ - 4800, - 9600, - 1, /* maximum step type count */ - 1, /* maximum power modes count */ - { /* motor slopes */ - { /* power mode 0 */ - { 3000, 1000, 256, 0.50}, /* full step */ - }, - }, - }, - {MOTOR_PLUSTEK_3600, /* PLUSTEK 3600 */ - 1200, - 2400, - 1, - 1, - { - { - { 3500, 1300, 60, 0.8 }, - { 3500, 3250, 60, 0.8 }, - }, - },}, - {MOTOR_IMG101, /* Canon Image Formula 101 */ - 600, - 1200, - 1, - 1, - { - { - { 3500, 1300, 60, 0.8 }, - { 3500, 3250, 60, 0.8 }, - }, - },}, - {MOTOR_PLUSTEK3800, /* Plustek OpticBook 3800 */ - 600, - 1200, - 1, - 1, - { - { - { 3500, 1300, 60, 0.8 }, - { 3500, 3250, 60, 0.8 }, - }, - },}, - {MOTOR_CANONLIDE80, - 2400, /* 2400 ???? */ - 4800, /* 9600 ???? */ - 1, /* max step type */ - 1, /* power mode count */ - { - { /* start speed, max end speed, step number */ - /* maximum speed (second field) is used to compute exposure as seen by motor */ - /* exposure=max speed/ slope dpi * base dpi */ - /* 5144 = max pixels at 600 dpi */ - /* 1288=(5144+8)*ydpi(=300)/base_dpi(=1200) , where 5152 is exposure */ - /* 6440=9660/(1932/1288) */ - { 9560, 1912, 31, 0.8 }, - }, - },}, -}; - -/* here we have the various device settings... - */ -static Genesys_Model umax_astra_4500_model = { - "umax-astra-4500", /* Name */ - "UMAX", /* Device vendor string */ - "Astra 4500", /* Device model name */ - MODEL_UMAX_ASTRA_4500, - GENESYS_GL646, - NULL, - - {1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (3.5), /* Start of scan area in mm (x) */ - SANE_FIX (7.5), /* Start of scan area in mm (y) */ - SANE_FIX (218.0), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (1.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 8, 16, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_BGR, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_UMAX, - DAC_WOLFSON_UMAX, - GPO_UMAX, - MOTOR_UMAX, - GENESYS_FLAG_UNTESTED, /* Which flags are needed for this scanner? */ - /* untested, values set by hmg */ - GENESYS_HAS_NO_BUTTONS, /* no buttons supported */ - 20, - 0, // shading_ta_lines - 200 -}; - -static Genesys_Model canon_lide_50_model = { - "canon-lide-50", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 35/40/50", /* Device model name */ - MODEL_CANON_LIDE_50, - GENESYS_GL841, - NULL, - - { 1200, 600, 400, 300, 240, 200, 150, 75, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 400, 300, 240, 200, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.42), /* Start of scan area in mm (x) */ - SANE_FIX (7.9), /* Start of scan area in mm (y) */ - SANE_FIX (218.0), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (6.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_CANONLIDE35, - DAC_CANONLIDE35, - GPO_CANONLIDE35, - MOTOR_CANONLIDE35, - GENESYS_FLAG_LAZY_INIT | /* Which flags are needed for this scanner? */ - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_DARK_WHITE_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | - GENESYS_HAS_FILE_SW | - GENESYS_HAS_EMAIL_SW | - GENESYS_HAS_COPY_SW, - 280, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model panasonic_kvss080_model = { - "panasonic-kv-ss080", /* Name */ - "Panasonic", /* Device vendor string */ - "KV-SS080", /* Device model name */ - MODEL_PANASONIC_KV_SS080, - GENESYS_GL843, - NULL, - - { 600, /* 500, 400,*/ 300, 200, 150, 100, 75, 0}, /* possible x-resolutions */ - { 1200, 600, /* 500, 400, */ 300, 200, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (7.2), /* Start of scan area in mm (x) */ - SANE_FIX (14.7), /* Start of scan area in mm (y) */ - SANE_FIX (217.7), /* Size of scan area in mm (x) */ - SANE_FIX (300.0), /* Size of scan area in mm (y) */ - - SANE_FIX (9.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 8, 16, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_KVSS080, - DAC_KVSS080, - GPO_KVSS080, - MOTOR_KVSS080, - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW , - 100, - 0, // shading_ta_lines - 100 -}; - -static Genesys_Model hp4850c_model = { - "hewlett-packard-scanjet-4850c", /* Name */ - "Hewlett Packard", /* Device vendor string */ - "ScanJet 4850C", /* Device model name */ - MODEL_HP_SCANJET_4850C, - GENESYS_GL843, - NULL, - - {2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - {2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (7.9), /* Start of scan area in mm (x) */ - SANE_FIX (5.9), /* Start of scan area in mm (y) */ - SANE_FIX (219.6), /* Size of scan area in mm (x) */ - SANE_FIX (314.5), /* Size of scan area in mm (y) */ - - SANE_FIX (3.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in line number */ - /* 0 38 76 OK 1200/2400 */ - /* 0 24 48 OK [100,600] dpi */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_G4050, - DAC_G4050, - GPO_G4050, - MOTOR_G4050, - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_STAGGERED_LINE | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_DARK_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, - 100, - 0, // shading_ta_lines - 100 -}; - -static Genesys_Model hpg4010_model = { - "hewlett-packard-scanjet-g4010", /* Name */ - "Hewlett Packard", /* Device vendor string */ - "ScanJet G4010", /* Device model name */ - MODEL_HP_SCANJET_G4010, - GENESYS_GL843, - NULL, - - { 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - { 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (8.0), /* Start of scan area in mm (x) */ - SANE_FIX (13.00), /* Start of scan area in mm (y) */ - SANE_FIX (217.9), /* Size of scan area in mm (x) 5148 pixels at 600 dpi*/ - SANE_FIX (315.0), /* Size of scan area in mm (y) */ - - SANE_FIX (3.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in line number */ - /* 0 38 76 OK 1200/2400 */ - /* 0 24 48 OK [100,600] dpi */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_G4050, - DAC_G4050, - GPO_G4050, - MOTOR_G4050, - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_STAGGERED_LINE | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_DARK_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, - 100, - 0, // shading_ta_lines - 100 -}; - -static Genesys_Model hpg4050_model = { - "hewlett-packard-scanjet-g4050", /* Name */ - "Hewlett Packard", /* Device vendor string */ - "ScanJet G4050", /* Device model name */ - MODEL_HP_SCANJET_G4050, - GENESYS_GL843, - NULL, - - { 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - { 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (8.0), /* Start of scan area in mm (x) */ - SANE_FIX (13.00), /* Start of scan area in mm (y) */ - SANE_FIX (217.9), /* Size of scan area in mm (x) 5148 pixels at 600 dpi*/ - SANE_FIX (315.0), /* Size of scan area in mm (y) */ - - SANE_FIX (3.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (8.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (13.00), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (217.9), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (250.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (40.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in line number */ - /* 0 38 76 OK 1200/2400 */ - /* 0 24 48 OK [100,600] dpi */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_G4050, - DAC_G4050, - GPO_G4050, - MOTOR_G4050, - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_STAGGERED_LINE | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_DARK_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, - 100, - 0, // shading_ta_lines - 100 -}; - - -static Genesys_Model canon_4400f_model = { - "canon-canoscan-4400f", /* Name */ - "Canon", /* Device vendor string */ - "Canoscan 4400f", /* Device model name */ - MODEL_CANON_CANOSCAN_4400F, - GENESYS_GL843, - NULL, - - { 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - { 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (6.0), /* Start of scan area in mm (x) */ - SANE_FIX (13.00), /* Start of scan area in mm (y) */ - SANE_FIX (217.9), /* Size of scan area in mm (x) 5148 pixels at 600 dpi*/ - SANE_FIX (315.0), /* Size of scan area in mm (y) */ - - SANE_FIX (3.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (8.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (13.00), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (217.9), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (250.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (40.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in line number */ - /* 0 38 76 OK 1200/2400 */ - /* 0 24 48 OK [100,600] dpi */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_CS4400F, - DAC_G4050, - GPO_CS4400F, - MOTOR_G4050, - GENESYS_FLAG_NO_CALIBRATION | - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_STAGGERED_LINE | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_DARK_CALIBRATION | - GENESYS_FLAG_FULL_HWDPI_MODE | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, - 100, - 0, // shading_ta_lines - 100 -}; - - -static Genesys_Model canon_8400f_model = { - "canon-canoscan-8400f", /* Name */ - "Canon", /* Device vendor string */ - "Canoscan 8400f", /* Device model name */ - MODEL_CANON_CANOSCAN_8400F, - GENESYS_GL843, - NULL, - - { 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - { 4800, 2400, 1200, 600, 400, 300, 200, 150, 100, 0}, - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (4.0), /* Start of scan area in mm (x) */ - SANE_FIX (13.00), /* Start of scan area in mm (y) */ - SANE_FIX (217.9), /* Size of scan area in mm (x) 5148 pixels at 600 dpi*/ - SANE_FIX (315.0), /* Size of scan area in mm (y) */ - - SANE_FIX (3.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (8.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (13.00), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (217.9), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (250.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (40.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in line number */ - /* 0 38 76 OK 1200/2400 */ - /* 0 24 48 OK [100,600] dpi */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_CS8400F, - DAC_CS8400F, - GPO_CS8400F, - MOTOR_CS8400F, - GENESYS_FLAG_NO_CALIBRATION | - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_STAGGERED_LINE | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_DARK_CALIBRATION | - GENESYS_FLAG_FULL_HWDPI_MODE | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, - 100, - 0, // shading_ta_lines - 100 -}; - - -static Genesys_Model canon_8600f_model = { - "canon-canoscan-8600f", // name - "Canon", // Device vendor string - "Canoscan 8600f", // Device model name - MODEL_CANON_CANOSCAN_8600F, - GENESYS_GL843, // ASIC type - NULL, - - { 4800, 2400, 1200, 600, 400, 300, 0}, // TODO: resolutions for non-XPA mode - { 4800, 2400, 1200, 600, 400, 300, 0}, // TODO: resolutions for non-XPA mode - { 16, 8, 0 }, // possible depths in gray mode - { 16, 8, 0 }, // possible depths in color mode - - SANE_FIX(24.0), // Start of scan area in mm (x) - SANE_FIX(10.0), // Start of scan area in mm (y) - SANE_FIX(216.0), // Size of scan area in mm (x) - SANE_FIX(297.0), // Size of scan area in mm (y) - - SANE_FIX(0.0), // Start of white strip in mm (y) - SANE_FIX(8.0), // Start of black mark in mm (x) - - SANE_FIX(95.0), // x_offset_ta - SANE_FIX(26.0), // y_offset_ta - SANE_FIX(70.0), // x_size_ta - SANE_FIX(230.0), // y_size_ta - - SANE_FIX(12.5), // y_offset_calib - - SANE_FIX(0.0), // Size of scan area after paper sensor stops - // sensing document in mm - SANE_FIX(0.0), // Amount of feeding needed to eject document - // after finishing scanning in mm - - 0, 48, 96, // RGB CCD Line-distance correction in line number - - COLOR_ORDER_RGB, // Order of the CCD/CIS colors - - SANE_FALSE, // Is this a CIS scanner? - SANE_FALSE, // Is this a sheetfed scanner? - CCD_CS8600F, - DAC_CS8600F, - GPO_CS8600F, - MOTOR_CS8600F, - GENESYS_FLAG_HAS_UTA | - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_STAGGERED_LINE | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_DARK_CALIBRATION | - GENESYS_FLAG_FULL_HWDPI_MODE | - GENESYS_FLAG_CUSTOM_GAMMA | - GENESYS_FLAG_SHADING_REPARK, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, - 50, // shading_lines - 50, // shading_ta_lines - 100 -}; - - -static Genesys_Model canon_lide_100_model = { - "canon-lide-100", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 100", /* Device model name */ - MODEL_CANON_LIDE_100, - GENESYS_GL847, - NULL, - - {4800, 2400, 1200, 600, 300, 200, 150, 100, 75, 0}, /* possible x-resolutions */ - {4800, 2400, 1200, 600, 300, 200, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (1.1), /* Start of scan area in mm (x) */ - SANE_FIX (8.3), /* Start of scan area in mm (y) */ - SANE_FIX (216.07), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (1.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE100, - DAC_CANONLIDE200, - GPO_CANONLIDE200, - MOTOR_CANONLIDE100, - /* Which flags are needed for this scanner? */ - GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_SIS_SENSOR - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_SHADING_REPARK - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, - 50, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model canon_lide_110_model = { - "canon-lide-110", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 110", /* Device model name */ - MODEL_CANON_LIDE_110, - GENESYS_GL124, - NULL, - - {4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75, 0}, /* possible x-resolutions */ - {4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (2.2), /* Start of scan area in mm (x) */ - SANE_FIX (9.0), /* Start of scan area in mm (y) */ - SANE_FIX (216.70), /* Size of scan area in mm (x) */ - SANE_FIX (300.0), /* Size of scan area in mm (y) */ - - SANE_FIX (1.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE110, - DAC_CANONLIDE110, - GPO_CANONLIDE110, - MOTOR_CANONLIDE110, - GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_SHADING_REPARK - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, - 50, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model canon_lide_120_model = { - "canon-lide-120", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 120", /* Device model name */ - MODEL_CANON_LIDE_120, - GENESYS_GL124, - NULL, - - {4800, 2400, 1200, 600, 300, 150, 100, 75, 0}, /* possible x-resolutions */ - {4800, 2400, 1200, 600, 300, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (8.0), /* Start of scan area in mm (y) */ - SANE_FIX (216.0), /* Size of scan area in mm (x) */ - SANE_FIX (300.0), /* Size of scan area in mm (y) */ - - SANE_FIX (1.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE120, - DAC_CANONLIDE120, - GPO_CANONLIDE120, - MOTOR_CANONLIDE120, - GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_SHADING_REPARK - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, - 50, - 0, // shading_ta_lines - 400 -}; - - -static Genesys_Model canon_lide_210_model = { - "canon-lide-210", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 210", /* Device model name */ - MODEL_CANON_LIDE_210, - GENESYS_GL124, - NULL, - - {4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75, 0}, /* possible x-resolutions */ - {4800, 2400, 1200, 600, /* 400,*/ 300, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (2.2), /* Start of scan area in mm (x) */ - SANE_FIX (8.7), /* Start of scan area in mm (y) */ - SANE_FIX (216.70), /* Size of scan area in mm (x) */ - SANE_FIX (297.5), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE210, - DAC_CANONLIDE110, - GPO_CANONLIDE210, - MOTOR_CANONLIDE210, - GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_SHADING_REPARK - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_EXTRA_SW, - 60, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model canon_lide_220_model = { - "canon-lide-220", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 220", /* Device model name */ - MODEL_CANON_LIDE_220, - GENESYS_GL124, /* or a compatible one */ - NULL, - - {4800, 2400, 1200, 600, 300, 150, 100, 75, 0}, /* possible x-resolutions */ - {4800, 2400, 1200, 600, 300, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (2.2), /* Start of scan area in mm (x) */ - SANE_FIX (8.7), /* Start of scan area in mm (y) */ - SANE_FIX (216.70), /* Size of scan area in mm (x) */ - SANE_FIX (297.5), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE220, - DAC_CANONLIDE110, - GPO_CANONLIDE210, - MOTOR_CANONLIDE210, - GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_SHADING_REPARK - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_EXTRA_SW, - 60, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model canon_5600f_model = { - "canon-5600f", /* Name */ - "Canon", /* Device vendor string */ - "5600F", /* Device model name */ - MODEL_CANON_CANOSCAN_5600F, - GENESYS_GL847, - NULL, - - {1200, 600, 400, 300, 200, 150, 100, 75, 0}, /* possible x-resolutions */ - {1200, 600, 400, 300, 200, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (1.1), /* Start of scan area in mm (x) */ - SANE_FIX (8.3), /* Start of scan area in mm (y) */ - SANE_FIX (216.07), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (3.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE200, - DAC_CANONLIDE200, - GPO_CANONLIDE200, - MOTOR_CANONLIDE200, - GENESYS_FLAG_UNTESTED /* not working yet */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_SIS_SENSOR - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, - 50, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model canon_lide_700f_model = { - "canon-lide-700f", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 700F", /* Device model name */ - MODEL_CANON_LIDE_700F, - GENESYS_GL847, - NULL, - - {4800, 2400, 1200, 600, 300, 200, 150, 100, 75, 0}, /* possible x-resolutions */ - {4800, 2400, 1200, 600, 300, 200, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (3.1), /* Start of scan area in mm (x) */ - SANE_FIX (8.1), /* Start of scan area in mm (y) */ - SANE_FIX (216.07), /* Size of scan area in mm (x) */ - SANE_FIX (297.0), /* Size of scan area in mm (y) */ - - SANE_FIX (1.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE700, - DAC_CANONLIDE700, - GPO_CANONLIDE700, - MOTOR_CANONLIDE700, - GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_SIS_SENSOR - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_SHADING_REPARK - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, - 70, - 0, // shading_ta_lines - 400 -}; - - - -static Genesys_Model canon_lide_200_model = { - "canon-lide-200", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 200", /* Device model name */ - MODEL_CANON_LIDE_200, - GENESYS_GL847, - NULL, - - {4800, 2400, 1200, 600, 300, 200, 150, 100, 75, 0}, /* possible x-resolutions */ - {4800, 2400, 1200, 600, 300, 200, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (1.1), /* Start of scan area in mm (x) */ - SANE_FIX (8.3), /* Start of scan area in mm (y) */ - SANE_FIX (216.07), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE200, - DAC_CANONLIDE200, - GPO_CANONLIDE200, - MOTOR_CANONLIDE200, - GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_SIS_SENSOR - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_SHADING_REPARK - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, - 50, - 0, // shading_ta_lines - 400 -}; - - -static Genesys_Model canon_lide_60_model = { - "canon-lide-60", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 60", /* Device model name */ - MODEL_CANON_LIDE_60, - GENESYS_GL841, - NULL, - - {1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.42), /* Start of scan area in mm (x) */ - SANE_FIX (7.9), /* Start of scan area in mm (y) */ - SANE_FIX (218.0), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (6.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_CANONLIDE35, - DAC_CANONLIDE35, - GPO_CANONLIDE35, - MOTOR_CANONLIDE35, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_WHITE_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - - GENESYS_HAS_COPY_SW /* Has four buttons: COPY, SCAN, PDF, EMAIL */ - | GENESYS_HAS_SCAN_SW - | GENESYS_HAS_FILE_SW - | GENESYS_HAS_EMAIL_SW, - 300, - 0, // shading_ta_lines - 400 -}; /* this is completely untested -- hmg */ - -static Genesys_Model canon_lide_80_model = { - "canon-lide-80", /* Name */ - "Canon", /* Device vendor string */ - "LiDE 80", /* Device model name */ - MODEL_CANON_LIDE_80, - GENESYS_GL841, - NULL, - - { 1200, 600, 400, 300, 240, 150, 100, 75, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 400, 300, 240, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - SANE_FIX (0.42), /* Start of scan area in mm (x) 0.42 */ - SANE_FIX (7.90), /* Start of scan area in mm (y) 7.90 */ - SANE_FIX (216.07), /* Size of scan area in mm (x) 218.00 */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (4.5), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CIS_CANONLIDE80, - DAC_CANONLIDE80, - GPO_CANONLIDE80, - MOTOR_CANONLIDE80, - GENESYS_FLAG_LAZY_INIT | /* Which flags are needed for this scanner? */ - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_DARK_WHITE_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | - GENESYS_HAS_FILE_SW | - GENESYS_HAS_EMAIL_SW | - GENESYS_HAS_COPY_SW, - 160, /* 280 @2400 */ - 0, // shading_ta_lines - 400 -}; - - -static Genesys_Model hp2300c_model = { - "hewlett-packard-scanjet-2300c", /* Name */ - "Hewlett Packard", /* Device vendor string */ - "ScanJet 2300c", /* Device model name */ - MODEL_HP_SCANJET_2300C, - GENESYS_GL646, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions, motor can go up to 1200 dpi */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (2.0), /* Start of scan area in mm (x_offset) */ - SANE_FIX (7.5), /* Start of scan area in mm (y_offset) */ - SANE_FIX (215.9), /* Size of scan area in mm (x) */ - SANE_FIX (295.0), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (1.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 16, 8, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_HP2300, - DAC_WOLFSON_HP2300, - GPO_HP2300, - MOTOR_HP2300, - GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_SEARCH_START - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW, - 40, - 0, // shading_ta_lines - 132 -}; - -static -Genesys_Model hp2400c_model = { - "hewlett-packard-scanjet-2400c", /* Name */ - "Hewlett Packard", /* Device vendor string */ - "ScanJet 2400c", /* Device model name */ - MODEL_HP_SCANJET_2400C, - GENESYS_GL646, - NULL, - - {1200, 600, 300, 150, 100, 50, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 100, 50, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (6.5), /* Start of scan area in mm (x) */ - SANE_FIX (2.5), /* Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (297.2), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (1.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_HP2400, - DAC_WOLFSON_HP2400, - GPO_HP2400, - MOTOR_HP2400, - GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_STAGGERED_LINE - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW, - 20, - 0, // shading_ta_lines - 132 -}; - -static -Genesys_Model visioneer_xp200_model = { - "visioneer-strobe-xp200", /* Name */ - "Visioneer", /* Device vendor string */ - "Strobe XP200", /* Device model name */ - MODEL_VISIONEER_STROBE_XP200, - GENESYS_GL646, - NULL, - - {600, 300, 200, 100, 75, 0}, /* possible x-resolutions */ - {600, 300, 200, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.5), /* Start of scan area in mm (x) */ - SANE_FIX (16.0), /* Start of scan area in mm (y) */ - SANE_FIX (215.9), /* Size of scan area in mm (x) */ - SANE_FIX (297.2), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CIS_XP200, - DAC_AD_XP200, /* Analog Device frontend */ - GPO_XP200, - MOTOR_XP200, - GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 120, - 0, // shading_ta_lines - 132 -}; - -static Genesys_Model hp3670c_model = { - "hewlett-packard-scanjet-3670c", /* Name */ - "Hewlett Packard", /* Device vendor string */ - "ScanJet 3670c", /* Device model name */ - MODEL_HP_SCANJET_3670C, - GENESYS_GL646, - NULL, - - {1200, 600, 300, 150, 100, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (8.5), /* Start of scan area in mm (x) */ - SANE_FIX (11.0), /* Start of scan area in mm (y) */ - SANE_FIX (215.9), /* Size of scan area in mm (x) */ - SANE_FIX (300.0), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (1.0), /* Start of black mark in mm (x) */ - - SANE_FIX (104.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (55.6), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (25.6), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (78.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (76.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_HP3670, - DAC_WOLFSON_HP3670, - GPO_HP3670, - MOTOR_HP3670, - GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_XPA - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_STAGGERED_LINE - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW, - 20, - 0, // shading_ta_lines - 200 -}; - -static Genesys_Model plustek_st12_model = { - "plustek-opticpro-st12", /* Name */ - "Plustek", /* Device vendor string */ - "OpticPro ST12", /* Device model name */ - MODEL_PLUSTEK_OPTICPRO_ST12, - GENESYS_GL646, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (3.5), /* Start of scan area in mm (x) */ - SANE_FIX (7.5), /* Start of scan area in mm (y) */ - SANE_FIX (218.0), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (1.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 8, 16, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_BGR, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_ST12, - DAC_WOLFSON_ST12, - GPO_ST12, - MOTOR_UMAX, - GENESYS_FLAG_UNTESTED | GENESYS_FLAG_14BIT_GAMMA, /* Which flags are needed for this scanner? */ - GENESYS_HAS_NO_BUTTONS, /* no buttons supported */ - 20, - 0, // shading_ta_lines - 200 -}; - -static Genesys_Model plustek_st24_model = { - "plustek-opticpro-st24", /* Name */ - "Plustek", /* Device vendor string */ - "OpticPro ST24", /* Device model name */ - MODEL_PLUSTEK_OPTICPRO_ST24, - GENESYS_GL646, - NULL, - - {1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (3.5), /* Start of scan area in mm (x) */ - SANE_FIX (7.5), /* Start of scan area in mm (y) */ - SANE_FIX (218.0), /* Size of scan area in mm (x) */ - SANE_FIX (299.0), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (1.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 8, 16, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_BGR, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_ST24, - DAC_WOLFSON_ST24, - GPO_ST24, - MOTOR_ST24, - GENESYS_FLAG_UNTESTED - | GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_SEARCH_START - | GENESYS_FLAG_OFFSET_CALIBRATION, - GENESYS_HAS_NO_BUTTONS, /* no buttons supported */ - 20, - 0, // shading_ta_lines - 200 -}; - -static Genesys_Model medion_md5345_model = { - "medion-md5345-model", /* Name */ - "Medion", /* Device vendor string */ - "MD5345/MD6228/MD6471", /* Device model name */ - MODEL_MEDION_MD5345, - GENESYS_GL646, - NULL, - - {1200, 600, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX ( 0.30), /* Start of scan area in mm (x) */ - SANE_FIX ( 0.80), /* 2.79 < Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (296.4), /* Size of scan area in mm (y) */ - - SANE_FIX (0.00), /* Start of white strip in mm (y) */ - SANE_FIX (0.00), /* Start of black mark in mm (x) */ - - SANE_FIX (0.00), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.00), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (0.00), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (0.00), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.00), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 48, 24, 0, /* RGB CCD Line-distance correction in pixel */ - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_5345, - DAC_WOLFSON_5345, - GPO_5345, - MOTOR_5345, - GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_SEARCH_START - | GENESYS_FLAG_STAGGERED_LINE - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_SHADING_NO_MOVE - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_POWER_SW | GENESYS_HAS_OCR_SW | GENESYS_HAS_SCAN_SW, - 40, - 0, // shading_ta_lines - 200 -}; - -static Genesys_Model visioneer_xp300_model = { - "visioneer-strobe-xp300", /* Name */ - "Visioneer", /* Device vendor string */ - "Strobe XP300", /* Device model name */ - MODEL_VISIONEER_STROBE_XP300, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (1.0), /* Start of scan area in mm (y) */ - SANE_FIX (435.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (26.5), /* Size of scan area after paper sensor stops - sensing document in mm */ - /* this is larger than needed -- accounts for second sensor head, which is a - calibration item */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_XP300, - DAC_WOLFSON_XP300, - GPO_XP300, - MOTOR_XP300, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model syscan_docketport_665_model = { - "syscan-docketport-665", /* Name */ - "Syscan/Ambir", /* Device vendor string */ - "DocketPORT 665", /* Device model name */ - MODEL_SYSCAN_DOCKETPORT_665, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in mm (y) */ - SANE_FIX (108.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (17.5), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_DP665, - DAC_WOLFSON_XP300, - GPO_DP665, - MOTOR_DP665, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model visioneer_roadwarrior_model = { - "visioneer-roadwarrior", /* Name */ - "Visioneer", /* Device vendor string */ - "Readwarrior", /* Device model name */ - MODEL_VISIONEER_ROADWARRIOR, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (16.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_ROADWARRIOR, - DAC_WOLFSON_XP300, - GPO_DP665, - MOTOR_ROADWARRIOR, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model syscan_docketport_465_model = { - "syscan-docketport-465", /* Name */ - "Syscan", /* Device vendor string */ - "DocketPORT 465", /* Device model name */ - MODEL_SYSCAN_DOCKETPORT_465, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (16.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_ROADWARRIOR, - DAC_WOLFSON_XP300, - GPO_DP665, - MOTOR_ROADWARRIOR, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_NO_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_UNTESTED, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW, - 300, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model visioneer_xp100_r3_model = { - "visioneer-xp100-revision3", /* Name */ - "Visioneer", /* Device vendor string */ - "XP100 Revision 3", /* Device model name */ - MODEL_VISIONEER_STROBE_XP100_REVISION3, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (16.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_ROADWARRIOR, - DAC_WOLFSON_XP300, - GPO_DP665, - MOTOR_ROADWARRIOR, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model pentax_dsmobile_600_model = { - "pentax-dsmobile-600", /* Name */ - "Pentax", /* Device vendor string */ - "DSmobile 600", /* Device model name */ - MODEL_PENTAX_DSMOBILE_600, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (16.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_DSMOBILE600, - DAC_WOLFSON_DSM600, - GPO_DP665, - MOTOR_DSMOBILE_600, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model syscan_docketport_467_model = { - "syscan-docketport-467", /* Name */ - "Syscan", /* Device vendor string */ - "DocketPORT 467", /* Device model name */ - MODEL_SYSCAN_DOCKETPORT_467, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (16.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_DSMOBILE600, - DAC_WOLFSON_DSM600, - GPO_DP665, - MOTOR_DSMOBILE_600, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model syscan_docketport_685_model = { - "syscan-docketport-685", /* Name */ - "Syscan/Ambir", /* Device vendor string */ - "DocketPORT 685", /* Device model name */ - MODEL_SYSCAN_DOCKETPORT_685, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (1.0), /* Start of scan area in mm (y) */ - SANE_FIX (212.0), /* Size of scan area in mm (x) */ - SANE_FIX (500), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (26.5), /* Size of scan area after paper sensor stops - sensing document in mm */ - /* this is larger than needed -- accounts for second sensor head, which is a - calibration item */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_DP685, - DAC_WOLFSON_DSM600, - GPO_DP685, - MOTOR_XP300, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model syscan_docketport_485_model = { - "syscan-docketport-485", /* Name */ - "Syscan/Ambir", /* Device vendor string */ - "DocketPORT 485", /* Device model name */ - MODEL_SYSCAN_DOCKETPORT_485, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (1.0), /* Start of scan area in mm (y) */ - SANE_FIX (435.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (26.5), /* Size of scan area after paper sensor stops - sensing document in mm */ - /* this is larger than needed -- accounts for second sensor head, which is a - calibration item */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_XP300, - DAC_WOLFSON_XP300, - GPO_XP300, - MOTOR_XP300, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model dct_docketport_487_model = { - "dct-docketport-487", /* Name */ - "DCT", /* Device vendor string */ - "DocketPORT 487", /* Device model name */ - MODEL_DCT_DOCKETPORT_487, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.0), /* Start of scan area in mm (x) */ - SANE_FIX (1.0), /* Start of scan area in mm (y) */ - SANE_FIX (435.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (26.5), /* Size of scan area after paper sensor stops - sensing document in mm */ - /* this is larger than needed -- accounts for second sensor head, which is a - calibration item */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_XP300, - DAC_WOLFSON_XP300, - GPO_XP300, - MOTOR_XP300, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_UNTESTED, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model visioneer_7100_model = { - "visioneer-7100-model", /* Name */ - "Visioneer", /* Device vendor string */ - "OneTouch 7100", /* Device model name */ - MODEL_VISIONEER_7100, - GENESYS_GL646, - NULL, - - {1200, 600, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX ( 4.00), /* Start of scan area in mm (x) */ - SANE_FIX ( 0.80), /* 2.79 < Start of scan area in mm (y) */ - SANE_FIX (215.9), /* Size of scan area in mm (x) */ - SANE_FIX (296.4), /* Size of scan area in mm (y) */ - - SANE_FIX (0.00), /* Start of white strip in mm (y) */ - SANE_FIX (0.00), /* Start of black mark in mm (x) */ - - SANE_FIX (0.00), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.00), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (0.00), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (0.00), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.00), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 48, 24, 0, /* RGB CCD Line-distance correction in pixel */ -/* 48, 24, 0, */ - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_5345, - DAC_WOLFSON_5345, - GPO_5345, - MOTOR_5345, - GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_SEARCH_START - | GENESYS_FLAG_STAGGERED_LINE - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_POWER_SW | GENESYS_HAS_OCR_SW | GENESYS_HAS_SCAN_SW, - 40, - 0, // shading_ta_lines - 200 -}; - -static Genesys_Model xerox_2400_model = { - "xerox-2400-model", /* Name */ - "Xerox", /* Device vendor string */ - "OneTouch 2400", /* Device model name */ - MODEL_XEROX_2400, - GENESYS_GL646, - NULL, - - {1200, 600, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible x-resolutions */ - {2400, 1200, 600, 400, 300, 200, 150, 100, 75, 50, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX ( 4.00), /* Start of scan area in mm (x) */ - SANE_FIX ( 0.80), /* 2.79 < Start of scan area in mm (y) */ - SANE_FIX (215.9), /* Size of scan area in mm (x) */ - SANE_FIX (296.4), /* Size of scan area in mm (y) */ - - SANE_FIX (0.00), /* Start of white strip in mm (y) */ - SANE_FIX (0.00), /* Start of black mark in mm (x) */ - - SANE_FIX (0.00), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.00), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (0.00), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (0.00), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.00), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 48, 24, 0, /* RGB CCD Line-distance correction in pixel */ -/* 48, 24, 0, */ - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_5345, - DAC_WOLFSON_5345, - GPO_5345, - MOTOR_5345, - GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_SEARCH_START - | GENESYS_FLAG_STAGGERED_LINE - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_POWER_SW | GENESYS_HAS_OCR_SW | GENESYS_HAS_SCAN_SW, - 40, - 0, // shading_ta_lines - 200 -}; - - -static Genesys_Model xerox_travelscanner_model = { - "xerox-travelscanner", /* Name */ - "Xerox", /* Device vendor string */ - "Travelscanner 100", /* Device model name */ - MODEL_XEROX_TRAVELSCANNER_100, - GENESYS_GL841, - NULL, - - {600, 300, 150, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (4.0), /* Start of scan area in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in mm (y) */ - SANE_FIX (220.0), /* Size of scan area in mm (x) */ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (16.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_TRUE, /* Is this a CIS scanner? */ - SANE_TRUE, /* Is this a sheetfed scanner? */ - CCD_ROADWARRIOR, - DAC_WOLFSON_XP300, - GPO_DP665, - MOTOR_ROADWARRIOR, - GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */ - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION, - GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, - 100, - 0, // shading_ta_lines - 400 -}; - -static Genesys_Model plustek_3600_model = { - "plustek-opticbook-3600", /* Name */ - "PLUSTEK", /* Device vendor string */ - "OpticBook 3600", /* Device model name */ - MODEL_PLUSTEK_OPTICPRO_3600, - GENESYS_GL841, - NULL, - {/*1200,*/ 600, 400, 300, 200, 150, 100, 75, 0}, /* possible x-resolutions */ - {/*2400,*/ 1200, 600, 400, 300, 200, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (0.42),/*SANE_FIX (0.42), Start of scan area in mm (x) */ - SANE_FIX (6.75),/*SANE_FIX (7.9), Start of scan area in mm (y) */ - SANE_FIX (216.0),/*SANE_FIX (216.0), Size of scan area in mm (x) */ - SANE_FIX (297.0),/*SANE_FIX (297.0), Size of scan area in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_PLUSTEK_3600, - DAC_PLUSTEK_3600, - GPO_PLUSTEK_3600, - MOTOR_PLUSTEK_3600, - GENESYS_FLAG_UNTESTED /* not fully working yet */ - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_LAZY_INIT,/* - | GENESYS_FLAG_NO_CALIBRATION,*/ - GENESYS_HAS_NO_BUTTONS, - 7, - 0, // shading_ta_lines - 200 -}; - -static Genesys_Model hpn6310_model = { - "hewlett-packard-scanjet-N6310", /* Name */ - "Hewlett Packard", /* Device vendor string */ - "ScanJet N6310", /* Device model name */ - MODEL_HP_SCANJET_N6310, - GENESYS_GL847, - NULL, - - { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 0}, - { 2400, 1200, 600, 400, 300, 200, 150, 100, 75, 0}, - - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (6), /* Start of scan area in mm (x) */ - SANE_FIX (2), /* Start of scan area in mm (y) */ - SANE_FIX (216), /* Size of scan area in mm (x) 5148 pixels at 600 dpi*/ - SANE_FIX (511), /* Size of scan area in mm (y) */ - - SANE_FIX (3.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 0, 0, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_HP_N6310, - DAC_CANONLIDE200, /*Not defined yet for N6310 */ - GPO_HP_N6310, - MOTOR_CANONLIDE200, /*Not defined yet for N6310 */ - GENESYS_FLAG_UNTESTED /* not fully working yet */ - | GENESYS_FLAG_LAZY_INIT - | GENESYS_FLAG_14BIT_GAMMA - | GENESYS_FLAG_DARK_CALIBRATION - | GENESYS_FLAG_OFFSET_CALIBRATION - | GENESYS_FLAG_CUSTOM_GAMMA - | GENESYS_FLAG_SKIP_WARMUP - | GENESYS_FLAG_NO_CALIBRATION, - - GENESYS_HAS_NO_BUTTONS, - 100, - 0, // shading_ta_lines - 100 -}; - - -static Genesys_Model plustek_3800_model = { - "plustek-opticbook-3800", /* Name */ - "PLUSTEK", /* Device vendor string */ - "OpticBook 3800", /* Device model name */ - MODEL_PLUSTEK_OPTICBOOK_3800, - GENESYS_GL845, - NULL, - - {1200, 600, 300, 150, 100, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (7.2), /* Start of scan area in mm (x) */ - SANE_FIX (14.7), /* Start of scan area in mm (y) */ - SANE_FIX (217.7), /* Size of scan area in mm (x) */ - SANE_FIX (300.0), /* Size of scan area in mm (y) */ - - SANE_FIX (9.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_PLUSTEK3800, - DAC_PLUSTEK3800, - GPO_PLUSTEK3800, - MOTOR_PLUSTEK3800, - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_NO_BUTTONS, /* TODO there are 4 buttons to support */ - 100, - 0, // shading_ta_lines - 100 -}; - - -static Genesys_Model canon_formula101_model = { - "canon-image-formula-101", /* Name */ - "Canon", /* Device vendor string */ - "Image Formula 101", /* Device model name */ - MODEL_CANON_IMAGE_FORMULA_101, - GENESYS_GL846, - NULL, - - {1200, 600, 300, 150, 100, 75, 0}, /* possible x-resolutions */ - {1200, 600, 300, 150, 100, 75, 0}, /* possible y-resolutions */ - {16, 8, 0}, /* possible depths in gray mode */ - {16, 8, 0}, /* possible depths in color mode */ - - SANE_FIX (7.2), /* Start of scan area in mm (x) */ - SANE_FIX (14.7), /* Start of scan area in mm (y) */ - SANE_FIX (217.7), /* Size of scan area in mm (x) */ - SANE_FIX (300.0), /* Size of scan area in mm (y) */ - - SANE_FIX (9.0), /* Start of white strip in mm (y) */ - SANE_FIX (0.0), /* Start of black mark in mm (x) */ - - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (x) */ - SANE_FIX (0.0), /* Size of scan area in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */ - - SANE_FIX (0.0), /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_FIX (0.0), /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - 0, 24, 48, /* RGB CCD Line-distance correction in pixel */ - - COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */ - - SANE_FALSE, /* Is this a CIS scanner? */ - SANE_FALSE, /* Is this a sheetfed scanner? */ - CCD_IMG101, - DAC_IMG101, - GPO_IMG101, - MOTOR_IMG101, - GENESYS_FLAG_LAZY_INIT | - GENESYS_FLAG_SKIP_WARMUP | - GENESYS_FLAG_OFFSET_CALIBRATION | - GENESYS_FLAG_CUSTOM_GAMMA, - GENESYS_HAS_NO_BUTTONS , - 100, - 0, // shading_ta_lines - 100 -}; - - -static Genesys_USB_Device_Entry genesys_usb_device_list[] = { - /* GL646 devices */ - {0x03f0, 0x0901, &hp2300c_model}, - {0x03f0, 0x0a01, &hp2400c_model}, - {0x03f0, 0x1405, &hp3670c_model}, - {0x0461, 0x0377, &medion_md5345_model}, - {0x04a7, 0x0229, &visioneer_7100_model}, - {0x0461, 0x038b, &xerox_2400_model}, - {0x04a7, 0x0426, &visioneer_xp200_model}, - {0x0638, 0x0a10, &umax_astra_4500_model}, - {0x07b3, 0x0600, &plustek_st12_model}, - {0x07b3, 0x0601, &plustek_st24_model}, - /* GL841 devices */ - {0x04a7, 0x0474, &visioneer_xp300_model}, - {0x04a7, 0x0494, &visioneer_roadwarrior_model}, - {0x04a7, 0x049b, &visioneer_xp100_r3_model}, - {0x04a7, 0x04ac, &xerox_travelscanner_model}, - {0x04a9, 0x2213, &canon_lide_50_model}, - {0x04a9, 0x221c, &canon_lide_60_model}, - {0x04a9, 0x2214, &canon_lide_80_model}, - {0x07b3, 0x0900, &plustek_3600_model}, - {0x0a17, 0x3210, &pentax_dsmobile_600_model}, - {0x04f9, 0x2038, &pentax_dsmobile_600_model}, /* clone, only usb id is different */ - {0x0a82, 0x4800, &syscan_docketport_485_model}, - {0x0a82, 0x4802, &syscan_docketport_465_model}, - {0x0a82, 0x4803, &syscan_docketport_665_model}, - {0x0a82, 0x480c, &syscan_docketport_685_model}, - {0x1dcc, 0x4810, &dct_docketport_487_model}, - {0x1dcc, 0x4812, &syscan_docketport_467_model}, - /* GL843 devices */ - {0x04da, 0x100f, &panasonic_kvss080_model}, - {0x03f0, 0x1b05, &hp4850c_model}, - {0x03f0, 0x4505, &hpg4010_model}, - {0x03f0, 0x4605, &hpg4050_model}, - {0x04a9, 0x2228, &canon_4400f_model}, - {0x04a9, 0x221e, &canon_8400f_model}, - {0x04a9, 0x2229, &canon_8600f_model}, - /* GL845 devices */ - {0x07b3, 0x1300, &plustek_3800_model}, - /* GL846 devices */ - {0x1083, 0x162e, &canon_formula101_model}, - /* GL847 devices */ - {0x04a9, 0x1904, &canon_lide_100_model}, - {0x04a9, 0x1905, &canon_lide_200_model}, - {0x04a9, 0x1906, &canon_5600f_model}, - {0x04a9, 0x1907, &canon_lide_700f_model}, - {0x03f0, 0x4705, &hpn6310_model}, - /* GL124 devices */ - {0x04a9, 0x1909, &canon_lide_110_model}, - {0x04a9, 0x190e, &canon_lide_120_model}, - {0x04a9, 0x190a, &canon_lide_210_model}, - {0x04a9, 0x190f, &canon_lide_220_model}, - {0, 0, NULL} -}; - -#define MAX_SCANNERS (sizeof(genesys_usb_device_list) / \ - sizeof(genesys_usb_device_list[0])) diff --git a/backend/genesys_gl124.cc b/backend/genesys_gl124.cc deleted file mode 100644 index a535d58..0000000 --- a/backend/genesys_gl124.cc +++ /dev/null @@ -1,3592 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2010-2016 Stéphane Voltz <stef.dev@free.fr> - - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#define DEBUG_DECLARE_ONLY - -#include "genesys_gl124.h" - -#include <vector> - -/**************************************************************************** - Mid level functions - ****************************************************************************/ - -static SANE_Bool gl124_get_fast_feed_bit(Genesys_Register_Set* regs) -{ - return (bool)(regs->get8(REG02) & REG02_FASTFED); -} - -static SANE_Bool gl124_get_filter_bit(Genesys_Register_Set* regs) -{ - return (bool)(regs->get8(REG04) & REG04_FILTER); -} - -static SANE_Bool gl124_get_lineart_bit(Genesys_Register_Set* regs) -{ - return (bool)(regs->get8(REG04) & REG04_LINEART); -} - -static SANE_Bool gl124_get_bitset_bit(Genesys_Register_Set* regs) -{ - return (bool)(regs->get8(REG04) & REG04_BITSET); -} - -static SANE_Bool gl124_get_gain4_bit (Genesys_Register_Set * regs) -{ - return (bool)(regs->get8(REG06) & REG06_GAIN4); -} - -static SANE_Bool -gl124_test_buffer_empty_bit (SANE_Byte val) -{ - if (val & BUFEMPTY) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl124_test_motor_flag_bit (SANE_Byte val) -{ - if (val & MOTORENB) - return SANE_TRUE; - return SANE_FALSE; -} - -/** @brief sensor profile - * search for the database of motor profiles and get the best one. Each - * profile is at a specific dpihw. Use LiDE 110 table by default. - * @param sensor_type sensor id - * @param dpi hardware dpi for the scan - * @param half_ccd flag to signal half ccd mode - * @return a pointer to a Sensor_Profile struct - */ -static Sensor_Profile *get_sensor_profile(int sensor_type, int dpi, int half_ccd) -{ - unsigned int i; - int idx; - - i=0; - idx=-1; - while(i<sizeof(sensors)/sizeof(Sensor_Profile)) - { - /* exact match */ - if(sensors[i].sensor_type==sensor_type - && sensors[i].dpi==dpi - && sensors[i].half_ccd==half_ccd) - { - return &(sensors[i]); - } - - /* closest match */ - if(sensors[i].sensor_type==sensor_type - && sensors[i].half_ccd==half_ccd) - { - if(idx<0) - { - idx=i; - } - else - { - if(sensors[i].dpi>=dpi - && sensors[i].dpi<sensors[idx].dpi) - { - idx=i; - } - } - } - i++; - } - - /* default fallback */ - if(idx<0) - { - DBG (DBG_warn,"%s: using default sensor profile\n",__func__); - idx=0; - } - - return &(sensors[idx]); -} - - -static SANE_Status -gl124_homsnr_gpio(Genesys_Device *dev) -{ -uint8_t val; -SANE_Status status=SANE_STATUS_GOOD; - - RIE (sanei_genesys_read_register (dev, REG32, &val)); - val &= ~REG32_GPIO10; - RIE (sanei_genesys_write_register (dev, REG32, val)); - return status; -} - -/**@brief compute half ccd mode - * Compute half CCD mode flag. Half CCD is on when dpiset it twice - * the actual scanning resolution. Used for fast scans. - * @param model pointer to device model - * @param xres required horizontal resolution - * @return SANE_TRUE if half CCD mode enabled - */ -static SANE_Bool compute_half_ccd(const Genesys_Sensor& sensor, int xres) -{ - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - if (xres<=300 && sensor.ccd_size_divisor > 1) - { - return SANE_TRUE; - } - return SANE_FALSE; -} - -/** @brief set all registers to default values . - * This function is called only once at the beginning and - * fills register startup values for registers reused across scans. - * Those that are rarely modified or not modified are written - * individually. - * @param dev device structure holding register set to initialize - */ -static void -gl124_init_registers (Genesys_Device * dev) -{ - DBGSTART; - - dev->reg.clear(); - - /* default to LiDE 110 */ - SETREG (0x01,0xa2); /* + REG01_SHDAREA */ - SETREG (0x02,0x90); - SETREG (0x03,0x50); - SETREG (0x04,0x03); - SETREG (0x05,0x00); - if(dev->model->ccd_type==CIS_CANONLIDE120) - { - SETREG (0x06,0x50); - SETREG (0x07,0x00); - } - else - { - SETREG (0x03,0x50 & ~REG03_AVEENB); - SETREG (0x06,0x50 | REG06_GAIN4); - } - SETREG (0x09,0x00); - SETREG (0x0a,0xc0); - SETREG (0x0b,0x2a); - SETREG (0x0c,0x12); - SETREG (0x11,0x00); - SETREG (0x12,0x00); - SETREG (0x13,0x0f); - SETREG (0x14,0x00); - SETREG (0x15,0x80); - SETREG (0x16,0x10); - SETREG (0x17,0x04); - SETREG (0x18,0x00); - SETREG (0x19,0x01); - SETREG (0x1a,0x30); - SETREG (0x1b,0x00); - SETREG (0x1c,0x00); - SETREG (0x1d,0x01); - SETREG (0x1e,0x10); - SETREG (0x1f,0x00); - SETREG (0x20,0x15); - SETREG (0x21,0x00); - if(dev->model->ccd_type!=CIS_CANONLIDE120) - { - SETREG (0x22,0x02); - } - else - { - SETREG (0x22,0x14); - } - SETREG (0x23,0x00); - SETREG (0x24,0x00); - SETREG (0x25,0x00); - SETREG (0x26,0x0d); - SETREG (0x27,0x48); - SETREG (0x28,0x00); - SETREG (0x29,0x56); - SETREG (0x2a,0x5e); - SETREG (0x2b,0x02); - SETREG (0x2c,0x02); - SETREG (0x2d,0x58); - SETREG (0x3b,0x00); - SETREG (0x3c,0x00); - SETREG (0x3d,0x00); - SETREG (0x3e,0x00); - SETREG (0x3f,0x02); - SETREG (0x40,0x00); - SETREG (0x41,0x00); - SETREG (0x42,0x00); - SETREG (0x43,0x00); - SETREG (0x44,0x00); - SETREG (0x45,0x00); - SETREG (0x46,0x00); - SETREG (0x47,0x00); - SETREG (0x48,0x00); - SETREG (0x49,0x00); - SETREG (0x4f,0x00); - SETREG (0x52,0x00); - SETREG (0x53,0x02); - SETREG (0x54,0x04); - SETREG (0x55,0x06); - SETREG (0x56,0x04); - SETREG (0x57,0x04); - SETREG (0x58,0x04); - SETREG (0x59,0x04); - SETREG (0x5a,0x1a); - SETREG (0x5b,0x00); - SETREG (0x5c,0xc0); - SETREG (0x5f,0x00); - SETREG (0x60,0x02); - SETREG (0x61,0x00); - SETREG (0x62,0x00); - SETREG (0x63,0x00); - SETREG (0x64,0x00); - SETREG (0x65,0x00); - SETREG (0x66,0x00); - SETREG (0x67,0x00); - SETREG (0x68,0x00); - SETREG (0x69,0x00); - SETREG (0x6a,0x00); - SETREG (0x6b,0x00); - SETREG (0x6c,0x00); - SETREG (0x6e,0x00); - SETREG (0x6f,0x00); - if(dev->model->ccd_type!=CIS_CANONLIDE120) - { - SETREG (0x6d,0xd0); - SETREG (0x71,0x08); - } - else - { - SETREG (0x6d,0x00); - SETREG (0x71,0x1f); - } - SETREG (0x70,0x00); - SETREG (0x72,0x08); - SETREG (0x73,0x0a); - - /* CKxMAP */ - SETREG (0x74,0x00); - SETREG (0x75,0x00); - SETREG (0x76,0x3c); - SETREG (0x77,0x00); - SETREG (0x78,0x00); - SETREG (0x79,0x9f); - SETREG (0x7a,0x00); - SETREG (0x7b,0x00); - SETREG (0x7c,0x55); - - SETREG (0x7d,0x00); - SETREG (0x7e,0x08); - SETREG (0x7f,0x58); - if(dev->model->ccd_type!=CIS_CANONLIDE120) - { - SETREG (0x80,0x00); - SETREG (0x81,0x14); - } - else - { - SETREG (0x80,0x00); - SETREG (0x81,0x10); - } - - /* STRPIXEL */ - SETREG (0x82,0x00); - SETREG (0x83,0x00); - SETREG (0x84,0x00); - /* ENDPIXEL */ - SETREG (0x85,0x00); - SETREG (0x86,0x00); - SETREG (0x87,0x00); - - SETREG (0x88,0x00); - SETREG (0x89,0x65); - SETREG (0x8a,0x00); - SETREG (0x8b,0x00); - SETREG (0x8c,0x00); - SETREG (0x8d,0x00); - SETREG (0x8e,0x00); - SETREG (0x8f,0x00); - SETREG (0x90,0x00); - SETREG (0x91,0x00); - SETREG (0x92,0x00); - SETREG (0x93,0x00); - SETREG (0x94,0x14); - SETREG (0x95,0x30); - SETREG (0x96,0x00); - SETREG (0x97,0x90); - SETREG (0x98,0x01); - SETREG (0x99,0x1f); - SETREG (0x9a,0x00); - SETREG (0x9b,0x80); - SETREG (0x9c,0x80); - SETREG (0x9d,0x3f); - SETREG (0x9e,0x00); - SETREG (0x9f,0x00); - SETREG (0xa0,0x20); - SETREG (0xa1,0x30); - SETREG (0xa2,0x00); - SETREG (0xa3,0x20); - SETREG (0xa4,0x01); - SETREG (0xa5,0x00); - SETREG (0xa6,0x00); - SETREG (0xa7,0x08); - SETREG (0xa8,0x00); - SETREG (0xa9,0x08); - SETREG (0xaa,0x01); - SETREG (0xab,0x00); - SETREG (0xac,0x00); - SETREG (0xad,0x40); - SETREG (0xae,0x01); - SETREG (0xaf,0x00); - SETREG (0xb0,0x00); - SETREG (0xb1,0x40); - SETREG (0xb2,0x00); - SETREG (0xb3,0x09); - SETREG (0xb4,0x5b); - SETREG (0xb5,0x00); - SETREG (0xb6,0x10); - SETREG (0xb7,0x3f); - SETREG (0xb8,0x00); - SETREG (0xbb,0x00); - SETREG (0xbc,0xff); - SETREG (0xbd,0x00); - SETREG (0xbe,0x07); - SETREG (0xc3,0x00); - SETREG (0xc4,0x00); - - /* gamma - SETREG (0xc5,0x00); - SETREG (0xc6,0x00); - SETREG (0xc7,0x00); - SETREG (0xc8,0x00); - SETREG (0xc9,0x00); - SETREG (0xca,0x00); - SETREG (0xcb,0x00); - SETREG (0xcc,0x00); - SETREG (0xcd,0x00); - SETREG (0xce,0x00); - */ - if(dev->model->ccd_type==CIS_CANONLIDE120) - { - SETREG (0xc5,0x20); - SETREG (0xc6,0xeb); - SETREG (0xc7,0x20); - SETREG (0xc8,0xeb); - SETREG (0xc9,0x20); - SETREG (0xca,0xeb); - } - - /* memory layout - SETREG (0xd0,0x0a); - SETREG (0xd1,0x1f); - SETREG (0xd2,0x34); */ - SETREG (0xd3,0x00); - SETREG (0xd4,0x00); - SETREG (0xd5,0x00); - SETREG (0xd6,0x00); - SETREG (0xd7,0x00); - SETREG (0xd8,0x00); - SETREG (0xd9,0x00); - - /* memory layout - SETREG (0xe0,0x00); - SETREG (0xe1,0x48); - SETREG (0xe2,0x15); - SETREG (0xe3,0x90); - SETREG (0xe4,0x15); - SETREG (0xe5,0x91); - SETREG (0xe6,0x2a); - SETREG (0xe7,0xd9); - SETREG (0xe8,0x2a); - SETREG (0xe9,0xad); - SETREG (0xea,0x40); - SETREG (0xeb,0x22); - SETREG (0xec,0x40); - SETREG (0xed,0x23); - SETREG (0xee,0x55); - SETREG (0xef,0x6b); - SETREG (0xf0,0x55); - SETREG (0xf1,0x6c); - SETREG (0xf2,0x6a); - SETREG (0xf3,0xb4); - SETREG (0xf4,0x6a); - SETREG (0xf5,0xb5); - SETREG (0xf6,0x7f); - SETREG (0xf7,0xfd);*/ - - SETREG (0xf8,0x01); /* other value is 0x05 */ - SETREG (0xf9,0x00); - SETREG (0xfa,0x00); - SETREG (0xfb,0x00); - SETREG (0xfc,0x00); - SETREG (0xff,0x00); - - /* fine tune upon device description */ - dev->reg.find_reg(0x05).value &= ~REG05_DPIHW; - switch (sanei_genesys_find_sensor_any(dev).optical_res) - { - case 600: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_600; - break; - case 1200: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_1200; - break; - case 2400: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_2400; - break; - case 4800: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_4800; - break; - } - - dev->calib_reg = dev->reg; - - DBGCOMPLETED; -} - -/**@brief send slope table for motor movement - * Send slope_table in machine byte order - * @param dev device to send slope table - * @param table_nr index of the slope table in ASIC memory - * Must be in the [0-4] range. - * @param slope_table pointer to 16 bit values array of the slope table - * @param steps number of elemnts in the slope table - */ -static SANE_Status -gl124_send_slope_table (Genesys_Device * dev, int table_nr, - uint16_t * slope_table, int steps) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - char msg[10000]; - - DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __func__, - table_nr, steps); - - /* sanity check */ - if(table_nr<0 || table_nr>4) - { - DBG (DBG_error, "%s: invalid table number %d!\n", __func__, table_nr); - return SANE_STATUS_INVAL; - } - - std::vector<uint8_t> table(steps * 2); - for (i = 0; i < steps; i++) - { - table[i * 2] = slope_table[i] & 0xff; - table[i * 2 + 1] = slope_table[i] >> 8; - } - - if (DBG_LEVEL >= DBG_io) - { - sprintf (msg, "write slope %d (%d)=", table_nr, steps); - for (i = 0; i < steps; i++) - { - sprintf (msg+strlen(msg), ",%d", slope_table[i]); - } - DBG (DBG_io, "%s: %s\n", __func__, msg); - } - - /* slope table addresses are fixed */ - status = sanei_genesys_write_ahb(dev, 0x10000000 + 0x4000 * table_nr, steps * 2, table.data()); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: write to AHB failed writing slope table %d (%s)\n", - __func__, table_nr, sane_strstatus (status)); - } - - DBGCOMPLETED; - return status; -} - -/** @brief * Set register values of 'special' ti type frontend - * Registers value are taken from the frontend register data - * set. - * @param dev device owning the AFE - * @param set flag AFE_INIT to specify the AFE must be reset before writing data - * */ -static SANE_Status -gl124_set_ti_fe (Genesys_Device * dev, uint8_t set) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - - DBGSTART; - if (set == AFE_INIT) - { - DBG (DBG_proc, "%s: setting DAC %u\n", __func__, dev->model->dac_type); - - dev->frontend = dev->frontend_initial; - } - - /* start writing to DAC */ - status = sanei_genesys_fe_write_data (dev, 0x00, 0x80); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to write reg0: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - /* write values to analog frontend */ - for (uint16_t addr = 0x01; addr < 0x04; addr++) - { - status = sanei_genesys_fe_write_data(dev, addr, dev->frontend.regs.get_value(addr)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write reg %d: %s\n", __func__, addr, - sane_strstatus(status)); - return status; - } - } - - status = sanei_genesys_fe_write_data (dev, 0x04, 0x00); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to write reg4: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - /* these are not really sign for this AFE */ - for (i = 0; i < 3; i++) - { - status = sanei_genesys_fe_write_data(dev, 0x05 + i, dev->frontend.regs.get_value(0x24 + i)); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to write reg %d: %s\n", __func__, i+5, - sane_strstatus (status)); - return status; - } - } - - /* close writing to DAC */ - if(dev->model->dac_type == DAC_CANONLIDE120) - { - status = sanei_genesys_fe_write_data (dev, 0x00, 0x01); - } - else - { - status = sanei_genesys_fe_write_data (dev, 0x00, 0x11); - } - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to write reg0: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - DBGCOMPLETED; - - return status; -} - - -/* Set values of analog frontend */ -static SANE_Status -gl124_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - DBG(DBG_proc, "%s (%s)\n", __func__, set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set == - AFE_POWER_SAVE ? "powersave" : "huh?"); - - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - dev->frontend = dev->frontend_initial; - } - - RIE (sanei_genesys_read_register (dev, REG0A, &val)); - - /* route to correct analog FE */ - switch ((val & REG0A_SIFSEL)>>REG0AS_SIFSEL) - { - case 3: - status=gl124_set_ti_fe (dev, set); - break; - case 0: - case 1: - case 2: - default: - DBG(DBG_error, "%s: unsupported analog FE 0x%02x\n", __func__, val); - status=SANE_STATUS_INVAL; - break; - } - - DBGCOMPLETED; - return status; -} - - -/**@brief compute exposure to use - * compute the sensor exposure based on target resolution - * @param dev pointer to device description - * @param xres sensor's required resolution - * @param half_ccd flag for half ccd mode - */ -static int gl124_compute_exposure(Genesys_Device *dev, int xres, int half_ccd) -{ - Sensor_Profile* sensor_profile = get_sensor_profile(dev->model->ccd_type, xres, half_ccd); - return sensor_profile->exposure; -} - - -static SANE_Status -gl124_init_motor_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int scan_exposure_time, - float scan_yres, - int scan_step_type, - unsigned int scan_lines, - unsigned int scan_dummy, - unsigned int feed_steps, - ScanColorMode scan_mode, - unsigned int flags) -{ - SANE_Status status = SANE_STATUS_GOOD; - int use_fast_fed; - unsigned int lincnt, fast_dpi; - uint16_t scan_table[SLOPE_TABLE_SIZE]; - uint16_t fast_table[SLOPE_TABLE_SIZE]; - int scan_steps,fast_steps,factor; - unsigned int feedl,dist; - uint32_t z1, z2; - float yres; - int min_speed; - unsigned int linesel; - - DBGSTART; - DBG(DBG_info, "%s : scan_exposure_time=%d, scan_yres=%g, scan_step_type=%d, scan_lines=%d, " - "scan_dummy=%d, feed_steps=%d, scan_mode=%d, flags=%x\n", __func__, scan_exposure_time, - scan_yres, scan_step_type, scan_lines, scan_dummy, feed_steps, - static_cast<unsigned>(scan_mode), flags); - - /* we never use fast fed since we do manual feed for the scans */ - use_fast_fed=0; - factor=1; - - /* enforce motor minimal scan speed - * @TODO extend motor struct for this value */ - if (scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - { - min_speed = 900; - } - else - { - switch(dev->model->motor_type) - { - case MOTOR_CANONLIDE110: - min_speed = 600; - break; - case MOTOR_CANONLIDE120: - min_speed = 900; - break; - default: - min_speed = 900; - break; - } - } - - /* compute min_speed and linesel */ - if(scan_yres<min_speed) - { - yres=min_speed; - linesel=yres/scan_yres-1; - /* limit case, we need a linesel > 0 */ - if(linesel==0) - { - linesel=1; - yres=scan_yres*2; - } - } - else - { - yres=scan_yres; - linesel=0; - } - - DBG (DBG_io2, "%s: final yres=%f, linesel=%d\n", __func__, yres, linesel); - - lincnt=scan_lines*(linesel+1); - sanei_genesys_set_triple(reg,REG_LINCNT,lincnt); - DBG (DBG_io, "%s: lincnt=%d\n", __func__, lincnt); - - /* compute register 02 value */ - uint8_t r02 = REG02_NOTHOME; - - if (use_fast_fed) { - r02 |= REG02_FASTFED; - } else { - r02 &= ~REG02_FASTFED; - } - - if (flags & MOTOR_FLAG_AUTO_GO_HOME) - r02 |= REG02_AGOHOME; - - if ((flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE) - ||(yres>=sensor.optical_res)) - { - r02 |= REG02_ACDCDIS; - } - - reg->set8(REG02, r02); - sanei_genesys_set_motor_power(*reg, true); - - /* SCANFED */ - sanei_genesys_set_double(reg,REG_SCANFED,4); - - /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - yres, - scan_exposure_time, - dev->motor.base_ydpi, - scan_step_type, - factor, - dev->model->motor_type, - motors); - RIE(gl124_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps)); - RIE(gl124_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps)); - - /* STEPNO */ - sanei_genesys_set_double(reg,REG_STEPNO,scan_steps); - - /* fast table */ - fast_dpi=yres; - - /* - if (scan_mode != ScanColorMode::COLOR_SINGLE_PASS) - { - fast_dpi*=3; - } - */ - sanei_genesys_slope_table(fast_table, - &fast_steps, - fast_dpi, - scan_exposure_time, - dev->motor.base_ydpi, - scan_step_type, - factor, - dev->model->motor_type, - motors); - RIE(gl124_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps)); - RIE(gl124_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps)); - - /* FASTNO */ - sanei_genesys_set_double(reg,REG_FASTNO,fast_steps); - - /* FSHDEC */ - sanei_genesys_set_double(reg,REG_FSHDEC,fast_steps); - - /* FMOVNO */ - sanei_genesys_set_double(reg,REG_FMOVNO,fast_steps); - - /* substract acceleration distance from feedl */ - feedl=feed_steps; - feedl<<=scan_step_type; - - dist = scan_steps; - if (flags & MOTOR_FLAG_FEED) - dist *=2; - if (use_fast_fed) - { - dist += fast_steps*2; - } - DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); - - /* get sure we don't use insane value */ - if(dist<feedl) - feedl -= dist; - else - feedl = 0; - - sanei_genesys_set_triple(reg,REG_FEEDL,feedl); - DBG (DBG_io, "%s: feedl=%d\n", __func__, feedl); - - /* doesn't seem to matter that much */ - sanei_genesys_calculate_zmode2 (use_fast_fed, - scan_exposure_time, - scan_table, - scan_steps, - feedl, - scan_steps, - &z1, - &z2); - - sanei_genesys_set_triple(reg, REG_Z1MOD,z1); - DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); - - sanei_genesys_set_triple(reg, REG_Z2MOD, z2); - DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); - - /* LINESEL */ - reg->set8_mask(REG1D, linesel, REG1D_LINESEL); - reg->set8(REGA0, (scan_step_type << REGA0S_STEPSEL) | (scan_step_type << REGA0S_FSTPSEL)); - - /* FMOVDEC */ - sanei_genesys_set_double(reg,REG_FMOVDEC,fast_steps); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/** @brief copy sensor specific settings - * Set up register set for the given sensor resolution. Values are from the device table - * in genesys_devices.c for registers: - * [0x16 ... 0x1d] - * [0x52 ... 0x5e] - * Other come from the specific device sensor table in genesys_gl124.h: - * 0x18, 0x20, 0x61, 0x98 and - * @param dev device to set up - * @param regs register set to modify - * @param dpi resolution of the sensor during scan - * @param half_ccd flag for half ccd mode - * */ -static void gl124_setup_sensor(Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, int dpi, int half_ccd) -{ - int dpihw; - uint32_t exp; - - DBGSTART; - - // we start at 6, 0-5 is a 16 bits cache for exposure - for (uint16_t addr = 0x16; addr < 0x1e; addr++) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - // skip writing 5d,5e which is AFE address because - // they are not defined in register set */ - for (uint16_t addr = 0x52; addr < 0x52 + 11; addr++) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - /* set EXPDUMMY and CKxMAP */ - dpihw = sanei_genesys_compute_dpihw(dev, sensor, dpi); - Sensor_Profile* sensor_profile = get_sensor_profile(dev->model->ccd_type, dpihw, half_ccd); - - regs->set8(0x18, sensor_profile->reg18); - regs->set8(0x20, sensor_profile->reg20); - regs->set8(0x61, sensor_profile->reg61); - regs->set8(0x98, sensor_profile->reg98); - if (sensor_profile->reg16 != 0) { - regs->set8(0x16, sensor_profile->reg16); - } - if (sensor_profile->reg70 != 0) { - regs->set8(0x70, sensor_profile->reg70); - } - - - sanei_genesys_set_triple(regs,REG_SEGCNT,sensor_profile->segcnt); - sanei_genesys_set_double(regs,REG_TG0CNT,sensor_profile->tg0cnt); - sanei_genesys_set_double(regs,REG_EXPDMY,sensor_profile->expdummy); - - /* if no calibration has been done, set default values for exposures */ - exp = sensor.exposure.red; - if(exp==0) - { - exp=sensor_profile->expr; - } - sanei_genesys_set_triple(regs,REG_EXPR,exp); - - exp =sensor.exposure.green; - if(exp==0) - { - exp=sensor_profile->expg; - } - sanei_genesys_set_triple(regs,REG_EXPG,exp); - - exp = sensor.exposure.blue; - if(exp==0) - { - exp=sensor_profile->expb; - } - sanei_genesys_set_triple(regs,REG_EXPB,exp); - - sanei_genesys_set_triple(regs,REG_CK1MAP,sensor_profile->ck1map); - sanei_genesys_set_triple(regs,REG_CK3MAP,sensor_profile->ck3map); - sanei_genesys_set_triple(regs,REG_CK4MAP,sensor_profile->ck4map); - - /* order of the sub-segments */ - dev->order=sensor_profile->order; - - DBGCOMPLETED; -} - -/** @brief setup optical related registers - * start and pixels are expressed in optical sensor resolution coordinate - * space. - * @param dev scanner device to use - * @param reg registers to set up - * @param exposure_time exposure time to use - * @param used_res scanning resolution used, may differ from - * scan's one - * @param start logical start pixel coordinate - * @param pixels logical number of pixels to use - * @param channels number of color channels (currently 1 or 3) - * @param depth bit depth of the scan (1, 8 or 16) - * @param half_ccd SANE_TRUE if sensor's timings are such that x coordinates - * must be halved - * @param color_filter color channel to use as gray data - * @param flags optical flags (@see ) - * @return SANE_STATUS_GOOD if OK - */ -static SANE_Status -gl124_init_optical_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int exposure_time, - int used_res, - unsigned int start, - unsigned int pixels, - int channels, - int depth, - SANE_Bool half_ccd, - ColorFilter color_filter, - int flags) -{ - unsigned int words_per_line, segcnt; - unsigned int startx, endx, used_pixels, segnb; - unsigned int dpiset, cksel, dpihw, factor; - unsigned int bytes; - GenesysRegister *r; - SANE_Status status = SANE_STATUS_GOOD; - uint32_t expmax, exp; - - DBG(DBG_proc, "%s : exposure_time=%d, used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, " - "half_ccd=%d, flags=%x\n", __func__, exposure_time, used_res, start, pixels, channels, depth, - half_ccd, flags); - - /* resolution is divided according to CKSEL */ - r = sanei_genesys_get_address (reg, REG18); - cksel= (r->value & REG18_CKSEL)+1; - DBG (DBG_io2, "%s: cksel=%d\n", __func__, cksel); - - /* to manage high resolution device while keeping good - * low resolution scanning speed, we make hardware dpi vary */ - dpihw=sanei_genesys_compute_dpihw(dev, sensor, used_res * cksel); - factor=sensor.optical_res/dpihw; - DBG (DBG_io2, "%s: dpihw=%d (factor=%d)\n", __func__, dpihw, factor); - - /* sensor parameters */ - gl124_setup_sensor(dev, sensor, reg, dpihw, half_ccd); - dpiset = used_res * cksel; - - /* start and end coordinate in optical dpi coordinates */ - /* startx = start/cksel + sensor.dummy_pixel; XXX STEF XXX */ - startx = start/cksel; - used_pixels=pixels/cksel; - endx = startx + used_pixels; - - /* pixel coordinate factor correction when used dpihw is not maximal one */ - startx/=factor; - endx/=factor; - used_pixels=endx-startx; - - status = gl124_set_fe(dev, sensor, AFE_SET); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to set frontend: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - /* enable shading */ - r = sanei_genesys_get_address (reg, REG01); - r->value &= ~REG01_SCAN; - if ((flags & OPTICAL_FLAG_DISABLE_SHADING) || - (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) - { - r->value &= ~REG01_DVDSET; - } - else - { - r->value |= REG01_DVDSET; - } - r->value &= ~REG01_SCAN; - - r = sanei_genesys_get_address (reg, REG03); - if((dev->model->ccd_type!=CIS_CANONLIDE120)&&(used_res>=600)) - { - r->value &= ~REG03_AVEENB; - DBG (DBG_io, "%s: disabling AVEENB\n", __func__); - } - else - { - r->value |= ~REG03_AVEENB; - DBG (DBG_io, "%s: enabling AVEENB\n", __func__); - } - - sanei_genesys_set_lamp_power(dev, sensor, *reg, !(flags & OPTICAL_FLAG_DISABLE_LAMP)); - - /* BW threshold */ - RIE (sanei_genesys_write_register (dev, REG114, dev->settings.threshold)); - RIE (sanei_genesys_write_register (dev, REG115, dev->settings.threshold)); - - /* monochrome / color scan */ - r = sanei_genesys_get_address (reg, REG04); - switch (depth) - { - case 1: - r->value &= ~REG04_BITSET; - r->value |= REG04_LINEART; - break; - case 8: - r->value &= ~(REG04_LINEART | REG04_BITSET); - break; - case 16: - r->value &= ~REG04_LINEART; - r->value |= REG04_BITSET; - break; - } - - r->value &= ~REG04_FILTER; - if (channels == 1) - { - switch (color_filter) - { - case ColorFilter::RED: - r->value |= 0x10; - break; - case ColorFilter::BLUE: - r->value |= 0x30; - break; - case ColorFilter::GREEN: - r->value |= 0x20; - break; - default: - break; // should not happen - } - } - - /* register 05 */ - r = sanei_genesys_get_address (reg, REG05); - - /* set up dpihw */ - r->value &= ~REG05_DPIHW; - switch(dpihw) - { - case 600: - r->value |= REG05_DPIHW_600; - break; - case 1200: - r->value |= REG05_DPIHW_1200; - break; - case 2400: - r->value |= REG05_DPIHW_2400; - break; - case 4800: - r->value |= REG05_DPIHW_4800; - break; - } - - /* enable gamma tables */ - if (flags & OPTICAL_FLAG_DISABLE_GAMMA) - r->value &= ~REG05_GMMENB; - else - r->value |= REG05_GMMENB; - - if(half_ccd) - { - sanei_genesys_set_double(reg,REG_DPISET,dpiset*2); - DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset*2); - } - else - { - sanei_genesys_set_double(reg,REG_DPISET,dpiset); - DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); - } - - r = sanei_genesys_get_address (reg, REG06); - r->value |= REG06_GAIN4; - - /* CIS scanners can do true gray by setting LEDADD */ - /* we set up LEDADD only when asked */ - if (dev->model->is_cis == SANE_TRUE) - { - r = sanei_genesys_get_address (reg, REG60); - r->value &= ~REG60_LEDADD; - if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) - { - r->value |= REG60_LEDADD; - sanei_genesys_get_triple(reg,REG_EXPR,&expmax); - sanei_genesys_get_triple(reg,REG_EXPG,&exp); - if(exp>expmax) - { - expmax=exp; - } - sanei_genesys_get_triple(reg,REG_EXPB,&exp); - if(exp>expmax) - { - expmax=exp; - } - sanei_genesys_set_triple(&dev->reg,REG_EXPR,expmax); - sanei_genesys_set_triple(&dev->reg,REG_EXPG,expmax); - sanei_genesys_set_triple(&dev->reg,REG_EXPB,expmax); - } - /* RGB weighting, REG_TRUER,G and B are to be set */ - r = sanei_genesys_get_address (reg, 0x01); - r->value &= ~REG01_TRUEGRAY; - if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) - { - r->value |= REG01_TRUEGRAY; - sanei_genesys_write_register (dev, REG_TRUER, 0x80); - sanei_genesys_write_register (dev, REG_TRUEG, 0x80); - sanei_genesys_write_register (dev, REG_TRUEB, 0x80); - } - } - - /* segment number */ - r = sanei_genesys_get_address (reg, 0x98); - segnb = r->value & 0x0f; - - sanei_genesys_set_triple(reg,REG_STRPIXEL,startx/segnb); - DBG (DBG_io2, "%s: strpixel used=%d\n", __func__, startx/segnb); - sanei_genesys_get_triple(reg,REG_SEGCNT,&segcnt); - if(endx/segnb==segcnt) - { - endx=0; - } - sanei_genesys_set_triple(reg,REG_ENDPIXEL,endx/segnb); - DBG (DBG_io2, "%s: endpixel used=%d\n", __func__, endx/segnb); - - /* words(16bit) before gamma, conversion to 8 bit or lineart */ - words_per_line = (used_pixels * dpiset) / dpihw; - bytes = depth / 8; - if (depth == 1) - { - words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0); - } - else - { - words_per_line *= bytes; - } - - dev->bpl = words_per_line; - dev->cur = 0; - dev->skip = 0; - dev->len = dev->bpl/segnb; - dev->dist = dev->bpl/segnb; - dev->segnb = segnb; - dev->line_count = 0; - dev->line_interp = 0; - - DBG (DBG_io2, "%s: used_pixels =%d\n", __func__, used_pixels); - DBG (DBG_io2, "%s: pixels =%d\n", __func__, pixels); - DBG (DBG_io2, "%s: depth =%d\n", __func__, depth); - DBG (DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long)dev->bpl); - DBG (DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long)dev->len); - DBG (DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long)dev->dist); - DBG (DBG_io2, "%s: dev->line_interp=%lu\n", __func__, (unsigned long)dev->line_interp); - - words_per_line *= channels; - dev->wpl = words_per_line; - - /* allocate buffer for odd/even pixels handling */ - dev->oe_buffer.clear(); - dev->oe_buffer.alloc(dev->wpl); - - /* MAXWD is expressed in 2 words unit */ - sanei_genesys_set_triple(reg,REG_MAXWD,(words_per_line)); - DBG (DBG_io2, "%s: words_per_line used=%d\n", __func__, words_per_line); - - sanei_genesys_set_triple(reg,REG_LPERIOD,exposure_time); - DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time); - - sanei_genesys_set_double(reg,REG_DUMMY,sensor.dummy_pixel); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -static SANE_Status -gl124_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set* reg, - SetupParams& params) -{ - params.assert_valid(); - - int used_res; - int start, used_pixels; - int bytes_per_line; - int move; - unsigned int lincnt; - unsigned int oflags, mflags; /**> optical and motor flags */ - int exposure_time; - int stagger; - - int dummy = 0; - int slope_dpi = 0; - int scan_step_type = 1; - int max_shift; - size_t requested_buffer_size, read_buffer_size; - - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - unsigned optical_res; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - - half_ccd=compute_half_ccd(sensor, params.xres); - - /* optical_res */ - optical_res = sensor.optical_res; - if (half_ccd) - optical_res /= 2; - DBG (DBG_info, "%s: optical_res=%d\n", __func__, optical_res); - - /* stagger */ - if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG (DBG_info, "gl124_init_scan_regs : stagger=%d lines\n", stagger); - - /** @brief compute used resolution */ - if (params.flags & SCAN_FLAG_USE_OPTICAL_RES) - { - used_res = optical_res; - } - else - { - /* resolution is choosen from a fixed list and can be used directly, - * unless we have ydpi higher than sensor's maximum one */ - if(params.xres>optical_res) - used_res=optical_res; - else - used_res = params.xres; - } - - /* compute scan parameters values */ - /* pixels are allways given at full optical resolution */ - /* use detected left margin and fixed value */ - /* start */ - /* add x coordinates */ - start = params.startx; - - if (stagger > 0) - start |= 1; - - /* compute correct pixels number */ - used_pixels = (params.pixels * optical_res) / params.xres; - DBG (DBG_info, "%s: used_pixels=%d\n", __func__, used_pixels); - - /* round up pixels number if needed */ - if (used_pixels * params.xres < params.pixels * optical_res) - used_pixels++; - - /* we want even number of pixels here */ - if(used_pixels & 1) - used_pixels++; - - /* slope_dpi */ - /* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */ - if (dev->model->is_cis) - slope_dpi = params.yres * params.channels; - else - slope_dpi = params.yres; - - /* scan_step_type */ - if(params.flags & SCAN_FLAG_FEEDING) - { - scan_step_type=0; - exposure_time=MOVE_EXPOSURE; - } - else - { - exposure_time = gl124_compute_exposure (dev, used_res, half_ccd); - scan_step_type = sanei_genesys_compute_step_type(motors, dev->model->motor_type, exposure_time); - } - - DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, scan_step_type); - - /*** optical parameters ***/ - /* in case of dynamic lineart, we use an internal 8 bit gray scan - * to generate 1 lineart data */ - if (params.flags & SCAN_FLAG_DYNAMIC_LINEART) { - params.depth = 8; - } - - /* we enable true gray for cis scanners only, and just when doing - * scan since color calibration is OK for this mode - */ - oflags = 0; - if (params.flags & SCAN_FLAG_DISABLE_SHADING) - oflags |= OPTICAL_FLAG_DISABLE_SHADING; - if (params.flags & SCAN_FLAG_DISABLE_GAMMA) - oflags |= OPTICAL_FLAG_DISABLE_GAMMA; - if (params.flags & SCAN_FLAG_DISABLE_LAMP) - oflags |= OPTICAL_FLAG_DISABLE_LAMP; - if (params.flags & SCAN_FLAG_CALIBRATION) - oflags |= OPTICAL_FLAG_DISABLE_DOUBLE; - - if (dev->model->is_cis && dev->settings.true_gray) - { - oflags |= OPTICAL_FLAG_ENABLE_LEDADD; - } - - /* now _LOGICAL_ optical values used are known, setup registers */ - status = gl124_init_optical_regs_scan (dev, - sensor, - reg, - exposure_time, - used_res, - start, - used_pixels, - params.channels, - params.depth, - half_ccd, - params.color_filter, - oflags); - if (status != SANE_STATUS_GOOD) - return status; - - /*** motor parameters ***/ - - /* max_shift */ - max_shift=sanei_genesys_compute_max_shift(dev,params.channels,params.yres,params.flags); - - /* lines to scan */ - lincnt = params.lines + max_shift + stagger; - - /* add tl_y to base movement */ - move = params.starty; - DBG(DBG_info, "%s: move=%d steps\n", __func__, move); - - mflags=0; - if(params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) - mflags|=MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; - if(params.flags & SCAN_FLAG_FEEDING) - mflags|=MOTOR_FLAG_FEED; - - status = gl124_init_motor_regs_scan (dev, sensor, - reg, - exposure_time, - slope_dpi, - scan_step_type, - dev->model->is_cis ? lincnt * params.channels : lincnt, - dummy, - move, - params.scan_mode, - mflags); - if (status != SANE_STATUS_GOOD) - return status; - - /*** prepares data reordering ***/ - - /* words_per_line */ - bytes_per_line = (used_pixels * used_res) / optical_res; - bytes_per_line = (bytes_per_line * params.channels * params.depth) / 8; - - /* since we don't have sheetfed scanners to handle, - * use huge read buffer */ - /* TODO find the best size according to settings */ - requested_buffer_size = 16 * bytes_per_line; - - read_buffer_size = - 2 * requested_buffer_size + - ((max_shift + stagger) * used_pixels * params.channels * params.depth) / 8; - - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); - - dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); - - dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); - - dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * dev->settings.pixels * params.channels * params.depth) / 8); - - dev->read_bytes_left = bytes_per_line * lincnt; - - DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); - dev->read_active = SANE_TRUE; - - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; - DBG(DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - - dev->total_bytes_read = 0; - if (params.depth == 1) - dev->total_bytes_to_read = - ((dev->settings.pixels * dev->settings.lines) / 8 + - (((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) * - params.channels; - else - dev->total_bytes_to_read = - dev->settings.pixels * dev->settings.lines * params.channels * (params.depth / 8); - - DBG(DBG_info, "%s: total bytes to send = %lu\n", __func__, (u_long) dev->total_bytes_to_read); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static void -gl124_calculate_current_setup (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int depth; - int start; - - int used_res; - int used_pixels; - unsigned int lincnt; - int exposure_time; - int stagger; - SANE_Bool half_ccd; - - int max_shift, dpihw; - - int optical_res; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - /* start */ - start = SANE_UNFIX (dev->model->x_offset); - start += dev->settings.tl_x; - start = (start * sensor.optical_res) / MM_PER_INCH; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; - params.starty = 0; // not used - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = 0; - - half_ccd=compute_half_ccd(sensor, params.xres); - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - - /* optical_res */ - optical_res = sensor.optical_res; - - if (params.xres <= (unsigned) optical_res) - used_res = params.xres; - else - used_res=optical_res; - - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - - /* compute correct pixels number */ - used_pixels = (params.pixels * optical_res) / params.xres; - DBG (DBG_info, "%s: used_pixels=%d\n", __func__, used_pixels); - - /* exposure */ - exposure_time = gl124_compute_exposure (dev, params.xres, half_ccd); - DBG (DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - - /* max_shift */ - max_shift=sanei_genesys_compute_max_shift(dev, params.channels, params.yres, 0); - - /* compute hw dpi for sensor */ - dpihw=sanei_genesys_compute_dpihw(dev, sensor,used_res); - - Sensor_Profile* sensor_profile = get_sensor_profile(dev->model->ccd_type, dpihw, half_ccd); - dev->segnb=sensor_profile->reg98 & 0x0f; - - /* stagger */ - if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG (DBG_info, "%s: stagger=%d lines\n", __func__, stagger); - - /* lincnt */ - lincnt = params.lines + max_shift + stagger; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; - DBG (DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - - DBGCOMPLETED; -} - -/** - * for fast power saving methods only, like disabling certain amplifiers - * @param dev device to use - * @param enable true to set inot powersaving - * */ -static SANE_Status -gl124_save_power (Genesys_Device * dev, SANE_Bool enable) -{ - DBG(DBG_proc, "%s: enable = %d\n", __func__, enable); - if (dev == NULL) - return SANE_STATUS_INVAL; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl124_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ ) -{ - GenesysRegister *r; - - DBG(DBG_proc, "%s (delay = %d)\n", __func__, delay); - - r = sanei_genesys_get_address (&dev->reg, REG03); - r->value &= ~0xf0; - if(delay<15) - { - r->value |= delay; - } - else - { - r->value |= 0x0f; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl124_start_action (Genesys_Device * dev) -{ - return sanei_genesys_write_register (dev, 0x0f, 0x01); -} - -static SANE_Status -gl124_stop_action (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val40, val; - unsigned int loop; - - DBGSTART; - - /* post scan gpio : without that HOMSNR is unreliable */ - gl124_homsnr_gpio(dev); - - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - status = sanei_genesys_read_register (dev, REG100, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read reg100: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* only stop action if needed */ - if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG)) - { - DBG (DBG_info, "%s: already stopped\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - /* ends scan */ - val = dev->reg.get8(REG01); - val &= ~REG01_SCAN; - dev->reg.set8(REG01, val); - status = sanei_genesys_write_register (dev, REG01, val); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to write register 01: %s\n", __func__, - sane_strstatus (status)); - return status; - } - sanei_genesys_sleep_ms(100); - - loop = 10; - while (loop > 0) - { - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - status = sanei_genesys_read_register (dev, REG100, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus (status)); - DBGCOMPLETED; - return status; - } - - /* if scanner is in command mode, we are done */ - if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG) - && !(val & MOTORENB)) - { - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - sanei_genesys_sleep_ms(100); - loop--; - } - - DBGCOMPLETED; - return SANE_STATUS_IO_ERROR; -} - - -/** @brief setup GPIOs for scan - * Setup GPIO values to drive motor (or light) needed for the - * target resolution - * @param *dev device to set up - * @param resolution dpi of the target scan - * @return SANE_STATUS_GOOD unless REG32 cannot be read - */ -static SANE_Status -gl124_setup_scan_gpio(Genesys_Device *dev, int resolution) -{ -SANE_Status status = SANE_STATUS_GOOD; -uint8_t val; - - DBGSTART; - RIE (sanei_genesys_read_register (dev, REG32, &val)); - - /* LiDE 110, 210 and 220 cases */ - if(dev->model->gpo_type != GPO_CANONLIDE120) - { - if(resolution>=dev->motor.base_ydpi/2) - { - val &= 0xf7; - } - else if(resolution>=dev->motor.base_ydpi/4) - { - val &= 0xef; - } - else - { - val |= 0x10; - } - } - /* 120 : <=300 => 0x53 */ - else - { /* base_ydpi is 4800 */ - if(resolution<=300) - { - val &= 0xf7; - } - else if(resolution<=600) - { - val |= 0x08; - } - else if(resolution<=1200) - { - val &= 0xef; - val |= 0x08; - } - else - { - val &= 0xf7; - } - } - val |= 0x02; - RIE (sanei_genesys_write_register (dev, REG32, val)); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* Send the low-level scan command */ -/* todo : is this that useful ? */ -static SANE_Status -gl124_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SANE_Bool start_motor) -{ - (void) sensor; - - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - DBGSTART; - if (reg == NULL) - return SANE_STATUS_INVAL; - - /* set up GPIO for scan */ - RIE(gl124_setup_scan_gpio(dev,dev->settings.yres)); - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - - /* enable scan and motor */ - RIE (sanei_genesys_read_register (dev, REG01, &val)); - val |= REG01_SCAN; - RIE (sanei_genesys_write_register (dev, REG01, val)); - - if (start_motor) - { - RIE (sanei_genesys_write_register (dev, REG0F, 1)); - } - else - { - RIE (sanei_genesys_write_register (dev, REG0F, 0)); - } - - DBGCOMPLETED; - return status; -} - - -/* Send the stop scan command */ -static SANE_Status -gl124_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (check_stop = %d)\n", __func__, check_stop); - if (reg == NULL) - return SANE_STATUS_INVAL; - - if (dev->model->is_sheetfed == SANE_TRUE) - { - status = SANE_STATUS_GOOD; - } - else /* flat bed scanners */ - { - status = gl124_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - return status; -} - - -/** rewind scan - * Move back by the same amount of distance than previous scan. - * @param dev device to rewind - * @returns SANE_STATUS_GOOD on success - */ -static -SANE_Status gl124_rewind(Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t byte; - - DBGSTART; - - /* set motor reverse */ - RIE (sanei_genesys_read_register (dev, 0x02, &byte)); - byte |= 0x04; - RIE (sanei_genesys_write_register(dev, 0x02, byte)); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - /* and start scan, then wait completion */ - RIE (gl124_begin_scan (dev, sensor, &dev->reg, SANE_TRUE)); - do - { - sanei_genesys_sleep_ms(100); - RIE (sanei_genesys_read_register (dev, REG100, &byte)); - } - while(byte & REG100_MOTMFLG); - RIE (gl124_end_scan (dev, &dev->reg, SANE_TRUE)); - - /* restore direction */ - RIE (sanei_genesys_read_register (dev, 0x02, &byte)); - byte &= 0xfb; - RIE (sanei_genesys_write_register(dev, 0x02, byte)); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/** Park head - * Moves the slider to the home (top) position slowly - * @param dev device to park - * @param wait_until_home true to make the function waiting for head - * to be home before returning, if fals returne immediately - * @returns SANE_STATUS_GOO on success */ -static -SANE_Status -gl124_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - uint8_t val; - float resolution; - int loop = 0; - - DBG(DBG_proc, "%s (wait_until_home = %d)\n", __func__, wait_until_home); - - /* post scan gpio : without that HOMSNR is unreliable */ - gl124_homsnr_gpio(dev); - - /* first read gives HOME_SENSOR true */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - sanei_genesys_sleep_ms(100); - - /* second is reliable */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - /* is sensor at home? */ - if (val & HOMESNR) - { - DBG (DBG_info, "%s: already at home, completed\n", __func__); - dev->scanhead_position_in_steps = 0; - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - /* feed a little first */ - if (dev->model->model_id == MODEL_CANON_LIDE_210) - { - status = gl124_feed (dev, 20, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to do initial feed: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - local_reg = dev->reg; - resolution=sanei_genesys_get_lowest_dpi(dev); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 100; - params.starty = 30000; - params.pixels = 100; - params.lines = 100; - params.depth = 8; - params.channels = 1; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - - /* set up for reverse and no scan */ - r = sanei_genesys_get_address(&local_reg, REG02); - r->value |= REG02_MTRREV; - - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - RIE(gl124_setup_scan_gpio(dev,resolution)); - - try { - status = gl124_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl124_stop_action (dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl124_stop_action (dev); - } catch (...) {} - /* restore original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - /* post scan gpio : without that HOMSNR is unreliable */ - gl124_homsnr_gpio(dev); - - if (wait_until_home) - { - - while (loop < 300) /* do not wait longer then 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - if (val & HOMESNR) /* home sensor */ - { - DBG(DBG_info, "%s: reached home position\n", __func__); - DBGCOMPLETED; - dev->scanhead_position_in_steps = 0; - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl124_stop_action (dev); - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief moves the slider to steps at motor base dpi - * @param dev device to work on - * @param steps number of steps to move - * @param reverse true is moving backward - * */ -static SANE_Status -gl124_feed (Genesys_Device * dev, unsigned int steps, int reverse) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - float resolution; - uint8_t val; - - DBGSTART; - DBG (DBG_io, "%s: steps=%d\n", __func__, steps); - - /* prepare local registers */ - local_reg = dev->reg; - - resolution=sanei_genesys_get_lowest_ydpi(dev); - const auto& sensor = sanei_genesys_find_sensor(dev, resolution); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = steps; - params.pixels = 100; - params.lines = 3; - params.depth = 8; - params.channels = 3; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus (status)); - DBGCOMPLETED; - return status; - } - - /* set exposure to zero */ - sanei_genesys_set_triple(&local_reg,REG_EXPR,0); - sanei_genesys_set_triple(&local_reg,REG_EXPG,0); - sanei_genesys_set_triple(&local_reg,REG_EXPB,0); - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT)); - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRMCNT)); - - /* set up for no scan */ - r = sanei_genesys_get_address (&local_reg, REG01); - r->value &= ~REG01_SCAN; - - /* set up for reverse if needed */ - if(reverse) - { - r = sanei_genesys_get_address (&local_reg, REG02); - r->value |= REG02_MTRREV; - } - - /* send registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - status = gl124_start_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus (status)); - gl124_stop_action (dev); - - /* restore original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - /* wait until feed count reaches the required value, but do not - * exceed 30s */ - do - { - status = sanei_genesys_get_status (dev, &val); - } - while (status == SANE_STATUS_GOOD && !(val & FEEDFSH)); - - /* then stop scanning */ - RIE(gl124_stop_action (dev)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels - area at 600 dpi from very top of scanner */ -static SANE_Status -gl124_search_start_position (Genesys_Device * dev) -{ - int size; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg = dev->reg; - int steps; - - int pixels = 600; - int dpi = 300; - - DBGSTART; - - /* sets for a 200 lines * 600 pixels */ - /* normal scan with no shading */ - - // FIXME: the current approach of doing search only for one resolution does not work on scanners - // whith employ different sensors with potentially different settings. - auto& sensor = sanei_genesys_find_sensor_for_write(dev, dpi); - - SetupParams params; - params.xres = dpi; - params.yres = dpi; - params.startx = 0; - params.starty = 0; /*we should give a small offset here~60 steps */ - params.pixels = 600; - params.lines = dev->model->search_lines; - params.depth = 8; - params.channels = 1; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::GREEN; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; - - status = gl124_init_scan_regs(dev, sensor, &local_reg, params); - - if (status!=SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to init scan registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* send to scanner */ - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - size = pixels * dev->model->search_lines; - - std::vector<uint8_t> data(size); - - status = gl124_begin_scan (dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner (dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl124_search_position.pnm", data.data(), 8, 1, pixels, - dev->model->search_lines); - - status = gl124_end_scan (dev, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* update regs to copy ASIC internal state */ - dev->reg = local_reg; - - status = - sanei_genesys_search_reference_point (dev, sensor, data.data(), 0, dpi, pixels, - dev->model->search_lines); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set search reference point: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* - * sets up register for coarse gain calibration - * todo: check it for scanners using it */ -static SANE_Status -gl124_init_regs_for_coarse_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t channels; - uint8_t cksel; - - DBGSTART; - cksel = (regs.find_reg(0x18).value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */ - - /* set line size */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) { - channels = 3; - } else { - channels = 1; - } - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = sensor.optical_res / cksel; - params.lines = 20; - params.depth = 16; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_set_motor_power(regs, false); - - DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, - sensor.optical_res / cksel, dev->settings.xres); - - status = dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* init registers for shading calibration */ -/* shading calibration is done at dpihw */ -static SANE_Status -gl124_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - int move, resolution, dpihw, factor; - - DBGSTART; - - /* initial calibration reg values */ - regs = dev->reg; - - dev->calib_channels = 3; - dev->calib_lines = dev->model->shading_lines; - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dev->settings.xres); - if(dpihw>=2400) - { - dev->calib_lines *= 2; - } - resolution=dpihw; - - /* if half CCD mode, use half resolution */ - if(compute_half_ccd(sensor, dev->settings.xres)==SANE_TRUE) - { - resolution /= 2; - dev->calib_lines /= 2; - } - dev->calib_resolution = resolution; - dev->calib_total_bytes_to_read = 0; - factor=sensor.optical_res/resolution; - dev->calib_pixels = sensor.sensor_pixels/factor; - - /* distance to move to reach white target at high resolution */ - move=0; - if(dev->settings.yres>=1200) - { - move = SANE_UNFIX (dev->model->y_offset_calib); - move = (move * (dev->motor.base_ydpi/4)) / MM_PER_INCH; - } - DBG (DBG_io, "%s: move=%d steps\n", __func__, move); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = move; - params.pixels = dev->calib_pixels; - params.lines = dev->calib_lines; - params.depth = 16; - params.channels = dev->calib_channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, ®s, params); - - sanei_genesys_set_motor_power(regs, false); - - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to setup scan: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - dev->scanhead_position_in_steps += dev->calib_lines + move; - - status = dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to bulk write registers: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static void gl124_wait_for_motor_stop(Genesys_Device* dev) -{ - DBG_HELPER(dbg); - uint8_t val40, val; - - TIE(sanei_genesys_get_status(dev, &val)); - TIE(sanei_genesys_read_register(dev, REG100, &val40)); - - if ((val & MOTORENB) == 0 && (val40 & REG100_MOTMFLG) == 0) - return; - - do { - sanei_genesys_sleep_ms(10); - TIE(sanei_genesys_get_status(dev, &val)); - TIE(sanei_genesys_read_register(dev, REG100, &val40)); - } while ((val & MOTORENB) ||(val40 & REG100_MOTMFLG)); - sanei_genesys_sleep_ms(50); -} - -/** @brief set up registers for the actual scan - */ -static SANE_Status -gl124_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int flags; - int depth; - float move; - int move_dpi; - float start; - - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - /* y (motor) distance to move to reach scanned area */ - move_dpi = dev->motor.base_ydpi/4; - move = SANE_UNFIX (dev->model->y_offset); - move += dev->settings.tl_y; - move = (move * move_dpi) / MM_PER_INCH; - DBG (DBG_info, "%s: move=%f steps\n", __func__, move); - - if(channels*dev->settings.yres>=600 && move>700) - { - status = gl124_feed (dev, move-500, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to move to scan area\n",__func__); - return status; - } - move=500; - } - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - /* start */ - start = SANE_UNFIX (dev->model->x_offset); - start += dev->settings.tl_x; - if(compute_half_ccd(sensor, dev->settings.xres)==SANE_TRUE) - { - start /=2; - } - start = (start * sensor.optical_res) / MM_PER_INCH; - - flags = 0; - - /* enable emulated lineart from gray data */ - if(dev->settings.scan_mode == ScanColorMode::LINEART - && dev->settings.dynamic_lineart) - { - flags |= SCAN_FLAG_DYNAMIC_LINEART; - } - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; - params.starty = move; - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = flags; - - status = gl124_init_scan_regs(dev, sensor, &dev->reg, params); - - if (status != SANE_STATUS_GOOD) - return status; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** - * Send shading calibration data. The buffer is considered to always hold values - * for all the channels. - */ -static SANE_Status -gl124_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint32_t addr, length, strpixel ,endpixel, x, factor, segcnt, pixels, i; - uint32_t lines, channels; - uint16_t dpiset,dpihw; - uint8_t val,*ptr,*src; - - DBGSTART; - DBG( DBG_io2, "%s: writing %d bytes of shading data\n",__func__,size); - - /* logical size of a color as seen by generic code of the frontend */ - length = (uint32_t) (size / 3); - sanei_genesys_get_triple(&dev->reg,REG_STRPIXEL,&strpixel); - sanei_genesys_get_triple(&dev->reg,REG_ENDPIXEL,&endpixel); - sanei_genesys_get_triple(&dev->reg,REG_SEGCNT,&segcnt); - if(endpixel==0) - { - endpixel=segcnt; - } - DBG( DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d, SEGCNT=%d\n",__func__,strpixel,endpixel,endpixel-strpixel,segcnt); - - /* compute deletion factor */ - sanei_genesys_get_double(&dev->reg,REG_DPISET,&dpiset); - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dpiset); - factor=dpihw/dpiset; - DBG( DBG_io2, "%s: factor=%d\n",__func__,factor); - - /* binary data logging */ - if(DBG_LEVEL>=DBG_data) - { - dev->binary=fopen("binary.pnm","wb"); - sanei_genesys_get_triple(&dev->reg, REG_LINCNT, &lines); - channels=dev->current_setup.channels; - if(dev->binary!=NULL) - { - fprintf(dev->binary,"P5\n%d %d\n%d\n",(endpixel-strpixel)/factor*channels*dev->segnb,lines/channels,255); - } - } - - /* turn pixel value into bytes 2x16 bits words */ - strpixel*=2*2; /* 2 words of 2 bytes */ - endpixel*=2*2; - segcnt*=2*2; - pixels=endpixel-strpixel; - - DBG( DBG_io2, "%s: using chunks of %d bytes (%d shading data pixels)\n",__func__,length, length/4); - std::vector<uint8_t> buffer(pixels * dev->segnb, 0); - - /* write actual red data */ - for(i=0;i<3;i++) - { - /* copy data to work buffer and process it */ - /* coefficent destination */ - ptr = buffer.data(); - - /* iterate on both sensor segment */ - for(x=0;x<pixels;x+=4*factor) - { - /* coefficient source */ - src=data+x+strpixel+i*length; - - /* iterate over all the segments */ - switch(dev->segnb) - { - case 1: - ptr[0+pixels*0]=src[0+segcnt*0]; - ptr[1+pixels*0]=src[1+segcnt*0]; - ptr[2+pixels*0]=src[2+segcnt*0]; - ptr[3+pixels*0]=src[3+segcnt*0]; - break; - case 2: - ptr[0+pixels*0]=src[0+segcnt*0]; - ptr[1+pixels*0]=src[1+segcnt*0]; - ptr[2+pixels*0]=src[2+segcnt*0]; - ptr[3+pixels*0]=src[3+segcnt*0]; - ptr[0+pixels*1]=src[0+segcnt*1]; - ptr[1+pixels*1]=src[1+segcnt*1]; - ptr[2+pixels*1]=src[2+segcnt*1]; - ptr[3+pixels*1]=src[3+segcnt*1]; - break; - case 4: - ptr[0+pixels*0]=src[0+segcnt*0]; - ptr[1+pixels*0]=src[1+segcnt*0]; - ptr[2+pixels*0]=src[2+segcnt*0]; - ptr[3+pixels*0]=src[3+segcnt*0]; - ptr[0+pixels*1]=src[0+segcnt*2]; - ptr[1+pixels*1]=src[1+segcnt*2]; - ptr[2+pixels*1]=src[2+segcnt*2]; - ptr[3+pixels*1]=src[3+segcnt*2]; - ptr[0+pixels*2]=src[0+segcnt*1]; - ptr[1+pixels*2]=src[1+segcnt*1]; - ptr[2+pixels*2]=src[2+segcnt*1]; - ptr[3+pixels*2]=src[3+segcnt*1]; - ptr[0+pixels*3]=src[0+segcnt*3]; - ptr[1+pixels*3]=src[1+segcnt*3]; - ptr[2+pixels*3]=src[2+segcnt*3]; - ptr[3+pixels*3]=src[3+segcnt*3]; - break; - } - - /* next shading coefficient */ - ptr+=4; - } - RIE (sanei_genesys_read_register (dev, 0xd0+i, &val)); - addr = val * 8192 + 0x10000000; - status = sanei_genesys_write_ahb(dev, addr, pixels*dev->segnb, buffer.data()); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s; write to AHB failed (%s)\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - - return status; -} - - -/** @brief move to calibration area - * This functions moves scanning head to calibration area - * by doing a 600 dpi scan - * @param dev scanner device - * @return SANE_STATUS_GOOD on success, else the error code - */ -static SANE_Status -move_to_calibration_area (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - int pixels; - int size; - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - - pixels = (sensor.sensor_pixels*600)/sensor.optical_res; - - /* initial calibration reg values */ - regs = dev->reg; - - SetupParams params; - params.xres = 600; - params.yres = 600; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = 1; - params.depth = 8; - params.channels = 3; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus (status)); - return status; - } - - size = pixels * 3; - std::vector<uint8_t> line(size); - - /* write registers and scan data */ - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - DBG (DBG_info, "%s: starting line reading\n", __func__); - RIE(gl124_begin_scan (dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), size)); - - /* stop scanning */ - RIE(gl124_stop_action (dev)); - - if (DBG_LEVEL >= DBG_data) - { - sanei_genesys_write_pnm_file("gl124_movetocalarea.pnm", line.data(), 8, 3, pixels, 1); - } - - DBGCOMPLETED; - return status; -} - -/* this function does the led calibration by scanning one line of the calibration - area below scanner's top on white strip. - --needs working coarse/gain -*/ -static SANE_Status -gl124_led_calibration (Genesys_Device * dev, Genesys_Sensor& sensor, Genesys_Register_Set& regs) -{ - int num_pixels; - int total_size; - int resolution; - int dpihw; - int i, j; - SANE_Status status = SANE_STATUS_GOOD; - int val; - int channels, depth; - int avg[3]; - int turn; - uint16_t exp[3],target; - SANE_Bool acceptable; - SANE_Bool half_ccd; - - DBGSTART; - - /* move to calibration area */ - move_to_calibration_area(dev, sensor, regs); - - /* offset calibration is always done in 16 bit depth color mode */ - channels = 3; - depth=16; - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dev->settings.xres); - half_ccd=compute_half_ccd(sensor, dev->settings.xres); - if(half_ccd==SANE_TRUE) - { - resolution = dpihw/2; - } - else - { - resolution = dpihw; - } - Sensor_Profile* sensor_profile = get_sensor_profile(dev->model->ccd_type, dpihw, half_ccd); - num_pixels = (sensor.sensor_pixels*resolution)/sensor.optical_res; - - /* initial calibration reg values */ - regs = dev->reg; - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = 0; - params.pixels = num_pixels; - params.lines = 1; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus (status)); - return status; - } - - total_size = num_pixels * channels * (depth/8) * 1; /* colors * bytes_per_color * scan lines */ - std::vector<uint8_t> line(total_size); - - /* initial loop values and boundaries */ - exp[0]=sensor_profile->expr; - exp[1]=sensor_profile->expg; - exp[2]=sensor_profile->expb; - target=sensor.gain_white_ref*256; - - turn = 0; - - /* no move during led calibration */ - sanei_genesys_set_motor_power(regs, false); - do - { - /* set up exposure */ - sanei_genesys_set_triple(®s,REG_EXPR,exp[0]); - sanei_genesys_set_triple(®s,REG_EXPG,exp[1]); - sanei_genesys_set_triple(®s,REG_EXPB,exp[2]); - - /* write registers and scan data */ - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - DBG(DBG_info, "%s: starting line reading\n", __func__); - RIE(gl124_begin_scan (dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, line.data(), total_size)); - - /* stop scanning */ - RIE(gl124_stop_action (dev)); - - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl124_led_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, line.data(), depth, channels, num_pixels, 1); - } - - /* compute average */ - for (j = 0; j < channels; j++) - { - avg[j] = 0; - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * num_pixels + 1] * 256 + - line[i * 2 + j * 2 * num_pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - avg[j] += val; - } - - avg[j] /= num_pixels; - } - - DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); - - /* check if exposure gives average within the boundaries */ - acceptable = SANE_TRUE; - for(i=0;i<3;i++) - { - /* we accept +- 2% delta from target */ - if(abs(avg[i]-target)>target/50) - { - exp[i]=(exp[i]*target)/avg[i]; - acceptable = SANE_FALSE; - } - } - - turn++; - } - while (!acceptable && turn < 100); - - DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); - - /* set these values as final ones for scan */ - sanei_genesys_set_triple(&dev->reg,REG_EXPR,exp[0]); - sanei_genesys_set_triple(&dev->reg,REG_EXPG,exp[1]); - sanei_genesys_set_triple(&dev->reg,REG_EXPB,exp[2]); - - /* store in this struct since it is the one used by cache calibration */ - sensor.exposure.red = exp[0]; - sensor.exposure.green = exp[1]; - sensor.exposure.blue = exp[2]; - - DBGCOMPLETED; - return status; -} - -/** - * average dark pixels of a 8 bits scan - */ -static int -dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, - unsigned int channels, unsigned int black) -{ - unsigned int i, j, k, average, count; - unsigned int avg[3]; - uint8_t val; - - /* computes average value on black margin */ - for (k = 0; k < channels; k++) - { - avg[k] = 0; - count = 0; - for (i = 0; i < lines; i++) - { - for (j = 0; j < black; j++) - { - val = data[i * channels * pixels + j + k]; - avg[k] += val; - count++; - } - } - if (count) - avg[k] /= count; - DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); - } - average = 0; - for (i = 0; i < channels; i++) - average += avg[i]; - average /= channels; - DBG(DBG_info, "%s: average = %d\n", __func__, average); - return average; -} - - -static SANE_Status -gl124_offset_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t reg0a; - unsigned int channels, bpp; - int pass = 0, avg, total_size; - int topavg, bottomavg, resolution, lines; - int top, bottom, black_pixels, pixels; - - DBGSTART; - - /* no gain nor offset for TI AFE */ - RIE (sanei_genesys_read_register (dev, REG0A, ®0a)); - if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3) - { - DBGCOMPLETED; - return status; - } - - /* offset calibration is always done in color mode */ - channels = 3; - resolution=sensor.optical_res; - dev->calib_pixels = sensor.sensor_pixels; - lines=1; - bpp=8; - pixels= (sensor.sensor_pixels*resolution) / sensor.optical_res; - black_pixels = (sensor.black_pixels * resolution) / sensor.optical_res; - DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = bpp; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_set_motor_power(regs, false); - - /* allocate memory for scans */ - total_size = pixels * channels * lines * (bpp/8); /* colors * bytes_per_color * scan lines */ - - std::vector<uint8_t> first_line(total_size); - std::vector<uint8_t> second_line(total_size); - - /* init gain */ - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - - /* scan with no move */ - bottom = 10; - dev->frontend.set_offset(0, bottom); - dev->frontend.set_offset(1, bottom); - dev->frontend.set_offset(2, bottom); - - RIE(gl124_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting first line reading\n", __func__); - RIE(gl124_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size)); - if (DBG_LEVEL >= DBG_data) - { - char title[30]; - snprintf(title, 30, "gl124_offset%03d.pnm", bottom); - sanei_genesys_write_pnm_file(title, first_line.data(), bpp, channels, pixels, lines); - } - - bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); - - /* now top value */ - top = 255; - dev->frontend.set_offset(0, top); - dev->frontend.set_offset(1, top); - dev->frontend.set_offset(2, top); - RIE(gl124_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl124_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, second_line.data(), total_size)); - - topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); - - /* loop until acceptable level */ - while ((pass < 32) && (top - bottom > 1)) - { - pass++; - - /* settings for new scan */ - dev->frontend.set_offset(0, (top + bottom) / 2); - dev->frontend.set_offset(1, (top + bottom) / 2); - dev->frontend.set_offset(2, (top + bottom) / 2); - - /* scan with no move */ - RIE(gl124_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl124_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) - { - char title[30]; - snprintf(title, 30, "gl124_offset%03d.pnm", dev->frontend.get_offset(1)); - sanei_genesys_write_pnm_file(title, second_line.data(), bpp, channels, pixels, lines); - } - - avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); - - /* compute new boundaries */ - if (topavg == avg) - { - topavg = avg; - top = dev->frontend.get_offset(1); - } - else - { - bottomavg = avg; - bottom = dev->frontend.get_offset(1); - } - } - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* alternative coarse gain calibration - this on uses the settings from offset_calibration and - uses only one scanline - */ -/* - with offset and coarse calibration we only want to get our input range into - a reasonable shape. the fine calibration of the upper and lower bounds will - be done with shading. - */ -static SANE_Status -gl124_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi) -{ - int pixels; - int total_size; - uint8_t reg0a; - int i, j, channels; - SANE_Status status = SANE_STATUS_GOOD; - int max[3]; - float gain[3],coeff; - int val, code, lines; - int resolution; - int bpp; - - DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi); - - /* no gain nor offset for TI AFE */ - RIE (sanei_genesys_read_register (dev, REG0A, ®0a)); - if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3) - { - DBGCOMPLETED; - return status; - } - - /* coarse gain calibration is always done in color mode */ - channels = 3; - - /* follow CKSEL */ - if(dev->settings.xres<sensor.optical_res) - { - coeff=0.9; - /*resolution=sensor.optical_res/2;*/ - resolution=sensor.optical_res; - } - else - { - resolution=sensor.optical_res; - coeff=1.0; - } - lines=10; - bpp=8; - pixels = (sensor.sensor_pixels * resolution) / sensor.optical_res; - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = bpp; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - try { - status = gl124_init_scan_regs(dev, sensor, ®s, params); - } catch (...) { - try { - sanei_genesys_set_motor_power(regs, false); - } catch (...) {} - throw; - } - - sanei_genesys_set_motor_power(regs, false); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - RIE (dev->model->cmd_set->bulk_write_register(dev, regs)); - - total_size = pixels * channels * (16/bpp) * lines; - - std::vector<uint8_t> line(total_size); - - RIE(gl124_set_fe(dev, sensor, AFE_SET)); - RIE(gl124_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl124_gain.pnm", line.data(), bpp, channels, pixels, lines); - - /* average value on each channel */ - for (j = 0; j < channels; j++) - { - max[j] = 0; - for (i = pixels/4; i < (pixels*3/4); i++) - { - if(bpp==16) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * pixels + 1] * 256 + - line[i * 2 + j * 2 * pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - } - else - { - if (dev->model->is_cis) - val = line[i + j * pixels]; - else - val = line[i * channels + j]; - } - - max[j] += val; - } - max[j] = max[j] / (pixels/2); - - gain[j] = ((float) sensor.gain_white_ref*coeff) / max[j]; - - /* turn logical gain value into gain code, checking for overflow */ - code = 283 - 208 / gain[j]; - if (code > 255) - code = 255; - else if (code < 0) - code = 0; - dev->frontend.set_gain(j, code); - - DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], - gain[j], dev->frontend.get_gain(j)); - } - - if (dev->model->is_cis) { - uint8_t gain0 = dev->frontend.get_gain(0); - if (gain0 > dev->frontend.get_gain(1)) { - gain0 = dev->frontend.get_gain(1); - } - if (gain0 > dev->frontend.get_gain(2)) { - gain0 = dev->frontend.get_gain(2); - } - dev->frontend.set_gain(0, gain0); - dev->frontend.set_gain(1, gain0); - dev->frontend.set_gain(2, gain0); - } - - if (channels == 1) { - dev->frontend.set_gain(0, dev->frontend.get_gain(1)); - dev->frontend.set_gain(2, dev->frontend.get_gain(1)); - } - - RIE (gl124_stop_action (dev)); - - status = gl124_slow_back_home (dev, SANE_TRUE); - - DBGCOMPLETED; - return status; -} - -/* - * wait for lamp warmup by scanning the same line until difference - * between 2 scans is below a threshold - */ -static SANE_Status -gl124_init_regs_for_warmup (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - int *channels, int *total_size) -{ - int num_pixels; - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - if (dev == NULL || reg == NULL || channels == NULL || total_size == NULL) - return SANE_STATUS_INVAL; - - *channels=3; - - *reg = dev->reg; - - SetupParams params; - params.xres = sensor.optical_res; - params.yres = dev->motor.base_ydpi; - params.startx = sensor.sensor_pixels / 4; - params.starty = 0; - params.pixels = sensor.sensor_pixels / 2; - params.lines = 1; - params.depth = 8; - params.channels = *channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl124_init_scan_regs(dev, sensor, reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - num_pixels = dev->current_setup.pixels; - - *total_size = num_pixels * 3 * 1; /* colors * bytes_per_color * scan lines */ - - sanei_genesys_set_motor_power(*reg, false); - RIE (dev->model->cmd_set->bulk_write_register(dev, *reg)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief default GPIO values - * set up GPIO/GPOE for idle state - * @param dev device to set up - * @return SANE_STATUS_GOOD unless a GPIO register cannot be written - */ -static SANE_Status -gl124_init_gpio (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - int idx; - - DBGSTART; - - /* per model GPIO layout */ - if (dev->model->model_id == MODEL_CANON_LIDE_110) - { - idx = 0; - } - else if (dev->model->model_id == MODEL_CANON_LIDE_120) - { - idx = 2; - } - else - { /* canon LiDE 210 and 220 case */ - idx = 1; - } - - RIE (sanei_genesys_write_register (dev, REG31, gpios[idx].r31)); - RIE (sanei_genesys_write_register (dev, REG32, gpios[idx].r32)); - RIE (sanei_genesys_write_register (dev, REG33, gpios[idx].r33)); - RIE (sanei_genesys_write_register (dev, REG34, gpios[idx].r34)); - RIE (sanei_genesys_write_register (dev, REG35, gpios[idx].r35)); - RIE (sanei_genesys_write_register (dev, REG36, gpios[idx].r36)); - RIE (sanei_genesys_write_register (dev, REG38, gpios[idx].r38)); - - DBGCOMPLETED; - return status; -} - -/** - * set memory layout by filling values in dedicated registers - */ -static SANE_Status -gl124_init_memory_layout (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - int idx = 0; - - DBGSTART; - - /* point to per model memory layout */ - if (dev->model->model_id == MODEL_CANON_LIDE_110 ||dev->model->model_id == MODEL_CANON_LIDE_120) - { - idx = 0; - } - else - { /* canon LiDE 210 and 220 case */ - idx = 1; - } - - /* setup base address for shading data. */ - /* values must be multiplied by 8192=0x4000 to give address on AHB */ - /* R-Channel shading bank0 address setting for CIS */ - sanei_genesys_write_register (dev, 0xd0, layouts[idx].rd0); - /* G-Channel shading bank0 address setting for CIS */ - sanei_genesys_write_register (dev, 0xd1, layouts[idx].rd1); - /* B-Channel shading bank0 address setting for CIS */ - sanei_genesys_write_register (dev, 0xd2, layouts[idx].rd2); - - /* setup base address for scanned data. */ - /* values must be multiplied by 1024*2=0x0800 to give address on AHB */ - /* R-Channel ODD image buffer 0x0124->0x92000 */ - /* size for each buffer is 0x16d*1k word */ - sanei_genesys_write_register (dev, 0xe0, layouts[idx].re0); - sanei_genesys_write_register (dev, 0xe1, layouts[idx].re1); - /* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/ - sanei_genesys_write_register (dev, 0xe2, layouts[idx].re2); - sanei_genesys_write_register (dev, 0xe3, layouts[idx].re3); - - /* R-Channel EVEN image buffer 0x0292 */ - sanei_genesys_write_register (dev, 0xe4, layouts[idx].re4); - sanei_genesys_write_register (dev, 0xe5, layouts[idx].re5); - /* R-Channel EVEN image buffer end-address 0x03ff*/ - sanei_genesys_write_register (dev, 0xe6, layouts[idx].re6); - sanei_genesys_write_register (dev, 0xe7, layouts[idx].re7); - - /* same for green, since CIS, same addresses */ - sanei_genesys_write_register (dev, 0xe8, layouts[idx].re0); - sanei_genesys_write_register (dev, 0xe9, layouts[idx].re1); - sanei_genesys_write_register (dev, 0xea, layouts[idx].re2); - sanei_genesys_write_register (dev, 0xeb, layouts[idx].re3); - sanei_genesys_write_register (dev, 0xec, layouts[idx].re4); - sanei_genesys_write_register (dev, 0xed, layouts[idx].re5); - sanei_genesys_write_register (dev, 0xee, layouts[idx].re6); - sanei_genesys_write_register (dev, 0xef, layouts[idx].re7); - -/* same for blue, since CIS, same addresses */ - sanei_genesys_write_register (dev, 0xf0, layouts[idx].re0); - sanei_genesys_write_register (dev, 0xf1, layouts[idx].re1); - sanei_genesys_write_register (dev, 0xf2, layouts[idx].re2); - sanei_genesys_write_register (dev, 0xf3, layouts[idx].re3); - sanei_genesys_write_register (dev, 0xf4, layouts[idx].re4); - sanei_genesys_write_register (dev, 0xf5, layouts[idx].re5); - sanei_genesys_write_register (dev, 0xf6, layouts[idx].re6); - sanei_genesys_write_register (dev, 0xf7, layouts[idx].re7); - - DBGCOMPLETED; - return status; -} - -/** - * initialize backend and ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home - */ -static SANE_Status -gl124_init(Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG_INIT (); - DBGSTART; - - status=sanei_genesys_asic_init(dev, 0); - - DBGCOMPLETED; - return status; -} - - -/* * - * initialize ASIC from power on condition - */ -static SANE_Status -gl124_boot (Genesys_Device * dev, SANE_Bool cold) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - DBGSTART; - - /* reset ASIC in case of cold boot */ - if(cold) - { - RIE (sanei_genesys_write_register (dev, 0x0e, 0x01)); - RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); - } - - /* enable GPOE 17 */ - RIE (sanei_genesys_write_register (dev, 0x36, 0x01)); - - /* set GPIO 17 */ - RIE (sanei_genesys_read_register (dev, 0x33, &val)); - val |= 0x01; - RIE (sanei_genesys_write_register (dev, 0x33, val)); - - /* test CHKVER */ - RIE (sanei_genesys_read_register (dev, REG100, &val)); - if (val & REG100_CHKVER) - { - RIE (sanei_genesys_read_register (dev, 0x00, &val)); - DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); - } - - /* Set default values for registers */ - gl124_init_registers (dev); - - /* Write initial registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, dev->reg)); - - /* tune reg 0B */ - val = REG0B_30MHZ | REG0B_ENBDRAM | REG0B_64M; - RIE (sanei_genesys_write_register (dev, REG0B, val)); - dev->reg.remove_reg(0x0b); - - /* set up end access */ - RIE (sanei_genesys_write_0x8c (dev, 0x10, 0x0b)); - RIE (sanei_genesys_write_0x8c (dev, 0x13, 0x0e)); - - /* CIS_LINE */ - SETREG (0x08, REG08_CIS_LINE); - RIE (sanei_genesys_write_register (dev, 0x08, dev->reg.find_reg(0x08).value)); - - /* setup gpio */ - RIE (gl124_init_gpio (dev)); - - /* setup internal memory layout */ - RIE (gl124_init_memory_layout (dev)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -static SANE_Status -gl124_update_hardware_sensors (Genesys_Scanner * s) -{ - /* do what is needed to get a new set of events, but try to not loose - any of them. - */ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val=0; - - RIE (sanei_genesys_read_register (s->dev, REG31, &val)); - - /* TODO : for the next scanner special case, - * add another per scanner button profile struct to avoid growing - * hard-coded button mapping here. - */ - if((s->dev->model->gpo_type == GPO_CANONLIDE110) - ||(s->dev->model->gpo_type == GPO_CANONLIDE120)) - { - s->buttons[BUTTON_SCAN_SW].write((val & 0x01) == 0); - s->buttons[BUTTON_FILE_SW].write((val & 0x08) == 0); - s->buttons[BUTTON_EMAIL_SW].write((val & 0x04) == 0); - s->buttons[BUTTON_COPY_SW].write((val & 0x02) == 0); - } - else - { /* LiDE 210 case */ - s->buttons[BUTTON_EXTRA_SW].write((val & 0x01) == 0); - s->buttons[BUTTON_SCAN_SW].write((val & 0x02) == 0); - s->buttons[BUTTON_COPY_SW].write((val & 0x04) == 0); - s->buttons[BUTTON_EMAIL_SW].write((val & 0x08) == 0); - s->buttons[BUTTON_FILE_SW].write((val & 0x10) == 0); - } - return status; -} - - -/** the gl124 command set */ -static Genesys_Command_Set gl124_cmd_set = { - "gl124-generic", /* the name of this set */ - - [](Genesys_Device* dev) -> bool { (void) dev; return true; }, - - gl124_init, - gl124_init_regs_for_warmup, - gl124_init_regs_for_coarse_calibration, - gl124_init_regs_for_shading, - gl124_init_regs_for_scan, - - gl124_get_filter_bit, - gl124_get_lineart_bit, - gl124_get_bitset_bit, - gl124_get_gain4_bit, - gl124_get_fast_feed_bit, - gl124_test_buffer_empty_bit, - gl124_test_motor_flag_bit, - - gl124_set_fe, - gl124_set_powersaving, - gl124_save_power, - - gl124_begin_scan, - gl124_end_scan, - - sanei_genesys_send_gamma_table, - - gl124_search_start_position, - - gl124_offset_calibration, - gl124_coarse_gain_calibration, - gl124_led_calibration, - - gl124_wait_for_motor_stop, - gl124_slow_back_home, - gl124_rewind, - - sanei_genesys_bulk_write_register, - NULL, - sanei_genesys_bulk_read_data, - - gl124_update_hardware_sensors, - - /* no sheetfed support for now */ - NULL, - NULL, - NULL, - NULL, - - sanei_genesys_is_compatible_calibration, - NULL, - gl124_send_shading_data, - gl124_calculate_current_setup, - gl124_boot -}; - -SANE_Status -sanei_gl124_init_cmd_set (Genesys_Device * dev) -{ - dev->model->cmd_set = &gl124_cmd_set; - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_gl124.h b/backend/genesys_gl124.h deleted file mode 100644 index 751321d..0000000 --- a/backend/genesys_gl124.h +++ /dev/null @@ -1,489 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2010-2016 Stéphane Voltz <stef.dev@free.fr> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#include "genesys.h" - -#define REG01 0x01 -#define REG01_CISSET 0x80 -#define REG01_DOGENB 0x40 -#define REG01_DVDSET 0x20 -#define REG01_STAGGER 0x10 -#define REG01_COMPENB 0x08 -#define REG01_TRUEGRAY 0x04 -#define REG01_SHDAREA 0x02 -#define REG01_SCAN 0x01 - -#define REG02 0x02 -#define REG02_NOTHOME 0x80 -#define REG02_ACDCDIS 0x40 -#define REG02_AGOHOME 0x20 -#define REG02_MTRPWR 0x10 -#define REG02_FASTFED 0x08 -#define REG02_MTRREV 0x04 -#define REG02_HOMENEG 0x02 -#define REG02_LONGCURV 0x01 - -#define REG03 0x03 -#define REG03_LAMPDOG 0x80 -#define REG03_AVEENB 0x40 -#define REG03_XPASEL 0x20 -#define REG03_LAMPPWR 0x10 -#define REG03_LAMPTIM 0x0f - -#define REG04 0x04 -#define REG04_LINEART 0x80 -#define REG04_BITSET 0x40 -#define REG04_FILTER 0x30 -#define REG04_AFEMOD 0x07 - -#define REG05 0x05 -#define REG05_DPIHW 0xc0 -#define REG05_DPIHW_600 0x00 -#define REG05_DPIHW_1200 0x40 -#define REG05_DPIHW_2400 0x80 -#define REG05_DPIHW_4800 0xc0 -#define REG05_MTLLAMP 0x30 -#define REG05_GMMENB 0x08 -#define REG05_ENB20M 0x04 -#define REG05_MTLBASE 0x03 - -#define REG06 0x06 -#define REG06_SCANMOD 0xe0 -#define REG06S_SCANMOD 5 -#define REG06_PWRBIT 0x10 -#define REG06_GAIN4 0x08 -#define REG06_OPTEST 0x07 - -#define REG07_LAMPSIM 0x80 - -#define REG08_DRAM2X 0x80 -#define REG08_MPENB 0x20 -#define REG08_CIS_LINE 0x10 -#define REG08_IR2_ENB 0x08 -#define REG08_IR1_ENB 0x04 -#define REG08_ENB24M 0x01 - -#define REG09_MCNTSET 0xc0 -#define REG09_EVEN1ST 0x20 -#define REG09_BLINE1ST 0x10 -#define REG09_BACKSCAN 0x08 -#define REG09_OUTINV 0x04 -#define REG09_SHORTTG 0x02 - -#define REG09S_MCNTSET 6 -#define REG09S_CLKSET 4 - -#define REG0A 0x0a -#define REG0A_SIFSEL 0xc0 -#define REG0AS_SIFSEL 6 -#define REG0A_SHEETFED 0x20 -#define REG0A_LPWMEN 0x10 - -#define REG0B 0x0b -#define REG0B_DRAMSEL 0x07 -#define REG0B_16M 0x01 -#define REG0B_64M 0x02 -#define REG0B_128M 0x03 -#define REG0B_256M 0x04 -#define REG0B_512M 0x05 -#define REG0B_1G 0x06 -#define REG0B_ENBDRAM 0x08 -#define REG0B_RFHDIS 0x10 -#define REG0B_CLKSET 0xe0 -#define REG0B_24MHZ 0x00 -#define REG0B_30MHZ 0x20 -#define REG0B_40MHZ 0x40 -#define REG0B_48MHZ 0x60 -#define REG0B_60MHZ 0x80 - -#define REG0D 0x0d -#define REG0D_MTRP_RDY 0x80 -#define REG0D_FULLSTP 0x10 -#define REG0D_CLRMCNT 0x04 -#define REG0D_CLRDOCJM 0x02 -#define REG0D_CLRLNCNT 0x01 - -#define REG0F 0x0f - -#define REG16_CTRLHI 0x80 -#define REG16_TOSHIBA 0x40 -#define REG16_TGINV 0x20 -#define REG16_CK1INV 0x10 -#define REG16_CK2INV 0x08 -#define REG16_CTRLINV 0x04 -#define REG16_CKDIS 0x02 -#define REG16_CTRLDIS 0x01 - -#define REG17_TGMODE 0xc0 -#define REG17_SNRSYN 0x0f - -#define REG18 0x18 -#define REG18_CNSET 0x80 -#define REG18_DCKSEL 0x60 -#define REG18_CKTOGGLE 0x10 -#define REG18_CKDELAY 0x0c -#define REG18_CKSEL 0x03 - -#define REG1A_SW2SET 0x80 -#define REG1A_SW1SET 0x40 -#define REG1A_MANUAL3 0x02 -#define REG1A_MANUAL1 0x01 -#define REG1A_CK4INV 0x08 -#define REG1A_CK3INV 0x04 -#define REG1A_LINECLP 0x02 - -#define REG1C_TBTIME 0x07 - -#define REG1D 0x1d -#define REG1D_CK4LOW 0x80 -#define REG1D_CK3LOW 0x40 -#define REG1D_CK1LOW 0x20 -#define REG1D_LINESEL 0x1f -#define REG1DS_LINESEL 0 - -#define REG1E 0x1e -#define REG1E_WDTIME 0xf0 -#define REG1ES_WDTIME 4 -#define REG1E_WDTIME 0xf0 - -#define REG30 0x30 -#define REG31 0x31 -#define REG32 0x32 -#define REG32_GPIO16 0x80 -#define REG32_GPIO15 0x40 -#define REG32_GPIO14 0x20 -#define REG32_GPIO13 0x10 -#define REG32_GPIO12 0x08 -#define REG32_GPIO11 0x04 -#define REG32_GPIO10 0x02 -#define REG32_GPIO9 0x01 -#define REG33 0x33 -#define REG34 0x34 -#define REG35 0x35 -#define REG36 0x36 -#define REG37 0x37 -#define REG38 0x38 -#define REG39 0x39 - -#define REG60 0x60 -#define REG60_LED4TG 0x80 -#define REG60_YENB 0x40 -#define REG60_YBIT 0x20 -#define REG60_ACYNCNRLC 0x10 -#define REG60_ENOFFSET 0x08 -#define REG60_LEDADD 0x04 -#define REG60_CK4ADC 0x02 -#define REG60_AUTOCONF 0x01 - -#define REG80 0x80 -#define REG81 0x81 - -#define REGA0 0xa0 -#define REGA0_FSTPSEL 0x28 -#define REGA0S_FSTPSEL 3 -#define REGA0_STEPSEL 0x03 -#define REGA0S_STEPSEL 0 - -#define REGA1 0xa1 -#define REGA2 0xa2 -#define REGA3 0xa3 -#define REGA4 0xa4 -#define REGA5 0xa5 -#define REGA6 0xa6 -#define REGA7 0xa7 -#define REGA8 0xa8 -#define REGA9 0xa9 -#define REGAA 0xaa -#define REGAB 0xab -#define REGAC 0xac -#define REGAD 0xad -#define REGAE 0xae -#define REGAF 0xaf -#define REGB0 0xb0 -#define REGB1 0xb1 - -#define REGB2 0xb2 -#define REGB2_Z1MOD 0x1f -#define REGB3 0xb3 -#define REGB3_Z1MOD 0xff -#define REGB4 0xb4 -#define REGB4_Z1MOD 0xff - -#define REGB5 0xb5 -#define REGB5_Z2MOD 0x1f -#define REGB6 0xb6 -#define REGB6_Z2MOD 0xff -#define REGB7 0xb7 -#define REGB7_Z2MOD 0xff - -#define REG100 0x100 -#define REG100_DOCSNR 0x80 -#define REG100_ADFSNR 0x40 -#define REG100_COVERSNR 0x20 -#define REG100_CHKVER 0x10 -#define REG100_DOCJAM 0x08 -#define REG100_HISPDFLG 0x04 -#define REG100_MOTMFLG 0x02 -#define REG100_DATAENB 0x01 - -#define REG114 0x114 -#define REG115 0x115 - -#define REG_LINCNT 0x25 -#define REG_MAXWD 0x28 -#define REG_DPISET 0x2c -#define REG_FEEDL 0x3d -#define REG_CK1MAP 0x74 -#define REG_CK3MAP 0x77 -#define REG_CK4MAP 0x7a -#define REG_LPERIOD 0x7d -#define REG_DUMMY 0x80 -#define REG_STRPIXEL 0x82 -#define REG_ENDPIXEL 0x85 -#define REG_EXPDMY 0x88 -#define REG_EXPR 0x8a -#define REG_EXPG 0x8d -#define REG_EXPB 0x90 -#define REG_SEGCNT 0x93 -#define REG_TG0CNT 0x96 -#define REG_SCANFED 0xa2 -#define REG_STEPNO 0xa4 -#define REG_FWDSTEP 0xa6 -#define REG_BWDSTEP 0xa8 -#define REG_FASTNO 0xaa -#define REG_FSHDEC 0xac -#define REG_FMOVNO 0xae -#define REG_FMOVDEC 0xb0 -#define REG_Z1MOD 0xb2 -#define REG_Z2MOD 0xb5 - -#define REG_TRUER 0x110 -#define REG_TRUEG 0x111 -#define REG_TRUEB 0x112 - -#define SETREG(adr,val) { dev->reg.init_reg(adr, val); } - -typedef struct -{ - uint8_t r31; - uint8_t r32; - uint8_t r33; - uint8_t r34; - uint8_t r35; - uint8_t r36; - uint8_t r38; -} Gpio_layout; - -/** @brief gpio layout - * describes initial gpio settings for a given model - * registers 0x31 to 0x38 - */ -static Gpio_layout gpios[]={ - /* LiDE 110 */ - { /* 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38 */ - 0x9f, 0x59, 0x01, 0x80, 0x5f, 0x01, 0x00 - }, - /* LiDE 210 */ - { - 0x9f, 0x59, 0x01, 0x80, 0x5f, 0x01, 0x00 - }, - /* LiDE 120 */ - { - 0x9f, 0x53, 0x01, 0x80, 0x5f, 0x01, 0x00 - }, -}; - -typedef struct -{ - uint8_t rd0; - uint8_t rd1; - uint8_t rd2; - uint8_t re0; - uint8_t re1; - uint8_t re2; - uint8_t re3; - uint8_t re4; - uint8_t re5; - uint8_t re6; - uint8_t re7; -} Memory_layout; - -static Memory_layout layouts[]={ - /* LIDE 110, 120 */ - { /* 0xd0 0xd1 0xd2 */ - 0x0a, 0x15, 0x20, - /* 0xe0 0xe1 0xe2 0xe3 0xe4 0xe5 0xe6 0xe7 */ - 0x00, 0xac, 0x08, 0x55, 0x08, 0x56, 0x0f, 0xff - }, - /* LIDE 210, 220 */ - { - 0x0a, 0x1f, 0x34, - 0x01, 0x24, 0x08, 0x91, 0x08, 0x92, 0x0f, 0xff - } -}; - -/** @brief structure for sensor settings - * this structure describes the sensor settings to use for a given - * exposure. Data settings are identified by - * - sensor id - * - sensor hardware dpi - * - half ccd mode - */ -typedef struct { - int sensor_type; /**> sensor id */ - int dpi; /**> maximum dpi for which data are valid */ - int half_ccd; /**> half ccd mode */ - int exposure; /**> exposure */ - int ck1map; /**> CK1MAP */ - int ck3map; /**> CK3MAP */ - int ck4map; /**> CK4MAP */ - int segcnt; /**> SEGCNT */ - int tg0cnt; /**> TG0CNT */ - int expdummy; /**> exposure dummy */ - int expr; /**> initial red exposure */ - int expg; /**> initial green exposure */ - int expb; /**> initial blue exposure */ - size_t *order; /**> order of sub-segments */ - uint8_t reg18; /**> register 0x18 value */ - uint8_t reg20; /**> register 0x20 value */ - uint8_t reg61; /**> register 0x61 value */ - uint8_t reg98; /**> register 0x98 value */ - uint8_t reg16; /**> register 0x16 value */ - uint8_t reg70; /**> register 0x70 value */ -} Sensor_Profile; - -static size_t order_01[]={0,1}; -static size_t order_0213[]={0,2,1,3}; - -/** @brief database of sensor profiles - * database of sensor profiles giving for each sensor and a given resolution, the period, and timings - * to setup the sensor for the scan. - */ -static Sensor_Profile sensors[]={ - /* LiDE 110 */ - {CIS_CANONLIDE110, 600, 1, 2768, 0x1e, 0x9f, 0x55, 2584, 154, 101, 388, 574, 393, NULL , 0x00, 0x0c, 0x20, 0x21, 0x00, 0x00}, - {CIS_CANONLIDE110, 600, 0, 5360, 0x1e, 0x9f, 0x55, 5168, 163, 101, 388, 574, 393, NULL , 0x00, 0x0a, 0x20, 0x21, 0x00, 0x00}, - {CIS_CANONLIDE110, 1200, 0, 10528, 0x1e, 0x9f, 0x55, 5168, 163, 101, 388, 574, 393, order_01 , 0x00, 0x08, 0x20, 0x22, 0x00, 0x00}, - {CIS_CANONLIDE110, 2400, 0, 20864, 0x1e, 0x9f, 0x55, 5168, 163, 4679, 6839, 8401, 6859, order_0213, 0x00, 0x06, 0x20, 0x24, 0x00, 0x00}, - - /* LiDE 120 */ - {CIS_CANONLIDE120, 600, 1, 4608, 0x0f, 0x00, 0x55, 2552, 112, 94, 894, 1044, 994, NULL , 0x00, 0x02, 0x20, 0x21, 0x15, 0x00}, - {CIS_CANONLIDE120, 600, 0, 5360, 0x0f, 0x00, 0x55, 5104, 139, 94, 1644, 1994, 1844, NULL , 0x00, 0x02, 0x20, 0x21, 0x11, 0x1f}, - {CIS_CANONLIDE120, 1200, 0, 10528, 0x0f, 0x00, 0x55,10208, 192, 94, 3194, 3794, 3594, NULL , 0x00, 0x02, 0x20, 0x21, 0x15, 0x1f}, - {CIS_CANONLIDE120, 2400, 0, 20864, 0x0f, 0x00, 0x55,20416, 298, 94, 6244, 7544, 7094, NULL , 0x00, 0x02, 0x20, 0x21, 0x11, 0x00}, - - /* LiDE 210 */ - {CIS_CANONLIDE210, 600, 1, 2768, 0x1e, 0x9f, 0x55, 2584, 154, 101, 388, 574, 393, NULL , 0x00, 0x0c, 0x20, 0x21, 0x00, 0x00}, - {CIS_CANONLIDE210, 600, 0, 5360, 0x1e, 0x9f, 0x55, 5168, 163, 101, 388, 574, 393, NULL , 0x00, 0x0a, 0x20, 0x21, 0x00, 0x00}, - {CIS_CANONLIDE210, 1200, 0, 10528, 0x1e, 0x9f, 0x55, 5168, 163, 101, 388, 574, 393, order_01 , 0x00, 0x08, 0x20, 0x22, 0x00, 0x00}, - {CIS_CANONLIDE210, 2400, 0, 20864, 0x1e, 0x9f, 0x55, 5168, 163, 4679, 6839, 8401, 6859, order_0213, 0x00, 0x06, 0x20, 0x24, 0x00, 0x00}, - - /* LiDE 220 */ - {CIS_CANONLIDE220, 600, 1, 2768, 0x0f, 0x9f, 0x55, 2584, 154, 101, 388, 574, 393, NULL , 0x00, 0x0c, 0x20, 0x21, 0x00, 0x00}, - {CIS_CANONLIDE220, 600, 0, 5360, 0x0f, 0x9f, 0x55, 5168, 163, 101, 388, 574, 393, NULL , 0x00, 0x0a, 0x20, 0x21, 0x00, 0x00}, - {CIS_CANONLIDE220, 1200, 0, 10528, 0x0f, 0x9f, 0x55, 5168, 163, 101, 388, 574, 393, order_01 , 0x00, 0x08, 0x20, 0x22, 0x00, 0x00}, - {CIS_CANONLIDE220, 2400, 0, 20864, 0x0f, 0x9f, 0x55, 5168, 163, 4679, 6839, 8401, 6859, order_0213, 0x00, 0x06, 0x20, 0x24, 0x00, 0x00}, -}; - - -#define MOVE_DPI 200 -#define MOVE_EXPOSURE 2304 -/** @brief reference slope tables - * slope table directly extracted from USB logs, with a 'termination' value of 0. - */ -static uint32_t lide210_fast[] = { 62496, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2051, 1432, 1372, 1323, 1280, 1246, 1216, 1188, 1163, 1142, 1121, 1101, 1084, 1068, 1051, 1036, 1020, 1007, 995, 983, 971, 959, 949, 938, 929, 917, 908, 900, 891, 882, 874, 866, 857, 849, 843, 835, 829, 821, 816, 808, 802, 795, 789, 784, 778, 773, 765, 760, 755, 749, 744, 739, 734, 731, 726, 721, 716, 711, 707, 702, 698, 693, 690, 685, 682, 677, 672, 669, 665, 662, 657, 654, 650, 647, 644, 639, 637, 632, 629, 626, 622, 619, 617, 614, 610, 607, 604, 601, 599, 595, 592, 589, 587, 584, 581, 579, 576, 572, 570, 567, 564, 562, 559, 557, 554, 552, 549, 547, 544, 542, 539, 538, 536, 533, 531, 529, 526, 524, 522, 519, 518, 516, 513, 511, 509, 506, 505, 503, 501, 498, 497, 495, 493, 491, 490, 487, 485, 483, 482, 480, 477, 476, 474, 472, 470, 469, 467, 465, 464, 462, 460, 458, 456, 455, 453, 451, 450, 448, 447, 445, 444, 442, 440, 439, 437, 436, 434, 433, 431, 430, 428, 427, 425, 423, 422, 420, 419, 417, 417, 415, 414, 413, 411, 410, 408, 407, 405, 404, 402, 401, 400, 399, 398, 396, 395, 393, 392, 391, 390, 389, 387, 386, 385, 383, 382, 381, 380, 379, 377, 376, 375, 374, 373, 371, 370, 369, 368, 367, 366, 364, 363, 363, 361, 360, 359, 358, 357, 356, 355, 353, 352, 352, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 335, 335, 0}; -static uint32_t lide110_ok[] = { 62496, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2051, 1961, 1901, 1852, 1809, 1775, 1745, 1717, 1692, 1671, 1650, 1630, 1613, 1597, 1580, 1565, 1549, 1536, 1524, 1512, 1500, 1488, 1478, 1467, 1458, 1446, 1437, 1429, 1420, 1411, 1403, 1395, 1386, 1378, 1372, 1364, 1358, 1350, 1345, 1337, 1331, 1324, 1318, 1313, 1307, 1302, 1294, 1289, 1284, 1278, 1273, 1268, 1263, 1260, 1255, 1250, 1245, 1240, 1236, 1231, 1227, 1222, 1219, 1214, 1211, 1206, 1201, 1198, 1194, 1191, 1186, 1183, 1179, 1176, 1173, 1168, 1166, 1161, 1158, 1155, 1151, 1148, 1146, 1143, 1139, 1136, 1133, 1130, 1128, 1124, 1121, 1118, 1116, 1113, 1110, 1108, 1105, 1101, 1099, 1096, 1093, 1091, 1088, 1086, 1083, 1081, 1078, 1076, 1073, 1071, 1068, 1067, 1065, 1062, 1060, 1058, 1055, 1053, 1051, 1048, 1047, 1045, 1042, 1040, 1038, 1035, 1034, 1032, 1030, 1027, 1026, 1024, 1022, 1020, 1019, 1016, 1014, 1012, 1011, 1009, 1006, 1005, 1003, 1001, 999, 998, 996, 994, 993, 991, 989, 987, 985, 984, 982, 980, 979, 977, 976, 974, 973, 971, 969, 968, 966, 965, 963, 962, 960, 959, 957, 956, 954, 952, 951, 949, 948, 946, 946, 944, 943, 942, 940, 939, 937, 936, 934, 933, 931, 930, 929, 928, 927, 925, 924, 922, 921, 920, 919, 918, 916, 915, 914, 912, 911, 910, 909, 908, 906, 905, 904, 903, 902, 900, 899, 898, 897, 896, 895, 893, 892, 892, 890, 889, 888, 887, 886, 885, 884, 882, 881, 881, 879, 878, 877, 876, 875, 874, 873, 872, 871, 870, 869, 868, 867, 864, 857, 849, 843, 835, 829, 821, 816, 808, 802, 795, 789, 784, 778, 773, 765, 760, 755, 749, 744, 739, 734, 731, 726, 721, 716, 711, 707, 702, 698, 693, 690, 685, 682, 677, 672, 669, 665, 662, 657, 654, 650, 647, 644, 639, 637, 632, 629, 626, 622, 619, 617, 614, 610, 607, 604, 601, 599, 595, 592, 589, 587, 584, 581, 579, 576, 572, 570, 567, 564, 562, 559, 557, 554, 552, 549, 547, 544, 542, 539, 538, 536, 533, 531, 529, 526, 524, 522, 519, 518, 516, 513, 511, 509, 506, 505, 503, 501, 498, 497, 495, 493, 491, 490, 487, 485, 483, 482, 480, 477, 476, 474, 472, 470, 469, 467, 465, 464, 462, 460, 458, 456, 455, 453, 451, 450, 448, 447, 445, 444, 442, 440, 439, 437, 436, 434, 433, 431, 430, 428, 427, 425, 423, 422, 420, 419, 417, 417, 415, 414, 413, 411, 410, 408, 407, 405, 404, 402, 401, 400, 399, 398, 396, 395, 393, 392, 391, 390, 389, 387, 386, 385, 383, 382, 381, 380, 379, 377, 376, 375, 374, 373, 371, 370, 369, 368, 367, 366, 364, 363, 363, 361, 360, 359, 358, 357, 356, 355, 353, 352, 352, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 335, 335, 0}; -static uint32_t lide120_fast[] = { 62496, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 1957, 1845, 1768, 1710, 1665, 1624, 1588, 1557, 1529, 1504, 1481, 1458, 1440, 1420, 1403, 1386, 1370, 1356, 1343, 1329, 1316, 1303, 1293, 1280, 1270, 1260, 1250, 1241, 1231, 1222, 1214, 1206, 1197, 1189, 1182, 1174, 1167, 1160, 1153, 1147, 1140, 1133, 1128, 1121, 1116, 1110, 1104, 1099, 1093, 1088, 1082, 1077, 1072, 1067, 1062, 1058, 1053, 1049, 1045, 1040, 1035, 1032, 1027, 1023, 1020, 1015, 1012, 1008, 1004, 1000, 997, 993, 989, 985, 982, 979, 975, 972, 969, 966, 963, 959, 956, 953, 950, 947, 945, 942, 939, 936, 933, 930, 928, 925, 922, 920, 917, 914, 911, 909, 907, 904, 902, 899, 897, 895, 892, 890, 888, 886, 883, 881, 879, 876, 874, 872, 870, 864, 864, 0}; -static uint32_t lide120_ok[] = { 62496, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2286, 2264, 2248, 2232, 2221, 2211, 2205, 2195, 2190, 2180, 2175, 2170, 2160, 2155, 2150, 2145, 2140, 2135, 2130, 2125, 2121, 2116, 2111, 2106, 2106, 2102, 2097, 2092, 2087, 2087, 2083, 2078, 2074, 2074, 2069, 2064, 2064, 2060, 2055, 2055, 2051, 2051, 2046, 2042, 2042, 2038, 2038, 2033, 2029, 2029, 2024, 2024, 2020, 2010, 2010, 670*2, 0}; -static uint32_t lide110_slow[] = { 62496, 7896, 2632, 0}; -static uint32_t lide120_slow[] = { 62464, 7896, 2632, 0}; -static uint32_t lide110_max[] = { 62496, 31296, 10432, 0}; -static uint32_t lide120_max[] = { 62592, 62592, 41728, 31296, 10432, 0}; -static uint32_t lide210_max[] = { 62496, 31296, 20864, 10432, 0}; - -/* NEXT LPERIOD=PREVIOUS*2-192 */ -/** @brief database of motor profiles - * database of motor profiles, for each exposure deigned for the sensor, gives the reference slope table to use - * for scan. - */ -static Motor_Profile motors[]={ - {MOTOR_CANONLIDE110, 2768, 0, lide210_fast}, - {MOTOR_CANONLIDE110, 5360, 1, lide110_ok}, - {MOTOR_CANONLIDE110, 10528, 1, lide110_slow}, - {MOTOR_CANONLIDE110, 20864, 2, lide110_max}, - {MOTOR_CANONLIDE120, 4608, 0, lide120_fast}, - {MOTOR_CANONLIDE120, 5360, 1, lide120_ok}, - {MOTOR_CANONLIDE120, 10528, 2, lide120_slow}, - {MOTOR_CANONLIDE120, 20864, 2, lide120_max}, - {MOTOR_CANONLIDE210, 2768, 0, lide210_fast}, - {MOTOR_CANONLIDE210, 5360, 1, lide110_ok}, - {MOTOR_CANONLIDE210, 10528, 1, lide110_slow}, - {MOTOR_CANONLIDE210, 20864, 2, lide210_max}, - {0, 0, 0, NULL}, -}; - -static -SANE_Status gl124_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, SetupParams& params); - -static SANE_Status gl124_start_action (Genesys_Device * dev); -static SANE_Status -gl124_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SANE_Bool start_motor); -static SANE_Status -gl124_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop); -static SANE_Status -gl124_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home); -static SANE_Status gl124_init(Genesys_Device * dev); -static SANE_Status gl124_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size); - -static SANE_Status gl124_feed (Genesys_Device * dev, unsigned int steps, int reverse); - -static SANE_Status -gl124_stop_action (Genesys_Device * dev); - -static SANE_Status -gl124_send_slope_table (Genesys_Device * dev, int table_nr, - uint16_t * slope_table, int steps); diff --git a/backend/genesys_gl646.cc b/backend/genesys_gl646.cc deleted file mode 100644 index b2b9f62..0000000 --- a/backend/genesys_gl646.cc +++ /dev/null @@ -1,4911 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2003 Oliver Rauch - Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de> - Copyright (C) 2004 Gerhard Jaeger <gerhard@gjaeger.de> - Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> - Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - Copyright (C) 2007 Luke <iceyfor@gmail.com> - Copyright (C) 2011 Alexey Osipov <simba@lerlan.ru> for HP2400 description - and tuning - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#define DEBUG_DECLARE_ONLY - -#include "genesys_gl646.h" - -#include <vector> - -/** - * reads value from gpio endpoint - */ -static void gl646_gpio_read(UsbDevice& usb_dev, uint8_t* value) -{ - DBG_HELPER(dbg); - usb_dev.control_msg(REQUEST_TYPE_IN, REQUEST_REGISTER, GPIO_READ, INDEX, 1, value); -} - -/** - * writes the given value to gpio endpoint - */ -static void gl646_gpio_write(UsbDevice& usb_dev, uint8_t value) -{ - DBG_HELPER_ARGS(dbg, "(0x%02x)", value); - usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, GPIO_WRITE, INDEX, 1, &value); -} - -/** - * writes the given value to gpio output enable endpoint - */ -static void gl646_gpio_output_enable(UsbDevice& usb_dev, uint8_t value) -{ - DBG_HELPER_ARGS(dbg, "(0x%02x)", value); - usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, GPIO_OUTPUT_ENABLE, INDEX, 1, &value); -} - -/* Read bulk data (e.g. scanned data) */ -static SANE_Status -gl646_bulk_read_data (Genesys_Device * dev, uint8_t addr, - uint8_t * data, size_t len) -{ - SANE_Status status = sanei_genesys_bulk_read_data(dev, addr, data, len); - if (status != SANE_STATUS_GOOD) { - return status; - } - if (dev->model->is_sheetfed == SANE_TRUE) { - gl646_detect_document_end (dev); - } - return status; -} - -static SANE_Bool -gl646_get_fast_feed_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x02); - if (r && (r->value & REG02_FASTFED)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl646_get_filter_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x04); - if (r && (r->value & REG04_FILTER)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl646_get_lineart_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x04); - if (r && (r->value & REG04_LINEART)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl646_get_bitset_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x04); - if (r && (r->value & REG04_BITSET)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl646_get_gain4_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x06); - if (r && (r->value & REG06_GAIN4)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl646_test_buffer_empty_bit (SANE_Byte val) -{ - if (val & REG41_BUFEMPTY) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl646_test_motor_flag_bit (SANE_Byte val) -{ - if (val & REG41_MOTMFLG) - return SANE_TRUE; - return SANE_FALSE; -} - -/** - * decodes and prints content of status (0x41) register - * @param val value read from reg41 - */ -static void -print_status (uint8_t val) -{ - char msg[80]; - - sprintf (msg, "%s%s%s%s%s%s%s%s", - val & REG41_PWRBIT ? "PWRBIT " : "", - val & REG41_BUFEMPTY ? "BUFEMPTY " : "", - val & REG41_FEEDFSH ? "FEEDFSH " : "", - val & REG41_SCANFSH ? "SCANFSH " : "", - val & REG41_HOMESNR ? "HOMESNR " : "", - val & REG41_LAMPSTS ? "LAMPSTS " : "", - val & REG41_FEBUSY ? "FEBUSY " : "", - val & REG41_MOTMFLG ? "MOTMFLG" : ""); - DBG(DBG_info, "status=%s\n", msg); -} - -/** - * start scanner's motor - * @param dev scanner's device - */ -static SANE_Status -gl646_start_motor (Genesys_Device * dev) -{ - return sanei_genesys_write_register (dev, 0x0f, 0x01); -} - - -/** - * stop scanner's motor - * @param dev scanner's device - */ -static SANE_Status -gl646_stop_motor (Genesys_Device * dev) -{ - return sanei_genesys_write_register (dev, 0x0f, 0x00); -} - - -/** - * find the lowest resolution for the sensor in the given mode. - * @param sensor id of the sensor - * @param color true is color mode - * @return the closest resolution for the sensor and mode - */ -static int -get_lowest_resolution(int sensor_id, unsigned channels) -{ - int i, nb; - int dpi; - - i = 0; - dpi = 9600; - nb = sizeof (sensor_master) / sizeof (Sensor_Master); - while (i < nb) - { - /* computes distance and keep mode if it is closer than previous */ - if (sensor_id == sensor_master[i].sensor - && sensor_master[i].channels == channels) - { - if (sensor_master[i].dpi < dpi) - { - dpi = sensor_master[i].dpi; - } - } - i++; - } - DBG(DBG_info, "%s: %d\n", __func__, dpi); - return dpi; -} - -/** - * find the closest match in mode tables for the given resolution and scan mode. - * @param sensor id of the sensor - * @param required required resolution - * @param color true is color mode - * @return the closest resolution for the sensor and mode - */ -static int -get_closest_resolution(int sensor_id, int required, unsigned channels) -{ - int i, nb; - int dist, dpi; - - i = 0; - dpi = 0; - dist = 9600; - nb = sizeof (sensor_master) / sizeof (Sensor_Master); - while (i < nb) - { - /* exit on perfect match */ - if (sensor_id == sensor_master[i].sensor - && sensor_master[i].dpi == required - && sensor_master[i].channels == channels) - { - DBG(DBG_info, "%s: match found for %d\n", __func__, required); - return required; - } - /* computes distance and keep mode if it is closer than previous */ - if (sensor_id == sensor_master[i].sensor - && sensor_master[i].channels == channels) - { - if (abs (sensor_master[i].dpi - required) < dist) - { - dpi = sensor_master[i].dpi; - dist = abs (sensor_master[i].dpi - required); - } - } - i++; - } - DBG(DBG_info, "%s: closest match for %d is %d\n", __func__, required, dpi); - return dpi; -} - -/** - * Computes if sensor will be set up for half ccd pixels for the given - * scan mode. - * @param sensor id of the sensor - * @param required required resolution - * @param color true is color mode - * @return SANE_TRUE if half ccd is used - */ -static SANE_Bool is_half_ccd(int sensor_id, int required, unsigned channels) -{ - int i, nb; - - i = 0; - nb = sizeof (sensor_master) / sizeof (Sensor_Master); - while (i < nb) - { - /* exit on perfect match */ - if (sensor_id == sensor_master[i].sensor - && sensor_master[i].dpi == required - && sensor_master[i].channels == channels) - { - DBG(DBG_io, "%s: match found for %d (half_ccd=%d)\n", __func__, required, - sensor_master[i].half_ccd); - return sensor_master[i].half_ccd; - } - i++; - } - DBG(DBG_info, "%s: failed to find match for %d dpi\n", __func__, required); - return SANE_FALSE; -} - -/** - * Returns the cksel values used by the required scan mode. - * @param sensor id of the sensor - * @param required required resolution - * @param color true is color mode - * @return cksel value for mode - */ -static int get_cksel(int sensor_id, int required, unsigned channels) -{ - int i, nb; - - i = 0; - nb = sizeof (sensor_master) / sizeof (Sensor_Master); - while (i < nb) - { - /* exit on perfect match */ - if (sensor_id == sensor_master[i].sensor - && sensor_master[i].dpi == required - && sensor_master[i].channels == channels) - { - DBG(DBG_io, "%s: match found for %d (cksel=%d)\n", __func__, required, - sensor_master[i].cksel); - return sensor_master[i].cksel; - } - i++; - } - DBG(DBG_error, "%s: failed to find match for %d dpi\n", __func__, required); - /* fail safe fallback */ - return 1; -} - -/** - * Setup register and motor tables for a scan at the - * given resolution and color mode. TODO try to not use any filed from - * the device. - * @param dev pointer to a struct describing the device - * @param regs register set to fill - * @param slope_table1 first motor table to fill - * @param slope_table2 second motor table to fill - * @return SANE_STATUS_GOOD if registers could be set, SANE_STATUS_INVAL if - * conditions can't be met. - * @note No harcoded SENSOR or MOTOR 'names' should be present and - * registers are set from settings tables and flags related - * to the hardware capabilities. - * */ -static SANE_Status -gl646_setup_registers (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, - SetupParams& params, - uint16_t * slope_table1, - uint16_t * slope_table2, - bool xcorrection) -{ - int resolution = params.xres; - uint32_t move = params.starty; - uint32_t linecnt = params.lines; - - uint32_t startx = 0; - /* pixels are allways given at full CCD optical resolution */ - /* use detected left margin and fixed value */ - if (xcorrection == SANE_TRUE) { - if (sensor.CCD_start_xoffset > 0) { - startx = sensor.CCD_start_xoffset; - } else { - startx = sensor.dummy_pixel; - } - } else { - // startx cannot be below dummy pixel value - startx = sensor.dummy_pixel; - } - - /* add x coordinates : expressed in sensor max dpi */ - startx += params.startx; - - /* stagger works with odd start cordinates */ - if (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE) { - startx |= 1; - } - - uint32_t pixels = (params.pixels * sensor.optical_res) / params.xres; - /* special requirement for 400 dpi on 1200 dpi sensors */ - if (params.xres == 400) - { - pixels = (pixels / 6) * 6; - } - /* TODO check for pixel width overflow */ - uint32_t endx = startx + pixels; - - SANE_Status status = SANE_STATUS_GOOD; - int i, nb; - Sensor_Master *sensor_mst = NULL; - Motor_Master *motor = NULL; - Sensor_Settings *settings = NULL; - GenesysRegister *r; - unsigned int used1, used2, vfinal; - unsigned int bpp; /**> bytes per pixel */ - uint32_t z1, z2; - uint16_t ex, sx; - int stagger, words_per_line, max_shift; - size_t requested_buffer_size; - size_t read_buffer_size; - SANE_Bool half_ccd = SANE_FALSE; - SANE_Int xresolution; - int feedl; - - DBG(DBG_proc, "%s: start\n", __func__); - DBG(DBG_info, "%s: startx=%d, endx=%d, linecnt=%d\n", __func__, startx, endx, linecnt); - - /* x resolution is capped by sensor's capability */ - if (resolution > sensor.optical_res) - { - xresolution = sensor.optical_res; - } - else - { - xresolution = resolution; - } - - /* for the given resolution, search for master - * sensor mode setting */ - i = 0; - nb = sizeof (sensor_master) / sizeof (Sensor_Master); - while (i < nb) - { - if (dev->model->ccd_type == sensor_master[i].sensor - && sensor_master[i].dpi == xresolution - && sensor_master[i].channels == params.channels) - { - sensor_mst = &sensor_master[i]; - } - i++; - } - if (sensor_mst == NULL) - { - DBG(DBG_error, "%s: unable to find settings for sensor %d at %d dpi channels=%d\n", __func__, - dev->model->ccd_type, xresolution, params.channels); - return SANE_STATUS_INVAL; - } - - /* for the given resolution, search for master - * motor mode setting */ - i = 0; - nb = sizeof (motor_master) / sizeof (Motor_Master); - while (i < nb) - { - if (dev->model->motor_type == motor_master[i].motor - && motor_master[i].dpi == resolution - && motor_master[i].channels == params.channels) - { - motor = &motor_master[i]; - } - i++; - } - if (motor == NULL) - { - DBG(DBG_error, "%s: unable to find settings for motor %d at %d dpi, color=%d\n", __func__, - dev->model->motor_type, resolution, params.channels); - return SANE_STATUS_INVAL; - } - - /* now we can search for the specific sensor settings */ - i = 0; - nb = sizeof (sensor_settings) / sizeof (Sensor_Settings); - while (i < nb) - { - if (sensor_mst->sensor == sensor_settings[i].sensor - && sensor_mst->cksel == sensor_settings[i].cksel) - { - settings = &sensor_settings[i]; - } - i++; - } - if (settings == NULL) - { - DBG(DBG_error, "%s: unable to find settings for sensor %d with '%d' ccd timing\n", __func__, - sensor_mst->sensor, sensor_mst->cksel); - return SANE_STATUS_INVAL; - } - - /* half_ccd if manual clock programming or dpi is half dpiset */ - half_ccd = sensor_mst->half_ccd; - - /* now apply values from settings to registers */ - if (sensor_mst->regs_0x10_0x15 != NULL) - { - for (i = 0; i < 6; i++) - { - r = sanei_genesys_get_address (regs, 0x10 + i); - r->value = sensor_mst->regs_0x10_0x15[i]; - } - } - else - { - for (i = 0; i < 6; i++) - { - r = sanei_genesys_get_address (regs, 0x10 + i); - r->value = 0; - } - } - - for (i = 0; i < 4; i++) - { - r = sanei_genesys_get_address (regs, 0x08 + i); - if (half_ccd == SANE_TRUE) - r->value = settings->manual_0x08_0x0b[i]; - else - r->value = settings->regs_0x08_0x0b[i]; - } - - for (i = 0; i < 8; i++) - { - r = sanei_genesys_get_address (regs, 0x16 + i); - r->value = settings->regs_0x16_0x1d[i]; - } - - for (i = 0; i < 13; i++) - { - r = sanei_genesys_get_address (regs, 0x52 + i); - r->value = settings->regs_0x52_0x5e[i]; - } - if (half_ccd == SANE_TRUE) - { - for (i = 0; i < 7; i++) - { - r = sanei_genesys_get_address (regs, 0x52 + i); - r->value = settings->manual_0x52_0x58[i]; - } - } - - /* now generate slope tables : we are not using generate_slope_table3 yet */ - sanei_genesys_generate_slope_table (slope_table1, motor->steps1, - motor->steps1 + 1, motor->vend1, - motor->vstart1, motor->vend1, - motor->steps1, motor->g1, &used1, - &vfinal); - sanei_genesys_generate_slope_table (slope_table2, motor->steps2, - motor->steps2 + 1, motor->vend2, - motor->vstart2, motor->vend2, - motor->steps2, motor->g2, &used2, - &vfinal); - - /* R01 */ - /* now setup other registers for final scan (ie with shading enabled) */ - /* watch dog + shading + scan enable */ - regs->find_reg(0x01).value |= REG01_DOGENB | REG01_DVDSET | REG01_SCAN; - if (dev->model->is_cis == SANE_TRUE) - regs->find_reg(0x01).value |= REG01_CISSET; - else - regs->find_reg(0x01).value &= ~REG01_CISSET; - - /* if device has no calibration, don't enable shading correction */ - if (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION) - { - regs->find_reg(0x01).value &= ~REG01_DVDSET; - } - - regs->find_reg(0x01).value &= ~REG01_FASTMOD; - if (motor->fastmod) - regs->find_reg(0x01).value |= REG01_FASTMOD; - - /* R02 */ - /* allow moving when buffer full by default */ - if (dev->model->is_sheetfed == SANE_FALSE) - dev->reg.find_reg(0x02).value &= ~REG02_ACDCDIS; - else - dev->reg.find_reg(0x02).value |= REG02_ACDCDIS; - - /* setup motor power and direction */ - sanei_genesys_set_motor_power(*regs, true); - regs->find_reg(0x02).value &= ~REG02_MTRREV; - - /* fastfed enabled (2 motor slope tables) */ - if (motor->fastfed) - regs->find_reg(0x02).value |= REG02_FASTFED; - else - regs->find_reg(0x02).value &= ~REG02_FASTFED; - - /* step type */ - regs->find_reg(0x02).value &= ~REG02_STEPSEL; - switch (motor->steptype) - { - case FULL_STEP: - break; - case HALF_STEP: - regs->find_reg(0x02).value |= 1; - break; - case QUATER_STEP: - regs->find_reg(0x02).value |= 2; - break; - default: - regs->find_reg(0x02).value |= 3; - break; - } - - /* if sheetfed, no AGOHOME */ - if (dev->model->is_sheetfed == SANE_TRUE) - { - regs->find_reg(0x02).value &= ~REG02_AGOHOME; - } - else - { - regs->find_reg(0x02).value |= REG02_AGOHOME; - } - - /* R03 */ - regs->find_reg(0x03).value &= ~REG03_AVEENB; - /* regs->find_reg(0x03).value |= REG03_AVEENB; */ - regs->find_reg(0x03).value &= ~REG03_LAMPDOG; - - /* select XPA */ - regs->find_reg(0x03).value &= ~REG03_XPASEL; - if (params.flags & SCAN_FLAG_USE_XPA) { - regs->find_reg(0x03).value |= REG03_XPASEL; - } - regs->state.is_xpa_on = params.flags & SCAN_FLAG_USE_XPA; - - /* R04 */ - /* monochrome / color scan */ - switch (params.depth) - { - case 1: - regs->find_reg(0x04).value &= ~REG04_BITSET; - regs->find_reg(0x04).value |= REG04_LINEART; - break; - case 8: - regs->find_reg(0x04).value &= ~(REG04_LINEART | REG04_BITSET); - break; - case 16: - regs->find_reg(0x04).value &= ~REG04_LINEART; - regs->find_reg(0x04).value |= REG04_BITSET; - break; - } - - /* R05 */ - regs->find_reg(0x05).value &= ~REG05_DPIHW; - switch (sensor.optical_res) - { - case 600: - regs->find_reg(0x05).value |= REG05_DPIHW_600; - break; - case 1200: - regs->find_reg(0x05).value |= REG05_DPIHW_1200; - break; - case 2400: - regs->find_reg(0x05).value |= REG05_DPIHW_2400; - break; - default: - regs->find_reg(0x05).value |= REG05_DPIHW; - } - - /* gamma enable for scans */ - if (dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) - regs->find_reg(0x05).value |= REG05_GMM14BIT; - - regs->find_reg(0x05).value &= ~REG05_GMMENB; - - /* true CIS gray if needed */ - if (dev->model->is_cis == SANE_TRUE && params.channels == 1 - && dev->settings.true_gray) - { - regs->find_reg(0x05).value |= REG05_LEDADD; - } - else - { - regs->find_reg(0x05).value &= ~REG05_LEDADD; - } - - /* cktoggle, ckdelay and cksel at once, cktdelay=2 => half_ccd for md5345 */ - regs->find_reg(0x18).value = sensor_mst->r18; - - /* manual CCD/2 clock programming => half_ccd for hp2300 */ - regs->find_reg(0x1d).value = sensor_mst->r1d; - - /* HP2400 1200dpi mode tuning */ - - if (dev->model->ccd_type == CCD_HP2400) - { - /* reset count of dummy lines to zero */ - regs->find_reg(0x1e).value &= ~REG1E_LINESEL; - if (params.xres >= 1200) - { - /* there must be one dummy line */ - regs->find_reg(0x1e).value |= 1 & REG1E_LINESEL; - - /* GPO12 need to be set to zero */ - regs->find_reg(0x66).value &= ~0x20; - } - else - { - /* set GPO12 back to one */ - regs->find_reg(0x66).value |= 0x20; - } - } - - /* motor steps used */ - regs->find_reg(0x21).value = motor->steps1; - regs->find_reg(0x22).value = motor->fwdbwd; - regs->find_reg(0x23).value = motor->fwdbwd; - regs->find_reg(0x24).value = motor->steps1; - - /* scanned area height must be enlarged by max color shift needed */ - max_shift=sanei_genesys_compute_max_shift(dev,params.channels, params.yres, 0); - - /* we adjust linecnt according to real motor dpi */ - linecnt = (linecnt * motor->ydpi) / params.yres + max_shift; - - /* at QUATER_STEP lines are 'staggered' and need correction */ - stagger = 0; - if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - { - /* for HP3670, stagger happens only at >=1200 dpi */ - if ((dev->model->motor_type != MOTOR_HP3670 && dev->model->motor_type != MOTOR_HP2400) - || params.yres >= (unsigned) sensor.optical_res) - { - stagger = (4 * params.yres) / dev->motor.base_ydpi; - } - } - linecnt += stagger; - - DBG(DBG_info, "%s : max_shift=%d, stagger=%d lines\n", __func__, max_shift, stagger); - - /* CIS scanners read one line per color channel - * since gray mode use 'add' we also read 3 channels even not in - * color mode */ - if (dev->model->is_cis == SANE_TRUE) - { - sanei_genesys_set_triple(regs, REG_LINCNT, linecnt * 3); - linecnt *= params.channels; - } - else - { - sanei_genesys_set_triple(regs, REG_LINCNT, linecnt); - } - - /* scanner's x coordinates are expressed in physical DPI but they must be divided by cksel */ - sx = startx / sensor_mst->cksel; - ex = endx / sensor_mst->cksel; - if (half_ccd == SANE_TRUE) - { - sx /= 2; - ex /= 2; - } - sanei_genesys_set_double(regs, REG_STRPIXEL, sx); - sanei_genesys_set_double(regs, REG_ENDPIXEL, ex); - DBG(DBG_info, "%s: startx=%d, endx=%d, half_ccd=%d\n", __func__, sx, ex, half_ccd); - - /* words_per_line must be computed according to the scan's resolution */ - /* in fact, words_per_line _gives_ the actual scan resolution */ - words_per_line = (((endx - startx) * sensor_mst->xdpi) / sensor.optical_res); - bpp=params.depth/8; - if (params.depth == 1) - { - words_per_line = (words_per_line+7)/8 ; - bpp=1; - } - else - { - words_per_line *= bpp; - } - dev->bpl = words_per_line; - words_per_line *= params.channels; - dev->wpl = words_per_line; - - DBG(DBG_info, "%s: wpl=%d\n", __func__, words_per_line); - sanei_genesys_set_triple(regs, REG_MAXWD, words_per_line); - - sanei_genesys_set_double(regs, REG_DPISET, sensor_mst->dpiset); - sanei_genesys_set_double(regs, REG_LPERIOD, sensor_mst->exposure); - - /* move distance must be adjusted to take into account the extra lines - * read to reorder data */ - feedl = move; - if (stagger + max_shift > 0 && feedl != 0) - { - if (feedl > - ((max_shift + stagger) * dev->motor.optical_ydpi) / motor->ydpi) - feedl = - feedl - - ((max_shift + stagger) * dev->motor.optical_ydpi) / motor->ydpi; - } - - /* we assume all scans are done with 2 tables */ - /* - feedl = feed_steps - fast_slope_steps*2 - - (slow_slope_steps >> scan_step_type); */ - /* but head has moved due to shading calibration => dev->scanhead_position_in_steps */ - if (feedl > 0) - { - /* take into account the distance moved during calibration */ - /* feedl -= dev->scanhead_position_in_steps; */ - DBG(DBG_info, "%s: initial move=%d\n", __func__, feedl); - DBG(DBG_info, "%s: scanhead_position_in_steps=%d\n", __func__, - dev->scanhead_position_in_steps); - - /* TODO clean up this when I'll fully understand. - * for now, special casing each motor */ - switch (dev->model->motor_type) - { - case MOTOR_5345: - switch (motor->ydpi) - { - case 200: - feedl -= 70; - break; - case 300: - feedl -= 70; - break; - case 400: - feedl += 130; - break; - case 600: - feedl += 160; - break; - case 1200: - feedl += 160; - break; - case 2400: - feedl += 180; - break; - default: - break; - } - break; - case MOTOR_HP2300: - switch (motor->ydpi) - { - case 75: - feedl -= 180; - break; - case 150: - feedl += 0; - break; - case 300: - feedl += 30; - break; - case 600: - feedl += 35; - break; - case 1200: - feedl += 45; - break; - default: - break; - } - break; - case MOTOR_HP2400: - switch (motor->ydpi) - { - case 150: - feedl += 150; - break; - case 300: - feedl += 220; - break; - case 600: - feedl += 260; - break; - case 1200: - feedl += 280; /* 300 */ - break; - case 50: - feedl += 0; - break; - case 100: - feedl += 100; - break; - default: - break; - } - break; - - /* theorical value */ - default: - if (motor->fastfed) - { - feedl = - feedl - 2 * motor->steps2 - - (motor->steps1 >> motor->steptype); - } - else - { - feedl = feedl - (motor->steps1 >> motor->steptype); - } - break; - } - /* security */ - if (feedl < 0) - feedl = 0; - } - - DBG(DBG_info, "%s: final move=%d\n", __func__, feedl); - sanei_genesys_set_triple(regs, REG_FEEDL, feedl); - - regs->find_reg(0x65).value = motor->mtrpwm; - - sanei_genesys_calculate_zmode2 (regs->find_reg(0x02).value & REG02_FASTFED, - sensor_mst->exposure, - slope_table1, - motor->steps1, - move, motor->fwdbwd, &z1, &z2); - - /* no z1/z2 for sheetfed scanners */ - if (dev->model->is_sheetfed == SANE_TRUE) - { - z1 = 0; - z2 = 0; - } - sanei_genesys_set_double(regs, REG_Z1MOD, z1); - sanei_genesys_set_double(regs, REG_Z2MOD, z2); - regs->find_reg(0x6b).value = motor->steps2; - regs->find_reg(0x6c).value = - (regs->find_reg(0x6c).value & REG6C_TGTIME) | ((z1 >> 13) & 0x38) | ((z2 >> 16) - & 0x07); - - RIE (write_control (dev, sensor, xresolution)); - - /* setup analog frontend */ - RIE (gl646_set_fe(dev, sensor, AFE_SET, xresolution)); - - /* now we're done with registers setup values used by data transfer */ - /* we setup values needed for the data transfer */ - - /* we must use a round number of words_per_line */ - requested_buffer_size = 8 * words_per_line; - read_buffer_size = - 2 * requested_buffer_size + - ((max_shift + stagger) * params.pixels * params.channels * params.depth) / 8; - - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); - - dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); - - dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); - - dev->out_buffer.clear(); - dev->out_buffer.alloc(8 * params.pixels * params.channels * bpp); - - /* scan bytes to read */ - dev->read_bytes_left = words_per_line * linecnt; - - DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); - dev->read_active = SANE_TRUE; - - dev->current_setup.params = params; - dev->current_setup.pixels = - ((endx - startx) * sensor_mst->xdpi) / sensor.optical_res; - dev->current_setup.lines = linecnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = sensor_mst->exposure; - dev->current_setup.xres = sensor_mst->xdpi; - dev->current_setup.yres = motor->ydpi; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - - /* total_bytes_to_read is the number of byte to send to frontend - * total_bytes_read is the number of bytes sent to frontend - * read_bytes_left is the number of bytes to read from the scanner - */ - dev->total_bytes_read = 0; - if (params.depth == 1) { - dev->total_bytes_to_read = ((params.pixels * params.lines) / 8 + - (((params.pixels * params.lines) % 8) ? 1 : 0)) * params.channels; - } else { - dev->total_bytes_to_read = params.pixels * params.lines * params.channels * bpp; - } - - /* select color filter based on settings */ - regs->find_reg(0x04).value &= ~REG04_FILTER; - if (params.channels == 1) { - switch (params.color_filter) { - case ColorFilter::RED: - regs->find_reg(0x04).value |= 0x04; - break; - case ColorFilter::GREEN: - regs->find_reg(0x04).value |= 0x08; - break; - case ColorFilter::BLUE: - regs->find_reg(0x04).value |= 0x0c; - break; - default: - break; - } - } - - DBG(DBG_proc, "%s: end\n", __func__); - return SANE_STATUS_GOOD; -} - - -/** copy sensor specific settings */ -/* *dev : device infos - *regs : regiters to be set - extended : do extended set up - half_ccd: set up for half ccd resolution - all registers 08-0B, 10-1D, 52-5E are set up. They shouldn't - appear anywhere else but in register init -*/ -static void -gl646_setup_sensor (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * regs) -{ - (void) dev; - DBG(DBG_proc, "%s: start\n", __func__); - - for (const auto& reg_setting : sensor.custom_regs) { - regs->set8(reg_setting.address, reg_setting.value); - } - // FIXME: all other drivers don't set exposure here - sanei_genesys_set_exposure(*regs, sensor.exposure); - - DBG(DBG_proc, "%s: end\n", __func__); -} - -/** Test if the ASIC works - */ -static SANE_Status -gl646_asic_test (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - size_t size, verify_size; - unsigned int i; - - DBG(DBG_proc, "%s: start\n", __func__); - - /* set and read exposure time, compare if it's the same */ - status = sanei_genesys_write_register (dev, 0x38, 0xde); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_write_register (dev, 0x39, 0xad); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_read_register (dev, 0x4e, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read register: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (val != 0xde) /* value of register 0x38 */ - { - DBG(DBG_error, "%s: register contains invalid value\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - status = sanei_genesys_read_register (dev, 0x4f, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read register: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (val != 0xad) /* value of register 0x39 */ - { - DBG(DBG_error, "%s: register contains invalid value\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - /* ram test: */ - size = 0x40000; - verify_size = size + 0x80; - /* todo: looks like the read size must be a multiple of 128? - otherwise the read doesn't succeed the second time after the scanner has - been plugged in. Very strange. */ - - std::vector<uint8_t> data(size); - std::vector<uint8_t> verify_data(verify_size); - - for (i = 0; i < (size - 1); i += 2) - { - data[i] = i / 512; - data[i + 1] = (i / 2) % 256; - } - - status = sanei_genesys_set_buffer_address (dev, 0x0000); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_bulk_write_data(dev, 0x3c, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_set_buffer_address (dev, 0x0000); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = - gl646_bulk_read_data (dev, 0x45, verify_data.data(), verify_size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* i + 2 is needed as the changed address goes into effect only after one - data word is sent. */ - for (i = 0; i < size; i++) - { - if (verify_data[i + 2] != data[i]) - { - DBG(DBG_error, "%s: data verification error\n", __func__); - return SANE_STATUS_IO_ERROR; - } - } - - DBG(DBG_info, "%s: end\n", __func__); - - return SANE_STATUS_GOOD; -} - -/** - * Set all registers to default values after init - * @param dev scannerr's device to set - */ -static void -gl646_init_regs (Genesys_Device * dev) -{ - int addr; - - DBG(DBG_proc, "%s\n", __func__); - - dev->reg.clear(); - - for (addr = 1; addr <= 0x0b; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x10; addr <= 0x29; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x2c; addr <= 0x39; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x3d; addr <= 0x3f; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x52; addr <= 0x5e; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x60; addr <= 0x6d; addr++) - dev->reg.init_reg(addr, 0); - - dev->reg.find_reg(0x01).value = 0x20 /*0x22 */ ; /* enable shading, CCD, color, 1M */ - dev->reg.find_reg(0x02).value = 0x30 /*0x38 */ ; /* auto home, one-table-move, full step */ - if (dev->model->motor_type == MOTOR_5345) - dev->reg.find_reg(0x02).value |= 0x01; /* half-step */ - switch (dev->model->motor_type) - { - case MOTOR_5345: - dev->reg.find_reg(0x02).value |= 0x01; /* half-step */ - break; - case MOTOR_XP200: - /* for this sheetfed scanner, no AGOHOME, nor backtracking */ - dev->reg.find_reg(0x02).value = 0x50; - break; - default: - break; - } - dev->reg.find_reg(0x03).value = 0x1f /*0x17 */ ; /* lamp on */ - dev->reg.find_reg(0x04).value = 0x13 /*0x03 */ ; /* 8 bits data, 16 bits A/D, color, Wolfson fe *//* todo: according to spec, 0x0 is reserved? */ - switch (dev->model->dac_type) - { - case DAC_AD_XP200: - dev->reg.find_reg(0x04).value = 0x12; - break; - default: - /* Wolfson frontend */ - dev->reg.find_reg(0x04).value = 0x13; - break; - } - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - dev->reg.find_reg(0x05).value = 0x00; /* 12 bits gamma, disable gamma, 24 clocks/pixel */ - switch (sensor.optical_res) - { - case 600: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_600; - break; - case 1200: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_1200; - break; - case 2400: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_2400; - break; - default: - dev->reg.find_reg(0x05).value |= REG05_DPIHW; - break; - } - if (dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) - dev->reg.find_reg(0x05).value |= REG05_GMM14BIT; - if (dev->model->dac_type == DAC_AD_XP200) - dev->reg.find_reg(0x05).value |= 0x01; /* 12 clocks/pixel */ - - if (dev->model->ccd_type == CCD_HP2300) - dev->reg.find_reg(0x06).value = 0x00; /* PWRBIT off, shading gain=4, normal AFE image capture */ - else - dev->reg.find_reg(0x06).value = 0x18; /* PWRBIT on, shading gain=8, normal AFE image capture */ - - - gl646_setup_sensor(dev, sensor, &dev->reg); - - dev->reg.find_reg(0x1e).value = 0xf0; /* watch-dog time */ - - switch (dev->model->ccd_type) - { - case CCD_HP2300: - dev->reg.find_reg(0x1e).value = 0xf0; - dev->reg.find_reg(0x1f).value = 0x10; - dev->reg.find_reg(0x20).value = 0x20; - break; - case CCD_HP2400: - dev->reg.find_reg(0x1e).value = 0x80; - dev->reg.find_reg(0x1f).value = 0x10; - dev->reg.find_reg(0x20).value = 0x20; - break; - case CCD_HP3670: - dev->reg.find_reg(0x19).value = 0x2a; - dev->reg.find_reg(0x1e).value = 0x80; - dev->reg.find_reg(0x1f).value = 0x10; - dev->reg.find_reg(0x20).value = 0x20; - break; - case CIS_XP200: - dev->reg.find_reg(0x1e).value = 0x10; - dev->reg.find_reg(0x1f).value = 0x01; - dev->reg.find_reg(0x20).value = 0x50; - break; - default: - dev->reg.find_reg(0x1f).value = 0x01; - dev->reg.find_reg(0x20).value = 0x50; - break; - } - - dev->reg.find_reg(0x21).value = 0x08 /*0x20 */ ; /* table one steps number for forward slope curve of the acc/dec */ - dev->reg.find_reg(0x22).value = 0x10 /*0x08 */ ; /* steps number of the forward steps for start/stop */ - dev->reg.find_reg(0x23).value = 0x10 /*0x08 */ ; /* steps number of the backward steps for start/stop */ - dev->reg.find_reg(0x24).value = 0x08 /*0x20 */ ; /* table one steps number backward slope curve of the acc/dec */ - dev->reg.find_reg(0x25).value = 0x00; /* scan line numbers (7000) */ - dev->reg.find_reg(0x26).value = 0x00 /*0x1b */ ; - dev->reg.find_reg(0x27).value = 0xd4 /*0x58 */ ; - dev->reg.find_reg(0x28).value = 0x01; /* PWM duty for lamp control */ - dev->reg.find_reg(0x29).value = 0xff; - - dev->reg.find_reg(0x2c).value = 0x02; /* set resolution (600 DPI) */ - dev->reg.find_reg(0x2d).value = 0x58; - dev->reg.find_reg(0x2e).value = 0x78; /* set black&white threshold high level */ - dev->reg.find_reg(0x2f).value = 0x7f; /* set black&white threshold low level */ - - dev->reg.find_reg(0x30).value = 0x00; /* begin pixel position (16) */ - dev->reg.find_reg(0x31).value = sensor.dummy_pixel /*0x10 */ ; /* TGW + 2*TG_SHLD + x */ - dev->reg.find_reg(0x32).value = 0x2a /*0x15 */ ; /* end pixel position (5390) */ - dev->reg.find_reg(0x33).value = 0xf8 /*0x0e */ ; /* TGW + 2*TG_SHLD + y */ - dev->reg.find_reg(0x34).value = sensor.dummy_pixel; - dev->reg.find_reg(0x35).value = 0x01 /*0x00 */ ; /* set maximum word size per line, for buffer full control (10800) */ - dev->reg.find_reg(0x36).value = 0x00 /*0x2a */ ; - dev->reg.find_reg(0x37).value = 0x00 /*0x30 */ ; - dev->reg.find_reg(0x38).value = 0x2a; // line period (exposure time = 11000 pixels) */ - dev->reg.find_reg(0x39).value = 0xf8; - dev->reg.find_reg(0x3d).value = 0x00; /* set feed steps number of motor move */ - dev->reg.find_reg(0x3e).value = 0x00; - dev->reg.find_reg(0x3f).value = 0x01 /*0x00 */ ; - - dev->reg.find_reg(0x60).value = 0x00; /* Z1MOD, 60h:61h:(6D b5:b3), remainder for start/stop */ - dev->reg.find_reg(0x61).value = 0x00; /* (21h+22h)/LPeriod */ - dev->reg.find_reg(0x62).value = 0x00; /* Z2MODE, 62h:63h:(6D b2:b0), remainder for start scan */ - dev->reg.find_reg(0x63).value = 0x00; /* (3Dh+3Eh+3Fh)/LPeriod for one-table mode,(21h+1Fh)/LPeriod */ - dev->reg.find_reg(0x64).value = 0x00; /* motor PWM frequency */ - dev->reg.find_reg(0x65).value = 0x00; /* PWM duty cycle for table one motor phase (63 = max) */ - if (dev->model->motor_type == MOTOR_5345) - dev->reg.find_reg(0x65).value = 0x02; /* PWM duty cycle for table one motor phase (63 = max) */ - dev->reg.find_reg(0x66).value = dev->gpo.value[0]; - dev->reg.find_reg(0x67).value = dev->gpo.value[1]; - dev->reg.find_reg(0x68).value = dev->gpo.enable[0]; - dev->reg.find_reg(0x69).value = dev->gpo.enable[1]; - - switch (dev->model->motor_type) - { - case MOTOR_HP2300: - case MOTOR_HP2400: - dev->reg.find_reg(0x6a).value = 0x7f; /* table two steps number for acc/dec */ - dev->reg.find_reg(0x6b).value = 0x78; /* table two steps number for acc/dec */ - dev->reg.find_reg(0x6d).value = 0x7f; - break; - case MOTOR_5345: - dev->reg.find_reg(0x6a).value = 0x42; /* table two fast moving step type, PWM duty for table two */ - dev->reg.find_reg(0x6b).value = 0xff; /* table two steps number for acc/dec */ - dev->reg.find_reg(0x6d).value = 0x41; /* select deceleration steps whenever go home (0), accel/decel stop time (31 * LPeriod) */ - break; - case MOTOR_XP200: - dev->reg.find_reg(0x6a).value = 0x7f; /* table two fast moving step type, PWM duty for table two */ - dev->reg.find_reg(0x6b).value = 0x08; /* table two steps number for acc/dec */ - dev->reg.find_reg(0x6d).value = 0x01; /* select deceleration steps whenever go home (0), accel/decel stop time (31 * LPeriod) */ - break; - case MOTOR_HP3670: - dev->reg.find_reg(0x6a).value = 0x41; /* table two steps number for acc/dec */ - dev->reg.find_reg(0x6b).value = 0xc8; /* table two steps number for acc/dec */ - dev->reg.find_reg(0x6d).value = 0x7f; - break; - default: - dev->reg.find_reg(0x6a).value = 0x40; /* table two fast moving step type, PWM duty for table two */ - dev->reg.find_reg(0x6b).value = 0xff; /* table two steps number for acc/dec */ - dev->reg.find_reg(0x6d).value = 0x01; /* select deceleration steps whenever go home (0), accel/decel stop time (31 * LPeriod) */ - break; - } - dev->reg.find_reg(0x6c).value = 0x00; /* peroid times for LPeriod, expR,expG,expB, Z1MODE, Z2MODE (one period time) */ -} - - -/* Send slope table for motor movement - slope_table in machine byte order -*/ -static SANE_Status -gl646_send_slope_table (Genesys_Device * dev, int table_nr, - uint16_t * slope_table, int steps) -{ - int dpihw; - int start_address; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (table_nr = %d, steps = %d)=%d .. %d\n", __func__, table_nr, steps, - slope_table[0], slope_table[steps - 1]); - - dpihw = dev->reg.find_reg(0x05).value >> 6; - - if (dpihw == 0) /* 600 dpi */ - start_address = 0x08000; - else if (dpihw == 1) /* 1200 dpi */ - start_address = 0x10000; - else if (dpihw == 2) /* 2400 dpi */ - start_address = 0x1f800; - else /* reserved */ - return SANE_STATUS_INVAL; - - std::vector<uint8_t> table(steps * 2); - for (int i = 0; i < steps; i++) - { - table[i * 2] = slope_table[i] & 0xff; - table[i * 2 + 1] = slope_table[i] >> 8; - } - - status = - sanei_genesys_set_buffer_address (dev, start_address + table_nr * 0x100); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_bulk_write_data(dev, 0x3c, table.data(), steps * 2); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send slope table: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - -/* Set values of Analog Device type frontend */ -static SANE_Status -gl646_set_ad_fe (Genesys_Device * dev, uint8_t set) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - - DBG(DBG_proc, "%s(): start\n", __func__); - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - - dev->frontend = dev->frontend_initial; - - /* write them to analog frontend */ - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write reg0: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write reg1: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - if (set == AFE_SET) - { - for (i = 0; i < 3; i++) - { - status = sanei_genesys_fe_write_data(dev, 0x02 + i, dev->frontend.get_gain(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write gain %d: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - for (i = 0; i < 3; i++) - { - status = sanei_genesys_fe_write_data(dev, 0x05 + i, dev->frontend.get_offset(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write offset %d: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - } - /* - if (set == AFE_POWER_SAVE) - { - status = - sanei_genesys_fe_write_data (dev, 0x00, dev->frontend.reg[0] | 0x04); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write reg0: %s\n", __func__, sane_strstatus(status)); - return status; - } - } */ - DBG(DBG_proc, "%s(): end\n", __func__); - - return status; -} - -/** set up analog frontend - * set up analog frontend - * @param dev device to set up - * @param set action from AFE_SET, AFE_INIT and AFE_POWERSAVE - * @param dpi resolution of the scan since it affects settings - * @return SANE_STATUS_GOOD if evrithing OK - */ -static SANE_Status -gl646_wm_hp3670(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set, int dpi) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - - DBGSTART; - switch (set) - { - case AFE_INIT: - status = sanei_genesys_fe_write_data (dev, 0x04, 0x80); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: reset failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_sleep_ms(200); - RIE (sanei_genesys_write_register (dev, 0x50, 0x00)); - dev->frontend = dev->frontend_initial; - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg1 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x02, dev->frontend.regs.get_value(0x02)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg2 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - gl646_gpio_output_enable(dev->usb_dev, 0x07); - break; - case AFE_POWER_SAVE: - status = sanei_genesys_fe_write_data (dev, 0x01, 0x06); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg1 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data (dev, 0x06, 0x0f); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg6 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - return status; - break; - default: /* AFE_SET */ - /* mode setup */ - i = dev->frontend.regs.get_value(0x03); - if (dpi > sensor.optical_res / 2) - { - /* fe_reg_0x03 must be 0x12 for 1200 dpi in DAC_WOLFSON_HP3670. - * DAC_WOLFSON_HP2400 in 1200 dpi mode works well with - * fe_reg_0x03 set to 0x32 or 0x12 but not to 0x02 */ - i = 0x12; - } - status = sanei_genesys_fe_write_data (dev, 0x03, i); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg3 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - /* offset and sign (or msb/lsb ?) */ - for (i = 0; i < 3; i++) - { - status = - sanei_genesys_fe_write_data(dev, 0x20 + i, dev->frontend.get_offset(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing offset%d failed: %s\n", __func__, i, - sane_strstatus (status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x24 + i, - dev->frontend.regs.get_value(0x24 + i)); /* MSB/LSB ? */ - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing sign%d failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - - /* gain */ - for (i = 0; i < 3; i++) - { - status = - sanei_genesys_fe_write_data(dev, 0x28 + i, dev->frontend.get_gain(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing gain%d failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - } - - DBGCOMPLETED; - return status; -} - -/** Set values of analog frontend - * @param dev device to set - * @param set action to execute - * @param dpi dpi to setup the AFE - * @return error or SANE_STATUS_GOOD */ -static SANE_Status -gl646_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set, int dpi) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - uint8_t val; - - DBG(DBG_proc, "%s (%s,%d)\n", __func__, set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set == - AFE_POWER_SAVE ? "powersave" : "huh?", dpi); - - /* Analog Device type frontend */ - if ((dev->reg.find_reg(0x04).value & REG04_FESET) == 0x02) - return gl646_set_ad_fe (dev, set); - - /* Wolfson type frontend */ - if ((dev->reg.find_reg(0x04).value & REG04_FESET) != 0x03) - { - DBG(DBG_proc, "%s(): unsupported frontend type %d\n", __func__, - dev->reg.find_reg(0x04).value & REG04_FESET); - return SANE_STATUS_UNSUPPORTED; - } - - /* per frontend function to keep code clean */ - switch (dev->model->dac_type) - { - case DAC_WOLFSON_HP3670: - case DAC_WOLFSON_HP2400: - return gl646_wm_hp3670(dev, sensor, set, dpi); - break; - default: - DBG(DBG_proc, "%s(): using old method\n", __func__); - break; - } - - /* initialize analog frontend */ - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - dev->frontend = dev->frontend_initial; - - /* reset only done on init */ - status = sanei_genesys_fe_write_data (dev, 0x04, 0x80); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: init fe failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* enable GPIO for some models */ - if (dev->model->ccd_type == CCD_HP2300) - { - val = 0x07; - gl646_gpio_output_enable(dev->usb_dev, val); - } - return status; - } - - /* set fontend to power saving mode */ - if (set == AFE_POWER_SAVE) - { - status = sanei_genesys_fe_write_data (dev, 0x01, 0x02); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing data failed: %s\n", __func__, sane_strstatus(status)); - } - return status; - } - - /* here starts AFE_SET */ - /* TODO : base this test on cfg reg3 or a CCD family flag to be created */ - /* if (dev->model->ccd_type != CCD_HP2300 - && dev->model->ccd_type != CCD_HP3670 - && dev->model->ccd_type != CCD_HP2400) */ - { - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg0 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x02, dev->frontend.regs.get_value(0x02)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg2 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - /* start with reg3 */ - status = sanei_genesys_fe_write_data(dev, 0x03, dev->frontend.regs.get_value(0x03)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg3 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - switch (dev->model->ccd_type) - { - default: - for (i = 0; i < 3; i++) - { - status = - sanei_genesys_fe_write_data(dev, 0x24 + i, - dev->frontend.regs.get_value(0x24 + i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing sign[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x28 + i, dev->frontend.get_gain(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing gain[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x20 + i, dev->frontend.get_offset(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing offset[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - break; - /* just can't have it to work .... - case CCD_HP2300: - case CCD_HP2400: - case CCD_HP3670: - - status = - sanei_genesys_fe_write_data(dev, 0x23, dev->frontend.get_offset(1)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing offset[1] failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x28, dev->frontend.get_gain(1)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing gain[1] failed: %s\n", __func__, sane_strstatus (status)); - return status; - } - break; */ - } - - /* end with reg1 */ - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg1 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - - DBG(DBG_proc, "%s: end\n", __func__); - - return SANE_STATUS_GOOD; -} - -/** Set values of analog frontend - * this this the public interface, the gl646 as to use one more - * parameter to work effectively, hence the redirection - * @param dev device to set - * @param set action to execute - * @return error or SANE_STATUS_GOOD */ -static SANE_Status -gl646_public_set_fe (Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set) -{ - return gl646_set_fe(dev, sensor, set, dev->settings.yres); -} - -/** - * enters or leaves power saving mode - * limited to AFE for now. - * @param dev scanner's device - * @param enable SANE_TRUE to enable power saving, SANE_FALSE to leave it - * @return allways SANE_STATUS_GOOD - */ -static -SANE_Status -gl646_save_power (Genesys_Device * dev, SANE_Bool enable) -{ - - DBGSTART; - DBG(DBG_info, "%s: enable = %d\n", __func__, enable); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - if (enable) - { - /* gl646_set_fe(dev, sensor, AFE_POWER_SAVE); */ - } - else - { - gl646_set_fe(dev, sensor, AFE_INIT, 0); - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl646_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ ) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); - int rate, exposure_time, tgtime, time; - - DBG(DBG_proc, "%s (delay = %d)\n", __func__, delay); - - local_reg.init_reg(0x01, dev->reg.get8(0x01)); // disable fastmode - local_reg.init_reg(0x03, dev->reg.get8(0x03)); // Lamp power control - local_reg.init_reg(0x05, dev->reg.get8(0x05) & ~REG05_BASESEL); // 24 clocks/pixel - local_reg.init_reg(0x38, 0x00); // line period low - local_reg.init_reg(0x39, 0x00); //line period high - local_reg.init_reg(0x6c, 0x00); // period times for LPeriod, expR,expG,expB, Z1MODE, Z2MODE - - if (!delay) - local_reg.find_reg(0x03).value &= 0xf0; /* disable lampdog and set lamptime = 0 */ - else if (delay < 20) - local_reg.find_reg(0x03).value = (local_reg.get8(0x03) & 0xf0) | 0x09; /* enable lampdog and set lamptime = 1 */ - else - local_reg.find_reg(0x03).value = (local_reg.get8(0x03) & 0xf0) | 0x0f; /* enable lampdog and set lamptime = 7 */ - - time = delay * 1000 * 60; /* -> msec */ - exposure_time = - (uint32_t) (time * 32000.0 / - (24.0 * 64.0 * (local_reg.get8(0x03) & REG03_LAMPTIM) * - 1024.0) + 0.5); - /* 32000 = system clock, 24 = clocks per pixel */ - rate = (exposure_time + 65536) / 65536; - if (rate > 4) - { - rate = 8; - tgtime = 3; - } - else if (rate > 2) - { - rate = 4; - tgtime = 2; - } - else if (rate > 1) - { - rate = 2; - tgtime = 1; - } - else - { - rate = 1; - tgtime = 0; - } - - local_reg.find_reg(0x6c).value |= tgtime << 6; - exposure_time /= rate; - - if (exposure_time > 65535) - exposure_time = 65535; - - local_reg.find_reg(0x38).value = exposure_time / 256; - local_reg.find_reg(0x39).value = exposure_time & 255; - - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - - -/** - * loads document into scanner - * currently only used by XP200 - * bit2 (0x04) of gpio is paper event (document in/out) on XP200 - * HOMESNR is set if no document in front of sensor, the sequence of events is - * paper event -> document is in the sheet feeder - * HOMESNR becomes 0 -> document reach sensor - * HOMESNR becomes 1 ->document left sensor - * paper event -> document is out - */ -static SANE_Status -gl646_load_document (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - // FIXME: sequential not really needed in this case - Genesys_Register_Set regs(Genesys_Register_Set::SEQUENTIAL); - unsigned int used, vfinal, count; - uint16_t slope_table[255]; - uint8_t val; - - DBG(DBG_proc, "%s: start\n", __func__); - - /* no need to load document is flatbed scanner */ - if (dev->model->is_sheetfed == SANE_FALSE) - { - DBG(DBG_proc, "%s: nothing to load\n", __func__); - DBG(DBG_proc, "%s: end\n", __func__); - return SANE_STATUS_GOOD; - } - - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* HOMSNR is set if a document is inserted */ - if ((val & REG41_HOMESNR)) - { - /* if no document, waits for a paper event to start loading */ - /* with a 60 seconde minutes timeout */ - count = 0; - do - { - gl646_gpio_read(dev->usb_dev, &val); - - DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, val); - if ((val & 0x04) != 0x04) - { - DBG(DBG_warn, "%s: no paper detected\n", __func__); - } - sanei_genesys_sleep_ms(200); - count++; - } - while (((val & 0x04) != 0x04) && (count < 300)); /* 1 min time out */ - if (count == 300) - { - DBG(DBG_error, "%s: timeout waiting for document\n", __func__); - return SANE_STATUS_NO_DOCS; - } - } - - /* set up to fast move before scan then move until document is detected */ - regs.init_reg(0x01, 0x90); - - /* AGOME, 2 slopes motor moving */ - regs.init_reg(0x02, 0x79); - - /* motor feeding steps to 0 */ - regs.init_reg(0x3d, 0); - regs.init_reg(0x3e, 0); - regs.init_reg(0x3f, 0); - - /* 50 fast moving steps */ - regs.init_reg(0x6b, 50); - - /* set GPO */ - regs.init_reg(0x66, 0x30); - - /* stesp NO */ - regs.init_reg(0x21, 4); - regs.init_reg(0x22, 1); - regs.init_reg(0x23, 1); - regs.init_reg(0x24, 4); - - /* generate slope table 2 */ - sanei_genesys_generate_slope_table (slope_table, - 50, - 51, - 2400, - 6000, 2400, 50, 0.25, &used, &vfinal); -/* document loading: - * send regs - * start motor - * wait e1 status to become e0 - */ - status = gl646_send_slope_table (dev, 1, slope_table, 50); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send slope table 1: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl646_start_motor (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - - count = 0; - do - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_sleep_ms(200); - count++; - } - while ((val & REG41_MOTMFLG) && (count < 300)); - if (count == 300) - { - DBG(DBG_error, "%s: can't load document\n", __func__); - return SANE_STATUS_JAMMED; - } - - /* when loading OK, document is here */ - dev->document = SANE_TRUE; - - /* set up to idle */ - regs.set8(0x02, 0x71); - regs.set8(0x3f, 1); - regs.set8(0x6b, 8); - status = sanei_genesys_bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write idle registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: end\n", __func__); - - return status; -} - -/** - * detects end of document and adjust current scan - * to take it into account - * used by sheetfed scanners - */ -static SANE_Status -gl646_detect_document_end (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val, gpio; - unsigned int bytes_left, lines; - - DBG(DBG_proc, "%s: start\n", __func__); - - /* test for document presence */ - RIE (sanei_genesys_get_status (dev, &val)); - if (DBG_LEVEL > DBG_info) - { - print_status (val); - } - gl646_gpio_read(dev->usb_dev, &gpio); - DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, gpio); - - /* detect document event. There one event when the document go in, - * then another when it leaves */ - if ((dev->document == SANE_TRUE) && (gpio & 0x04) - && (dev->total_bytes_read > 0)) - { - DBG(DBG_info, "%s: no more document\n", __func__); - dev->document = SANE_FALSE; - - /* adjust number of bytes to read: - * total_bytes_to_read is the number of byte to send to frontend - * total_bytes_read is the number of bytes sent to frontend - * read_bytes_left is the number of bytes to read from the scanner - */ - DBG(DBG_io, "%s: total_bytes_to_read=%lu\n", __func__, (u_long) dev->total_bytes_to_read); - DBG(DBG_io, "%s: total_bytes_read =%lu\n", __func__, (u_long) dev->total_bytes_read); - DBG(DBG_io, "%s: read_bytes_left =%lu\n", __func__, (u_long) dev->read_bytes_left); - - /* amount of data available from scanner is what to scan */ - status = sanei_genesys_read_valid_words (dev, &bytes_left); - - /* we add the number of lines needed to read the last part of the document in */ - lines = - (SANE_UNFIX (dev->model->y_offset) * dev->current_setup.yres) / - MM_PER_INCH; - DBG(DBG_io, "%s: adding %d line to flush\n", __func__, lines); - bytes_left += lines * dev->wpl; - if (dev->current_setup.depth > 8) - { - bytes_left = 2 * bytes_left; - } - if (dev->current_setup.channels > 1) - { - bytes_left = 3 * bytes_left; - } - if (bytes_left < dev->read_bytes_left) - { - dev->total_bytes_to_read = dev->total_bytes_read + bytes_left; - dev->read_bytes_left = bytes_left; - } - DBG(DBG_io, "%s: total_bytes_to_read=%lu\n", __func__, (u_long) dev->total_bytes_to_read); - DBG(DBG_io, "%s: total_bytes_read =%lu\n", __func__, (u_long) dev->total_bytes_read); - DBG(DBG_io, "%s: read_bytes_left =%lu\n", __func__, (u_long) dev->read_bytes_left); - } - DBG(DBG_proc, "%s: end\n", __func__); - - return status; -} - -/** - * eject document from the feeder - * currently only used by XP200 - * TODO we currently rely on AGOHOME not being set for sheetfed scanners, - * maybe check this flag in eject to let the document being eject automaticaly - */ -static SANE_Status -gl646_eject_document (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - // FIXME: SEQUENTIAL not really needed in this case - Genesys_Register_Set regs((Genesys_Register_Set::SEQUENTIAL)); - unsigned int used, vfinal, count; - uint16_t slope_table[255]; - uint8_t gpio, state; - - DBG(DBG_proc, "%s: start\n", __func__); - - /* at the end there will be noe more document */ - dev->document = SANE_FALSE; - - // first check for document event - gl646_gpio_read(dev->usb_dev, &gpio); - - DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, gpio); - - /* test status : paper event + HOMESNR -> no more doc ? */ - status = sanei_genesys_get_status (dev, &state); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus(status)); - return status; - } - DBG(DBG_info, "%s: state=0x%02x\n", __func__, state); - if (DBG_LEVEL > DBG_info) - { - print_status (state); - } - - /* HOMSNR=0 if no document inserted */ - if ((state & REG41_HOMESNR) != 0) - { - dev->document = SANE_FALSE; - DBG(DBG_info, "%s: no more document to eject\n", __func__); - DBG(DBG_proc, "%s: end\n", __func__); - return status; - } - - /* there is a document inserted, eject it */ - status = sanei_genesys_write_register (dev, 0x01, 0xb0); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* wait for motor to stop */ - do - { - sanei_genesys_sleep_ms(200); - status = sanei_genesys_get_status (dev, &state); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - while (state & REG41_MOTMFLG); - - /* set up to fast move before scan then move until document is detected */ - regs.init_reg(0x01, 0xb0); - - /* AGOME, 2 slopes motor moving , eject 'backward' */ - regs.init_reg(0x02, 0x5d); - - /* motor feeding steps to 119880 */ - regs.init_reg(0x3d, 1); - regs.init_reg(0x3e, 0xd4); - regs.init_reg(0x3f, 0x48); - - /* 60 fast moving steps */ - regs.init_reg(0x6b, 60); - - /* set GPO */ - regs.init_reg(0x66, 0x30); - - /* stesp NO */ - regs.init_reg(0x21, 4); - regs.init_reg(0x22, 1); - regs.init_reg(0x23, 1); - regs.init_reg(0x24, 4); - - /* generate slope table 2 */ - sanei_genesys_generate_slope_table (slope_table, - 60, - 61, - 1600, - 10000, 1600, 60, 0.25, &used, &vfinal); -/* document eject: - * send regs - * start motor - * wait c1 status to become c8 : HOMESNR and ~MOTFLAG - */ - status = gl646_send_slope_table (dev, 1, slope_table, 60); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send slope table 1: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl646_start_motor (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus (status)); - return SANE_STATUS_IO_ERROR; - } - - /* loop until paper sensor tells paper is out, and till motor is running */ - /* use a 30 timeout */ - count = 0; - do - { - status = sanei_genesys_get_status (dev, &state); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus(status)); - return status; - } - print_status (state); - sanei_genesys_sleep_ms(200); - count++; - } - while (((state & REG41_HOMESNR) == 0) && (count < 150)); - - // read GPIO on exit - gl646_gpio_read(dev->usb_dev, &gpio); - - DBG(DBG_info, "%s: GPIO=0x%02x\n", __func__, gpio); - - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - -/* Send the low-level scan command */ -static SANE_Status -gl646_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SANE_Bool start_motor) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - // FIXME: SEQUENTIAL not really needed in this case - Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); - - DBG(DBG_proc, "%s\n", __func__); - - local_reg.init_reg(0x03, sanei_genesys_read_reg_from_set(reg, 0x03)); - local_reg.init_reg(0x01, sanei_genesys_read_reg_from_set(reg, 0x01) | REG01_SCAN); /* set scan bit */ - - if (start_motor) { - local_reg.init_reg(0x0f, 0x01); - } else { - local_reg.init_reg(0x0f, 0x00); // do not start motor yet - } - - status = sanei_genesys_bulk_write_register(dev, local_reg); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: end\n", __func__); - - return status; -} - - -/* Send the stop scan command */ -static SANE_Status -end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop, SANE_Bool eject) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i = 0; - uint8_t val, scanfsh = 0; - - DBG(DBG_proc, "%s (check_stop = %d, eject = %d)\n", __func__, check_stop, eject); - - /* we need to compute scanfsh before cancelling scan */ - if (dev->model->is_sheetfed == SANE_TRUE) - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read register: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (val & REG41_SCANFSH) - scanfsh = 1; - if (DBG_LEVEL > DBG_io2) - { - print_status (val); - } - } - - /* ends scan */ - val = sanei_genesys_read_reg_from_set (reg, 0x01); - val &= ~REG01_SCAN; - sanei_genesys_set_reg_from_set (reg, 0x01, val); - status = sanei_genesys_write_register (dev, 0x01, val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register 01: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* for sheetfed scanners, we may have to eject document */ - if (dev->model->is_sheetfed == SANE_TRUE) - { - if (eject == SANE_TRUE && dev->document == SANE_TRUE) - { - status = gl646_eject_document (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to eject document\n", __func__); - return status; - } - } - if (check_stop) - { - for (i = 0; i < 30; i++) /* do not wait longer than wait 3 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read register: %s\n", __func__, - sane_strstatus(status)); - return status; - } - if (val & REG41_SCANFSH) - scanfsh = 1; - if (DBG_LEVEL > DBG_io2) - { - print_status (val); - } - - if (!(val & REG41_MOTMFLG) && (val & REG41_FEEDFSH) && scanfsh) - { - DBG(DBG_proc, "%s: scanfeed finished\n", __func__); - break; /* leave for loop */ - } - - sanei_genesys_sleep_ms(100); - } - } - } - else /* flat bed scanners */ - { - if (check_stop) - { - for (i = 0; i < 300; i++) /* do not wait longer than wait 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read register: %s\n", __func__, - sane_strstatus(status)); - return status; - } - if (val & REG41_SCANFSH) - scanfsh = 1; - if (DBG_LEVEL > DBG_io) - { - print_status (val); - } - - if (!(val & REG41_MOTMFLG) && (val & REG41_FEEDFSH) && scanfsh) - { - DBG(DBG_proc, "%s: scanfeed finished\n", __func__); - break; /* leave while loop */ - } - - if ((!(val & REG41_MOTMFLG)) && (val & REG41_HOMESNR)) - { - DBG(DBG_proc, "%s: head at home\n", __func__); - break; /* leave while loop */ - } - - sanei_genesys_sleep_ms(100); - } - } - } - - DBG(DBG_proc, "%s: end (i=%u)\n", __func__, i); - - return status; -} - -/* Send the stop scan command */ -static SANE_Status -gl646_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop) -{ - return end_scan (dev, reg, check_stop, SANE_FALSE); -} - -/** - * parks head - * @param dev scanner's device - * @param wait_until_home true if the function waits until head parked - */ -static -SANE_Status -gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Settings settings; - uint8_t val; - int i; - int loop = 0; - - DBG(DBG_proc, "%s: start , wait_until_home = %d\n", __func__, wait_until_home); - - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL > DBG_io) - { - print_status (val); - } - - dev->scanhead_position_in_steps = 0; - - if (val & REG41_HOMESNR) /* is sensor at home? */ - { - DBG(DBG_info, "%s: end since already at home\n", __func__); - return SANE_STATUS_GOOD; - } - - /* stop motor if needed */ - if (val & REG41_MOTMFLG) - { - status = gl646_stop_motor (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop motor: %s\n", __func__, sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - sanei_genesys_sleep_ms(200); - } - - /* when scanhead is moving then wait until scanhead stops or timeout */ - DBG(DBG_info, "%s: ensuring that motor is off\n", __func__); - val = REG41_MOTMFLG; - for (i = 400; i > 0 && (val & REG41_MOTMFLG); i--) /* do not wait longer than 40 seconds, count down to get i = 0 when busy */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to read home sensor & motor status: %s\n", __func__, - sane_strstatus(status)); - return status; - } - if (((val & (REG41_MOTMFLG | REG41_HOMESNR)) == REG41_HOMESNR)) /* at home and motor is off */ - { - DBG(DBG_info, "%s: already at home and not moving\n", __func__); - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - } - - if (!i) /* the loop counted down to 0, scanner still is busy */ - { - DBG(DBG_error, "%s: motor is still on: device busy\n", __func__); - return SANE_STATUS_DEVICE_BUSY; - } - - /* setup for a backward scan of 65535 steps, with no actual data reading */ - settings.scan_method = ScanMethod::FLATBED; - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - settings.xres = get_lowest_resolution(dev->model->ccd_type, 1); - settings.yres = settings.xres; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = 600; - settings.lines = 1; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - const auto& sensor = sanei_genesys_find_sensor(dev, settings.xres); - - status = setup_for_scan(dev, sensor, &dev->reg, settings, SANE_TRUE, SANE_TRUE, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup for scan: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* backward , no actual data scanned TODO more setup flags to avoid this register manipulations ? */ - dev->reg.find_reg(0x02).value |= REG02_MTRREV; - dev->reg.find_reg(0x01).value &= ~REG01_SCAN; - sanei_genesys_set_triple(&dev->reg, REG_FEEDL, 65535); - - /* sets frontend */ - status = gl646_set_fe(dev, sensor, AFE_SET, settings.xres); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* write scan registers */ - try { - status = sanei_genesys_bulk_write_register(dev, dev->reg); - } catch (...) { - DBG(DBG_error, "%s: failed to bulk write registers\n", __func__); - } - if (status != SANE_STATUS_GOOD) - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - - /* registers are restored to an iddl state, give up if no head to park */ - if (dev->model->is_sheetfed == SANE_TRUE) - { - DBG(DBG_proc, "%s: end \n", __func__); - return SANE_STATUS_GOOD; - } - - /* starts scan */ - status = gl646_begin_scan(dev, sensor, &dev->reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: \n", __func__); - return status; - } - - /* loop until head parked */ - if (wait_until_home) - { - while (loop < 300) /* do not wait longer then 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to read home sensor: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - if (val & 0x08) /* home sensor */ - { - DBG(DBG_info, "%s: reached home position\n", __func__); - DBG(DBG_proc, "%s: end\n", __func__); - sanei_genesys_sleep_ms(500); - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl646_stop_motor (dev); - end_scan(dev, &dev->reg, SANE_TRUE, SANE_FALSE); - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** - * Automatically set top-left edge of the scan area by scanning an - * area at 300 dpi from very top of scanner - * @param dev device stucture describing the scanner - * @return SANE_STATUS_GOOD in cas of success, else failure code - */ -static SANE_Status -gl646_search_start_position (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Settings settings; - unsigned int resolution, x, y; - - DBG(DBG_proc, "%s: start\n", __func__); - - /* we scan at 300 dpi */ - resolution = get_closest_resolution(dev->model->ccd_type, 300, 1); - - // FIXME: the current approach of doing search only for one resolution does not work on scanners - // whith employ different sensors with potentially different settings. - auto& sensor = sanei_genesys_find_sensor_for_write(dev, resolution); - - /* fill settings for a gray level scan */ - settings.scan_method = ScanMethod::FLATBED; - settings.scan_mode = ScanColorMode::GRAY; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = 600; - settings.lines = dev->model->search_lines; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - /* scan the desired area */ - std::vector<uint8_t> data; - status = simple_scan(dev, sensor, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, data); - - /* process data if scan is OK */ - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: simple_scan failed\n", __func__); - DBGCOMPLETED; - return status; - } - - - /* handle stagger case : reorder gray data and thus loose some lines */ - if (dev->current_setup.stagger > 0) - { - DBG(DBG_proc, "%s: 'un-staggering'\n", __func__); - for (y = 0; y < settings.lines - dev->current_setup.stagger; y++) - { - /* one point out of 2 is 'unaligned' */ - for (x = 0; x < settings.pixels; x += 2) - { - data[y * settings.pixels + x] = - data[(y + dev->current_setup.stagger) * settings.pixels + - x]; - } - } - /* correct line number */ - settings.lines -= dev->current_setup.stagger; - } - if (DBG_LEVEL >= DBG_data) - { - sanei_genesys_write_pnm_file("gl646_search_position.pnm", data.data(), settings.depth, 1, - settings.pixels, settings.lines); - } - - /* now search reference points on the data */ - status = - sanei_genesys_search_reference_point (dev, sensor, data.data(), - sensor.CCD_start_xoffset, - resolution, settings.pixels, - settings.lines); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set search reference point: %s\n", __func__, - sane_strstatus(status)); - } - - DBGCOMPLETED; - return status; -} - -/** - * internally overriden during effective calibration - * sets up register for coarse gain calibration - */ -static SANE_Status -gl646_init_regs_for_coarse_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - (void) sensor; - (void) regs; - - DBG(DBG_proc, "%s\n", __func__); - DBG(DBG_proc, "%s: end\n", __func__); - - /* to make compilers happy ... */ - if (!dev) - { - return SANE_STATUS_INVAL; - } - - return SANE_STATUS_GOOD; -} - - -/** - * init registers for shading calibration - * we assume that scanner's head is on an area suiting shading calibration. - * We scan a full scan width area by the shading line number for the device - * at either at full sensor's resolution or half depending upon half_ccd - * @param dev scanner's device - * @return SANE_STATUS_GOOD if success, else error code - */ -static SANE_Status -gl646_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - (void) regs; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Settings settings; - /* 1: no half_ccd, 2: use half number of pixels */ - int half_ccd = 1; - int cksel = 1; - - DBG(DBG_proc, "%s: start\n", __func__); - - /* fill settings for scan : always a color scan */ - int channels = 3; - - if (sensor.ccd_size_divisor > 1) - { - // when shading all (full width) line, we must adapt to half_ccd case - if (is_half_ccd(dev->model->ccd_type, dev->settings.xres, channels) == SANE_TRUE) - { - half_ccd = 2; - } - } - - settings.scan_method = dev->settings.scan_method; - settings.scan_mode = dev->settings.scan_mode; - if (dev->model->is_cis == SANE_FALSE) - { - // FIXME: always a color scan, but why don't we set scan_mode to COLOR_SINGLE_PASS always? - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - } - settings.xres = sensor.optical_res / half_ccd; - cksel = get_cksel(dev->model->ccd_type, dev->settings.xres, channels); - settings.xres = settings.xres / cksel; - settings.yres = settings.xres; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = - (sensor.sensor_pixels * settings.xres) / sensor.optical_res; - dev->calib_lines = dev->model->shading_lines; - settings.lines = dev->calib_lines * (3 - half_ccd); - settings.depth = 16; - settings.color_filter = dev->settings.color_filter; - - settings.disable_interpolation = dev->settings.disable_interpolation; - settings.threshold = dev->settings.threshold; - settings.dynamic_lineart = SANE_FALSE; - - /* keep account of the movement for final scan move */ - dev->scanhead_position_in_steps += settings.lines; - - /* we don't want top offset, but we need right margin to be the same - * than the one for the final scan */ - status = setup_for_scan(dev, sensor, &dev->reg, settings, SANE_TRUE, SANE_FALSE, SANE_FALSE); - - /* used when sending shading calibration data */ - dev->calib_pixels = settings.pixels; - dev->calib_channels = dev->current_setup.channels; - if (dev->model->is_cis == SANE_FALSE) - { - dev->calib_channels = 3; - } - - /* no shading */ - dev->reg.find_reg(0x01).value &= ~REG01_DVDSET; - dev->reg.find_reg(0x02).value |= REG02_ACDCDIS; /* ease backtracking */ - dev->reg.find_reg(0x02).value &= ~(REG02_FASTFED | REG02_AGOHOME); - dev->reg.find_reg(0x05).value &= ~REG05_GMMENB; - sanei_genesys_set_motor_power(dev->reg, false); - - /* TODO another flag to setup regs ? */ - /* enforce needed LINCNT, getting rid of extra lines for color reordering */ - if (dev->model->is_cis == SANE_FALSE) - { - sanei_genesys_set_triple(&dev->reg, REG_LINCNT, dev->calib_lines); - } - else - { - sanei_genesys_set_triple(&dev->reg, REG_LINCNT, dev->calib_lines * 3); - } - - /* copy reg to calib_reg */ - dev->calib_reg = dev->reg; - - /* this is an hack to make calibration cache working .... */ - /* if we don't do this, cache will be identified at the shading calibration - * dpi which is different from calibration one */ - dev->current_setup.xres = dev->settings.xres; - DBG(DBG_info, "%s:\n\tdev->settings.xres=%d\n\tdev->settings.yres=%d\n", __func__, - dev->settings.xres, dev->settings.yres); - - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - -static bool gl646_needs_home_before_init_regs_for_scan(Genesys_Device* dev) -{ - return (dev->scanhead_position_in_steps > 0 && - dev->settings.scan_method == ScanMethod::FLATBED); -} - -/** - * set up registers for the actual scan. The scan's parameters are given - * through the device settings. It allocates the scan buffers. - */ -static SANE_Status -gl646_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - - RIE(setup_for_scan(dev, sensor, &dev->reg, dev->settings, SANE_FALSE, SANE_TRUE, SANE_TRUE)); - - /* gamma is only enabled at final scan time */ - if (dev->settings.depth < 16) - dev->reg.find_reg(0x05).value |= REG05_GMMENB; - - DBGCOMPLETED; - return status; -} - -/** - * set up registers for the actual scan. The scan's parameters are given - * through the device settings. It allocates the scan buffers. - * @param dev scanner's device - * @param regs registers to set up - * @param settings settings of scan - * @param split SANE_TRUE if move to scan area is split from scan, SANE_FALSE is - * scan first moves to area - * @param xcorrection take x geometry correction into account (fixed and detected offsets) - * @param ycorrection take y geometry correction into account - */ -static SANE_Status -setup_for_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set *regs, - Genesys_Settings settings, - SANE_Bool split, - SANE_Bool xcorrection, - SANE_Bool ycorrection) -{ - SANE_Status status = SANE_STATUS_GOOD; - SANE_Int depth; - int channels; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - if (settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - { - channels = 3; - } - else - { - channels = 1; - } - - depth=settings.depth; - if (settings.scan_mode == ScanColorMode::LINEART) - { - if (settings.dynamic_lineart == SANE_TRUE) - { - depth = 8; - } - else - { - /* XXX STEF XXX : why does the common layer never send depth=1 ? */ - depth = 1; - } - } - - // compute distance to move - float move = 0; - // XXX STEF XXX MD5345 -> optical_ydpi, other base_ydpi => half/full step ? */ - if (split == SANE_FALSE) { - if (dev->model->is_sheetfed == SANE_FALSE) { - if (ycorrection == SANE_TRUE) { - move = SANE_UNFIX(dev->model->y_offset); - } - - // add tl_y to base movement - } - move += settings.tl_y; - - if (move < 0) { - DBG(DBG_error, "%s: overriding negative move value %f\n", __func__, move); - move = 0; - } - } - move = (move * dev->motor.optical_ydpi) / MM_PER_INCH; - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - float start = settings.tl_x; - if (xcorrection) { - if (settings.scan_method == ScanMethod::FLATBED) { - start += SANE_UNFIX(dev->model->x_offset); - } else { - start += SANE_UNFIX(dev->model->x_offset_ta); - } - } - start = (start * sensor.optical_res) / MM_PER_INCH; - - SetupParams params; - params.xres = settings.xres; - params.yres = settings.yres; - params.startx = start; - params.starty = move; - params.pixels = settings.pixels; - params.lines = settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = settings.scan_mode; - params.color_filter = settings.color_filter; - params.flags = 0; - if (settings.scan_method == ScanMethod::TRANSPARENCY) { - params.flags |= SCAN_FLAG_USE_XPA; - } - - uint16_t slope_table0[256] = {}; - uint16_t slope_table1[256] = {}; - - /* set up correct values for scan (gamma and shading enabled) */ - status = gl646_setup_registers(dev, sensor, regs, params, slope_table0, slope_table1, - xcorrection); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed setup registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* send computed slope tables */ - status = - gl646_send_slope_table (dev, 0, slope_table0, - sanei_genesys_read_reg_from_set (regs, 0x21)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send slope table 0: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = - gl646_send_slope_table (dev, 1, slope_table1, - sanei_genesys_read_reg_from_set (regs, 0x6b)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send slope table 1: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return status; -} - -/** - * this function sen gamm table to ASIC - */ -static SANE_Status -gl646_send_gamma_table (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int size; - int address; - SANE_Status status = SANE_STATUS_GOOD; - int bits; - - DBGSTART; - - /* gamma table size */ - if (dev->model->flags & GENESYS_FLAG_14BIT_GAMMA) - { - size = 16384; - bits = 14; - } - else - { - size = 4096; - bits = 12; - } - - /* allocate temporary gamma tables: 16 bits words, 3 channels */ - std::vector<uint8_t> gamma(size * 2 * 3); - - RIE(sanei_genesys_generate_gamma_buffer(dev, sensor, bits, size-1, size, gamma.data())); - - /* table address */ - switch (dev->reg.find_reg(0x05).value >> 6) - { - case 0: /* 600 dpi */ - address = 0x09000; - break; - case 1: /* 1200 dpi */ - address = 0x11000; - break; - case 2: /* 2400 dpi */ - address = 0x20000; - break; - default: - return SANE_STATUS_INVAL; - } - - /* send address */ - status = sanei_genesys_set_buffer_address (dev, address); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* send data */ - status = sanei_genesys_bulk_write_data(dev, 0x3c, gamma.data(), size * 2 * 3); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send gamma table: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief this function does the led calibration. - * this function does the led calibration by scanning one line of the calibration - * area below scanner's top on white strip. The scope of this function is - * currently limited to the XP200 - */ -static SANE_Status -gl646_led_calibration (Genesys_Device * dev, Genesys_Sensor& sensor, Genesys_Register_Set& regs) -{ - (void) regs; - int total_size; - unsigned int i, j; - SANE_Status status = SANE_STATUS_GOOD; - int val; - unsigned int channels; - int avg[3], avga, avge; - int turn; - uint16_t expr, expg, expb; - Genesys_Settings settings; - SANE_Int resolution; - - SANE_Bool acceptable = SANE_FALSE; - - DBG(DBG_proc, "%s\n", __func__); - if (!dev->model->is_cis) - { - DBG(DBG_proc, "%s: not a cis scanner, nothing to do...\n", __func__); - return SANE_STATUS_GOOD; - } - - /* get led calibration resolution */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - { - channels = 3; - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - } - else - { - channels = 1; - settings.scan_mode = ScanColorMode::GRAY; - } - resolution = get_closest_resolution(dev->model->ccd_type, sensor.optical_res, channels); - - /* offset calibration is always done in color mode */ - settings.scan_method = ScanMethod::FLATBED; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = - (sensor.sensor_pixels * resolution) / sensor.optical_res; - settings.lines = 1; - settings.depth = 16; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - /* colors * bytes_per_color * scan lines */ - total_size = settings.pixels * channels * 2 * 1; - - std::vector<uint8_t> line(total_size); - -/* - we try to get equal bright leds here: - - loop: - average per color - adjust exposure times - - Sensor_Master uint8_t regs_0x10_0x15[6]; - */ - expr = sensor.exposure.red; - expg = sensor.exposure.green; - expb = sensor.exposure.blue; - - turn = 0; - - do - { - sensor.exposure.red = expr; - sensor.exposure.green = expg; - sensor.exposure.blue = expb; - - DBG(DBG_info, "%s: starting first line reading\n", __func__); - - status = simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl646_led_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, line.data(), 16, channels, settings.pixels, 1); - } - - acceptable = SANE_TRUE; - - for (j = 0; j < channels; j++) - { - avg[j] = 0; - for (i = 0; i < settings.pixels; i++) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * settings.pixels + 1] * 256 + - line[i * 2 + j * 2 * settings.pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - avg[j] += val; - } - - avg[j] /= settings.pixels; - } - - DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); - - acceptable = SANE_TRUE; - - if (!acceptable) - { - avga = (avg[0] + avg[1] + avg[2]) / 3; - expr = (expr * avga) / avg[0]; - expg = (expg * avga) / avg[1]; - expb = (expb * avga) / avg[2]; - - /* keep exposure time in a working window */ - avge = (expr + expg + expb) / 3; - if (avge > 0x2000) - { - expr = (expr * 0x2000) / avge; - expg = (expg * 0x2000) / avge; - expb = (expb * 0x2000) / avge; - } - if (avge < 0x400) - { - expr = (expr * 0x400) / avge; - expg = (expg * 0x400) / avge; - expb = (expb * 0x400) / avge; - } - } - - turn++; - - } - while (!acceptable && turn < 100); - - DBG(DBG_info,"%s: acceptable exposure: 0x%04x,0x%04x,0x%04x\n", __func__, expr, expg, expb); - - DBGCOMPLETED; - return status; -} - -/** - * average dark pixels of a scan - */ -static int -dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, - unsigned int channels, unsigned int black) -{ - unsigned int i, j, k, average, count; - unsigned int avg[3]; - uint8_t val; - - /* computes average value on black margin */ - for (k = 0; k < channels; k++) - { - avg[k] = 0; - count = 0; - for (i = 0; i < lines; i++) - { - for (j = 0; j < black; j++) - { - val = data[i * channels * pixels + j + k]; - avg[k] += val; - count++; - } - } - if (count) - avg[k] /= count; - DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); - } - average = 0; - for (i = 0; i < channels; i++) - average += avg[i]; - average /= channels; - DBG(DBG_info, "%s: average = %d\n", __func__, average); - return average; -} - - -/** @brief calibration for AD frontend devices - * we do simple scan until all black_pixels are higher than 0, - * raising offset at each turn. - */ -static SANE_Status -ad_fe_offset_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - SANE_Status status = SANE_STATUS_GOOD; - unsigned int channels; - int pass = 0; - SANE_Int resolution; - Genesys_Settings settings; - unsigned int x, y, adr, min; - unsigned int bottom, black_pixels; - - DBG(DBG_proc, "%s: start\n", __func__); - channels = 3; - resolution = get_closest_resolution(dev->model->ccd_type, sensor.optical_res, channels); - black_pixels = - (sensor.black_pixels * resolution) / sensor.optical_res; - DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); - - settings.scan_method = ScanMethod::FLATBED; - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = - (sensor.sensor_pixels * resolution) / sensor.optical_res; - settings.lines = CALIBRATION_LINES; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - /* scan first line of data with no gain */ - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - - std::vector<uint8_t> line; - - /* scan with no move */ - bottom = 1; - do - { - pass++; - dev->frontend.set_offset(0, bottom); - dev->frontend.set_offset(1, bottom); - dev->frontend.set_offset(2, bottom); - status = - simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to scan first line\n", __func__); - return status; - } - if (DBG_LEVEL >= DBG_data) - { - char title[30]; - snprintf(title, 30, "gl646_offset%03d.pnm", (int)bottom); - sanei_genesys_write_pnm_file (title, line.data(), 8, channels, - settings.pixels, settings.lines); - } - - min = 0; - for (y = 0; y < settings.lines; y++) - { - for (x = 0; x < black_pixels; x++) - { - adr = (x + y * settings.pixels) * channels; - if (line[adr] > min) - min = line[adr]; - if (line[adr + 1] > min) - min = line[adr + 1]; - if (line[adr + 2] > min) - min = line[adr + 2]; - } - } - - DBG(DBG_io2, "%s: pass=%d, min=%d\n", __func__, pass, min); - bottom++; - } - while (pass < 128 && min == 0); - if (pass == 128) - { - DBG(DBG_error, "%s: failed to find correct offset\n", __func__); - return SANE_STATUS_INVAL; - } - - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - -#define DARK_TARGET 8 -/** - * This function does the offset calibration by scanning one line of the calibration - * area below scanner's top. There is a black margin and the remaining is white. - * genesys_search_start() must have been called so that the offsets and margins - * are already known. - * @param dev scanner's device - * @return SANE_STATUS_GOOD if success, else error code is failure -*/ -static SANE_Status -gl646_offset_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - (void) regs; - SANE_Status status = SANE_STATUS_GOOD; - unsigned int channels; - int pass = 0, avg; - SANE_Int resolution; - Genesys_Settings settings; - int topavg, bottomavg; - int top, bottom, black_pixels; - - /* Analog Device fronted have a different calibration */ - if (dev->model->dac_type == DAC_AD_XP200) - { - return ad_fe_offset_calibration (dev, sensor); - } - - DBG(DBG_proc, "%s: start\n", __func__); - - /* setup for a RGB scan, one full sensor's width line */ - /* resolution is the one from the final scan */ - channels = 3; - if (dev->settings.xres > sensor.optical_res) { - resolution = get_closest_resolution(dev->model->ccd_type, sensor.optical_res, channels); - } else { - resolution = get_closest_resolution(dev->model->ccd_type, dev->settings.xres, channels); - } - black_pixels = - (sensor.black_pixels * resolution) / sensor.optical_res; - DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); - - settings.scan_method = ScanMethod::FLATBED; - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = - (sensor.sensor_pixels * resolution) / sensor.optical_res; - settings.lines = CALIBRATION_LINES; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - /* scan first line of data with no gain, but with offset from - * last calibration */ - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - - /* scan with no move */ - bottom = 90; - dev->frontend.set_offset(0, bottom); - dev->frontend.set_offset(1, bottom); - dev->frontend.set_offset(2, bottom); - - std::vector<uint8_t> first_line, second_line; - - status = simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, first_line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to scan first line\n", __func__); - return status; - } - if (DBG_LEVEL >= DBG_data) - { - char title[30]; - snprintf(title, 30, "gl646_offset%03d.pnm", bottom); - sanei_genesys_write_pnm_file(title, first_line.data(), 8, channels, - settings.pixels, settings.lines); - } - bottomavg = dark_average(first_line.data(), settings.pixels, settings.lines, channels, - black_pixels); - DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); - - /* now top value */ - top = 231; - dev->frontend.set_offset(0, top); - dev->frontend.set_offset(1, top); - dev->frontend.set_offset(2, top); - status = simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, second_line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to scan first line\n", __func__); - return status; - } - - if (DBG_LEVEL >= DBG_data) - { - char title[30]; - snprintf(title, 30, "gl646_offset%03d.pnm", top); - sanei_genesys_write_pnm_file (title, second_line.data(), 8, channels, - settings.pixels, settings.lines); - } - topavg = dark_average(second_line.data(), settings.pixels, settings.lines, channels, - black_pixels); - DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); - - /* loop until acceptable level */ - while ((pass < 32) && (top - bottom > 1)) - { - pass++; - - /* settings for new scan */ - dev->frontend.set_offset(0, (top + bottom) / 2); - dev->frontend.set_offset(1, (top + bottom) / 2); - dev->frontend.set_offset(2, (top + bottom) / 2); - - /* scan with no move */ - status = simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, second_line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to scan first line\n", __func__); - return status; - } - - if (DBG_LEVEL >= DBG_data) - { - char title[30]; - snprintf(title, 30, "gl646_offset%03d.pnm", dev->frontend.get_offset(1)); - sanei_genesys_write_pnm_file (title, second_line.data(), 8, channels, - settings.pixels, settings.lines); - } - - avg = - dark_average (second_line.data(), settings.pixels, settings.lines, channels, - black_pixels); - DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); - - /* compute new boundaries */ - if (topavg == avg) - { - topavg = avg; - top = dev->frontend.get_offset(1); - } - else - { - bottomavg = avg; - bottom = dev->frontend.get_offset(1); - } - } - - /* in case of debug do a final scan to get result */ - if (DBG_LEVEL >= DBG_data) - { - status = simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, second_line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to scan final line\n", __func__); - return status; - } - sanei_genesys_write_pnm_file("gl646_offset-final.pnm", second_line.data(), 8, channels, - settings.pixels, settings.lines); - } - - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - -/** @brief gain calibration for Analog Device frontends - * Alternative coarse gain calibration - */ -static SANE_Status -ad_fe_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi) -{ - (void) regs; - unsigned int i, channels, val; - unsigned int size, count, resolution, pass; - SANE_Status status = SANE_STATUS_GOOD; - float average; - Genesys_Settings settings; - char title[32]; - - DBGSTART; - - /* setup for a RGB scan, one full sensor's width line */ - /* resolution is the one from the final scan */ - channels = 3; - resolution = get_closest_resolution(dev->model->ccd_type, dpi, channels); - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - - settings.scan_method = ScanMethod::FLATBED; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = - (sensor.sensor_pixels * resolution) / sensor.optical_res; - settings.lines = CALIBRATION_LINES; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - size = channels * settings.pixels * settings.lines; - - /* start gain value */ - dev->frontend.set_gain(0, 1); - dev->frontend.set_gain(1, 1); - dev->frontend.set_gain(2, 1); - - average = 0; - pass = 0; - - std::vector<uint8_t> line; - - /* loop until each channel raises to acceptable level */ - while ((average < sensor.gain_white_ref) && (pass < 30)) - { - /* scan with no move */ - status = - simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to scan first line\n", __func__); - return status; - } - - /* log scanning data */ - if (DBG_LEVEL >= DBG_data) - { - sprintf (title, "gl646_alternative_gain%02d.pnm", (int)pass); - sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels, - settings.lines); - } - pass++; - - /* computes white average */ - average = 0; - count = 0; - for (i = 0; i < size; i++) - { - val = line[i]; - average += val; - count++; - } - average = average / count; - - uint8_t gain0 = dev->frontend.get_gain(0); - // adjusts gain for the channel - if (average < sensor.gain_white_ref) { - gain0 += 1; - } - - dev->frontend.set_gain(0, gain0); - dev->frontend.set_gain(1, gain0); - dev->frontend.set_gain(2, gain0); - - DBG(DBG_proc, "%s: average = %.2f, gain = %d\n", __func__, average, gain0); - } - - DBG(DBG_info, "%s: gains=(%d,%d,%d)\n", __func__, - dev->frontend.get_gain(0), - dev->frontend.get_gain(1), - dev->frontend.get_gain(2)); - DBGCOMPLETED; - return status; -} - -/** - * Alternative coarse gain calibration - * this on uses the settings from offset_calibration. First scan moves so - * we can go to calibration area for XPA. - * @param dev device for scan - * @param dpi resolutnio to calibrate at - */ -static SANE_Status -gl646_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi) -{ - unsigned int i, j, k, channels, val, maximum, idx; - unsigned int count, resolution, pass; - SANE_Status status = SANE_STATUS_GOOD; - float average[3]; - Genesys_Settings settings; - char title[32]; - - if (dev->model->ccd_type == CIS_XP200) - { - return ad_fe_coarse_gain_calibration (dev, sensor, regs, sensor.optical_res); - } - DBGSTART; - - /* setup for a RGB scan, one full sensor's width line */ - /* resolution is the one from the final scan */ - channels = 3; - - /* we are searching a sensor resolution */ - if (dpi > sensor.optical_res) { - resolution = sensor.optical_res; - } else { - resolution = get_closest_resolution(dev->model->ccd_type, dev->settings.xres, channels); - } - - settings.scan_method = dev->settings.scan_method; - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_y = 0; - if (settings.scan_method == ScanMethod::FLATBED) - { - settings.tl_x = 0; - settings.pixels = (sensor.sensor_pixels * resolution) / sensor.optical_res; - } - else - { - settings.tl_x = SANE_UNFIX (dev->model->x_offset_ta); - settings.pixels = (SANE_UNFIX (dev->model->x_size_ta) * resolution) / MM_PER_INCH; - } - settings.lines = CALIBRATION_LINES; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - /* start gain value */ - dev->frontend.set_gain(0, 1); - dev->frontend.set_gain(1, 1); - dev->frontend.set_gain(2, 1); - - if (channels > 1) - { - average[0] = 0; - average[1] = 0; - average[2] = 0; - idx = 0; - } - else - { - average[0] = 255; - average[1] = 255; - average[2] = 255; - switch (dev->settings.color_filter) { - case ColorFilter::RED: idx = 0; break; - case ColorFilter::GREEN: idx = 1; break; - case ColorFilter::BLUE: idx = 2; break; - default: idx = 0; break; // should not happen - } - average[idx] = 0; - } - pass = 0; - - std::vector<uint8_t> line; - - /* loop until each channel raises to acceptable level */ - while (((average[0] < sensor.gain_white_ref) - || (average[1] < sensor.gain_white_ref) - || (average[2] < sensor.gain_white_ref)) && (pass < 30)) - { - /* scan with no move */ - status = - simple_scan(dev, sensor, settings, SANE_FALSE, SANE_TRUE, SANE_FALSE, line); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to scan first line\n", __func__); - return status; - } - - /* log scanning data */ - if (DBG_LEVEL >= DBG_data) - { - sprintf (title, "gl646_gain%02d.pnm", (int)pass); - sanei_genesys_write_pnm_file(title, line.data(), 8, channels, settings.pixels, - settings.lines); - } - pass++; - - /* average high level for each channel and compute gain - to reach the target code - we only use the central half of the CCD data */ - for (k = idx; k < idx + channels; k++) - { - /* we find the maximum white value, so we can deduce a threshold - to average white values */ - maximum = 0; - for (i = 0; i < settings.lines; i++) - { - for (j = 0; j < settings.pixels; j++) - { - val = line[i * channels * settings.pixels + j + k]; - if (val > maximum) - maximum = val; - } - } - - /* threshold */ - maximum *= 0.9; - - /* computes white average */ - average[k] = 0; - count = 0; - for (i = 0; i < settings.lines; i++) - { - for (j = 0; j < settings.pixels; j++) - { - /* averaging only white points allow us not to care about dark margins */ - val = line[i * channels * settings.pixels + j + k]; - if (val > maximum) - { - average[k] += val; - count++; - } - } - } - average[k] = average[k] / count; - - /* adjusts gain for the channel */ - if (average[k] < sensor.gain_white_ref) - dev->frontend.set_gain(k, dev->frontend.get_gain(k) + 1); - - DBG(DBG_proc, "%s: channel %d, average = %.2f, gain = %d\n", __func__, k, average[k], - dev->frontend.get_gain(k)); - } - } - - if (channels < 3) { - dev->frontend.set_gain(1, dev->frontend.get_gain(0)); - dev->frontend.set_gain(2, dev->frontend.get_gain(0)); - } - - DBG(DBG_info, "%s: gains=(%d,%d,%d)\n", __func__, - dev->frontend.get_gain(0), - dev->frontend.get_gain(1), - dev->frontend.get_gain(2)); - DBGCOMPLETED; - return status; -} - -/** - * sets up the scanner's register for warming up. We scan 2 lines without moving. - * - */ -static SANE_Status -gl646_init_regs_for_warmup (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * local_reg, - int *channels, int *total_size) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Settings settings; - int resolution, lines; - - DBG(DBG_proc, "%s: start\n", __func__); - - dev->frontend = dev->frontend_initial; - - resolution = get_closest_resolution(dev->model->ccd_type, 300, 1); - - /* set up for a half width 2 lines gray scan without moving */ - settings.scan_method = ScanMethod::FLATBED; - settings.scan_mode = ScanColorMode::GRAY; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = - (sensor.sensor_pixels * resolution) / sensor.optical_res; - settings.lines = 2; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - /* setup for scan */ - status = setup_for_scan(dev, sensor, &dev->reg, settings, SANE_TRUE, SANE_FALSE, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: setup_for_scan failed (%s)\n", __func__, sane_strstatus(status)); - return status; - } - - /* we are not going to move, so clear these bits */ - dev->reg.find_reg(0x02).value &= ~(REG02_FASTFED | REG02_AGOHOME); - - /* don't enable any correction for this scan */ - dev->reg.find_reg(0x01).value &= ~REG01_DVDSET; - - /* copy to local_reg */ - *local_reg = dev->reg; - - /* turn off motor during this scan */ - sanei_genesys_set_motor_power(*local_reg, false); - - /* returned value to higher level warmup function */ - *channels = 1; - uint32_t value = 0; - sanei_genesys_get_triple(local_reg, REG_LINCNT, &value); - lines = value + 1; - *total_size = lines * settings.pixels; - - /* now registers are ok, write them to scanner */ - RIE (gl646_set_fe(dev, sensor, AFE_SET, settings.xres)); - RIE(sanei_genesys_bulk_write_register(dev, *local_reg)); - - DBGCOMPLETED; - return status; -} - - -/* - * this function moves head without scanning, forward, then backward - * so that the head goes to park position. - * as a by-product, also check for lock - */ -static SANE_Status -gl646_repark_head (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Settings settings; - unsigned int expected, steps; - - DBG(DBG_proc, "%s: start\n", __func__); - - settings.scan_method = ScanMethod::FLATBED; - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - settings.xres = get_closest_resolution(dev->model->ccd_type, 75, 1); - settings.yres = settings.xres; - settings.tl_x = 0; - settings.tl_y = 5; - settings.pixels = 600; - settings.lines = 4; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - const auto& sensor = sanei_genesys_find_sensor(dev, settings.xres); - - status = setup_for_scan(dev, sensor, &dev->reg, settings, SANE_FALSE, SANE_FALSE, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup for scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* TODO seems wrong ... no effective scan */ - dev->reg.find_reg(0x01).value &= ~REG01_SCAN; - - status = sanei_genesys_bulk_write_register(dev, dev->reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* start scan */ - status = gl646_begin_scan(dev, sensor, &dev->reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: \n", __func__); - return status; - } - - uint32_t value32 = 0; - sanei_genesys_get_triple(&dev->reg, REG_FEEDL, &value32); - expected = value32; - do - { - sanei_genesys_sleep_ms(100); - status = sanei_genesys_read_feed_steps (dev, &steps); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read feed steps: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - while (steps < expected); - - /* toggle motor flag, put an huge step number and redo move backward */ - status = gl646_slow_back_home (dev, 1); - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - -/* * - * initialize ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home - * @param dev device description of the scanner to initailize - * @return SANE_STATUS_GOOD if success, error code if failure - */ -static SANE_Status -gl646_init (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - struct timeval tv; - uint8_t cold = 0, val = 0; - uint32_t addr = 0xdead; - size_t len; - - DBG_INIT (); - DBG(DBG_proc, "%s: start\n", __func__); - - /* to detect real power up condition, we write to REG41 - * with pwrbit set, then read it back. When scanner is cold (just replugged) - * PWRBIT will be set in the returned value - */ - RIE (sanei_genesys_get_status (dev, &cold)); - DBG(DBG_info, "%s: status=0x%02x\n", __func__, cold); - cold = !(cold & REG41_PWRBIT); - if (cold) - { - DBG(DBG_info, "%s: device is cold\n", __func__); - } - else - { - DBG(DBG_info, "%s: device is hot\n", __func__); - } - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - /* if scanning session hasn't been initialized, set it up */ - if (!dev->already_initialized) - { - dev->dark_average_data.clear(); - dev->white_average_data.clear(); - - dev->settings.color_filter = ColorFilter::GREEN; - gettimeofday (&tv, NULL); - dev->init_date = tv.tv_sec; - - /* Set default values for registers */ - gl646_init_regs (dev); - - /* Init shading data */ - RIE (sanei_genesys_init_shading_data(dev, sensor, sensor.sensor_pixels)); - - /* initial calibration reg values */ - dev->calib_reg = dev->reg; - } - - /* execute physical unit init only if cold */ - if (cold) - { - DBG(DBG_info, "%s: device is cold\n", __func__); - - val = 0x04; - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_INIT, INDEX, 1, &val); - - /* ASIC reset */ - RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); - sanei_genesys_sleep_ms(100); - - /* Write initial registers */ - RIE(sanei_genesys_bulk_write_register(dev, dev->reg)); - - /* Test ASIC and RAM */ - if (!(dev->model->flags & GENESYS_FLAG_LAZY_INIT)) - { - RIE (gl646_asic_test (dev)); - } - - /* send gamma tables if needed */ - status = gl646_send_gamma_table(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send generic gamma tables: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* Set powersaving (default = 15 minutes) */ - RIE (gl646_set_powersaving (dev, 15)); - } /* end if cold */ - - /* Set analog frontend */ - RIE (gl646_set_fe(dev, sensor, AFE_INIT, 0)); - - /* GPO enabling for XP200 */ - if (dev->model->ccd_type == CIS_XP200) - { - sanei_genesys_write_register (dev, 0x68, dev->gpo.enable[0]); - sanei_genesys_write_register (dev, 0x69, dev->gpo.enable[1]); - - // enable GPIO - gl646_gpio_output_enable(dev->usb_dev, 6); - - // writes 0 to GPIO - gl646_gpio_write(dev->usb_dev, 0); - - // clear GPIO enable - gl646_gpio_output_enable(dev->usb_dev, 0); - - sanei_genesys_write_register (dev, 0x66, 0x10); - sanei_genesys_write_register (dev, 0x66, 0x00); - sanei_genesys_write_register (dev, 0x66, 0x10); - } - - /* MD6471/G2410 and XP200 read/write data from an undocumented memory area which - * is after the second slope table */ - if (dev->model->gpo_type != GPO_HP3670 - && dev->model->gpo_type != GPO_HP2400) - { - switch (sensor.optical_res) - { - case 600: - addr = 0x08200; - break; - case 1200: - addr = 0x10200; - break; - case 2400: - addr = 0x1fa00; - break; - } - status = sanei_genesys_set_buffer_address (dev, addr); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up control address\n", __func__); - return SANE_STATUS_INVAL; - } - sanei_usb_set_timeout (2 * 1000); - len = 6; - status = gl646_bulk_read_data (dev, 0x45, dev->control, len); - /* for some reason, read fails here for MD6471, HP2300 and XP200 - * one time out of 2 scanimage launches - */ - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_warn, "%s: failed to read control\n", __func__); - status = gl646_bulk_read_data (dev, 0x45, dev->control, len); - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_warn, "%s: failed to read control\n", __func__); - return SANE_STATUS_INVAL; - } - else - { - DBG(DBG_info, "%s: control read=0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__, - dev->control[0], dev->control[1], dev->control[2], dev->control[3], dev->control[4], - dev->control[5]); - } - sanei_usb_set_timeout (30 * 1000); - } - else - /* HP2400 and HP3670 case */ - { - dev->control[0] = 0x00; - dev->control[1] = 0x00; - dev->control[2] = 0x01; - dev->control[3] = 0x00; - dev->control[4] = 0x00; - dev->control[5] = 0x00; - } - - /* ensure head is correctly parked, and check lock */ - if (dev->model->is_sheetfed == SANE_FALSE) - { - if (dev->model->flags & GENESYS_FLAG_REPARK) - { - status = gl646_repark_head (dev); - if (status != SANE_STATUS_GOOD) - { - if (status == SANE_STATUS_INVAL) - { - DBG(DBG_error0, "Your scanner is locked. Please move the lock switch to the " - "unlocked position\n"); - return SANE_STATUS_JAMMED; - } - else - DBG(DBG_error, "%s: gl646_repark_head failed: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } - else - { - RIE (gl646_slow_back_home (dev, SANE_TRUE)); - } - } - - /* here session and device are initialized */ - dev->already_initialized = SANE_TRUE; - - DBG(DBG_proc, "%s: end\n", __func__); - return SANE_STATUS_GOOD; -} - -static -SANE_Status -gl646_move_to_ta (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - if (simple_move (dev, SANE_UNFIX (dev->model->y_offset_calib_ta)) != - SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move to calibration area\n", __func__); - return status; - } - DBGCOMPLETED; - return status; -} - - -/** - * Does a simple scan: ie no line reordering and avanced data buffering and - * shading correction. Memory for data is allocated in this function - * and must be freed by caller. - * @param dev device of the scanner - * @param settings parameters of the scan - * @param move SANE_TRUE if moving during scan - * @param forward SANE_TRUE if moving forward during scan - * @param shading SANE_TRUE to enable shading correction - * @param data pointer for the data - */ -static SANE_Status -simple_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Settings settings, SANE_Bool move, - SANE_Bool forward, SANE_Bool shading, std::vector<uint8_t>& data) -{ - SANE_Status status = SANE_STATUS_INVAL; - unsigned int size, lines, x, y, bpp; - SANE_Bool empty, split; - int count; - uint8_t val; - - DBG(DBG_proc, "%s: starting\n", __func__); - DBG(DBG_io, "%s: move=%d, forward=%d, shading=%d\n", __func__, move, forward, shading); - - /* round up to multiple of 3 in case of CIS scanner */ - if (dev->model->is_cis == SANE_TRUE) - { - settings.lines = ((settings.lines + 2) / 3) * 3; - } - - /* setup for move then scan */ - if (move == SANE_TRUE && settings.tl_y > 0) - { - split = SANE_FALSE; - } - else - { - split = SANE_TRUE; - } - status = setup_for_scan(dev, sensor, &dev->reg, settings, split, SANE_FALSE, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: setup_for_scan failed (%s)\n", __func__, sane_strstatus(status)); - return status; - } - - /* allocate memory fo scan : LINCNT may have been adjusted for CCD reordering */ - if (dev->model->is_cis == SANE_TRUE) - { - uint32_t value = 0; - sanei_genesys_get_triple(&dev->reg, REG_LINCNT, &value); - lines = value / 3; - } - else - { - uint32_t value = 0; - sanei_genesys_get_triple(&dev->reg, REG_LINCNT, &value); - lines = value + 1; - } - size = lines * settings.pixels; - if (settings.depth == 16) - bpp = 2; - else - bpp = 1; - size *= bpp; - if (settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - size *= 3; - data.clear(); - data.resize(size); - - DBG(DBG_io, "%s: allocated %d bytes of memory for %d lines\n", __func__, size, lines); - - /* put back real line number in settings */ - settings.lines = lines; - - /* initialize frontend */ - status = gl646_set_fe(dev, sensor, AFE_SET, settings.xres); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* no shading correction and not watch dog for simple scan */ - dev->reg.find_reg(0x01).value &= ~(REG01_DVDSET | REG01_DOGENB); - if (shading == SANE_TRUE) - { - dev->reg.find_reg(0x01).value |= REG01_DVDSET; - } - - /* enable gamma table for the scan */ - dev->reg.find_reg(0x05).value |= REG05_GMMENB; - - /* one table movement for simple scan */ - dev->reg.find_reg(0x02).value &= ~REG02_FASTFED; - - if (move == SANE_FALSE) - { - sanei_genesys_set_motor_power(dev->reg, false); - - /* no automatic go home if no movement */ - dev->reg.find_reg(0x02).value &= ~REG02_AGOHOME; - } - if (forward == SANE_FALSE) - { - dev->reg.find_reg(0x02).value |= REG02_MTRREV; - } - else - { - dev->reg.find_reg(0x02).value &= ~REG02_MTRREV; - } - - /* no automatic go home when using XPA */ - if (settings.scan_method == ScanMethod::TRANSPARENCY) - { - dev->reg.find_reg(0x02).value &= ~REG02_AGOHOME; - } - - /* write scan registers */ - status = sanei_genesys_bulk_write_register(dev, dev->reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* starts scan */ - status = gl646_begin_scan(dev, sensor, &dev->reg, move); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: \n", __func__); - return status; - } - - /* wait for buffers to be filled */ - count = 0; - do - { - sanei_genesys_sleep_ms(10); - RIE (sanei_genesys_get_status (dev, &val)); - if (DBG_LEVEL > DBG_info) - { - print_status (val); - } - RIE (sanei_genesys_test_buffer_empty (dev, &empty)); - count++; - } - while (empty && count < 1000); - if (count == 1000) - { - DBG(DBG_error, "%s: failed toread data\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner (dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* in case of CIS scanner, we must reorder data */ - if (dev->model->is_cis == SANE_TRUE - && settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - { - /* alloc one line sized working buffer */ - std::vector<uint8_t> buffer(settings.pixels * 3 * bpp); - - /* reorder one line of data and put it back to buffer */ - if (bpp == 1) - { - for (y = 0; y < lines; y++) - { - /* reorder line */ - for (x = 0; x < settings.pixels; x++) - { - buffer[x * 3] = data[y * settings.pixels * 3 + x]; - buffer[x * 3 + 1] = data[y * settings.pixels * 3 + settings.pixels + x]; - buffer[x * 3 + 2] = data[y * settings.pixels * 3 + 2 * settings.pixels + x]; - } - /* copy line back */ - memcpy (data.data() + settings.pixels * 3 * y, buffer.data(), - settings.pixels * 3); - } - } - else - { - for (y = 0; y < lines; y++) - { - /* reorder line */ - for (x = 0; x < settings.pixels; x++) - { - buffer[x * 6] = data[y * settings.pixels * 6 + x * 2]; - buffer[x * 6 + 1] = data[y * settings.pixels * 6 + x * 2 + 1]; - buffer[x * 6 + 2] = data[y * settings.pixels * 6 + 2 * settings.pixels + x * 2]; - buffer[x * 6 + 3] = data[y * settings.pixels * 6 + 2 * settings.pixels + x * 2 + 1]; - buffer[x * 6 + 4] = data[y * settings.pixels * 6 + 4 * settings.pixels + x * 2]; - buffer[x * 6 + 5] = data[y * settings.pixels * 6 + 4 * settings.pixels + x * 2 + 1]; - } - /* copy line back */ - memcpy (data.data() + settings.pixels * 6 * y, buffer.data(), - settings.pixels * 6); - } - } - } - - /* end scan , waiting the motor to stop if needed (if moving), but without ejecting doc */ - status = end_scan(dev, &dev->reg, SANE_TRUE, SANE_FALSE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: end\n", __func__); - return status; -} - -/** - * Does a simple move of the given distance by doing a scan at lowest resolution - * shading correction. Memory for data is allocated in this function - * and must be freed by caller. - * @param dev device of the scanner - * @param distance distance to move in MM - */ -static SANE_Status -simple_move (Genesys_Device * dev, SANE_Int distance) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Settings settings; - - DBG(DBG_proc, "%s: %d mm\n", __func__, distance); - - int resolution = get_lowest_resolution(dev->model->ccd_type, 3); - - const auto& sensor = sanei_genesys_find_sensor(dev, resolution); - - /* TODO give a no AGOHOME flag */ - settings.scan_method = ScanMethod::TRANSPARENCY; - settings.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - settings.xres = resolution; - settings.yres = resolution; - settings.tl_y = 0; - settings.tl_x = 0; - settings.pixels = - (sensor.sensor_pixels * settings.xres) / sensor.optical_res; - settings.lines = (distance * settings.xres) / MM_PER_INCH; - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - std::vector<uint8_t> data; - status = simple_scan(dev, sensor, settings, SANE_TRUE, SANE_TRUE, SANE_FALSE, data); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: simple_scan failed\n", __func__); - } - - DBGCOMPLETED - return status; -} - -/** - * update the status of the required sensor in the scanner session - * the button fileds are used to make events 'sticky' - */ -static SANE_Status -gl646_update_hardware_sensors (Genesys_Scanner * session) -{ - Genesys_Device *dev = session->dev; - uint8_t value; - - // do what is needed to get a new set of events, but try to not loose any of them. - gl646_gpio_read(dev->usb_dev, &value); - DBG(DBG_io, "%s: GPIO=0x%02x\n", __func__, value); - - // scan button - if (dev->model->buttons & GENESYS_HAS_SCAN_SW) { - switch (dev->model->gpo_type) { - case GPO_XP200: - session->buttons[BUTTON_SCAN_SW].write((value & 0x02) != 0); - break; - case GPO_5345: - session->buttons[BUTTON_SCAN_SW].write(value == 0x16); - break; - case GPO_HP2300: - session->buttons[BUTTON_SCAN_SW].write(value == 0x6c); - break; - case GPO_HP3670: - case GPO_HP2400: - session->buttons[BUTTON_SCAN_SW].write((value & 0x20) == 0); - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - } - - // email button - if (dev->model->buttons & GENESYS_HAS_EMAIL_SW) { - switch (dev->model->gpo_type) { - case GPO_5345: - session->buttons[BUTTON_EMAIL_SW].write(value == 0x12); - break; - case GPO_HP3670: - case GPO_HP2400: - session->buttons[BUTTON_EMAIL_SW].write((value & 0x08) == 0); - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - } - - // copy button - if (dev->model->buttons & GENESYS_HAS_COPY_SW) { - switch (dev->model->gpo_type) { - case GPO_5345: - session->buttons[BUTTON_COPY_SW].write(value == 0x11); - break; - case GPO_HP2300: - session->buttons[BUTTON_COPY_SW].write(value == 0x5c); - break; - case GPO_HP3670: - case GPO_HP2400: - session->buttons[BUTTON_COPY_SW].write((value & 0x10) == 0); - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - } - - // power button - if (dev->model->buttons & GENESYS_HAS_POWER_SW) { - switch (dev->model->gpo_type) { - case GPO_5345: - session->buttons[BUTTON_POWER_SW].write(value == 0x14); - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - } - - // ocr button - if (dev->model->buttons & GENESYS_HAS_OCR_SW) { - switch (dev->model->gpo_type) { - case GPO_5345: - session->buttons[BUTTON_OCR_SW].write(value == 0x13); - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - } - - // document detection - if (dev->model->buttons & GENESYS_HAS_PAGE_LOADED_SW) { - switch (dev->model->gpo_type) { - case GPO_XP200: - session->buttons[BUTTON_PAGE_LOADED_SW].write((value & 0x04) != 0); - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - } - - /* XPA detection */ - if (dev->model->flags & GENESYS_FLAG_XPA) - { - switch (dev->model->gpo_type) - { - case GPO_HP3670: - case GPO_HP2400: - /* test if XPA is plugged-in */ - if ((value & 0x40) == 0) - { - DBG(DBG_io, "%s: enabling XPA\n", __func__); - session->opt[OPT_SOURCE].cap &= ~SANE_CAP_INACTIVE; - } - else - { - DBG(DBG_io, "%s: disabling XPA\n", __func__); - session->opt[OPT_SOURCE].cap |= SANE_CAP_INACTIVE; - } - break; - default: - return SANE_STATUS_UNSUPPORTED; - } - } - - return SANE_STATUS_GOOD; -} - - -static SANE_Status -write_control (Genesys_Device * dev, const Genesys_Sensor& sensor, int resolution) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t control[4]; - uint32_t addr = 0xdead; - - /* 2300 does not write to 'control' */ - if (dev->model->motor_type == MOTOR_HP2300) - return SANE_STATUS_GOOD; - - /* MD6471/G2410/HP2300 and XP200 read/write data from an undocumented memory area which - * is after the second slope table */ - switch (sensor.optical_res) - { - case 600: - addr = 0x08200; - break; - case 1200: - addr = 0x10200; - break; - case 2400: - addr = 0x1fa00; - break; - default: - DBG(DBG_error, "%s: failed to compute control address\n", __func__); - return SANE_STATUS_INVAL; - } - - /* XP200 sets dpi, what other scanner put is unknown yet */ - switch (dev->model->motor_type) - { - case MOTOR_XP200: - /* we put scan's dpi, not motor one */ - control[0] = LOBYTE (resolution); - control[1] = HIBYTE (resolution); - control[2] = dev->control[4]; - control[3] = dev->control[5]; - break; - case MOTOR_HP3670: - case MOTOR_HP2400: - case MOTOR_5345: - default: - control[0] = dev->control[2]; - control[1] = dev->control[3]; - control[2] = dev->control[4]; - control[3] = dev->control[5]; - break; - } - - DBG(DBG_info, "%s: control write=0x%02x 0x%02x 0x%02x 0x%02x\n", __func__, control[0], control[1], - control[2], control[3]); - status = sanei_genesys_set_buffer_address (dev, addr); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up control address\n", __func__); - return SANE_STATUS_INVAL; - } - status = sanei_genesys_bulk_write_data(dev, 0x3c, control, 4); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up control\n", __func__); - return SANE_STATUS_INVAL; - } - return status; -} - -/** - * check if a stored calibration is compatible with requested scan. - * @return true if compatible, false if not. - * Whenever an error is met, it is returned. - * @param dev scanner device - * @param cache cache entry to test - * @param for_overwrite reserved for future use ... - */ -static bool -gl646_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Calibration_Cache * cache, - int for_overwrite) -{ - (void) sensor; -#ifdef HAVE_SYS_TIME_H - struct timeval time; -#endif - int compatible = 1; - - DBG(DBG_proc, "%s: start (for_overwrite=%d)\n", __func__, for_overwrite); - - if (cache == NULL) - return false; - - /* build minimal current_setup for calibration cache use only, it will be better - * computed when during setup for scan - */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - { - dev->current_setup.channels = 3; - } - else - { - dev->current_setup.channels = 1; - } - dev->current_setup.xres = dev->settings.xres; - - DBG(DBG_io, "%s: requested=(%d,%f), tested=(%d,%f)\n", __func__, dev->current_setup.channels, - dev->current_setup.xres, cache->used_setup.channels, cache->used_setup.xres); - - /* a calibration cache is compatible if color mode and x dpi match the user - * requested scan. In the case of CIS scanners, dpi isn't a criteria */ - if (dev->model->is_cis == SANE_FALSE) - { - compatible = - ((dev->current_setup.channels == cache->used_setup.channels) - && (((int) dev->current_setup.xres) == - ((int) cache->used_setup.xres))); - } - else - { - compatible = - (dev->current_setup.channels == cache->used_setup.channels); - } - if (dev->current_setup.params.scan_method != cache->used_setup.params.scan_method) - { - DBG(DBG_io, "%s: current method=%d, used=%d\n", __func__, - static_cast<unsigned>(dev->current_setup.params.scan_method), - static_cast<unsigned>(cache->used_setup.params.scan_method)); - compatible = 0; - } - if (!compatible) - { - DBG(DBG_proc, "%s: completed, non compatible cache\n", __func__); - return false; - } - - /* a cache entry expires after 30 minutes for non sheetfed scanners */ - /* this is not taken into account when overwriting cache entries */ -#ifdef HAVE_SYS_TIME_H - if(for_overwrite == SANE_FALSE) - { - gettimeofday (&time, NULL); - if ((time.tv_sec - cache->last_calibration > 30 * 60) - && (dev->model->is_sheetfed == SANE_FALSE)) - { - DBG(DBG_proc, "%s: expired entry, non compatible cache\n", __func__); - return false; - } - } -#endif - - DBG(DBG_proc, "%s: completed, cache compatible\n", __func__); - return true; -} - -/** - * search for a full width black or white strip. - * @param dev scanner device - * @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward - * @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip - * @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not - */ -static SANE_Status -gl646_search_strip(Genesys_Device * dev, const Genesys_Sensor& sensor, SANE_Bool forward, SANE_Bool black) -{ - SANE_Status status = SANE_STATUS_GOOD; - SANE_Bool half_ccd = SANE_FALSE; - Genesys_Settings settings; - int res = get_closest_resolution(dev->model->ccd_type, 75, 1); - unsigned int pass, count, found, x, y; - char title[80]; - - DBG(DBG_proc, "%s: start\n", __func__); - /* adapt to half_ccd case */ - if (sensor.ccd_size_divisor > 1) - { - /* walk the master mode list to find if half_ccd */ - // FIXME: possibly wrong channel count for is_half_ccd - if (is_half_ccd (dev->model->ccd_type, res, 3) == SANE_TRUE) - { - half_ccd = SANE_TRUE; - } - } - - /* we set up for a lowest available resolution color grey scan, full width */ - settings.scan_method = ScanMethod::FLATBED; - settings.scan_mode = ScanColorMode::GRAY; - settings.xres = res; - settings.yres = res; - settings.tl_x = 0; - settings.tl_y = 0; - settings.pixels = (SANE_UNFIX (dev->model->x_size) * res) / MM_PER_INCH; - if (half_ccd == SANE_TRUE) - { - settings.pixels /= 2; - } - - /* 15 mm at at time */ - settings.lines = (15 * settings.yres) / MM_PER_INCH; /* may become a parameter from genesys_devices.c */ - settings.depth = 8; - settings.color_filter = ColorFilter::RED; - - settings.disable_interpolation = 0; - settings.threshold = 0; - settings.dynamic_lineart = SANE_FALSE; - - /* signals if a strip of the given color has been found */ - found = 0; - - /* detection pass done */ - pass = 0; - - std::vector<uint8_t> data; - - /* loop until strip is found or maximum pass number done */ - while (pass < 20 && !found) - { - /* scan a full width strip */ - status = - simple_scan(dev, sensor, settings, SANE_TRUE, forward, SANE_FALSE, data); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: simple_scan failed\n", __func__); - return status; - } - if (DBG_LEVEL >= DBG_data) - { - sprintf (title, "gl646_search_strip_%s%02d.pnm", forward ? "fwd" : "bwd", - (int)pass); - sanei_genesys_write_pnm_file (title, data.data(), settings.depth, 1, - settings.pixels, settings.lines); - } - - /* search data to find black strip */ - /* when searching forward, we only need one line of the searched color since we - * will scan forward. But when doing backward search, we need all the area of the - * same color */ - if (forward) - { - for (y = 0; y < settings.lines && !found; y++) - { - count = 0; - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < settings.pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * settings.pixels + x] > 90) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * settings.pixels + x] < 60) - { - count++; - } - } - - /* at end of line, if count >= 3%, line is not fully of the desired color - * so we must go to next line of the buffer */ - /* count*100/pixels < 3 */ - if ((count * 100) / settings.pixels < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, - pass, y); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d\n", __func__, settings.pixels, count); - } - } - } - else /* since calibration scans are done forward, we need the whole area - to be of the required color when searching backward */ - { - count = 0; - for (y = 0; y < settings.lines; y++) - { - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < settings.pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * settings.pixels + x] > 60) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * settings.pixels + x] < 60) - { - count++; - } - } - } - - /* at end of area, if count >= 3%, area is not fully of the desired color - * so we must go to next buffer */ - if ((count * 100) / (settings.pixels * settings.lines) < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d\n", __func__, settings.pixels, count); - } - } - pass++; - } - if (found) - { - status = SANE_STATUS_GOOD; - DBG(DBG_info, "%s: strip found\n", __func__); - } - else - { - status = SANE_STATUS_UNSUPPORTED; - DBG(DBG_info, "%s: strip not found\n", __func__); - } - return status; -} - -/** the gl646 command set */ -static Genesys_Command_Set gl646_cmd_set = { - "gl646-generic", /* the name of this set */ - - gl646_needs_home_before_init_regs_for_scan, - - gl646_init, - gl646_init_regs_for_warmup, - gl646_init_regs_for_coarse_calibration, - gl646_init_regs_for_shading, - gl646_init_regs_for_scan, - - gl646_get_filter_bit, - gl646_get_lineart_bit, - gl646_get_bitset_bit, - gl646_get_gain4_bit, - gl646_get_fast_feed_bit, - gl646_test_buffer_empty_bit, - gl646_test_motor_flag_bit, - - gl646_public_set_fe, - gl646_set_powersaving, - gl646_save_power, - - gl646_begin_scan, - gl646_end_scan, - - gl646_send_gamma_table, - - gl646_search_start_position, - - gl646_offset_calibration, - gl646_coarse_gain_calibration, - gl646_led_calibration, - - NULL, - gl646_slow_back_home, - NULL, - - sanei_genesys_bulk_write_register, - sanei_genesys_bulk_write_data, - gl646_bulk_read_data, - - gl646_update_hardware_sensors, - - /* sheetfed related functions */ - gl646_load_document, - gl646_detect_document_end, - gl646_eject_document, - gl646_search_strip, - - gl646_is_compatible_calibration, - gl646_move_to_ta, - NULL, - NULL, - NULL -}; - -SANE_Status -sanei_gl646_init_cmd_set (Genesys_Device * dev) -{ - dev->model->cmd_set = &gl646_cmd_set; - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_gl646.h b/backend/genesys_gl646.h deleted file mode 100644 index 766176a..0000000 --- a/backend/genesys_gl646.h +++ /dev/null @@ -1,594 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2003-2004 Henning Meier-Geinitz <henning@meier-geinitz.de> - Copyright (C) 2004-2005 Gerhard Jaeger <gerhard@gjaeger.de> - Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> - Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#include "genesys.h" - -/* - * Genesys Logic GL646 based scanners - */ -/* Individual bits */ -#define REG01_CISSET 0x80 -#define REG01_DOGENB 0x40 -#define REG01_DVDSET 0x20 -#define REG01_FASTMOD 0x10 -#define REG01_COMPENB 0x08 -#define REG01_DRAMSEL 0x04 -#define REG01_SHDAREA 0x02 -#define REG01_SCAN 0x01 - -#define REG02_NOTHOME 0x80 -#define REG02_ACDCDIS 0x40 -#define REG02_AGOHOME 0x20 -#define REG02_MTRPWR 0x10 -#define REG02_FASTFED 0x08 -#define REG02_MTRREV 0x04 -#define REG02_STEPSEL 0x03 - -#define REG02_FULLSTEP 0x00 -#define REG02_HALFSTEP 0x01 -#define REG02_QUATERSTEP 0x02 - -#define REG03_TG3 0x80 -#define REG03_AVEENB 0x40 -#define REG03_XPASEL 0x20 -#define REG03_LAMPPWR 0x10 -#define REG03_LAMPDOG 0x08 -#define REG03_LAMPTIM 0x07 - -#define REG04_LINEART 0x80 -#define REG04_BITSET 0x40 -#define REG04_ADTYPE 0x30 -#define REG04_FILTER 0x0c -#define REG04_FESET 0x03 - -#define REG05_DPIHW 0xc0 -#define REG05_DPIHW_600 0x00 -#define REG05_DPIHW_1200 0x40 -#define REG05_DPIHW_2400 0x80 -#define REG05_DPIHW_4800 0xc0 -#define REG05_GMMTYPE 0x30 -#define REG05_GMM14BIT 0x10 -#define REG05_GMMENB 0x08 -#define REG05_LEDADD 0x04 -#define REG05_BASESEL 0x03 - -#define REG06_PWRBIT 0x10 -#define REG06_GAIN4 0x08 -#define REG06_OPTEST 0x07 - -#define REG07_DMASEL 0x02 -#define REG07_DMARDWR 0x01 - -#define REG16_CTRLHI 0x80 -#define REG16_SELINV 0x40 -#define REG16_TGINV 0x20 -#define REG16_CK1INV 0x10 -#define REG16_CK2INV 0x08 -#define REG16_CTRLINV 0x04 -#define REG16_CKDIS 0x02 -#define REG16_CTRLDIS 0x01 - -#define REG17_TGMODE 0xc0 -#define REG17_TGMODE_NO_DUMMY 0x00 -#define REG17_TGMODE_REF 0x40 -#define REG17_TGMODE_XPA 0x80 -#define REG17_TGW 0x3f - -#define REG18_CNSET 0x80 -#define REG18_DCKSEL 0x60 -#define REG18_CKTOGGLE 0x10 -#define REG18_CKDELAY 0x0c -#define REG18_CKSEL 0x03 - -#define REG1D_CKMANUAL 0x80 - -#define REG1E_WDTIME 0xf0 -#define REG1E_LINESEL 0x0f - -#define REG41_PWRBIT 0x80 -#define REG41_BUFEMPTY 0x40 -#define REG41_FEEDFSH 0x20 -#define REG41_SCANFSH 0x10 -#define REG41_HOMESNR 0x08 -#define REG41_LAMPSTS 0x04 -#define REG41_FEBUSY 0x02 -#define REG41_MOTMFLG 0x01 - -#define REG66_LOW_CURRENT 0x10 - -#define REG6A_FSTPSEL 0xc0 -#define REG6A_FASTPWM 0x3f - -#define REG6C_TGTIME 0xc0 -#define REG6C_Z1MOD 0x38 -#define REG6C_Z2MOD 0x07 - -#define REG_SCANFED 0x1f -#define REG_BUFSEL 0x20 -#define REG_LINCNT 0x25 -#define REG_DPISET 0x2c -#define REG_STRPIXEL 0x30 -#define REG_ENDPIXEL 0x32 -#define REG_DUMMY 0x34 -#define REG_MAXWD 0x35 -#define REG_LPERIOD 0x38 -#define REG_FEEDL 0x3d -#define REG_VALIDWORD 0x42 -#define REG_FEDCNT 0x48 -#define REG_SCANCNT 0x4b -#define REG_Z1MOD 0x60 -#define REG_Z2MOD 0x62 - - -#include "genesys.h" - -static SANE_Status gl646_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t set, int dpi); - -static SANE_Status gl646_public_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t set); - -static -SANE_Status -gl646_save_power (Genesys_Device * dev, SANE_Bool enable); - -static -SANE_Status -gl646_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home); - -static -SANE_Status -gl646_move_to_ta (Genesys_Device * dev); - -/** - * sets up the scanner for a scan, registers, gamma tables, shading tables - * and slope tables, based on the parameter struct. - * @param dev device to set up - * @param regs registers to set up - * @param settings settings of the scan - * @param split true if move before scan has to be done - * @param xcorrection true if scanner's X geometry must be taken into account to - * compute X, ie add left margins - * @param ycorrection true if scanner's Y geometry must be taken into account to - * compute Y, ie add top margins - */ -static SANE_Status -setup_for_scan (Genesys_Device *device, - const Genesys_Sensor& sensor, - Genesys_Register_Set *regs, - Genesys_Settings settings, - SANE_Bool split, - SANE_Bool xcorrection, - SANE_Bool ycorrection); - -/** - * sets up the registers for a scan corresponding to the settings. - * Builds motor slope tables. Computes buffer sizes and data amount to - * transfer. It also sets up analog frontend. - * */ -static SANE_Status -gl646_setup_registers (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, SetupParams& params, - uint16_t * slope_table1, - uint16_t * slope_table2, - bool xcorrection); - -/** - * Does a simple move of the given distance by doing a scan at lowest resolution - * shading correction. Memory for data is allocated in this function - * and must be freed by caller. - * @param dev device of the scanner - * @param distance distance to move in MM - */ -static SANE_Status -simple_move (Genesys_Device * dev, SANE_Int distance); - -/** - * Does a simple scan of the area given by the settings. Scanned data - * it put in an allocated area which must be freed by the caller. - * and slope tables, based on the parameter struct. There is no shading - * correction while gamma correction is active. - * @param dev device to set up - * @param settings settings of the scan - * @param move flag to enable scanhead to move - * @param forward flag to tell movement direction - * @param shading flag to tell if shading correction should be done - * @param data pointer that will point to the scanned data - */ -static SANE_Status -simple_scan(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Settings settings, SANE_Bool move, SANE_Bool forward, - SANE_Bool shading, std::vector<uint8_t>& data); - -/** - * Send the stop scan command - * */ -static SANE_Status -end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop, SANE_Bool eject); -/** - * writes control data to an area behind the last motor table. - */ -static SANE_Status write_control (Genesys_Device * dev, const Genesys_Sensor& sensor, - int resolution); - - -/** - * initialize scanner's registers at SANE init time - */ -static void gl646_init_regs (Genesys_Device * dev); - -static SANE_Status gl646_load_document (Genesys_Device * dev); - -static SANE_Status -gl646_detect_document_end (Genesys_Device * dev); - -#define FULL_STEP 0 -#define HALF_STEP 1 -#define QUATER_STEP 2 - -#define CALIBRATION_LINES 10 - -/** - * master motor settings table entry - */ -typedef struct -{ - /* key */ - SANE_Int motor; - SANE_Int dpi; - unsigned channels; - - /* settings */ - SANE_Int ydpi; /* real motor dpi, may be different from the resolution */ - SANE_Int steptype; /* 0=full, 1=half, 2=quarter */ - SANE_Bool fastmod; /* fast scanning 0/1 */ - SANE_Bool fastfed; /* fast fed slope tables */ - SANE_Int mtrpwm; - SANE_Int steps1; /* table 1 informations */ - SANE_Int vstart1; - SANE_Int vend1; - SANE_Int steps2; /* table 2 informations */ - SANE_Int vstart2; - SANE_Int vend2; - float g1; - float g2; - SANE_Int fwdbwd; /* forward/backward steps */ -} Motor_Master; - -/** - * master sensor settings table entry - */ -typedef struct -{ - /* key */ - SANE_Int sensor; /**< sensor identifier */ - SANE_Int dpi; /**< required dpi */ - unsigned channels; // 3 channels if color scan, 1 channel for gray scan - - /* settings */ - SANE_Int xdpi; /**< real sensor dpi, may be different from the required resolution */ - SANE_Int exposure; /**< exposure time */ - SANE_Int dpiset; /**< set sensor dpi */ - SANE_Int cksel; /**< dpiset 'divisor', part of reg 18h */ - SANE_Int dummy; /**< dummy exposure time */ - /* uint8_t regs_0x10_0x15[6];*/ - uint8_t *regs_0x10_0x15; /**< per color exposure time for CIS scanners */ - SANE_Bool half_ccd; /**> true if manual CCD/2 clock programming or real dpi is half dpiset */ - uint8_t r18; /**> content of register 18h */ - uint8_t r1d; /**> content of register 1dh */ -} Sensor_Master; - -/** - * settings for a given resolution and DPISET - * TODO clean up this when all scanners will have been added - */ -typedef struct -{ - /* key */ - SANE_Int sensor; - SANE_Int cksel; - - /* values */ - uint8_t regs_0x08_0x0b[4]; /**< settings for normal CCD clock */ - uint8_t manual_0x08_0x0b[4]; /**< settings for CCD/2 clock */ - uint8_t regs_0x16_0x1d[8]; - uint8_t regs_0x52_0x5e[13]; - uint8_t manual_0x52_0x58[7]; -} Sensor_Settings; - -static uint8_t xp200_color[6]={0x16, 0x44, 0x0c, 0x80, 0x09, 0x2e}; -static uint8_t xp200_gray[6]={0x05, 0x0a, 0x0f, 0xa0, 0x10, 0x10}; - -/** - * master sensor settings, for a given sensor and dpi, - * it gives exposure and CCD time - */ -static Sensor_Master sensor_master[] = { - /* HP3670 master settings */ - {CCD_HP3670, 75, 3, 75, 4879, 300, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 100, 3, 100, 4487, 400, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 150, 3, 150, 4879, 600, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 300, 3, 300, 4503, 1200, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 600, 3, 600, 10251, 1200, 2, 42, NULL, SANE_FALSE, 0x31, 0x43}, - {CCD_HP3670,1200, 3, 1200, 12750, 1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x43}, - {CCD_HP3670,2400, 3, 1200, 12750, 1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x43}, - {CCD_HP3670, 75, 1, 75, 4879, 300, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 100, 1, 100, 4487, 400, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 150, 1, 150, 4879, 600, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 300, 1, 300, 4503, 1200, 4, 42, NULL, SANE_FALSE, 0x33, 0x43}, - {CCD_HP3670, 600, 1, 600, 10251, 1200, 2, 42, NULL, SANE_FALSE, 0x31, 0x43}, - {CCD_HP3670,1200, 1, 1200, 12750, 1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x43}, - {CCD_HP3670,2400, 1, 1200, 12750, 1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x43}, - - /* HP 2400 master settings */ - {CCD_HP2400, 50, 3, 50, 7211, 200, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 100, 3, 100, 7211, 400, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 150, 3, 150, 7211, 600, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 300, 3, 300, 8751, 1200, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 600, 3, 600, 18760, 1200, 2, 42, NULL, SANE_FALSE, 0x31, 0x02}, - {CCD_HP2400,1200, 3, 1200, 21749, 1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x42}, - {CCD_HP2400, 50, 1, 50, 7211, 200, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 100, 1, 100, 7211, 400, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 150, 1, 150, 7211, 600, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 300, 1, 300, 8751, 1200, 4, 42, NULL, SANE_FALSE, 0x3f, 0x02}, - {CCD_HP2400, 600, 1, 600, 18760, 1200, 2, 42, NULL, SANE_FALSE, 0x31, 0x02}, - {CCD_HP2400,1200, 1, 1200, 21749, 1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x42}, - - /* XP 200 master settings */ - {CIS_XP200 , 75, 3, 75, 5700, 75, 1, 42, xp200_color, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 100, 3, 100, 5700, 100, 1, 42, xp200_color, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 200, 3, 200, 5700, 200, 1, 42, xp200_color, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 300, 3, 300, 9000, 300, 1, 42, xp200_color, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 600, 3, 600, 16000, 600, 1, 42, xp200_color, SANE_FALSE, 0x00, 0x11}, - - {CIS_XP200 , 75, 1, 75, 16000, 75, 1, 42, xp200_gray, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 100, 1, 100, 7800, 100, 1, 42, xp200_gray, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 200, 1, 200, 11000, 200, 1, 42, xp200_gray, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 300, 1, 300, 13000, 300, 1, 42, xp200_gray, SANE_FALSE, 0x00, 0x11}, - {CIS_XP200 , 600, 1, 600, 24000, 600, 1, 42, xp200_gray, SANE_FALSE, 0x00, 0x11}, - - /* HP 2300 master settings */ - {CCD_HP2300, 75, 3, 75, 4480, 150, 1, 42, NULL, SANE_TRUE , 0x20, 0x85}, - {CCD_HP2300, 150, 3, 150, 4350, 300, 1, 42, NULL, SANE_TRUE , 0x20, 0x85}, - {CCD_HP2300, 300, 3, 300, 4350, 600, 1, 42, NULL, SANE_TRUE , 0x20, 0x85}, - {CCD_HP2300, 600, 3, 600, 8700, 600, 1, 42, NULL, SANE_FALSE, 0x20, 0x05}, - {CCD_HP2300,1200, 3, 600, 8700, 600, 1, 42, NULL, SANE_FALSE, 0x20, 0x05}, - {CCD_HP2300, 75, 1, 75, 4480, 150, 1, 42, NULL, SANE_TRUE , 0x20, 0x85}, - {CCD_HP2300, 150, 1, 150, 4350, 300, 1, 42, NULL, SANE_TRUE , 0x20, 0x85}, - {CCD_HP2300, 300, 1, 300, 4350, 600, 1, 42, NULL, SANE_TRUE , 0x20, 0x85}, - {CCD_HP2300, 600, 1, 600, 8700, 600, 1, 42, NULL, SANE_FALSE, 0x20, 0x05}, - {CCD_HP2300,1200, 1, 600, 8700, 600, 1, 42, NULL, SANE_FALSE, 0x20, 0x05}, - /* non half ccd 300 dpi settings - {CCD_HP2300, 300, 3, 300, 8700, 300, 1, 42, NULL, SANE_FALSE, 0x20, 0x05}, - {CCD_HP2300, 300, 1, 300, 8700, 300, 1, 42, NULL, SANE_FALSE, 0x20, 0x05}, - */ - - /* MD5345/6471 master settings */ - {CCD_5345 , 50, 3, 50, 12000, 100, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 75, 3, 75, 11000, 150, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 100, 3, 100, 11000, 200, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 150, 3, 150, 11000, 300, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 200, 3, 200, 11000, 400, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 300, 3, 300, 11000, 600, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 400, 3, 400, 11000, 800, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 600, 3, 600, 11000,1200, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 ,1200, 3, 1200, 11000,1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x03}, - {CCD_5345 ,2400, 3, 1200, 11000,1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x03}, - {CCD_5345 , 50, 1, 50, 12000, 100, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 75, 1, 75, 11000, 150, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 100, 1, 100, 11000, 200, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 150, 1, 150, 11000, 300, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 200, 1, 200, 11000, 400, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 300, 1, 300, 11000, 600, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 400, 1, 400, 11000, 800, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 , 600, 1, 600, 11000,1200, 1, 42, NULL, SANE_TRUE , 0x28, 0x03}, - {CCD_5345 ,1200, 1, 1200, 11000,1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x03}, - {CCD_5345 ,2400, 1, 1200, 11000,1200, 1, 42, NULL, SANE_FALSE, 0x30, 0x03}, - -}; - -/** - * master motor settings, for a given motor and dpi, - * it gives steps and speed informations - */ -static Motor_Master motor_master[] = { - /* HP3670 motor settings */ - {MOTOR_HP3670, 75, 3, 75, FULL_STEP, SANE_FALSE, SANE_TRUE , 1, 200, 3429, 305, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 100, 3, 100, HALF_STEP, SANE_FALSE, SANE_TRUE , 1, 143, 2905, 187, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 150, 3, 150, HALF_STEP, SANE_FALSE, SANE_TRUE , 1, 73, 3429, 305, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 300, 3, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 1, 11, 1055, 563, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 600, 3, 600, FULL_STEP, SANE_FALSE, SANE_TRUE , 0, 3, 10687, 5126, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670,1200, 3,1200, HALF_STEP, SANE_FALSE, SANE_TRUE , 0, 3, 15937, 6375, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670,2400, 3,2400, HALF_STEP, SANE_FALSE, SANE_TRUE , 0, 3, 15937, 12750, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 75, 1, 75, FULL_STEP, SANE_FALSE, SANE_TRUE , 1, 200, 3429, 305, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 100, 1, 100, HALF_STEP, SANE_FALSE, SANE_TRUE , 1, 143, 2905, 187, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 150, 1, 150, HALF_STEP, SANE_FALSE, SANE_TRUE , 1, 73, 3429, 305, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 300, 1, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 1, 11, 1055, 563, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670, 600, 1, 600, FULL_STEP, SANE_FALSE, SANE_TRUE , 0, 3, 10687, 5126, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670,1200, 1,1200, HALF_STEP, SANE_FALSE, SANE_TRUE , 0, 3, 15937, 6375, 192, 3399, 337, 0.3, 0.4, 192}, - {MOTOR_HP3670,2400, 3,2400, HALF_STEP, SANE_FALSE, SANE_TRUE , 0, 3, 15937, 12750, 192, 3399, 337, 0.3, 0.4, 192}, - - /* HP2400/G2410 motor settings base motor dpi = 600 */ - {MOTOR_HP2400, 50, 3, 50, FULL_STEP, SANE_FALSE, SANE_TRUE , 63, 120, 8736, 601, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 100, 3, 100, HALF_STEP, SANE_FALSE, SANE_TRUE, 63, 120, 8736, 601, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 150, 3, 150, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 67, 15902, 902, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 300, 3, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 32, 16703, 2188, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 600, 3, 600, FULL_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 18761, 18761, 192, 4905, 627, 0.30, 0.4, 192}, - {MOTOR_HP2400,1200, 3,1200, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 43501, 43501, 192, 4905, 627, 0.30, 0.4, 192}, - {MOTOR_HP2400, 50, 1, 50, FULL_STEP, SANE_FALSE, SANE_TRUE , 63, 120, 8736, 601, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 100, 1, 100, HALF_STEP, SANE_FALSE, SANE_TRUE, 63, 120, 8736, 601, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 150, 1, 150, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 67, 15902, 902, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 300, 1, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 32, 16703, 2188, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400, 600, 1, 600, FULL_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 18761, 18761, 192, 4905, 337, 0.30, 0.4, 192}, - {MOTOR_HP2400,1200, 1,1200, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 43501, 43501, 192, 4905, 337, 0.30, 0.4, 192}, - - /* XP 200 motor settings */ - {MOTOR_XP200, 75, 3, 75, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 6000, 2136, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 100, 3, 100, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 6000, 2850, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 200, 3, 200, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 6999, 5700, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 250, 3, 250, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 6999, 6999, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 300, 3, 300, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 13500, 13500, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 600, 3, 600, HALF_STEP, SANE_TRUE , SANE_TRUE, 0, 4, 31998, 31998, 2, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 75, 1, 75, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 6000, 2000, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 100, 1, 100, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 6000, 1300, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 200, 1, 200, HALF_STEP, SANE_TRUE , SANE_TRUE, 0, 4, 6000, 3666, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 300, 1, 300, HALF_STEP, SANE_TRUE , SANE_FALSE, 0, 4, 6500, 6500, 8, 12000, 1200, 0.3, 0.5, 1}, - {MOTOR_XP200, 600, 1, 600, HALF_STEP, SANE_TRUE , SANE_TRUE, 0, 4, 24000, 24000, 2, 12000, 1200, 0.3, 0.5, 1}, - - /* HP scanjet 2300c */ - {MOTOR_HP2300, 75, 3, 75, FULL_STEP, SANE_FALSE, SANE_TRUE , 63, 120, 8139, 560, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 150, 3, 150, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 67, 7903, 543, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 300, 3, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 2175, 1087, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 600, 3, 600, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 8700, 4350, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300,1200, 3,1200, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 17400, 8700, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 75, 1, 75, FULL_STEP, SANE_FALSE, SANE_TRUE , 63, 120, 8139, 560, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 150, 1, 150, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 67, 7903, 543, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 300, 1, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 2175, 1087, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 600, 1, 600, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 8700, 4350, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300,1200, 1,1200, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 3, 17400, 8700, 120, 4905, 337, 0.3, 0.4, 16}, - /* non half ccd settings for 300 dpi - {MOTOR_HP2300, 300, 3, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 44, 5386, 2175, 120, 4905, 337, 0.3, 0.4, 16}, - {MOTOR_HP2300, 300, 1, 300, HALF_STEP, SANE_FALSE, SANE_TRUE , 63, 44, 5386, 2175, 120, 4905, 337, 0.3, 0.4, 16}, - */ - - /* MD5345/6471 motor settings */ - /* vfinal=(exposure/(1200/dpi))/step_type */ - {MOTOR_5345, 50, 3, 50, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 250, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 75, 3, 75, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 343, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 100, 3, 100, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 458, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 150, 3, 150, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 687, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 200, 3, 200, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 916, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 300, 3, 300, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 1375, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 400, 3, 400, HALF_STEP , SANE_FALSE, SANE_TRUE , 0, 32, 2000, 1833, 255, 2000, 300, 0.3, 0.4, 32}, - {MOTOR_5345, 500, 3, 500, HALF_STEP , SANE_FALSE, SANE_TRUE , 0, 32, 2291, 2291, 255, 2000, 300, 0.3, 0.4, 32}, - {MOTOR_5345, 600, 3, 600, HALF_STEP , SANE_FALSE, SANE_TRUE , 0, 32, 2750, 2750, 255, 2000, 300, 0.3, 0.4, 32}, - {MOTOR_5345, 1200, 3,1200, QUATER_STEP, SANE_FALSE, SANE_TRUE , 0, 16, 2750, 2750, 255, 2000, 300, 0.3, 0.4, 146}, - {MOTOR_5345, 2400, 3,2400, QUATER_STEP, SANE_FALSE, SANE_TRUE , 0, 16, 5500, 5500, 255, 2000, 300, 0.3, 0.4, 146}, - {MOTOR_5345, 50, 1, 50, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 250, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 75, 1, 75, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 343, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 100, 1, 100, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 458, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 150, 1, 150, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 687, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 200, 1, 200, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 916, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 300, 1, 300, HALF_STEP , SANE_FALSE, SANE_TRUE , 2, 255, 2500, 1375, 255, 2000, 300, 0.3, 0.4, 64}, - {MOTOR_5345, 400, 1, 400, HALF_STEP , SANE_FALSE, SANE_TRUE , 0, 32, 2000, 1833, 255, 2000, 300, 0.3, 0.4, 32}, - {MOTOR_5345, 500, 1, 500, HALF_STEP , SANE_FALSE, SANE_TRUE , 0, 32, 2291, 2291, 255, 2000, 300, 0.3, 0.4, 32}, - {MOTOR_5345, 600, 1, 600, HALF_STEP , SANE_FALSE, SANE_TRUE , 0, 32, 2750, 2750, 255, 2000, 300, 0.3, 0.4, 32}, - {MOTOR_5345, 1200, 1,1200, QUATER_STEP, SANE_FALSE, SANE_TRUE , 0, 16, 2750, 2750, 255, 2000, 300, 0.3, 0.4, 146}, - {MOTOR_5345, 2400, 1,2400, QUATER_STEP, SANE_FALSE, SANE_TRUE , 0, 16, 5500, 5500, 255, 2000, 300, 0.3, 0.4, 146}, /* 5500 guessed */ -}; - -/** - * sensor settings for a given sensor and timing method - */ -static Sensor_Settings sensor_settings[] = { - /* HP 3670 */ - {CCD_HP3670, 1, - {0x0d, 0x0f, 0x11, 0x13}, - {0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x07, 0x30, 0x2a, 0x00, 0x00, 0xc0, 0x43}, - {0x03, 0x07, 0x0b, 0x0f, 0x13, 0x17, 0x23, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, }, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - }, - {CCD_HP3670, 2, - {0x00, 0x05, 0x06, 0x08}, - {0x00, 0x00, 0x00, 0x00}, - {0x33, 0x07, 0x31, 0x2a, 0x02, 0x0e, 0xc0, 0x43}, - {0x0b, 0x0f, 0x13, 0x17, 0x03, 0x07, 0x63, 0x00, 0xc1, 0x02, 0x0e, 0x00, 0x00, }, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - }, - {CCD_HP3670, 4, - {0x00, 0x0a, 0x0b, 0x0d}, - {0x00, 0x00, 0x00, 0x00}, - {0x33, 0x07, 0x33, 0x2a, 0x02, 0x13, 0xc0, 0x43}, - {0x0f, 0x13, 0x17, 0x03, 0x07, 0x0b, 0x83, 0x15, 0xc1, 0x05, 0x0a, 0x0f, 0x00, }, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} - }, - /* HP 2400 */ - {CCD_HP2400, 4, - {0x14, 0x15, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00}, - {0xbf, 0x08, 0x3f, 0x2a, 0x00, 0x00, 0x00, 0x02}, - {11, 15, 19, 23, 3, 7, 0x63, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00}, - {11, 15, 19, 23, 3, 7, 0x63} - }, - {CCD_HP2400, 2, - {14, 15, 0, 0}, - {14, 15, 0, 0}, - {0xbf, 0x08, 0x31, 0x2a, 0, 0, 0, 0x02}, - {3, 7, 11, 15, 19, 23, 0x23, 0, 0xc1, 0, 0, 0, 0}, - {3, 7, 11, 15, 19, 23, 0x23} - }, - {CCD_HP2400, 1, - {0x02, 0x04, 0x00, 0x00}, - {0x02, 0x04, 0x00, 0x00}, - {0xbf, 0x08, 0x30, 0x2a, 0x00, 0x00, 0xc0, 0x42}, - {0x0b, 0x0f, 0x13, 0x17, 0x03, 0x07, 0x63, 0x00, 0xc1, 0x00, 0x0e, 0x00, 0x00}, - {0x0b, 0x0f, 0x13, 0x17, 0x03, 0x07, 0x63} - }, - {CIS_XP200, 1, - {6, 7, 10, 4}, - {6, 7, 10, 4}, - {0x24, 0x04, 0x00, 0x2a, 0x0a, 0x0a, 0, 0x11}, - {8, 2, 0, 0, 0, 0, 0x1a, 0x51, 0, 0, 0, 0, 0}, - {8, 2, 0, 0, 0, 0, 0x1a} - }, - {CCD_HP2300, 1, - {0x01, 0x03, 0x04, 0x06}, - {0x16, 0x00, 0x01, 0x03}, - {0xb7, 0x0a, 0x20, 0x2a, 0x6a, 0x8a, 0x00, 0x05}, - {0x0f, 0x13, 0x17, 0x03, 0x07, 0x0b, 0x83, 0x00, 0xc1, 0x06, 0x0b, 0x10, 0x16}, - {0x0f, 0x13, 0x17, 0x03, 0x07, 0x0b, 0x83} - }, - {CCD_5345, 1, - {0x0d, 0x0f, 0x11, 0x13}, - {0x00, 0x05, 0x06, 0x08}, /* manual clock 1/2 settings or half ccd */ - {0x0b, 0x0a, 0x30, 0x2a, 0x00, 0x00, 0x00, 0x03, }, - {0x03, 0x07, 0x0b, 0x0f, 0x13, 0x17, 0x23, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x13, 0x17, 0x03, 0x07, 0x0b, 0x83} /* half ccd settings */ - }, -}; diff --git a/backend/genesys_gl841.cc b/backend/genesys_gl841.cc deleted file mode 100644 index 9e8fc15..0000000 --- a/backend/genesys_gl841.cc +++ /dev/null @@ -1,5624 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2003 Oliver Rauch - Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de> - Copyright (C) 2004 Gerhard Jaeger <gerhard@gjaeger.de> - Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> - Copyright (C) 2005 Philipp Schmid <philipp8288@web.de> - Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com> - Copyright (C) 2010 Chris Berry <s0457957@sms.ed.ac.uk> and Michael Rickmann <mrickma@gwdg.de> - for Plustek Opticbook 3600 support - - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#define DEBUG_DECLARE_ONLY - -#include "genesys_gl841.h" - -#include <vector> - -/**************************************************************************** - Low level function - ****************************************************************************/ - -/* ------------------------------------------------------------------------ */ -/* Read and write RAM, registers and AFE */ -/* ------------------------------------------------------------------------ */ - -/* Set address for writing data */ -static SANE_Status -gl841_set_buffer_address_gamma (Genesys_Device * dev, uint32_t addr) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_io, "%s: setting address to 0x%05x\n", __func__, addr & 0xfffffff0); - - addr = addr >> 4; - - status = sanei_genesys_write_register (dev, 0x5c, (addr & 0xff)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while writing low byte: %s\n", __func__, sane_strstatus(status)); - return status; - } - - addr = addr >> 8; - status = sanei_genesys_write_register (dev, 0x5b, (addr & 0xff)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while writing high byte: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_io, "%s: completed\n", __func__); - - return status; -} - -/**************************************************************************** - Mid level functions - ****************************************************************************/ - -static SANE_Bool -gl841_get_fast_feed_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x02); - if (r && (r->value & REG02_FASTFED)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl841_get_filter_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x04); - if (r && (r->value & REG04_FILTER)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl841_get_lineart_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x04); - if (r && (r->value & REG04_LINEART)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl841_get_bitset_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x04); - if (r && (r->value & REG04_BITSET)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl841_get_gain4_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x06); - if (r && (r->value & REG06_GAIN4)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl841_test_buffer_empty_bit (SANE_Byte val) -{ - if (val & REG41_BUFEMPTY) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl841_test_motor_flag_bit (SANE_Byte val) -{ - if (val & REG41_MOTORENB) - return SANE_TRUE; - return SANE_FALSE; -} - -/** copy sensor specific settings */ -/* *dev : device infos - *regs : registers to be set - extended : do extended set up - half_ccd: set up for half ccd resolution - all registers 08-0B, 10-1D, 52-59 are set up. They shouldn't - appear anywhere else but in register_ini - -Responsible for signals to CCD/CIS: - CCD_CK1X (CK1INV(0x16),CKDIS(0x16),CKTOGGLE(0x18),CKDELAY(0x18),MANUAL1(0x1A),CK1MTGL(0x1C),CK1LOW(0x1D),CK1MAP(0x74,0x75,0x76),CK1NEG(0x7D)) - CCD_CK2X (CK2INV(0x16),CKDIS(0x16),CKTOGGLE(0x18),CKDELAY(0x18),MANUAL1(0x1A),CK1LOW(0x1D),CK1NEG(0x7D)) - CCD_CK3X (MANUAL3(0x1A),CK3INV(0x1A),CK3MTGL(0x1C),CK3LOW(0x1D),CK3MAP(0x77,0x78,0x79),CK3NEG(0x7D)) - CCD_CK4X (MANUAL3(0x1A),CK4INV(0x1A),CK4MTGL(0x1C),CK4LOW(0x1D),CK4MAP(0x7A,0x7B,0x7C),CK4NEG(0x7D)) - CCD_CPX (CTRLHI(0x16),CTRLINV(0x16),CTRLDIS(0x16),CPH(0x72),CPL(0x73),CPNEG(0x7D)) - CCD_RSX (CTRLHI(0x16),CTRLINV(0x16),CTRLDIS(0x16),RSH(0x70),RSL(0x71),RSNEG(0x7D)) - CCD_TGX (TGINV(0x16),TGMODE(0x17),TGW(0x17),EXPR(0x10,0x11),TGSHLD(0x1D)) - CCD_TGG (TGINV(0x16),TGMODE(0x17),TGW(0x17),EXPG(0x12,0x13),TGSHLD(0x1D)) - CCD_TGB (TGINV(0x16),TGMODE(0x17),TGW(0x17),EXPB(0x14,0x15),TGSHLD(0x1D)) - LAMP_SW (EXPR(0x10,0x11),XPA_SEL(0x03),LAMP_PWR(0x03),LAMPTIM(0x03),MTLLAMP(0x04),LAMPPWM(0x29)) - XPA_SW (EXPG(0x12,0x13),XPA_SEL(0x03),LAMP_PWR(0x03),LAMPTIM(0x03),MTLLAMP(0x04),LAMPPWM(0x29)) - LAMP_B (EXPB(0x14,0x15),LAMP_PWR(0x03)) - -other registers: - CISSET(0x01),CNSET(0x18),DCKSEL(0x18),SCANMOD(0x18),EXPDMY(0x19),LINECLP(0x1A),CKAREA(0x1C),TGTIME(0x1C),LINESEL(0x1E),DUMMY(0x34) - -Responsible for signals to AFE: - VSMP (VSMP(0x58),VSMPW(0x58)) - BSMP (BSMP(0x59),BSMPW(0x59)) - -other register settings depending on this: - RHI(0x52),RLOW(0x53),GHI(0x54),GLOW(0x55),BHI(0x56),BLOW(0x57), - -*/ -static void sanei_gl841_setup_sensor(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, - SANE_Bool extended, SANE_Bool half_ccd) -{ - DBG(DBG_proc, "%s\n", __func__); - - // that one is tricky at least - for (uint16_t addr = 0x08; addr <= 0x0b; ++addr) { - regs->set8(0x70 + addr - 0x08, sensor.custom_regs.get_value(addr)); - } - - // ignore registers in range [0x10..0x16) - for (uint16_t addr = 0x16; addr < 0x1e; ++addr) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - // ignore registers in range [0x5b..0x5e] - for (uint16_t addr = 0x52; addr < 0x52 + 9; ++addr) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - /* don't go any further if no extended setup */ - if (!extended) - return; - - /* todo : add more CCD types if needed */ - /* we might want to expand the Sensor struct to have these - 2 kind of settings */ - if (dev->model->ccd_type == CCD_5345) - { - if (half_ccd) - { - GenesysRegister* r; - /* settings for CCD used at half is max resolution */ - r = sanei_genesys_get_address (regs, 0x70); - r->value = 0x00; - r = sanei_genesys_get_address (regs, 0x71); - r->value = 0x05; - r = sanei_genesys_get_address (regs, 0x72); - r->value = 0x06; - r = sanei_genesys_get_address (regs, 0x73); - r->value = 0x08; - r = sanei_genesys_get_address (regs, 0x18); - r->value = 0x28; - r = sanei_genesys_get_address (regs, 0x58); - r->value = 0x80 | (r->value & 0x03); /* VSMP=16 */ - } - else - { - GenesysRegister* r; - /* swap latch times */ - r = sanei_genesys_get_address (regs, 0x18); - r->value = 0x30; - regs->set8(0x52, sensor.custom_regs.get_value(0x55)); - regs->set8(0x53, sensor.custom_regs.get_value(0x56)); - regs->set8(0x54, sensor.custom_regs.get_value(0x57)); - regs->set8(0x55, sensor.custom_regs.get_value(0x52)); - regs->set8(0x56, sensor.custom_regs.get_value(0x53)); - regs->set8(0x57, sensor.custom_regs.get_value(0x54)); - r = sanei_genesys_get_address (regs, 0x58); - r->value = 0x20 | (r->value & 0x03); /* VSMP=4 */ - } - return; - } - - if (dev->model->ccd_type == CCD_HP2300) - { - /* settings for CCD used at half is max resolution */ - GenesysRegister* r; - if (half_ccd) - { - r = sanei_genesys_get_address (regs, 0x70); - r->value = 0x16; - r = sanei_genesys_get_address (regs, 0x71); - r->value = 0x00; - r = sanei_genesys_get_address (regs, 0x72); - r->value = 0x01; - r = sanei_genesys_get_address (regs, 0x73); - r->value = 0x03; - /* manual clock programming */ - r = sanei_genesys_get_address (regs, 0x1d); - r->value |= 0x80; - } - else - { - r = sanei_genesys_get_address (regs, 0x70); - r->value = 1; - r = sanei_genesys_get_address (regs, 0x71); - r->value = 3; - r = sanei_genesys_get_address (regs, 0x72); - r->value = 4; - r = sanei_genesys_get_address (regs, 0x73); - r->value = 6; - } - r = sanei_genesys_get_address (regs, 0x58); - r->value = 0x80 | (r->value & 0x03); /* VSMP=16 */ - return; - } -} - -/** Test if the ASIC works - */ -/*TODO: make this functional*/ -static SANE_Status -sanei_gl841_asic_test (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - size_t size, verify_size; - unsigned int i; - - DBG(DBG_proc, "%s\n", __func__); - - return SANE_STATUS_INVAL; - - /* set and read exposure time, compare if it's the same */ - status = sanei_genesys_write_register (dev, 0x38, 0xde); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_write_register (dev, 0x39, 0xad); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_read_register (dev, 0x38, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read register: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (val != 0xde) /* value of register 0x38 */ - { - DBG(DBG_error, "%s: register contains invalid value\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - status = sanei_genesys_read_register (dev, 0x39, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read register: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (val != 0xad) /* value of register 0x39 */ - { - DBG(DBG_error, "%s: register contains invalid value\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - /* ram test: */ - size = 0x40000; - verify_size = size + 0x80; - /* todo: looks like the read size must be a multiple of 128? - otherwise the read doesn't succeed the second time after the scanner has - been plugged in. Very strange. */ - - std::vector<uint8_t> data(size); - std::vector<uint8_t> verify_data(verify_size); - - for (i = 0; i < (size - 1); i += 2) - { - data[i] = i / 512; - data[i + 1] = (i / 2) % 256; - } - - status = sanei_genesys_set_buffer_address (dev, 0x0000); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - -/* status = sanei_genesys_bulk_write_data(dev, 0x3c, data, size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write data: %s\n", __func__, sane_strstatus(status)); - free (data); - free (verify_data); - return status; - }*/ - - status = sanei_genesys_set_buffer_address (dev, 0x0000); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_bulk_read_data(dev, 0x45, verify_data.data(), verify_size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* todo: why i + 2 ? */ - for (i = 0; i < size; i++) - { - if (verify_data[i] != data[i]) - { - DBG(DBG_error, "%s: data verification error\n", __func__); - DBG(DBG_info, "0x%.8x: got %.2x %.2x %.2x %.2x, expected %.2x %.2x %.2x %.2x\n", - i, - verify_data[i], - verify_data[i+1], - verify_data[i+2], - verify_data[i+3], - data[i], - data[i+1], - data[i+2], - data[i+3]); - return SANE_STATUS_IO_ERROR; - } - } - - DBG(DBG_info, "%s: completed\n", __func__); - - return SANE_STATUS_GOOD; -} - -/* - * Set all registers LiDE 80 to default values - * (function called only once at the beginning) - * we are doing a special case to ease development - */ -static void -gl841_init_lide80 (Genesys_Device * dev) -{ - uint8_t val; - - INITREG (0x01, 0x82); /* 0x02 = SHDAREA and no CISSET ! */ - INITREG (0x02, 0x10); - INITREG (0x03, 0x50); - INITREG (0x04, 0x02); - INITREG (0x05, 0x4c); /* 1200 DPI */ - INITREG (0x06, 0x38); /* 0x38 scanmod=1, pwrbit, GAIN4 */ - INITREG (0x07, 0x00); - INITREG (0x08, 0x00); - INITREG (0x09, 0x11); - INITREG (0x0a, 0x00); - - INITREG (0x10, 0x40); - INITREG (0x11, 0x00); - INITREG (0x12, 0x40); - INITREG (0x13, 0x00); - INITREG (0x14, 0x40); - INITREG (0x15, 0x00); - INITREG (0x16, 0x00); - INITREG (0x17, 0x01); - INITREG (0x18, 0x00); - INITREG (0x19, 0x06); - INITREG (0x1a, 0x00); - INITREG (0x1b, 0x00); - INITREG (0x1c, 0x00); - INITREG (0x1d, 0x04); - INITREG (0x1e, 0x10); - INITREG (0x1f, 0x04); - INITREG (0x20, 0x02); - INITREG (0x21, 0x10); - INITREG (0x22, 0x20); - INITREG (0x23, 0x20); - INITREG (0x24, 0x10); - INITREG (0x25, 0x00); - INITREG (0x26, 0x00); - INITREG (0x27, 0x00); - - INITREG (0x29, 0xff); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - INITREG (0x2c, sensor.optical_res>>8); - INITREG (0x2d, sensor.optical_res & 0xff); - INITREG (0x2e, 0x80); - INITREG (0x2f, 0x80); - INITREG (0x30, 0x00); - INITREG (0x31, 0x10); - INITREG (0x32, 0x15); - INITREG (0x33, 0x0e); - INITREG (0x34, 0x40); - INITREG (0x35, 0x00); - INITREG (0x36, 0x2a); - INITREG (0x37, 0x30); - INITREG (0x38, 0x2a); - INITREG (0x39, 0xf8); - - INITREG (0x3d, 0x00); - INITREG (0x3e, 0x00); - INITREG (0x3f, 0x00); - - INITREG (0x52, 0x03); - INITREG (0x53, 0x07); - INITREG (0x54, 0x00); - INITREG (0x55, 0x00); - INITREG (0x56, 0x00); - INITREG (0x57, 0x00); - INITREG (0x58, 0x29); - INITREG (0x59, 0x69); - INITREG (0x5a, 0x55); - - INITREG (0x5d, 0x20); - INITREG (0x5e, 0x41); - INITREG (0x5f, 0x40); - INITREG (0x60, 0x00); - INITREG (0x61, 0x00); - INITREG (0x62, 0x00); - INITREG (0x63, 0x00); - INITREG (0x64, 0x00); - INITREG (0x65, 0x00); - INITREG (0x66, 0x00); - INITREG (0x67, 0x40); - INITREG (0x68, 0x40); - INITREG (0x69, 0x20); - INITREG (0x6a, 0x20); - INITREG (0x6c, dev->gpo.value[0]); - INITREG (0x6d, dev->gpo.value[1]); - INITREG (0x6e, dev->gpo.enable[0]); - INITREG (0x6f, dev->gpo.enable[1]); - INITREG (0x70, 0x00); - INITREG (0x71, 0x05); - INITREG (0x72, 0x07); - INITREG (0x73, 0x09); - INITREG (0x74, 0x00); - INITREG (0x75, 0x01); - INITREG (0x76, 0xff); - INITREG (0x77, 0x00); - INITREG (0x78, 0x0f); - INITREG (0x79, 0xf0); - INITREG (0x7a, 0xf0); - INITREG (0x7b, 0x00); - INITREG (0x7c, 0x1e); - INITREG (0x7d, 0x11); - INITREG (0x7e, 0x00); - INITREG (0x7f, 0x50); - INITREG (0x80, 0x00); - INITREG (0x81, 0x00); - INITREG (0x82, 0x0f); - INITREG (0x83, 0x00); - INITREG (0x84, 0x0e); - INITREG (0x85, 0x00); - INITREG (0x86, 0x0d); - INITREG (0x87, 0x02); - INITREG (0x88, 0x00); - INITREG (0x89, 0x00); - - /* specific scanner settings, clock and gpio first */ - sanei_genesys_read_register (dev, REG6B, &val); - sanei_genesys_write_register (dev, REG6B, 0x0c); - sanei_genesys_write_register (dev, 0x06, 0x10); - sanei_genesys_write_register (dev, REG6E, 0x6d); - sanei_genesys_write_register (dev, REG6F, 0x80); - sanei_genesys_write_register (dev, REG6B, 0x0e); - sanei_genesys_read_register (dev, REG6C, &val); - sanei_genesys_write_register (dev, REG6C, 0x00); - sanei_genesys_read_register (dev, REG6D, &val); - sanei_genesys_write_register (dev, REG6D, 0x8f); - sanei_genesys_read_register (dev, REG6B, &val); - sanei_genesys_write_register (dev, REG6B, 0x0e); - sanei_genesys_read_register (dev, REG6B, &val); - sanei_genesys_write_register (dev, REG6B, 0x0e); - sanei_genesys_read_register (dev, REG6B, &val); - sanei_genesys_write_register (dev, REG6B, 0x0a); - sanei_genesys_read_register (dev, REG6B, &val); - sanei_genesys_write_register (dev, REG6B, 0x02); - sanei_genesys_read_register (dev, REG6B, &val); - sanei_genesys_write_register (dev, REG6B, 0x06); - - sanei_genesys_write_0x8c (dev, 0x10, 0x94); - sanei_genesys_write_register (dev, 0x09, 0x10); - - /* set up GPIO : no address, so no bulk write, doesn't written directly either ? */ - /* - dev->reg.find_reg(0x6c).value = dev->gpo.value[0]; - dev->reg.find_reg(0x6d).value = dev->gpo.value[1]; - dev->reg.find_reg(0x6e).value = dev->gpo.enable[0]; - dev->reg.find_reg(0x6f).value = dev->gpo.enable[1]; */ - - // FIXME: the following code originally changed 0x6b, but due to bug the 0x6c register was - // effectively changed. The current behavior matches the old code, but should probably be fixed. - dev->reg.find_reg(0x6c).value |= REG6B_GPO18; - dev->reg.find_reg(0x6c).value &= ~REG6B_GPO17; - - sanei_gl841_setup_sensor(dev, sensor, &dev->reg, 0, 0); -} - -/* - * Set all registers to default values - * (function called only once at the beginning) - */ -static void -gl841_init_registers (Genesys_Device * dev) -{ - int addr; - - DBG(DBG_proc, "%s\n", __func__); - - dev->reg.clear(); - if (dev->model->model_id == MODEL_CANON_LIDE_80) - { - gl841_init_lide80(dev); - return ; - } - - for (addr = 1; addr <= 0x0a; addr++) { - dev->reg.init_reg(addr, 0); - } - for (addr = 0x10; addr <= 0x27; addr++) { - dev->reg.init_reg(addr, 0); - } - dev->reg.init_reg(0x29, 0); - for (addr = 0x2c; addr <= 0x39; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x3d; addr <= 0x3f; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x52; addr <= 0x5a; addr++) - dev->reg.init_reg(addr, 0); - for (addr = 0x5d; addr <= 0x87; addr++) - dev->reg.init_reg(addr, 0); - - - dev->reg.find_reg(0x01).value = 0x20; /* (enable shading), CCD, color, 1M */ - if (dev->model->is_cis == SANE_TRUE) { - dev->reg.find_reg(0x01).value |= REG01_CISSET; - } else { - dev->reg.find_reg(0x01).value &= ~REG01_CISSET; - } - - dev->reg.find_reg(0x02).value = 0x30 /*0x38 */ ; /* auto home, one-table-move, full step */ - dev->reg.find_reg(0x02).value |= REG02_AGOHOME; - sanei_genesys_set_motor_power(dev->reg, true); - dev->reg.find_reg(0x02).value |= REG02_FASTFED; - - dev->reg.find_reg(0x03).value = 0x1f /*0x17 */ ; /* lamp on */ - dev->reg.find_reg(0x03).value |= REG03_AVEENB; - - if (dev->model->ccd_type == CCD_PLUSTEK_3600) /* AD front end */ - { - dev->reg.find_reg(0x04).value = (2 << REG04S_AFEMOD) | 0x02; - } - else /* Wolfson front end */ - { - dev->reg.find_reg(0x04).value |= 1 << REG04S_AFEMOD; - } - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - dev->reg.find_reg(0x05).value = 0x00; /* disable gamma, 24 clocks/pixel */ - if (sensor.sensor_pixels < 0x1500) - dev->reg.find_reg(0x05).value |= REG05_DPIHW_600; - else if (sensor.sensor_pixels < 0x2a80) - dev->reg.find_reg(0x05).value |= REG05_DPIHW_1200; - else if (sensor.sensor_pixels < 0x5400) - dev->reg.find_reg(0x05).value |= REG05_DPIHW_2400; - else - { - dev->reg.find_reg(0x05).value |= REG05_DPIHW_2400; - DBG(DBG_warn, "%s: Cannot handle sensor pixel count %d\n", __func__, - sensor.sensor_pixels); - } - - - dev->reg.find_reg(0x06).value |= REG06_PWRBIT; - dev->reg.find_reg(0x06).value |= REG06_GAIN4; - - /* XP300 CCD needs different clock and clock/pixels values */ - if (dev->model->ccd_type != CCD_XP300 && dev->model->ccd_type != CCD_DP685 - && dev->model->ccd_type != CCD_PLUSTEK_3600) - { - dev->reg.find_reg(0x06).value |= 0 << REG06S_SCANMOD; - dev->reg.find_reg(0x09).value |= 1 << REG09S_CLKSET; - } - else - { - dev->reg.find_reg(0x06).value |= 0x05 << REG06S_SCANMOD; /* 15 clocks/pixel */ - dev->reg.find_reg(0x09).value = 0; /* 24 MHz CLKSET */ - } - - dev->reg.find_reg(0x1e).value = 0xf0; /* watch-dog time */ - - dev->reg.find_reg(0x17).value |= 1 << REG17S_TGW; - - dev->reg.find_reg(0x19).value = 0x50; - - dev->reg.find_reg(0x1d).value |= 1 << REG1DS_TGSHLD; - - dev->reg.find_reg(0x1e).value |= 1 << REG1ES_WDTIME; - -/*SCANFED*/ - dev->reg.find_reg(0x1f).value = 0x01; - -/*BUFSEL*/ - dev->reg.find_reg(0x20).value = 0x20; - -/*LAMPPWM*/ - dev->reg.find_reg(0x29).value = 0xff; - -/*BWHI*/ - dev->reg.find_reg(0x2e).value = 0x80; - -/*BWLOW*/ - dev->reg.find_reg(0x2f).value = 0x80; - -/*LPERIOD*/ - dev->reg.find_reg(0x38).value = 0x4f; - dev->reg.find_reg(0x39).value = 0xc1; - -/*VSMPW*/ - dev->reg.find_reg(0x58).value |= 3 << REG58S_VSMPW; - -/*BSMPW*/ - dev->reg.find_reg(0x59).value |= 3 << REG59S_BSMPW; - -/*RLCSEL*/ - dev->reg.find_reg(0x5a).value |= REG5A_RLCSEL; - -/*STOPTIM*/ - dev->reg.find_reg(0x5e).value |= 0x2 << REG5ES_STOPTIM; - - sanei_gl841_setup_sensor(dev, sensor, &dev->reg, 0, 0); - - /* set up GPIO */ - dev->reg.find_reg(0x6c).value = dev->gpo.value[0]; - dev->reg.find_reg(0x6d).value = dev->gpo.value[1]; - dev->reg.find_reg(0x6e).value = dev->gpo.enable[0]; - dev->reg.find_reg(0x6f).value = dev->gpo.enable[1]; - - /* TODO there is a switch calling to be written here */ - if (dev->model->gpo_type == GPO_CANONLIDE35) - { - dev->reg.find_reg(0x6b).value |= REG6B_GPO18; - dev->reg.find_reg(0x6b).value &= ~REG6B_GPO17; - } - - if (dev->model->gpo_type == GPO_XP300) - { - dev->reg.find_reg(0x6b).value |= REG6B_GPO17; - } - - if (dev->model->gpo_type == GPO_DP685) - { - /* REG6B_GPO18 lights on green led */ - dev->reg.find_reg(0x6b).value |= REG6B_GPO17|REG6B_GPO18; - } - - DBG(DBG_proc, "%s complete\n", __func__); -} - -/* Send slope table for motor movement - slope_table in machine byte order - */ -static SANE_Status -gl841_send_slope_table (Genesys_Device * dev, int table_nr, - uint16_t * slope_table, int steps) -{ - int dpihw; - int start_address; - SANE_Status status = SANE_STATUS_GOOD; - char msg[4000]; -/*#ifdef WORDS_BIGENDIAN*/ - int i; -/*#endif*/ - - DBG(DBG_proc, "%s (table_nr = %d, steps = %d)\n", __func__, table_nr, steps); - - dpihw = dev->reg.find_reg(0x05).value >> 6; - - if (dpihw == 0) /* 600 dpi */ - start_address = 0x08000; - else if (dpihw == 1) /* 1200 dpi */ - start_address = 0x10000; - else if (dpihw == 2) /* 2400 dpi */ - start_address = 0x20000; - else /* reserved */ - return SANE_STATUS_INVAL; - - std::vector<uint8_t> table(steps * 2); - for(i = 0; i < steps; i++) { - table[i * 2] = slope_table[i] & 0xff; - table[i * 2 + 1] = slope_table[i] >> 8; - } - - if (DBG_LEVEL >= DBG_io) - { - sprintf (msg, "write slope %d (%d)=", table_nr, steps); - for (i = 0; i < steps; i++) - { - sprintf (msg+strlen(msg), ",%d", slope_table[i]); - } - DBG(DBG_io, "%s: %s\n", __func__, msg); - } - - status = - sanei_genesys_set_buffer_address (dev, start_address + table_nr * 0x200); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_bulk_write_data(dev, 0x3c, table.data(), steps * 2); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send slope table: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: completed\n", __func__); - return status; -} - -static SANE_Status -gl841_set_lide80_fe (Genesys_Device * dev, uint8_t set) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - - dev->frontend = dev->frontend_initial; - - /* write them to analog frontend */ - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x00 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x03, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x03 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x06, dev->frontend.regs.get_value(0x02)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x06 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - if (set == AFE_SET) - { - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x00 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x06, dev->frontend.regs.get_value(0x20)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing offset failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x03, dev->frontend.regs.get_value(0x28)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing gain failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - return status; - DBGCOMPLETED; -} - -/* Set values of Analog Device type frontend */ -static SANE_Status -gl841_set_ad_fe (Genesys_Device * dev, uint8_t set) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - - /* special case for LiDE 80 analog frontend */ - if(dev->model->dac_type==DAC_CANONLIDE80) - { - return gl841_set_lide80_fe(dev, set); - } - - DBG(DBG_proc, "%s(): start\n", __func__); - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - - dev->frontend = dev->frontend_initial; - - /* write them to analog frontend */ - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x00 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x01 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - for (i = 0; i < 6; i++) - { - status = - sanei_genesys_fe_write_data (dev, 0x02 + i, 0x00); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing sign[%d] failed: %s\n", __func__, 0x02 + i, - sane_strstatus(status)); - return status; - } - } - } - if (set == AFE_SET) - { - /* write them to analog frontend */ - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x00 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg 0x01 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* Write fe 0x02 (red gain)*/ - status = sanei_genesys_fe_write_data(dev, 0x02, dev->frontend.get_gain(0)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing fe 0x02 (gain r) fail: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* Write fe 0x03 (green gain)*/ - status = sanei_genesys_fe_write_data(dev, 0x03, dev->frontend.get_gain(1)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing fe 0x03 (gain g) fail: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* Write fe 0x04 (blue gain)*/ - status = sanei_genesys_fe_write_data(dev, 0x04, dev->frontend.get_gain(2)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing fe 0x04 (gain b) fail: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* Write fe 0x05 (red offset)*/ - status = - sanei_genesys_fe_write_data(dev, 0x05, dev->frontend.get_offset(0)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: write fe 0x05 (offset r) fail: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* Write fe 0x06 (green offset)*/ - status = - sanei_genesys_fe_write_data(dev, 0x06, dev->frontend.get_offset(1)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: write fe 0x06 (offset g) fail: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* Write fe 0x07 (blue offset)*/ - status = - sanei_genesys_fe_write_data(dev, 0x07, dev->frontend.get_offset(2)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: write fe 0x07 (offset b) fail: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - DBG(DBG_proc, "%s(): end\n", __func__); - - return status; -} - -/* Set values of analog frontend */ -static SANE_Status -gl841_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - int i; - - DBG(DBG_proc, "%s (%s)\n", __func__, - set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set == - AFE_POWER_SAVE ? "powersave" : "huh?"); - - /* Analog Device type frontend */ - if ((dev->reg.find_reg(0x04).value & REG04_FESET) == 0x02) - { - return gl841_set_ad_fe (dev, set); - } - - if ((dev->reg.find_reg(0x04).value & REG04_FESET) != 0x00) - { - DBG(DBG_proc, "%s(): unsupported frontend type %d\n", __func__, - dev->reg.find_reg(0x04).value & REG04_FESET); - return SANE_STATUS_UNSUPPORTED; - } - - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - dev->frontend = dev->frontend_initial; - - /* reset only done on init */ - status = sanei_genesys_fe_write_data (dev, 0x04, 0x80); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: reset fe failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - DBG(DBG_proc, "%s(): frontend reset complete\n", __func__); - } - - - if (set == AFE_POWER_SAVE) - { - status = sanei_genesys_fe_write_data (dev, 0x01, 0x02); - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: writing data failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - return status; - } - - /* todo : base this test on cfg reg3 or a CCD family flag to be created */ - /*if (dev->model->ccd_type!=CCD_HP2300 && dev->model->ccd_type!=CCD_HP2400) */ - { - - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg0 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x02, dev->frontend.regs.get_value(0x02)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg2 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg1 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_fe_write_data(dev, 0x03, dev->frontend.regs.get_value(0x03)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg3 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_fe_write_data (dev, 0x06, dev->frontend.reg2[0]); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg6 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_fe_write_data (dev, 0x08, dev->frontend.reg2[1]); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg8 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_fe_write_data (dev, 0x09, dev->frontend.reg2[2]); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg9 failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - for (i = 0; i < 3; i++) - { - status = - sanei_genesys_fe_write_data(dev, 0x24 + i, dev->frontend.regs.get_value(0x24 + i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing sign[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x28 + i, dev->frontend.get_gain(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing gain[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - - status = - sanei_genesys_fe_write_data(dev, 0x20 + i, - dev->frontend.get_offset(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing offset[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - - - DBG(DBG_proc, "%s: completed\n", __func__); - - return SANE_STATUS_GOOD; -} - -#define MOTOR_ACTION_FEED 1 -#define MOTOR_ACTION_GO_HOME 2 -#define MOTOR_ACTION_HOME_FREE 3 - -/** @brief turn off motor - * - */ -static SANE_Status -gl841_init_motor_regs_off(Genesys_Register_Set * reg, - unsigned int scan_lines) -{ - unsigned int feedl; - GenesysRegister* r; - - DBG(DBG_proc, "%s : scan_lines=%d\n", __func__, scan_lines); - - feedl = 2; - - r = sanei_genesys_get_address (reg, 0x3d); - r->value = (feedl >> 16) & 0xf; - r = sanei_genesys_get_address (reg, 0x3e); - r->value = (feedl >> 8) & 0xff; - r = sanei_genesys_get_address (reg, 0x3f); - r->value = feedl & 0xff; - r = sanei_genesys_get_address (reg, 0x5e); - r->value &= ~0xe0; - - r = sanei_genesys_get_address (reg, 0x25); - r->value = (scan_lines >> 16) & 0xf; - r = sanei_genesys_get_address (reg, 0x26); - r->value = (scan_lines >> 8) & 0xff; - r = sanei_genesys_get_address (reg, 0x27); - r->value = scan_lines & 0xff; - - r = sanei_genesys_get_address (reg, 0x02); - r->value &= ~0x01; /*LONGCURV OFF*/ - r->value &= ~0x80; /*NOT_HOME OFF*/ - - r->value &= ~0x10; - - r->value &= ~0x06; - - r->value &= ~0x08; - - r->value &= ~0x20; - - r->value &= ~0x40; - - r = sanei_genesys_get_address (reg, 0x67); - r->value = 0x3f; - - r = sanei_genesys_get_address (reg, 0x68); - r->value = 0x3f; - - r = sanei_genesys_get_address (reg, REG_STEPNO); - r->value = 0; - - r = sanei_genesys_get_address (reg, REG_FASTNO); - r->value = 0; - - r = sanei_genesys_get_address (reg, 0x69); - r->value = 0; - - r = sanei_genesys_get_address (reg, 0x6a); - r->value = 0; - - r = sanei_genesys_get_address (reg, 0x5f); - r->value = 0; - - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief write motor table frequency - * Write motor frequency data table. - * @param dev device to set up motor - * @param ydpi motor target resolution - * @return SANE_STATUS_GOOD on success - */ -static SANE_Status gl841_write_freq(Genesys_Device *dev, unsigned int ydpi) -{ -SANE_Status status = SANE_STATUS_GOOD; -/**< fast table */ -uint8_t tdefault[] = {0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0x36,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xb6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0xf6,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76,0x18,0x76}; -uint8_t t1200[] = {0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc7,0x31,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc0,0x11,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0xc7,0xb1,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0x07,0xe0,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc7,0xf1,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc0,0x51,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0xc7,0x71,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20,0x07,0x20}; -uint8_t t300[] = {0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x08,0x32,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x00,0x13,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x08,0xb2,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x0c,0xa0,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x08,0xf2,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x00,0xd3,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x08,0x72,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60,0x0c,0x60}; -uint8_t t150[] = {0x0c,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0xcf,0x33,0x40,0x14,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x80,0x15,0x0c,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0xcf,0xb3,0x11,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x16,0xa0,0x0c,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0xcf,0xf3,0x40,0xd4,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x80,0xd5,0x0c,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0xcf,0x73,0x11,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60,0x16,0x60}; - -uint8_t *table; - - DBGSTART; - if(dev->model->motor_type == MOTOR_CANONLIDE80) - { - switch(ydpi) - { - case 3600: - case 1200: - table=t1200; - break; - case 900: - case 300: - table=t300; - break; - case 450: - case 150: - table=t150; - break; - default: - table=tdefault; - } - RIE(sanei_genesys_write_register(dev, 0x66, 0x00)); - RIE(sanei_genesys_write_register(dev, 0x5b, 0x0c)); - RIE(sanei_genesys_write_register(dev, 0x5c, 0x00)); - RIE(sanei_genesys_bulk_write_data(dev, 0x28, table, 128)); - RIE(sanei_genesys_write_register(dev, 0x5b, 0x00)); - RIE(sanei_genesys_write_register(dev, 0x5c, 0x00)); - } - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -static SANE_Status -gl841_init_motor_regs(Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int feed_steps,/*1/base_ydpi*/ -/*maybe float for half/quarter step resolution?*/ - unsigned int action, - unsigned int flags) -{ - SANE_Status status = SANE_STATUS_GOOD; - unsigned int fast_exposure; - int scan_power_mode; - int use_fast_fed = 0; - uint16_t fast_slope_table[256]; - unsigned int fast_slope_steps = 0; - unsigned int feedl; - GenesysRegister* r; -/*number of scan lines to add in a scan_lines line*/ - - DBG(DBG_proc, "%s : feed_steps=%d, action=%d, flags=%x\n", __func__, feed_steps, action, flags); - - memset(fast_slope_table,0xff,512); - - gl841_send_slope_table (dev, 0, fast_slope_table, 256); - gl841_send_slope_table (dev, 1, fast_slope_table, 256); - gl841_send_slope_table (dev, 2, fast_slope_table, 256); - gl841_send_slope_table (dev, 3, fast_slope_table, 256); - gl841_send_slope_table (dev, 4, fast_slope_table, 256); - - gl841_write_freq(dev, dev->motor.base_ydpi / 4); - - fast_slope_steps = 256; - if (action == MOTOR_ACTION_FEED || action == MOTOR_ACTION_GO_HOME) - { - /* FEED and GO_HOME can use fastest slopes available */ - fast_exposure = gl841_exposure_time(dev, sensor, - dev->motor.base_ydpi / 4, - 0, - 0, - 0, - &scan_power_mode); - DBG(DBG_info, "%s : fast_exposure=%d pixels\n", __func__, fast_exposure); - } - - if (action == MOTOR_ACTION_HOME_FREE) { -/* HOME_FREE must be able to stop in one step, so do not try to get faster */ - fast_exposure = dev->motor.slopes[0][0].maximum_start_speed; - } - - sanei_genesys_create_slope_table3 ( - dev, - fast_slope_table, - 256, - fast_slope_steps, - 0, - fast_exposure, - dev->motor.base_ydpi / 4, - &fast_slope_steps, - &fast_exposure, 0); - - feedl = feed_steps - fast_slope_steps*2; - use_fast_fed = 1; - -/* all needed slopes available. we did even decide which mode to use. - what next? - - transfer slopes -SCAN: -flags \ use_fast_fed ! 0 1 -------------------------\-------------------- - 0 ! 0,1,2 0,1,2,3 -MOTOR_FLAG_AUTO_GO_HOME ! 0,1,2,4 0,1,2,3,4 -OFF: none -FEED: 3 -GO_HOME: 3 -HOME_FREE: 3 - - setup registers - * slope specific registers (already done) - * DECSEL for HOME_FREE/GO_HOME/SCAN - * FEEDL - * MTRREV - * MTRPWR - * FASTFED - * STEPSEL - * MTRPWM - * FSTPSEL - * FASTPWM - * HOMENEG - * BWDSTEP - * FWDSTEP - * Z1 - * Z2 - */ - - r = sanei_genesys_get_address(reg, 0x3d); - r->value = (feedl >> 16) & 0xf; - r = sanei_genesys_get_address(reg, 0x3e); - r->value = (feedl >> 8) & 0xff; - r = sanei_genesys_get_address(reg, 0x3f); - r->value = feedl & 0xff; - r = sanei_genesys_get_address(reg, 0x5e); - r->value &= ~0xe0; - - r = sanei_genesys_get_address(reg, 0x25); - r->value = 0; - r = sanei_genesys_get_address(reg, 0x26); - r->value = 0; - r = sanei_genesys_get_address(reg, 0x27); - r->value = 0; - - r = sanei_genesys_get_address(reg, 0x02); - r->value &= ~0x01; /*LONGCURV OFF*/ - r->value &= ~0x80; /*NOT_HOME OFF*/ - - r->value |= 0x10; - - if (action == MOTOR_ACTION_GO_HOME) - r->value |= 0x06; - else - r->value &= ~0x06; - - if (use_fast_fed) - r->value |= 0x08; - else - r->value &= ~0x08; - - if (flags & MOTOR_FLAG_AUTO_GO_HOME) - r->value |= 0x20; - else - r->value &= ~0x20; - - r->value &= ~0x40; - - status = gl841_send_slope_table (dev, 3, fast_slope_table, 256); - - if (status != SANE_STATUS_GOOD) - return status; - - r = sanei_genesys_get_address(reg, 0x67); - r->value = 0x3f; - - r = sanei_genesys_get_address(reg, 0x68); - r->value = 0x3f; - - r = sanei_genesys_get_address(reg, REG_STEPNO); - r->value = 0; - - r = sanei_genesys_get_address(reg, REG_FASTNO); - r->value = 0; - - r = sanei_genesys_get_address(reg, 0x69); - r->value = 0; - - r = sanei_genesys_get_address(reg, 0x6a); - r->value = (fast_slope_steps >> 1) + (fast_slope_steps & 1); - - r = sanei_genesys_get_address(reg, 0x5f); - r->value = (fast_slope_steps >> 1) + (fast_slope_steps & 1); - - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl841_init_motor_regs_scan(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int scan_exposure_time,/*pixel*/ - float scan_yres,/*dpi, motor resolution*/ - int scan_step_type,/*0: full, 1: half, 2: quarter*/ - unsigned int scan_lines,/*lines, scan resolution*/ - unsigned int scan_dummy, -/*number of scan lines to add in a scan_lines line*/ - unsigned int feed_steps,/*1/base_ydpi*/ -/*maybe float for half/quarter step resolution?*/ - int scan_power_mode, - unsigned int flags) -{ - SANE_Status status = SANE_STATUS_GOOD; - unsigned int fast_exposure; - int use_fast_fed = 0; - int dummy_power_mode; - unsigned int fast_time; - unsigned int slow_time; - uint16_t slow_slope_table[256]; - uint16_t fast_slope_table[256]; - uint16_t back_slope_table[256]; - unsigned int slow_slope_time; - unsigned int fast_slope_time; - unsigned int slow_slope_steps = 0; - unsigned int fast_slope_steps = 0; - unsigned int back_slope_steps = 0; - unsigned int feedl; - GenesysRegister* r; - unsigned int min_restep = 0x20; - uint32_t z1, z2; - - DBG(DBG_proc, "%s : scan_exposure_time=%d, scan_yres=%g, scan_step_type=%d, scan_lines=%d," - " scan_dummy=%d, feed_steps=%d, scan_power_mode=%d, flags=%x\n", __func__, - scan_exposure_time, - scan_yres, - scan_step_type, - scan_lines, - scan_dummy, - feed_steps, - scan_power_mode, - flags); - - fast_exposure = gl841_exposure_time(dev, sensor, - dev->motor.base_ydpi / 4, - 0, - 0, - 0, - &dummy_power_mode); - - DBG(DBG_info, "%s : fast_exposure=%d pixels\n", __func__, fast_exposure); - - memset(slow_slope_table,0xff,512); - - gl841_send_slope_table (dev, 0, slow_slope_table, 256); - gl841_send_slope_table (dev, 1, slow_slope_table, 256); - gl841_send_slope_table (dev, 2, slow_slope_table, 256); - gl841_send_slope_table (dev, 3, slow_slope_table, 256); - gl841_send_slope_table (dev, 4, slow_slope_table, 256); - - /* motor frequency table */ - gl841_write_freq(dev, scan_yres); - -/* - we calculate both tables for SCAN. the fast slope step count depends on - how many steps we need for slow acceleration and how much steps we are - allowed to use. - */ - slow_slope_time = sanei_genesys_create_slope_table3 ( - dev, - slow_slope_table, 256, - 256, - scan_step_type, - scan_exposure_time, - scan_yres, - &slow_slope_steps, - NULL, - scan_power_mode); - - sanei_genesys_create_slope_table3 ( - dev, - back_slope_table, 256, - 256, - scan_step_type, - 0, - scan_yres, - &back_slope_steps, - NULL, - scan_power_mode); - - if (feed_steps < (slow_slope_steps >> scan_step_type)) { - /*TODO: what should we do here?? go back to exposure calculation?*/ - feed_steps = slow_slope_steps >> scan_step_type; - } - - if (feed_steps > fast_slope_steps*2 - - (slow_slope_steps >> scan_step_type)) - fast_slope_steps = 256; - else -/* we need to shorten fast_slope_steps here. */ - fast_slope_steps = (feed_steps - - (slow_slope_steps >> scan_step_type))/2; - - DBG(DBG_info, "%s: Maximum allowed slope steps for fast slope: %d\n", __func__, - fast_slope_steps); - - fast_slope_time = sanei_genesys_create_slope_table3 ( - dev, - fast_slope_table, 256, - fast_slope_steps, - 0, - fast_exposure, - dev->motor.base_ydpi / 4, - &fast_slope_steps, - &fast_exposure, - scan_power_mode); - - /* fast fed special cases handling */ - if (dev->model->gpo_type == GPO_XP300 - || dev->model->gpo_type == GPO_DP685) - { - /* quirk: looks like at least this scanner is unable to use - 2-feed mode */ - use_fast_fed = 0; - } - else if (feed_steps < fast_slope_steps*2 + (slow_slope_steps >> scan_step_type)) { - use_fast_fed = 0; - DBG(DBG_info, "%s: feed too short, slow move forced.\n", __func__); - } else { -/* for deciding whether we should use fast mode we need to check how long we - need for (fast)accelerating, moving, decelerating, (TODO: stopping?) - (slow)accelerating again versus (slow)accelerating and moving. we need - fast and slow tables here. -*/ -/*NOTE: scan_exposure_time is per scan_yres*/ -/*NOTE: fast_exposure is per base_ydpi/4*/ -/*we use full steps as base unit here*/ - fast_time = - fast_exposure / 4 * - (feed_steps - fast_slope_steps*2 - - (slow_slope_steps >> scan_step_type)) - + fast_slope_time*2 + slow_slope_time; - slow_time = - (scan_exposure_time * scan_yres) / dev->motor.base_ydpi * - (feed_steps - (slow_slope_steps >> scan_step_type)) - + slow_slope_time; - - DBG(DBG_info, "%s: Time for slow move: %d\n", __func__, slow_time); - DBG(DBG_info, "%s: Time for fast move: %d\n", __func__, fast_time); - - use_fast_fed = fast_time < slow_time; - } - - if (use_fast_fed) - feedl = feed_steps - fast_slope_steps*2 - - (slow_slope_steps >> scan_step_type); - else - if ((feed_steps << scan_step_type) < slow_slope_steps) - feedl = 0; - else - feedl = (feed_steps << scan_step_type) - slow_slope_steps; - DBG(DBG_info, "%s: Decided to use %s mode\n", __func__, use_fast_fed?"fast feed":"slow feed"); - -/* all needed slopes available. we did even decide which mode to use. - what next? - - transfer slopes -SCAN: -flags \ use_fast_fed ! 0 1 -------------------------\-------------------- - 0 ! 0,1,2 0,1,2,3 -MOTOR_FLAG_AUTO_GO_HOME ! 0,1,2,4 0,1,2,3,4 -OFF: none -FEED: 3 -GO_HOME: 3 -HOME_FREE: 3 - - setup registers - * slope specific registers (already done) - * DECSEL for HOME_FREE/GO_HOME/SCAN - * FEEDL - * MTRREV - * MTRPWR - * FASTFED - * STEPSEL - * MTRPWM - * FSTPSEL - * FASTPWM - * HOMENEG - * BWDSTEP - * FWDSTEP - * Z1 - * Z2 - */ - - r = sanei_genesys_get_address (reg, 0x3d); - r->value = (feedl >> 16) & 0xf; - r = sanei_genesys_get_address (reg, 0x3e); - r->value = (feedl >> 8) & 0xff; - r = sanei_genesys_get_address (reg, 0x3f); - r->value = feedl & 0xff; - r = sanei_genesys_get_address (reg, 0x5e); - r->value &= ~0xe0; - - r = sanei_genesys_get_address (reg, 0x25); - r->value = (scan_lines >> 16) & 0xf; - r = sanei_genesys_get_address (reg, 0x26); - r->value = (scan_lines >> 8) & 0xff; - r = sanei_genesys_get_address (reg, 0x27); - r->value = scan_lines & 0xff; - - r = sanei_genesys_get_address (reg, 0x02); - r->value &= ~0x01; /*LONGCURV OFF*/ - r->value &= ~0x80; /*NOT_HOME OFF*/ - r->value |= 0x10; - - r->value &= ~0x06; - - if (use_fast_fed) - r->value |= 0x08; - else - r->value &= ~0x08; - - if (flags & MOTOR_FLAG_AUTO_GO_HOME) - r->value |= 0x20; - else - r->value &= ~0x20; - - if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE) - r->value |= 0x40; - else - r->value &= ~0x40; - - status = gl841_send_slope_table (dev, 0, slow_slope_table, 256); - - if (status != SANE_STATUS_GOOD) - return status; - - status = gl841_send_slope_table (dev, 1, back_slope_table, 256); - - if (status != SANE_STATUS_GOOD) - return status; - - status = gl841_send_slope_table (dev, 2, slow_slope_table, 256); - - if (status != SANE_STATUS_GOOD) - return status; - - if (use_fast_fed) { - status = gl841_send_slope_table (dev, 3, fast_slope_table, 256); - - if (status != SANE_STATUS_GOOD) - return status; - } - - if (flags & MOTOR_FLAG_AUTO_GO_HOME){ - status = gl841_send_slope_table (dev, 4, fast_slope_table, 256); - - if (status != SANE_STATUS_GOOD) - return status; - } - - -/* now reg 0x21 and 0x24 are available, we can calculate reg 0x22 and 0x23, - reg 0x60-0x62 and reg 0x63-0x65 - rule: - 2*STEPNO+FWDSTEP=2*FASTNO+BWDSTEP -*/ -/* steps of table 0*/ - if (min_restep < slow_slope_steps*2+2) - min_restep = slow_slope_steps*2+2; -/* steps of table 1*/ - if (min_restep < back_slope_steps*2+2) - min_restep = back_slope_steps*2+2; -/* steps of table 0*/ - r = sanei_genesys_get_address (reg, REG_FWDSTEP); - r->value = min_restep - slow_slope_steps*2; -/* steps of table 1*/ - r = sanei_genesys_get_address (reg, REG_BWDSTEP); - r->value = min_restep - back_slope_steps*2; - -/* - for z1/z2: - in dokumentation mentioned variables a-d: - a = time needed for acceleration, table 1 - b = time needed for reg 0x1f... wouldn't that be reg0x1f*exposure_time? - c = time needed for acceleration, table 1 - d = time needed for reg 0x22... wouldn't that be reg0x22*exposure_time? - z1 = (c+d-1) % exposure_time - z2 = (a+b-1) % exposure_time -*/ -/* i don't see any effect of this. i can only guess that this will enhance - sub-pixel accuracy - z1 = (slope_0_time-1) % exposure_time; - z2 = (slope_0_time-1) % exposure_time; -*/ - z1 = z2 = 0; - - DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); - DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); - r = sanei_genesys_get_address (reg, 0x60); - r->value = ((z1 >> 16) & 0xff); - r = sanei_genesys_get_address (reg, 0x61); - r->value = ((z1 >> 8) & 0xff); - r = sanei_genesys_get_address (reg, 0x62); - r->value = (z1 & 0xff); - r = sanei_genesys_get_address (reg, 0x63); - r->value = ((z2 >> 16) & 0xff); - r = sanei_genesys_get_address (reg, 0x64); - r->value = ((z2 >> 8) & 0xff); - r = sanei_genesys_get_address (reg, 0x65); - r->value = (z2 & 0xff); - - r = sanei_genesys_get_address (reg, REG1E); - r->value &= REG1E_WDTIME; - r->value |= scan_dummy; - - r = sanei_genesys_get_address (reg, 0x67); - r->value = 0x3f | (scan_step_type << 6); - - r = sanei_genesys_get_address (reg, 0x68); - r->value = 0x3f; - - r = sanei_genesys_get_address (reg, REG_STEPNO); - r->value = (slow_slope_steps >> 1) + (slow_slope_steps & 1); - - r = sanei_genesys_get_address (reg, REG_FASTNO); - r->value = (back_slope_steps >> 1) + (back_slope_steps & 1); - - r = sanei_genesys_get_address (reg, 0x69); - r->value = (slow_slope_steps >> 1) + (slow_slope_steps & 1); - - r = sanei_genesys_get_address (reg, 0x6a); - r->value = (fast_slope_steps >> 1) + (fast_slope_steps & 1); - - r = sanei_genesys_get_address (reg, 0x5f); - r->value = (fast_slope_steps >> 1) + (fast_slope_steps & 1); - - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static int -gl841_get_dpihw(Genesys_Device * dev) -{ - GenesysRegister* r; - r = sanei_genesys_get_address(&dev->reg, 0x05); - if ((r->value & REG05_DPIHW) == REG05_DPIHW_600) - return 600; - if ((r->value & REG05_DPIHW) == REG05_DPIHW_1200) - return 1200; - if ((r->value & REG05_DPIHW) == REG05_DPIHW_2400) - return 2400; - return 0; -} - -static SANE_Status -gl841_init_optical_regs_off(Genesys_Register_Set * reg) -{ - GenesysRegister* r; - - DBGSTART; - - r = sanei_genesys_get_address(reg, 0x01); - r->value &= ~REG01_SCAN; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl841_init_optical_regs_scan(Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int exposure_time, - unsigned int used_res, - unsigned int start, - unsigned int pixels, - int channels, - int depth, - SANE_Bool half_ccd, - ColorFilter color_filter, - int flags - ) -{ - unsigned int words_per_line; - unsigned int end; - unsigned int dpiset; - GenesysRegister* r; - SANE_Status status = SANE_STATUS_GOOD; - uint16_t expavg, expr, expb, expg; - - DBG(DBG_proc, "%s : exposure_time=%d, used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, " - "half_ccd=%d, flags=%x\n", __func__, - exposure_time, - used_res, - start, - pixels, - channels, - depth, - half_ccd, - flags); - - end = start + pixels; - - status = gl841_set_fe(dev, sensor, AFE_SET); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* adjust used_res for chosen dpihw */ - used_res = used_res * gl841_get_dpihw(dev) / sensor.optical_res; - -/* - with half_ccd the optical resolution of the ccd is halved. We don't apply this - to dpihw, so we need to double dpiset. - - For the scanner only the ratio of dpiset and dpihw is of relevance to scale - down properly. -*/ - if (half_ccd) - dpiset = used_res * 2; - else - dpiset = used_res; - - /* gpio part.*/ - if (dev->model->gpo_type == GPO_CANONLIDE35) - { - r = sanei_genesys_get_address (reg, REG6C); - if (half_ccd) - r->value &= ~0x80; - else - r->value |= 0x80; - } - if (dev->model->gpo_type == GPO_CANONLIDE80) - { - r = sanei_genesys_get_address (reg, REG6C); - if (half_ccd) - { - r->value &= ~0x40; - r->value |= 0x20; - } - else - { - r->value &= ~0x20; - r->value |= 0x40; - } - } - - /* enable shading */ - r = sanei_genesys_get_address (reg, 0x01); - r->value |= REG01_SCAN; - if ((flags & OPTICAL_FLAG_DISABLE_SHADING) || - (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) - r->value &= ~REG01_DVDSET; - else - r->value |= REG01_DVDSET; - - /* average looks better than deletion, and we are already set up to - use one of the average enabled resolutions - */ - r = sanei_genesys_get_address (reg, 0x03); - r->value |= REG03_AVEENB; - sanei_genesys_set_lamp_power(dev, sensor, *reg, !(flags & OPTICAL_FLAG_DISABLE_LAMP)); - - /* BW threshold */ - r = sanei_genesys_get_address (reg, 0x2e); - r->value = dev->settings.threshold; - r = sanei_genesys_get_address (reg, 0x2f); - r->value = dev->settings.threshold; - - - /* monochrome / color scan */ - r = sanei_genesys_get_address (reg, 0x04); - switch (depth) { - case 1: - r->value &= ~REG04_BITSET; - r->value |= REG04_LINEART; - break; - case 8: - r->value &= ~(REG04_LINEART | REG04_BITSET); - break; - case 16: - r->value &= ~REG04_LINEART; - r->value |= REG04_BITSET; - break; - } - - /* AFEMOD should depend on FESET, and we should set these - * bits separately */ - r->value &= ~(REG04_FILTER | REG04_AFEMOD); - if (flags & OPTICAL_FLAG_ENABLE_LEDADD) - { - r->value |= 0x10; /* no filter */ - } - else if (channels == 1) - { - switch (color_filter) - { - case ColorFilter::RED: - r->value |= 0x14; - break; - case ColorFilter::GREEN: - r->value |= 0x18; - break; - case ColorFilter::BLUE: - r->value |= 0x1c; - break; - default: - r->value |= 0x10; - break; - } - } - else - { - if (dev->model->ccd_type == CCD_PLUSTEK_3600) - { - r->value |= 0x22; /* slow color pixel by pixel */ - } - else - { - r->value |= 0x10; /* color pixel by pixel */ - } - } - - /* CIS scanners can do true gray by setting LEDADD */ - r = sanei_genesys_get_address (reg, 0x87); - r->value &= ~REG87_LEDADD; - if (flags & OPTICAL_FLAG_ENABLE_LEDADD) - { - r->value |= REG87_LEDADD; - sanei_genesys_get_double (reg, REG_EXPR, &expr); - sanei_genesys_get_double (reg, REG_EXPG, &expg); - sanei_genesys_get_double (reg, REG_EXPB, &expb); - - /* use minimal exposure for best image quality */ - expavg = expg; - if (expr < expg) - expavg = expr; - if (expb < expavg) - expavg = expb; - - sanei_genesys_set_double(&dev->reg, REG_EXPR, expavg); - sanei_genesys_set_double(&dev->reg, REG_EXPG, expavg); - sanei_genesys_set_double(&dev->reg, REG_EXPB, expavg); - } - - /* enable gamma tables */ - r = sanei_genesys_get_address (reg, 0x05); - if (flags & OPTICAL_FLAG_DISABLE_GAMMA) - r->value &= ~REG05_GMMENB; - else - r->value |= REG05_GMMENB; - - /* sensor parameters */ - sanei_gl841_setup_sensor(dev, sensor, &dev->reg, 1, half_ccd); - - r = sanei_genesys_get_address (reg, 0x29); - r->value = 255; /*<<<"magic" number, only suitable for cis*/ - - sanei_genesys_set_double(reg, REG_DPISET, dpiset); - sanei_genesys_set_double(reg, REG_STRPIXEL, start); - sanei_genesys_set_double(reg, REG_ENDPIXEL, end); - DBG(DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d\n", __func__, start, end); - - /* words(16bit) before gamma, conversion to 8 bit or lineart*/ - words_per_line = (pixels * dpiset) / gl841_get_dpihw(dev); - - words_per_line *= channels; - - if (depth == 1) - words_per_line = (words_per_line >> 3) + ((words_per_line & 7)?1:0); - else - words_per_line *= depth / 8; - - dev->wpl = words_per_line; - dev->bpl = words_per_line; - - r = sanei_genesys_get_address (reg, 0x35); - r->value = LOBYTE (HIWORD (words_per_line)); - r = sanei_genesys_get_address (reg, 0x36); - r->value = HIBYTE (LOWORD (words_per_line)); - r = sanei_genesys_get_address (reg, 0x37); - r->value = LOBYTE (LOWORD (words_per_line)); - - sanei_genesys_set_double(reg, REG_LPERIOD, exposure_time); - - r = sanei_genesys_get_address (reg, 0x34); - r->value = sensor.dummy_pixel; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static int -gl841_get_led_exposure(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int d,r,g,b,m; - if (!dev->model->is_cis) - return 0; - d = dev->reg.find_reg(0x19).value; - - r = sensor.exposure.red; - g = sensor.exposure.green; - b = sensor.exposure.blue; - - m = r; - if (m < g) - m = g; - if (m < b) - m = b; - - return m + d; -} - -/** @brief compute exposure time - * Compute exposure time for the device and the given scan resolution, - * also compute scan_power_mode - */ -static int -gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor, - float slope_dpi, - int scan_step_type, - int start, - int used_pixels, - int *scan_power_mode) -{ -int exposure_time = 0; -int exposure_time2 = 0; -int led_exposure; - - *scan_power_mode=0; - led_exposure=gl841_get_led_exposure(dev, sensor); - exposure_time = sanei_genesys_exposure_time2( - dev, - slope_dpi, - scan_step_type, - start+used_pixels,/*+tgtime? currently done in sanei_genesys_exposure_time2 with tgtime = 32 pixel*/ - led_exposure, - *scan_power_mode); - - while(*scan_power_mode + 1 < dev->motor.power_mode_count) { - exposure_time2 = sanei_genesys_exposure_time2( - dev, - slope_dpi, - scan_step_type, - start+used_pixels,/*+tgtime? currently done in sanei_genesys_exposure_time2 with tgtime = 32 pixel*/ - led_exposure, - *scan_power_mode + 1); - if (exposure_time < exposure_time2) - break; - exposure_time = exposure_time2; - (*scan_power_mode)++; - } - - return exposure_time; -} - -/**@brief compute scan_step_type - * Try to do at least 4 steps per line. if that is impossible we will have to - * live with that. - * @param dev device - * @param yres motor resolution - */ -static int -gl841_scan_step_type(Genesys_Device *dev, int yres) -{ -int scan_step_type=0; - - /* TODO : check if there is a bug around the use of max_step_type */ - /* should be <=1, need to chek all devices entry in genesys_devices */ - if (yres*4 < dev->motor.base_ydpi || dev->motor.max_step_type <= 0) - { - scan_step_type = 0; - } - else if (yres*4 < dev->motor.base_ydpi*2 || dev->motor.max_step_type <= 1) - { - scan_step_type = 1; - } - else - { - scan_step_type = 2; - } - - /* this motor behaves differently */ - if (dev->model->motor_type==MOTOR_CANONLIDE80) - { - /* driven by 'frequency' tables ? */ - scan_step_type = 0; - } - - return scan_step_type; -} - -/* set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -static -SANE_Status -gl841_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SetupParams& params) -{ - params.assert_valid(); - - int used_res; - int start, used_pixels; - int bytes_per_line; - int move; - unsigned int lincnt; - int exposure_time; - int scan_power_mode; - int i; - int stagger; - int avg; - - int slope_dpi = 0; - int dummy = 0; - int scan_step_type = 1; - int max_shift; - size_t requested_buffer_size, read_buffer_size; - - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - int optical_res; - SANE_Status status = SANE_STATUS_GOOD; - unsigned int oflags; /**> optical flags */ - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - -/* -results: - -for scanner: -half_ccd -start -end -dpiset -exposure_time -dummy -z1 -z2 - -for ordered_read: - dev->words_per_line - dev->read_factor - dev->requested_buffer_size - dev->read_buffer_size - dev->read_pos - dev->read_bytes_in_buffer - dev->read_bytes_left - dev->max_shift - dev->stagger - -independent of our calculated values: - dev->total_bytes_read - dev->bytes_to_read - */ - -/* half_ccd */ - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - if (sensor.get_ccd_size_divisor_for_dpi(params.xres) > 1) { - half_ccd = SANE_TRUE; - } else { - half_ccd = SANE_FALSE; - } - -/* optical_res */ - - optical_res = sensor.optical_res; - if (half_ccd) - optical_res /= 2; - -/* stagger */ - - if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG(DBG_info, "%s : stagger=%d lines\n", __func__, stagger); - -/* used_res */ - i = optical_res / params.xres; - -/* gl841 supports 1/1 1/2 1/3 1/4 1/5 1/6 1/8 1/10 1/12 1/15 averaging */ - - if (i < 2 || (params.flags & SCAN_FLAG_USE_OPTICAL_RES)) /* optical_res >= xres > optical_res/2 */ - used_res = optical_res; - else if (i < 3) /* optical_res/2 >= xres > optical_res/3 */ - used_res = optical_res/2; - else if (i < 4) /* optical_res/3 >= xres > optical_res/4 */ - used_res = optical_res/3; - else if (i < 5) /* optical_res/4 >= xres > optical_res/5 */ - used_res = optical_res/4; - else if (i < 6) /* optical_res/5 >= xres > optical_res/6 */ - used_res = optical_res/5; - else if (i < 8) /* optical_res/6 >= xres > optical_res/8 */ - used_res = optical_res/6; - else if (i < 10) /* optical_res/8 >= xres > optical_res/10 */ - used_res = optical_res/8; - else if (i < 12) /* optical_res/10 >= xres > optical_res/12 */ - used_res = optical_res/10; - else if (i < 15) /* optical_res/12 >= xres > optical_res/15 */ - used_res = optical_res/12; - else - used_res = optical_res/15; - - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - /* start */ - /* add x coordinates */ - start = ((sensor.CCD_start_xoffset + params.startx) * used_res) / sensor.optical_res; - - /* needs to be aligned for used_res */ - start = (start * optical_res) / used_res; - - start += sensor.dummy_pixel + 1; - - if (stagger > 0) - start |= 1; - - /* in case of SHDAREA, we need to align start - * on pixel average factor, startx is different of - * 0 only when calling for function to setup for - * scan, where shading data needs to be align */ - if((dev->reg.find_reg(0x01).value & REG01_SHDAREA) != 0) - { - avg=optical_res/used_res; - start=(start/avg)*avg; - } - - /* compute correct pixels number */ - /* pixels */ - used_pixels = (params.pixels * optical_res) / params.xres; - - /* round up pixels number if needed */ - if (used_pixels * params.xres < params.pixels * optical_res) - used_pixels++; - -/* dummy */ - /* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1 - dummy line. Maybe the dummy line adds correctness since the motor runs - slower (higher dpi) - */ -/* for cis this creates better aligned color lines: -dummy \ scanned lines - 0: R G B R ... - 1: R G B - R ... - 2: R G B - - R ... - 3: R G B - - - R ... - 4: R G B - - - - R ... - 5: R G B - - - - - R ... - 6: R G B - - - - - - R ... - 7: R G B - - - - - - - R ... - 8: R G B - - - - - - - - R ... - 9: R G B - - - - - - - - - R ... - 10: R G B - - - - - - - - - - R ... - 11: R G B - - - - - - - - - - - R ... - 12: R G B - - - - - - - - - - - - R ... - 13: R G B - - - - - - - - - - - - - R ... - 14: R G B - - - - - - - - - - - - - - R ... - 15: R G B - - - - - - - - - - - - - - - R ... - -- pierre - */ - dummy = 0; - -/* slope_dpi */ -/* cis color scan is effectively a gray scan with 3 gray lines per color - line and a FILTER of 0 */ - if (dev->model->is_cis) - slope_dpi = params.yres* params.channels; - else - slope_dpi = params.yres; - - slope_dpi = slope_dpi * (1 + dummy); - - scan_step_type = gl841_scan_step_type(dev, params.yres); - exposure_time = gl841_exposure_time(dev, sensor, - slope_dpi, - scan_step_type, - start, - used_pixels, - &scan_power_mode); - DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - - /*** optical parameters ***/ - /* in case of dynamic lineart, we use an internal 8 bit gray scan - * to generate 1 lineart data */ - if(params.flags & SCAN_FLAG_DYNAMIC_LINEART) - { - params.depth=8; - } - - oflags=0; - if (params.flags & SCAN_FLAG_DISABLE_SHADING) - { - oflags |= OPTICAL_FLAG_DISABLE_SHADING; - } - if ((params.flags & SCAN_FLAG_DISABLE_GAMMA) || (params.depth==16)) - { - oflags |= OPTICAL_FLAG_DISABLE_GAMMA; - } - if (params.flags & SCAN_FLAG_DISABLE_LAMP) - { - oflags |= OPTICAL_FLAG_DISABLE_LAMP; - } - if (params.flags & SCAN_FLAG_ENABLE_LEDADD) - { - oflags |= OPTICAL_FLAG_ENABLE_LEDADD; - } - - status = gl841_init_optical_regs_scan(dev, sensor, - reg, - exposure_time, - used_res, - start, - used_pixels, - params.channels, - params.depth, - half_ccd, - params.color_filter, - oflags); - if (status != SANE_STATUS_GOOD) - { - return status; - } - -/*** motor parameters ***/ - - /* scanned area must be enlarged by max color shift needed */ - max_shift=sanei_genesys_compute_max_shift(dev, params.channels,params.yres,params.flags); - - /* lincnt */ - lincnt = params.lines + max_shift + stagger; - - /* add tl_y to base movement */ - move = params.starty; - DBG(DBG_info, "%s: move=%d steps\n", __func__, move); - - /* subtract current head position */ - move -= dev->scanhead_position_in_steps; - DBG(DBG_info, "%s: move=%d steps\n", __func__, move); - - if (move < 0) - move = 0; - - /* round it */ -/* the move is not affected by dummy -- pierre */ -/* move = ((move + dummy) / (dummy + 1)) * (dummy + 1); - DBG(DBG_info, "%s: move=%d steps\n", __func__, move);*/ - - if (params.flags & SCAN_FLAG_SINGLE_LINE) - status = gl841_init_motor_regs_off(reg, dev->model->is_cis?lincnt* params.channels:lincnt); - else - status = gl841_init_motor_regs_scan(dev, sensor, - reg, - exposure_time, - slope_dpi, - scan_step_type, - dev->model->is_cis?lincnt* params.channels:lincnt, - dummy, - move, - scan_power_mode, - (params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE)? - MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE:0 - ); - - if (status != SANE_STATUS_GOOD) - return status; - - - /*** prepares data reordering ***/ - -/* words_per_line */ - bytes_per_line = (used_pixels * used_res) / optical_res; - bytes_per_line = (bytes_per_line * params.channels * params.depth) / 8; - - requested_buffer_size = 8 * bytes_per_line; - /* we must use a round number of bytes_per_line */ - if (requested_buffer_size > sanei_genesys_get_bulk_max_size(dev)) - requested_buffer_size = - (sanei_genesys_get_bulk_max_size(dev) / bytes_per_line) * bytes_per_line; - - read_buffer_size = - 2 * requested_buffer_size + - ((max_shift + stagger) * used_pixels * params.channels * params.depth) / 8; - - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); - - dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); - - dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); - - dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * dev->settings.pixels * params.channels * params.depth) / 8); - - dev->read_bytes_left = bytes_per_line * lincnt; - - DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); - dev->read_active = SANE_TRUE; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res)/optical_res; - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - -/* TODO: should this be done elsewhere? */ - /* scan bytes to send to the frontend */ - /* theory : - target_size = - (dev->settings.pixels * dev->settings.lines * channels * depth) / 8; - but it suffers from integer overflow so we do the following: - - 1 bit color images store color data byte-wise, eg byte 0 contains - 8 bits of red data, byte 1 contains 8 bits of green, byte 2 contains - 8 bits of blue. - This does not fix the overflow, though. - 644mp*16 = 10gp, leading to an overflow - -- pierre - */ - - dev->total_bytes_read = 0; - if (params.depth == 1) - dev->total_bytes_to_read = - ((dev->settings.pixels * dev->settings.lines) / 8 + - (((dev->settings.pixels * dev->settings.lines)%8)?1:0) - ) * params.channels; - else - dev->total_bytes_to_read = - dev->settings.pixels * dev->settings.lines * params.channels * (params.depth / 8); - - DBG(DBG_info, "%s: total bytes to send = %lu\n", __func__, (u_long) dev->total_bytes_to_read); -/* END TODO */ - - DBG(DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; -} - -static void gl841_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int depth; - int start; - - int used_res; - int used_pixels; - unsigned int lincnt; - int exposure_time; - int scan_power_mode; - int i; - int stagger; - - int slope_dpi = 0; - int dummy = 0; - int scan_step_type = 1; - int max_shift; - - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - int optical_res; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - -/* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - -/* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - -/* start */ - start = SANE_UNFIX (dev->model->x_offset); - - start += dev->settings.tl_x; - - start = (start * sensor.optical_res) / MM_PER_INCH; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; - params.starty = 0; // not used - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = 0; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - -/* half_ccd */ - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - if (sensor.get_ccd_size_divisor_for_dpi(params.xres) > 1) { - half_ccd = SANE_TRUE; - } else { - half_ccd = SANE_FALSE; - } - -/* optical_res */ - - optical_res = sensor.optical_res; - if (half_ccd) - optical_res /= 2; - -/* stagger */ - - if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG(DBG_info, "%s: stagger=%d lines\n", __func__, stagger); - -/* used_res */ - i = optical_res / params.xres; - -/* gl841 supports 1/1 1/2 1/3 1/4 1/5 1/6 1/8 1/10 1/12 1/15 averaging */ - - if (i < 2) /* optical_res >= xres > optical_res/2 */ - used_res = optical_res; - else if (i < 3) /* optical_res/2 >= xres > optical_res/3 */ - used_res = optical_res/2; - else if (i < 4) /* optical_res/3 >= xres > optical_res/4 */ - used_res = optical_res/3; - else if (i < 5) /* optical_res/4 >= xres > optical_res/5 */ - used_res = optical_res/4; - else if (i < 6) /* optical_res/5 >= xres > optical_res/6 */ - used_res = optical_res/5; - else if (i < 8) /* optical_res/6 >= xres > optical_res/8 */ - used_res = optical_res/6; - else if (i < 10) /* optical_res/8 >= xres > optical_res/10 */ - used_res = optical_res/8; - else if (i < 12) /* optical_res/10 >= xres > optical_res/12 */ - used_res = optical_res/10; - else if (i < 15) /* optical_res/12 >= xres > optical_res/15 */ - used_res = optical_res/12; - else - used_res = optical_res/15; - - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - start = ((sensor.CCD_start_xoffset + params.startx) * used_res) / sensor.optical_res; - -/* needs to be aligned for used_res */ - start = (start * optical_res) / used_res; - - start += sensor.dummy_pixel + 1; - - if (stagger > 0) { - start |= 1; - } - - used_pixels = (params.pixels * optical_res) / params.xres; - - // round up pixels number if needed - if (used_pixels * params.xres < params.pixels * optical_res) { - used_pixels++; - } - - /* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1 - dummy line. Maybe the dummy line adds correctness since the motor runs - slower (higher dpi) - */ -/* for cis this creates better aligned color lines: -dummy \ scanned lines - 0: R G B R ... - 1: R G B - R ... - 2: R G B - - R ... - 3: R G B - - - R ... - 4: R G B - - - - R ... - 5: R G B - - - - - R ... - 6: R G B - - - - - - R ... - 7: R G B - - - - - - - R ... - 8: R G B - - - - - - - - R ... - 9: R G B - - - - - - - - - R ... - 10: R G B - - - - - - - - - - R ... - 11: R G B - - - - - - - - - - - R ... - 12: R G B - - - - - - - - - - - - R ... - 13: R G B - - - - - - - - - - - - - R ... - 14: R G B - - - - - - - - - - - - - - R ... - 15: R G B - - - - - - - - - - - - - - - R ... - -- pierre - */ - dummy = 0; - -/* cis color scan is effectively a gray scan with 3 gray lines per color - line and a FILTER of 0 */ - if (dev->model->is_cis) { - slope_dpi = params.yres * params.channels; - } else { - slope_dpi = params.yres; - } - - slope_dpi = slope_dpi * (1 + dummy); - - scan_step_type = gl841_scan_step_type(dev, params.yres); - exposure_time = gl841_exposure_time(dev, sensor, - slope_dpi, - scan_step_type, - start, - used_pixels, - &scan_power_mode); - DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - - /* scanned area must be enlarged by max color shift needed */ - max_shift = sanei_genesys_compute_max_shift(dev, params.channels, params.yres, 0); - - lincnt = params.lines + max_shift + stagger; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res)/optical_res; - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - - DBGCOMPLETED; -} - -/*for fast power saving methods only, like disabling certain amplifiers*/ -static SANE_Status gl841_save_power(Genesys_Device * dev, SANE_Bool enable) -{ - uint8_t val; - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - DBG(DBG_proc, "%s: enable = %d\n", __func__, enable); - - if (enable) - { - if (dev->model->gpo_type == GPO_CANONLIDE35) - { -/* expect GPIO17 to be enabled, and GPIO9 to be disabled, - while GPIO8 is disabled*/ -/* final state: GPIO8 disabled, GPIO9 enabled, GPIO17 disabled, - GPIO18 disabled*/ - - sanei_genesys_read_register(dev, REG6D, &val); - sanei_genesys_write_register(dev, REG6D, val | 0x80); - - sanei_genesys_sleep_ms(1); - - /*enable GPIO9*/ - sanei_genesys_read_register(dev, REG6C, &val); - sanei_genesys_write_register(dev, REG6C, val | 0x01); - - /*disable GPO17*/ - sanei_genesys_read_register(dev, REG6B, &val); - sanei_genesys_write_register(dev, REG6B, val & ~REG6B_GPO17); - - /*disable GPO18*/ - sanei_genesys_read_register(dev, REG6B, &val); - sanei_genesys_write_register(dev, REG6B, val & ~REG6B_GPO18); - - sanei_genesys_sleep_ms(1); - - sanei_genesys_read_register(dev, REG6D, &val); - sanei_genesys_write_register(dev, REG6D, val & ~0x80); - - } - if (dev->model->gpo_type == GPO_DP685) - { - sanei_genesys_read_register(dev, REG6B, &val); - sanei_genesys_write_register(dev, REG6B, val & ~REG6B_GPO17); - dev->reg.find_reg(0x6b).value &= ~REG6B_GPO17; - dev->calib_reg.find_reg(0x6b).value &= ~REG6B_GPO17; - } - - gl841_set_fe(dev, sensor, AFE_POWER_SAVE); - - } - else - { - if (dev->model->gpo_type == GPO_CANONLIDE35) - { -/* expect GPIO17 to be enabled, and GPIO9 to be disabled, - while GPIO8 is disabled*/ -/* final state: GPIO8 enabled, GPIO9 disabled, GPIO17 enabled, - GPIO18 enabled*/ - - sanei_genesys_read_register(dev, REG6D, &val); - sanei_genesys_write_register(dev, REG6D, val | 0x80); - - sanei_genesys_sleep_ms(10); - - /*disable GPIO9*/ - sanei_genesys_read_register(dev, REG6C, &val); - sanei_genesys_write_register(dev, REG6C, val & ~0x01); - - /*enable GPIO10*/ - sanei_genesys_read_register(dev, REG6C, &val); - sanei_genesys_write_register(dev, REG6C, val | 0x02); - - /*enable GPO17*/ - sanei_genesys_read_register(dev, REG6B, &val); - sanei_genesys_write_register(dev, REG6B, val | REG6B_GPO17); - dev->reg.find_reg(0x6b).value |= REG6B_GPO17; - dev->calib_reg.find_reg(0x6b).value |= REG6B_GPO17; - - /*enable GPO18*/ - sanei_genesys_read_register(dev, REG6B, &val); - sanei_genesys_write_register(dev, REG6B, val | REG6B_GPO18); - dev->reg.find_reg(0x6b).value |= REG6B_GPO18; - dev->calib_reg.find_reg(0x6b).value |= REG6B_GPO18; - - } - if (dev->model->gpo_type == GPO_DP665 - || dev->model->gpo_type == GPO_DP685) - { - sanei_genesys_read_register(dev, REG6B, &val); - sanei_genesys_write_register(dev, REG6B, val | REG6B_GPO17); - dev->reg.find_reg(0x6b).value |= REG6B_GPO17; - dev->calib_reg.find_reg(0x6b).value |= REG6B_GPO17; - } - - } - - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl841_set_powersaving (Genesys_Device * dev, - int delay /* in minutes */ ) -{ - SANE_Status status = SANE_STATUS_GOOD; - // FIXME: SEQUENTIAL not really needed in this case - Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); - int rate, exposure_time, tgtime, time; - - DBG(DBG_proc, "%s (delay = %d)\n", __func__, delay); - - local_reg.init_reg(0x01, dev->reg.get8(0x01)); /* disable fastmode */ - local_reg.init_reg(0x03, dev->reg.get8(0x03)); /* Lamp power control */ - local_reg.init_reg(0x05, dev->reg.get8(0x05)); /*& ~REG05_BASESEL*/; /* 24 clocks/pixel */ - local_reg.init_reg(0x18, 0x00); // Set CCD type - local_reg.init_reg(0x38, 0x00); - local_reg.init_reg(0x39, 0x00); - - // period times for LPeriod, expR,expG,expB, Z1MODE, Z2MODE - local_reg.init_reg(0x1c, dev->reg.get8(0x05) & ~REG1C_TGTIME); - - if (!delay) { - local_reg.find_reg(0x03).value = local_reg.find_reg(0x03).value & 0xf0; /* disable lampdog and set lamptime = 0 */ - } else if (delay < 20) { - local_reg.find_reg(0x03).value = (local_reg.find_reg(0x03).value & 0xf0) | 0x09; /* enable lampdog and set lamptime = 1 */ - } else { - local_reg.find_reg(0x03).value = (local_reg.find_reg(0x03).value & 0xf0) | 0x0f; /* enable lampdog and set lamptime = 7 */ - } - - time = delay * 1000 * 60; /* -> msec */ - exposure_time = - (uint32_t) (time * 32000.0 / - (24.0 * 64.0 * (local_reg.find_reg(0x03).value & REG03_LAMPTIM) * - 1024.0) + 0.5); - /* 32000 = system clock, 24 = clocks per pixel */ - rate = (exposure_time + 65536) / 65536; - if (rate > 4) - { - rate = 8; - tgtime = 3; - } - else if (rate > 2) - { - rate = 4; - tgtime = 2; - } - else if (rate > 1) - { - rate = 2; - tgtime = 1; - } - else - { - rate = 1; - tgtime = 0; - } - - local_reg.find_reg(0x1c).value |= tgtime; - exposure_time /= rate; - - if (exposure_time > 65535) - exposure_time = 65535; - - local_reg.set8(0x38, exposure_time >> 8); - local_reg.set8(0x39, exposure_time & 255); /* lowbyte */ - - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - - DBG(DBG_proc, "%s: completed\n", __func__); - return status; -} - -static SANE_Status -gl841_start_action (Genesys_Device * dev) -{ - return sanei_genesys_write_register (dev, 0x0f, 0x01); -} - -static SANE_Status -gl841_stop_action (Genesys_Device * dev) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val40, val; - unsigned int loop; - - DBG(DBG_proc, "%s\n", __func__); - - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - status = sanei_genesys_read_register(dev, 0x40, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* only stop action if needed */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)) - { - DBG(DBG_info, "%s: already stopped\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - local_reg = dev->reg; - - gl841_init_optical_regs_off(&local_reg); - - gl841_init_motor_regs_off(&local_reg,0); - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* looks like writing the right registers to zero is enough to get the chip - out of scan mode into command mode, actually triggering(writing to - register 0x0f) seems to be unnecessary */ - - loop = 10; - while (loop > 0) - { - status = sanei_genesys_read_register(dev, 0x40, &val40); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* if scanner is in command mode, we are done */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)) - { - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - sanei_genesys_sleep_ms(100); - loop--; - } - - DBGCOMPLETED; - return SANE_STATUS_IO_ERROR; -} - -static SANE_Status -gl841_get_paper_sensor(Genesys_Device * dev, SANE_Bool * paper_loaded) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - status = sanei_genesys_read_register(dev, REG6D, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read gpio: %s\n", __func__, sane_strstatus(status)); - return status; - } - *paper_loaded = (val & 0x1) == 0; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl841_eject_document (Genesys_Device * dev) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - SANE_Bool paper_loaded; - unsigned int init_steps; - float feed_mm; - int loop; - - DBG(DBG_proc, "%s\n", __func__); - - if (dev->model->is_sheetfed == SANE_FALSE) - { - DBG(DBG_proc, "%s: there is no \"eject sheet\"-concept for non sheet fed\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; - } - - - local_reg.clear(); - val = 0; - - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read status register: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl841_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop motor: %s\n", __func__, sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - - local_reg = dev->reg; - - gl841_init_optical_regs_off(&local_reg); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - gl841_init_motor_regs(dev, sensor, &local_reg, - 65536,MOTOR_ACTION_FEED,0); - - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - try { - status = gl841_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl841_stop_action(dev); - } catch (...) {} - try { - // restore original registers - sanei_genesys_bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl841_stop_action (dev); - /* send original registers */ - sanei_genesys_bulk_write_register(dev, dev->reg); - return status; - } - - RIE(gl841_get_paper_sensor(dev, &paper_loaded)); - if (paper_loaded) - { - DBG(DBG_info, "%s: paper still loaded\n", __func__); - /* force document TRUE, because it is definitely present */ - dev->document = SANE_TRUE; - dev->scanhead_position_in_steps = 0; - - loop = 300; - while (loop > 0) /* do not wait longer then 30 seconds */ - { - - RIE(gl841_get_paper_sensor(dev, &paper_loaded)); - - if (!paper_loaded) - { - DBG(DBG_info, "%s: reached home position\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - break; - } - sanei_genesys_sleep_ms(100); - --loop; - } - - if (loop == 0) - { - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl841_stop_action (dev); - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; - } - } - - feed_mm = SANE_UNFIX(dev->model->eject_feed); - if (dev->document) - { - feed_mm += SANE_UNFIX(dev->model->post_scan); - } - - status = sanei_genesys_read_feed_steps(dev, &init_steps); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read feed steps: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* now feed for extra <number> steps */ - loop = 0; - while (loop < 300) /* do not wait longer then 30 seconds */ - { - unsigned int steps; - - status = sanei_genesys_read_feed_steps(dev, &steps); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read feed steps: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_info, "%s: init_steps: %d, steps: %d\n", __func__, init_steps, steps); - - if (steps > init_steps + (feed_mm * dev->motor.base_ydpi) / MM_PER_INCH) - { - break; - } - - sanei_genesys_sleep_ms(100); - ++loop; - } - - status = gl841_stop_action(dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop motor: %s\n", __func__, sane_strstatus(status)); - return status; - } - - dev->document = SANE_FALSE; - - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; -} - - -static SANE_Status -gl841_load_document (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - SANE_Bool paper_loaded; - int loop = 300; - DBG(DBG_proc, "%s\n", __func__); - while (loop > 0) /* do not wait longer then 30 seconds */ - { - - RIE(gl841_get_paper_sensor(dev, &paper_loaded)); - - if (paper_loaded) - { - DBG(DBG_info, "%s: document inserted\n", __func__); - - /* when loading OK, document is here */ - dev->document = SANE_TRUE; - - // give user some time to place document correctly - sanei_genesys_sleep_ms(1000); - break; - } - sanei_genesys_sleep_ms(100); - --loop; - } - - if (loop == 0) - { - /* when we come here then the user needed to much time for this */ - DBG(DBG_error, "%s: timeout while waiting for document\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; -} - -/** - * detects end of document and adjust current scan - * to take it into account - * used by sheetfed scanners - */ -static SANE_Status -gl841_detect_document_end (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - SANE_Bool paper_loaded; - unsigned int scancnt = 0, lincnt, postcnt; - uint8_t val; - size_t total_bytes_to_read; - - DBG(DBG_proc, "%s: begin\n", __func__); - - RIE (gl841_get_paper_sensor (dev, &paper_loaded)); - - /* sheetfed scanner uses home sensor as paper present */ - if ((dev->document == SANE_TRUE) && !paper_loaded) - { - DBG(DBG_info, "%s: no more document\n", __func__); - dev->document = SANE_FALSE; - - /* we can't rely on total_bytes_to_read since the frontend - * might have been slow to read data, so we re-evaluate the - * amount of data to scan form the hardware settings - */ - try { - status = sanei_genesys_read_scancnt(dev, &scancnt); - } catch (...) { - dev->total_bytes_to_read = dev->total_bytes_read; - dev->read_bytes_left = 0; - throw; - } - - if(status!=SANE_STATUS_GOOD) - { - dev->total_bytes_to_read = dev->total_bytes_read; - dev->read_bytes_left = 0; - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; - } - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS && dev->model->is_cis) - { - scancnt/=3; - } - DBG(DBG_io, "%s: scancnt=%u lines\n", __func__, scancnt); - - RIE(sanei_genesys_read_register(dev, 0x25, &val)); - lincnt=65536*val; - RIE(sanei_genesys_read_register(dev, 0x26, &val)); - lincnt+=256*val; - RIE(sanei_genesys_read_register(dev, 0x27, &val)); - lincnt+=val; - DBG(DBG_io, "%s: lincnt=%u lines\n", __func__, lincnt); - postcnt=(SANE_UNFIX(dev->model->post_scan)/MM_PER_INCH)*dev->settings.yres; - DBG(DBG_io, "%s: postcnt=%u lines\n", __func__, postcnt); - - /* the current scancnt is also the final one, so we use it to - * compute total bytes to read. We also add the line count to eject document */ - total_bytes_to_read=(scancnt+postcnt)*dev->wpl; - - DBG(DBG_io, "%s: old total_bytes_to_read=%u\n", __func__, - (unsigned int)dev->total_bytes_to_read); - DBG(DBG_io, "%s: new total_bytes_to_read=%u\n", __func__, (unsigned int)total_bytes_to_read); - - /* assign new end value */ - if(dev->total_bytes_to_read>total_bytes_to_read) - { - DBG(DBG_io, "%s: scan shorten\n", __func__); - dev->total_bytes_to_read=total_bytes_to_read; - } - } - - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; -} - -/* Send the low-level scan command */ -/* todo : is this that useful ? */ -static SANE_Status -gl841_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SANE_Bool start_motor) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - // FIXME: SEQUENTIAL not really needed in this case - Genesys_Register_Set local_reg(Genesys_Register_Set::SEQUENTIAL); - uint8_t val; - - DBG(DBG_proc, "%s\n", __func__); - - if (dev->model->gpo_type == GPO_CANONLIDE80) - { - RIE (sanei_genesys_read_register (dev, REG6B, &val)); - val = REG6B_GPO18; - RIE (sanei_genesys_write_register (dev, REG6B, val)); - } - - if (dev->model->ccd_type != CCD_PLUSTEK_3600) { - local_reg.init_reg(0x03, sanei_genesys_read_reg_from_set(reg, 0x03) | REG03_LAMPPWR); - } else { - // TODO PLUSTEK_3600: why ?? - local_reg.init_reg(0x03, sanei_genesys_read_reg_from_set(reg, 0x03)); - } - - local_reg.init_reg(0x01, sanei_genesys_read_reg_from_set(reg, 0x01) | REG01_SCAN); /* set scan bit */ - local_reg.init_reg(0x0d, 0x01); - - if (start_motor) { - local_reg.init_reg(0x0f, 0x01); - } else { - // do not start motor yet - local_reg.init_reg(0x0f, 0x00); - } - - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: completed\n", __func__); - - return status; -} - - -/* Send the stop scan command */ -static SANE_Status -gl841_end_scan (Genesys_Device * dev, Genesys_Register_Set __sane_unused__ * reg, - SANE_Bool check_stop) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (check_stop = %d)\n", __func__, check_stop); - - if (dev->model->is_sheetfed == SANE_TRUE) - { - status = SANE_STATUS_GOOD; - } - else /* flat bed scanners */ - { - status = gl841_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBG(DBG_proc, "%s: completed\n", __func__); - - return status; -} - -/* Moves the slider to steps */ -static SANE_Status -gl841_feed (Genesys_Device * dev, int steps) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - int loop; - - DBG(DBG_proc, "%s (steps = %d)\n", __func__, steps); - - status = gl841_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop action: %s\n", __func__, sane_strstatus(status)); - return status; - } - - // FIXME: we should pick sensor according to the resolution scanner is currently operating on - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - local_reg = dev->reg; - - gl841_init_optical_regs_off(&local_reg); - - gl841_init_motor_regs(dev, sensor, &local_reg, steps,MOTOR_ACTION_FEED,0); - - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - try { - status = gl841_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl841_stop_action (dev); - } catch (...) {} - try { - // send original registers - sanei_genesys_bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl841_stop_action (dev); - /* send original registers */ - sanei_genesys_bulk_write_register(dev, dev->reg); - return status; - } - - loop = 0; - while (loop < 300) /* do not wait longer then 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (!(val & REG41_MOTORENB)) /* motor enabled */ - { - DBG(DBG_proc, "%s: finished\n", __func__); - dev->scanhead_position_in_steps += steps; - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl841_stop_action (dev); - - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; -} - -/* Moves the slider to the home (top) position slowly */ -static SANE_Status -gl841_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - uint8_t val; - int loop = 0; - - DBG(DBG_proc, "%s (wait_until_home = %d)\n", __func__, wait_until_home); - - if (dev->model->is_sheetfed == SANE_TRUE) - { - DBG(DBG_proc, "%s: there is no \"home\"-concept for sheet fed\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; - } - - /* reset gpio pin */ - if (dev->model->gpo_type == GPO_CANONLIDE35) - { - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - val = dev->gpo.value[0]; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - } - if (dev->model->gpo_type == GPO_CANONLIDE80) - { - RIE (sanei_genesys_read_register (dev, REG6B, &val)); - val = REG6B_GPO18 | REG6B_GPO17; - RIE (sanei_genesys_write_register (dev, REG6B, val)); - } - gl841_save_power(dev, SANE_FALSE); - - /* first read gives HOME_SENSOR true */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - sanei_genesys_sleep_ms(100); - - /* second is reliable */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - dev->scanhead_position_in_steps = 0; - - if (val & REG41_HOMESNR) /* is sensor at home? */ - { - DBG(DBG_info, "%s: already at home, completed\n", __func__); - dev->scanhead_position_in_steps = 0; - return SANE_STATUS_GOOD; - } - - /* end previous scan if any */ - r = sanei_genesys_get_address(&dev->reg, REG01); - r->value &= ~REG01_SCAN; - status = sanei_genesys_write_register (dev, REG01, r->value); - - /* if motor is on, stop current action */ - if (val & REG41_MOTORENB) - { - status = gl841_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop motor: %s\n", __func__, sane_strstatus(status)); - return SANE_STATUS_IO_ERROR; - } - } - - local_reg = dev->reg; - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - gl841_init_motor_regs(dev, sensor, &local_reg, 65536,MOTOR_ACTION_GO_HOME,0); - - /* set up for reverse and no scan */ - r = sanei_genesys_get_address(&local_reg, REG02); - r->value |= REG02_MTRREV; - r = sanei_genesys_get_address(&local_reg, REG01); - r->value &= ~REG01_SCAN; - - RIE (sanei_genesys_bulk_write_register(dev, local_reg)); - - try { - status = gl841_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl841_stop_action(dev); - } catch (...) {} - try { - sanei_genesys_bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl841_stop_action (dev); - /* send original registers */ - sanei_genesys_bulk_write_register(dev, dev->reg); - return status; - } - - if (wait_until_home) - { - while (loop < 300) /* do not wait longer then 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - if (val & REG41_HOMESNR) /* home sensor */ - { - DBG(DBG_info, "%s: reached home position\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl841_stop_action (dev); - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; -} - -/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels - area at 600 dpi from very top of scanner */ -static SANE_Status -gl841_search_start_position (Genesys_Device * dev) -{ - int size; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - int steps; - - int pixels = 600; - int dpi = 300; - - DBGSTART; - - local_reg = dev->reg; - - /* sets for a 200 lines * 600 pixels */ - /* normal scan with no shading */ - - // FIXME: the current approach of doing search only for one resolution does not work on scanners - // whith employ different sensors with potentially different settings. - auto& sensor = sanei_genesys_find_sensor_for_write(dev, dpi); - - SetupParams params; - params.xres = dpi; - params.yres = dpi; - params.startx = 0; - params.starty = 0; /*we should give a small offset here~60 steps*/ - params.pixels = 600; - params.lines = dev->model->search_lines; - params.depth = 8; - params.channels = 1; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::GREEN; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; - - status = gl841_init_scan_regs(dev, sensor, &local_reg, params); - - if(status!=SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to init scan registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* send to scanner */ - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - size = pixels * dev->model->search_lines; - - std::vector<uint8_t> data(size); - - status = gl841_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl841_search_position.pnm", data.data(), 8, 1, pixels, - dev->model->search_lines); - - status = gl841_end_scan(dev, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* update regs to copy ASIC internal state */ - dev->reg = local_reg; - -/*TODO: find out where sanei_genesys_search_reference_point - stores information, and use that correctly*/ - status = - sanei_genesys_search_reference_point (dev, sensor, data.data(), 0, dpi, pixels, - dev->model->search_lines); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set search reference point: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - return SANE_STATUS_GOOD; -} - -/* - * sets up register for coarse gain calibration - * todo: check it for scanners using it */ -static SANE_Status -gl841_init_regs_for_coarse_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t channels; - uint8_t cksel; - - DBGSTART; - - cksel = (regs.find_reg(0x18).value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */ - - /* set line size */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else { - channels = 1; - } - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = sensor.optical_res / cksel; /* XXX STEF XXX !!! */ - params.lines = 20; - params.depth = 16; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl841_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, - sensor.optical_res / cksel, dev->settings.xres); - - status = sanei_genesys_bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - -/* if (DBG_LEVEL >= DBG_info) - sanei_gl841_print_registers (regs);*/ - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* init registers for shading calibration */ -static SANE_Status -gl841_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - SANE_Int ydpi; - float starty=0; - - DBGSTART; - DBG(DBG_proc, "%s: lines = %d\n", __func__, (int)(dev->calib_lines)); - - /* initial calibration reg values */ - regs = dev->reg; - - ydpi = dev->motor.base_ydpi; - if (dev->model->motor_type == MOTOR_PLUSTEK_3600) /* TODO PLUSTEK_3600: 1200dpi not yet working, produces dark bar */ - { - ydpi = 600; - } - if (dev->model->motor_type == MOTOR_CANONLIDE80) - { - ydpi = gl841_get_dpihw(dev); - /* get over extra dark area for this model. - It looks like different devices have dark areas of different width - due to manufacturing variability. The initial value of starty was 140, - but it moves the sensor almost past the dark area completely in places - on certain devices. - - On a particular device the black area starts at roughly position - 160 to 230 depending on location (the dark area is not completely - parallel to the frame). - */ - starty = 70; - } - - dev->calib_channels = 3; - dev->calib_lines = dev->model->shading_lines; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = ydpi; - params.startx = 0; - params.starty = starty; - params.pixels = (sensor.sensor_pixels * dev->settings.xres) / sensor.optical_res; - params.lines = dev->calib_lines; - params.depth = 16; - params.channels = dev->calib_channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_USE_OPTICAL_RES | - /*SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |*/ - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl841_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - dev->calib_pixels = dev->current_setup.pixels; - dev->scanhead_position_in_steps += dev->calib_lines + starty; - - status = sanei_genesys_bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* set up registers for the actual scan - */ -static SANE_Status -gl841_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int flags; - int depth; - float move; - int move_dpi; - float start; - - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - -/* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - -/* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - - /* steps to move to reach scanning area: - - first we move to physical start of scanning - either by a fixed steps amount from the black strip - or by a fixed amount from parking position, - minus the steps done during shading calibration - - then we move by the needed offset whitin physical - scanning area - - assumption: steps are expressed at maximum motor resolution - - we need: - SANE_Fixed y_offset; - SANE_Fixed y_size; - SANE_Fixed y_offset_calib; - mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */ - - /* if scanner uses GENESYS_FLAG_SEARCH_START y_offset is - relative from origin, else, it is from parking position */ - - move_dpi = dev->motor.base_ydpi; - - move = 0; - if (dev->model->flags & GENESYS_FLAG_SEARCH_START) - { - move += SANE_UNFIX (dev->model->y_offset_calib); - } - - DBG(DBG_info, "%s move=%f steps\n", __func__, move); - - move += SANE_UNFIX (dev->model->y_offset); - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - move += dev->settings.tl_y; - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - move = (move * move_dpi) / MM_PER_INCH; - -/* start */ - start = SANE_UNFIX (dev->model->x_offset); - - start += dev->settings.tl_x; - - start = (start * sensor.optical_res) / MM_PER_INCH; - - flags=0; - - /* we enable true gray for cis scanners only, and just when doing - * scan since color calibration is OK for this mode - */ - flags = 0; - - /* true gray (led add for cis scanners) */ - if(dev->model->is_cis && dev->settings.true_gray - && dev->settings.scan_mode != ScanColorMode::COLOR_SINGLE_PASS - && dev->model->ccd_type != CIS_CANONLIDE80) - { - // on Lide 80 the LEDADD bit results in only red LED array being lit - DBG(DBG_io, "%s: activating LEDADD\n", __func__); - flags |= SCAN_FLAG_ENABLE_LEDADD; - } - - /* enable emulated lineart from gray data */ - if(dev->settings.scan_mode == ScanColorMode::LINEART - && dev->settings.dynamic_lineart) - { - flags |= SCAN_FLAG_DYNAMIC_LINEART; - } - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; - params.starty = move; - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = flags; - - status = gl841_init_scan_regs(dev, sensor, &dev->reg, params); - - if (status != SANE_STATUS_GOOD) - return status; - - - DBG(DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; -} - -/* - * this function sends generic gamma table (ie linear ones) - * or the Sensor specific one if provided - */ -static SANE_Status -gl841_send_gamma_table(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int size; - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - - size = 256; - - /* allocate temporary gamma tables: 16 bits words, 3 channels */ - std::vector<uint8_t> gamma(size * 2 * 3); - - RIE(sanei_genesys_generate_gamma_buffer(dev, sensor, 16, 65535, size, gamma.data())); - - /* send address */ - status = gl841_set_buffer_address_gamma (dev, 0x00000); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* send data */ - status = sanei_genesys_bulk_write_data(dev, 0x28, gamma.data(), size * 2 * 3); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send gamma table: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* this function does the led calibration by scanning one line of the calibration - area below scanner's top on white strip. - --needs working coarse/gain -*/ -static SANE_Status -gl841_led_calibration (Genesys_Device * dev, Genesys_Sensor& sensor, Genesys_Register_Set& regs) -{ - int num_pixels; - int total_size; - int i, j; - SANE_Status status = SANE_STATUS_GOOD; - int val; - int channels; - int avg[3], avga, avge; - int turn; - uint16_t exp[3], target; - int move; - - SANE_Bool acceptable = SANE_FALSE; - - /* these 2 boundaries should be per sensor */ - uint16_t min_exposure=500; - uint16_t max_exposure; - - DBGSTART; - - /* feed to white strip if needed */ - if (dev->model->y_offset_calib>0) - { - move = SANE_UNFIX (dev->model->y_offset_calib); - move = (move * (dev->motor.base_ydpi)) / MM_PER_INCH; - DBG(DBG_io, "%s: move=%d lines\n", __func__, move); - status = gl841_feed(dev, move); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to feed: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - /* offset calibration is always done in color mode */ - channels = 3; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = (sensor.sensor_pixels*dev->settings.xres) / sensor.optical_res; - params.lines = 1; - params.depth = 16; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_USE_OPTICAL_RES; - - status = gl841_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - RIE(sanei_genesys_bulk_write_register(dev, regs)); - - num_pixels = dev->current_setup.pixels; - - total_size = num_pixels * channels * 2 * 1; /* colors * bytes_per_color * scan lines */ - - std::vector<uint8_t> line(total_size); - -/* - we try to get equal bright leds here: - - loop: - average per color - adjust exposure times - */ - - exp[0] = sensor.exposure.red; - exp[1] = sensor.exposure.green; - exp[2] = sensor.exposure.blue; - - turn = 0; - /* max exposure is set to ~2 time initial average - * exposure, or 2 time last calibration exposure */ - max_exposure=((exp[0]+exp[1]+exp[2])/3)*2; - target=sensor.gain_white_ref*256; - - do { - sensor.exposure.red = exp[0]; - sensor.exposure.green = exp[1]; - sensor.exposure.blue = exp[2]; - - sanei_genesys_set_exposure(regs, sensor.exposure); - RIE(sanei_genesys_write_register(dev, 0x10, (sensor.exposure.red >> 8) & 0xff)); - RIE(sanei_genesys_write_register(dev, 0x11, sensor.exposure.red & 0xff)); - RIE(sanei_genesys_write_register(dev, 0x12, (sensor.exposure.green >> 8) & 0xff)); - RIE(sanei_genesys_write_register(dev, 0x13, sensor.exposure.green & 0xff)); - RIE(sanei_genesys_write_register(dev, 0x14, (sensor.exposure.blue >> 8) & 0xff)); - RIE(sanei_genesys_write_register(dev, 0x15, sensor.exposure.blue & 0xff)); - - RIE(sanei_genesys_bulk_write_register(dev, regs)); - - DBG(DBG_info, "%s: starting line reading\n", __func__); - RIE(gl841_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) { - char fn[30]; - snprintf(fn, 30, "gl841_led_%d.pnm", turn); - sanei_genesys_write_pnm_file(fn, line.data(), 16, channels, num_pixels, 1); - } - - /* compute average */ - for (j = 0; j < channels; j++) - { - avg[j] = 0; - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * num_pixels + 1] * 256 + - line[i * 2 + j * 2 * num_pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - avg[j] += val; - } - - avg[j] /= num_pixels; - } - - DBG(DBG_info,"%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); - - acceptable = SANE_TRUE; - - /* exposure is acceptable if each color is in the %5 range - * of other color channels */ - if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 || - avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 || - avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95) - { - acceptable = SANE_FALSE; - } - - /* led exposure is not acceptable if white level is too low - * ~80 hardcoded value for white level */ - if(avg[0]<20000 || avg[1]<20000 || avg[2]<20000) - { - acceptable = SANE_FALSE; - } - - /* for scanners using target value */ - if(target>0) - { - acceptable = SANE_TRUE; - for(i=0;i<3;i++) - { - /* we accept +- 2% delta from target */ - if(abs(avg[i]-target)>target/50) - { - exp[i]=(exp[i]*target)/avg[i]; - acceptable = SANE_FALSE; - } - } - } - else - { - if (!acceptable) - { - avga = (avg[0]+avg[1]+avg[2])/3; - exp[0] = (exp[0] * avga) / avg[0]; - exp[1] = (exp[1] * avga) / avg[1]; - exp[2] = (exp[2] * avga) / avg[2]; - /* - keep the resulting exposures below this value. - too long exposure drives the ccd into saturation. - we may fix this by relying on the fact that - we get a striped scan without shading, by means of - statistical calculation - */ - avge = (exp[0] + exp[1] + exp[2]) / 3; - - if (avge > max_exposure) { - exp[0] = (exp[0] * max_exposure) / avge; - exp[1] = (exp[1] * max_exposure) / avge; - exp[2] = (exp[2] * max_exposure) / avge; - } - if (avge < min_exposure) { - exp[0] = (exp[0] * min_exposure) / avge; - exp[1] = (exp[1] * min_exposure) / avge; - exp[2] = (exp[2] * min_exposure) / avge; - } - - } - } - - RIE (gl841_stop_action (dev)); - - turn++; - - } while (!acceptable && turn < 100); - - DBG(DBG_info,"%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); - - gl841_slow_back_home(dev, SANE_TRUE); - - DBGCOMPLETED; - return status; -} - -/** @brief calibration for AD frontend devices - * offset calibration assumes that the scanning head is on a black area - * For LiDE80 analog frontend - * 0x0003 : is gain and belongs to [0..63] - * 0x0006 : is offset - * We scan a line with no gain until average offset reaches the target - */ -static SANE_Status -ad_fe_offset_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - int num_pixels; - int total_size; - int i; - int average; - int turn; - int top; - int bottom; - int target; - - DBGSTART; - - /* don't impact 3600 behavior since we can't test it */ - if (dev->model->ccd_type == CCD_PLUSTEK_3600) - { - DBGCOMPLETED; - return status; - } - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = (sensor.sensor_pixels*dev->settings.xres) / sensor.optical_res; - params.lines = 1; - params.depth = 8; - params.channels = 3; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_USE_OPTICAL_RES; - - status = gl841_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - num_pixels = dev->current_setup.pixels; - total_size = num_pixels * 3 * 2 * 1; - - std::vector<uint8_t> line(total_size); - - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - - /* loop on scan until target offset is reached */ - turn=0; - target=24; - bottom=0; - top=255; - do { - /* set up offset mid range */ - dev->frontend.set_offset(0, (top + bottom) / 2); - dev->frontend.set_offset(1, (top + bottom) / 2); - dev->frontend.set_offset(2, (top + bottom) / 2); - - /* scan line */ - DBG(DBG_info, "%s: starting line reading\n", __func__); - sanei_genesys_bulk_write_register(dev, regs); - gl841_set_fe(dev, sensor, AFE_SET); - gl841_begin_scan(dev, sensor, ®s, SANE_TRUE); - sanei_genesys_read_data_from_scanner(dev, line.data(), total_size); - gl841_stop_action (dev); - if (DBG_LEVEL >= DBG_data) { - char fn[30]; - snprintf(fn, 30, "gl841_offset_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, line.data(), 8, 3, num_pixels, 1); - } - - /* search for minimal value */ - average=0; - for(i=0;i<total_size;i++) - { - average+=line[i]; - } - average/=total_size; - DBG(DBG_data, "%s: average=%d\n", __func__, average); - - /* if min value is above target, the current value becomes the new top - * else it is the new bottom */ - if(average>target) - { - top=(top+bottom)/2; - } - else - { - bottom=(top+bottom)/2; - } - turn++; - } while ((top-bottom)>1 && turn < 100); - - // FIXME: don't overwrite the calibrated values - dev->frontend.set_offset(0, 0); - dev->frontend.set_offset(1, 0); - dev->frontend.set_offset(2, 0); - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - DBGCOMPLETED; - return status; -} - -/* this function does the offset calibration by scanning one line of the calibration - area below scanner's top. There is a black margin and the remaining is white. - sanei_genesys_search_start() must have been called so that the offsets and margins - are allready known. - -this function expects the slider to be where? -*/ -static SANE_Status -gl841_offset_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - int num_pixels; - int total_size; - int i, j; - SANE_Status status = SANE_STATUS_GOOD; - int val; - int channels; - int off[3],offh[3],offl[3],off1[3],off2[3]; - int min1[3],min2[3]; - int cmin[3],cmax[3]; - int turn; - SANE_Bool acceptable = SANE_FALSE; - int mintgt = 0x400; - - DBG(DBG_proc, "%s\n", __func__); - - /* Analog Device fronted have a different calibration */ - if ((dev->reg.find_reg(0x04).value & REG04_FESET) == 0x02) - { - return ad_fe_offset_calibration(dev, sensor, regs); - } - - /* offset calibration is always done in color mode */ - channels = 3; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = (sensor.sensor_pixels*dev->settings.xres) / sensor.optical_res; - params.lines = 1; - params.depth = 16; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_USE_OPTICAL_RES | - SCAN_FLAG_DISABLE_LAMP; - - status = gl841_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - num_pixels = dev->current_setup.pixels; - - total_size = num_pixels * channels * 2 * 1; /* colors * bytes_per_color * scan lines */ - - std::vector<uint8_t> first_line(total_size); - std::vector<uint8_t> second_line(total_size); - - /* scan first line of data with no offset nor gain */ -/*WM8199: gain=0.73; offset=-260mV*/ -/*okay. the sensor black level is now at -260mV. we only get 0 from AFE...*/ -/* we should probably do real calibration here: - * -detect acceptable offset with binary search - * -calculate offset from this last version - * - * acceptable offset means - * - few completely black pixels(<10%?) - * - few completely white pixels(<10%?) - * - * final offset should map the minimum not completely black - * pixel to 0(16 bits) - * - * this does account for dummy pixels at the end of ccd - * this assumes slider is at black strip(which is not quite as black as "no - * signal"). - * - */ - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - offh[0] = 0xff; - offh[1] = 0xff; - offh[2] = 0xff; - offl[0] = 0x00; - offl[1] = 0x00; - offl[2] = 0x00; - turn = 0; - - do { - - RIE(sanei_genesys_bulk_write_register(dev, regs)); - - for (j=0; j < channels; j++) { - off[j] = (offh[j]+offl[j])/2; - dev->frontend.set_offset(j, off[j]); - } - - status = gl841_set_fe(dev, sensor, AFE_SET); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_info, "%s: starting first line reading\n", __func__); - RIE(gl841_begin_scan(dev, sensor, ®s, SANE_TRUE)); - - RIE(sanei_genesys_read_data_from_scanner (dev, first_line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) { - char fn[30]; - snprintf(fn, 30, "gl841_offset1_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, first_line.data(), 16, channels, num_pixels, 1); - } - - acceptable = SANE_TRUE; - - for (j = 0; j < channels; j++) - { - cmin[j] = 0; - cmax[j] = 0; - - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - first_line[i * 2 + j * 2 * num_pixels + 1] * 256 + - first_line[i * 2 + j * 2 * num_pixels]; - else - val = - first_line[i * 2 * channels + 2 * j + 1] * 256 + - first_line[i * 2 * channels + 2 * j]; - if (val < 10) - cmin[j]++; - if (val > 65525) - cmax[j]++; - } - - /* TODO the DP685 has a black strip in the middle of the sensor - * should be handled in a more elegant way , could be a bug */ - if (dev->model->ccd_type == CCD_DP685) - cmin[j] -= 20; - - if (cmin[j] > num_pixels/100) { - acceptable = SANE_FALSE; - if (dev->model->is_cis) - offl[0] = off[0]; - else - offl[j] = off[j]; - } - if (cmax[j] > num_pixels/100) { - acceptable = SANE_FALSE; - if (dev->model->is_cis) - offh[0] = off[0]; - else - offh[j] = off[j]; - } - } - - DBG(DBG_info,"%s: black/white pixels: %d/%d,%d/%d,%d/%d\n", __func__, cmin[0], cmax[0], - cmin[1], cmax[1], cmin[2], cmax[2]); - - if (dev->model->is_cis) { - offh[2] = offh[1] = offh[0]; - offl[2] = offl[1] = offl[0]; - } - - RIE(gl841_stop_action(dev)); - - turn++; - } while (!acceptable && turn < 100); - - DBG(DBG_info,"%s: acceptable offsets: %d,%d,%d\n", __func__, off[0], off[1], off[2]); - - - for (j = 0; j < channels; j++) - { - off1[j] = off[j]; - - min1[j] = 65536; - - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - first_line[i * 2 + j * 2 * num_pixels + 1] * 256 + - first_line[i * 2 + j * 2 * num_pixels]; - else - val = - first_line[i * 2 * channels + 2 * j + 1] * 256 + - first_line[i * 2 * channels + 2 * j]; - if (min1[j] > val && val >= 10) - min1[j] = val; - } - } - - - offl[0] = off[0]; - offl[1] = off[0]; - offl[2] = off[0]; - turn = 0; - - do { - - for (j=0; j < channels; j++) { - off[j] = (offh[j]+offl[j])/2; - dev->frontend.set_offset(j, off[j]); - } - - status = gl841_set_fe(dev, sensor, AFE_SET); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(sanei_genesys_bulk_write_register(dev, regs)); - RIE(gl841_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, second_line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) { - char fn[30]; - snprintf(fn, 30, "gl841_offset2_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, second_line.data(), 16, channels, num_pixels, 1); - } - - acceptable = SANE_TRUE; - - for (j = 0; j < channels; j++) - { - cmin[j] = 0; - cmax[j] = 0; - - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - second_line[i * 2 + j * 2 * num_pixels + 1] * 256 + - second_line[i * 2 + j * 2 * num_pixels]; - else - val = - second_line[i * 2 * channels + 2 * j + 1] * 256 + - second_line[i * 2 * channels + 2 * j]; - if (val < 10) - cmin[j]++; - if (val > 65525) - cmax[j]++; - } - - if (cmin[j] > num_pixels/100) { - acceptable = SANE_FALSE; - if (dev->model->is_cis) - offl[0] = off[0]; - else - offl[j] = off[j]; - } - if (cmax[j] > num_pixels/100) { - acceptable = SANE_FALSE; - if (dev->model->is_cis) - offh[0] = off[0]; - else - offh[j] = off[j]; - } - } - - DBG(DBG_info, "%s: black/white pixels: %d/%d,%d/%d,%d/%d\n", __func__, cmin[0], cmax[0], - cmin[1], cmax[1], cmin[2], cmax[2]); - - if (dev->model->is_cis) { - offh[2] = offh[1] = offh[0]; - offl[2] = offl[1] = offl[0]; - } - - RIE(gl841_stop_action (dev)); - - turn++; - - } while (!acceptable && turn < 100); - - DBG(DBG_info, "%s: acceptable offsets: %d,%d,%d\n", __func__, off[0], off[1], off[2]); - - - for (j = 0; j < channels; j++) - { - off2[j] = off[j]; - - min2[j] = 65536; - - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - second_line[i * 2 + j * 2 * num_pixels + 1] * 256 + - second_line[i * 2 + j * 2 * num_pixels]; - else - val = - second_line[i * 2 * channels + 2 * j + 1] * 256 + - second_line[i * 2 * channels + 2 * j]; - if (min2[j] > val && val != 0) - min2[j] = val; - } - } - - DBG(DBG_info, "%s: first set: %d/%d,%d/%d,%d/%d\n", __func__, off1[0], min1[0], off1[1], min1[1], - off1[2], min1[2]); - - DBG(DBG_info, "%s: second set: %d/%d,%d/%d,%d/%d\n", __func__, off2[0], min2[0], off2[1], min2[1], - off2[2], min2[2]); - -/* - calculate offset for each channel - based on minimal pixel value min1 at offset off1 and minimal pixel value min2 - at offset off2 - - to get min at off, values are linearly interpolated: - min=real+off*fact - min1=real+off1*fact - min2=real+off2*fact - - fact=(min1-min2)/(off1-off2) - real=min1-off1*(min1-min2)/(off1-off2) - - off=(min-min1+off1*(min1-min2)/(off1-off2))/((min1-min2)/(off1-off2)) - - off=(min*(off1-off2)+min1*off2-off1*min2)/(min1-min2) - - */ - for (j = 0; j < channels; j++) - { - if (min2[j]-min1[j] == 0) { -/*TODO: try to avoid this*/ - DBG(DBG_warn, "%s: difference too small\n", __func__); - if (mintgt * (off1[j] - off2[j]) + min1[j] * off2[j] - min2[j] * off1[j] >= 0) - off[j] = 0x0000; - else - off[j] = 0xffff; - } else - off[j] = (mintgt * (off1[j] - off2[j]) + min1[j] * off2[j] - min2[j] * off1[j])/(min1[j]-min2[j]); - if (off[j] > 255) - off[j] = 255; - if (off[j] < 0) - off[j] = 0; - dev->frontend.set_offset(j, off[j]); - } - - DBG(DBG_info, "%s: final offsets: %d,%d,%d\n", __func__, off[0], off[1], off[2]); - - if (dev->model->is_cis) { - if (off[0] < off[1]) - off[0] = off[1]; - if (off[0] < off[2]) - off[0] = off[2]; - dev->frontend.set_offset(0, off[0]); - dev->frontend.set_offset(1, off[0]); - dev->frontend.set_offset(2, off[0]); - } - - if (channels == 1) - { - dev->frontend.set_offset(1, dev->frontend.get_offset(0)); - dev->frontend.set_offset(2, dev->frontend.get_offset(0)); - } - - DBG(DBG_proc, "%s: completed\n", __func__); - return status; -} - - -/* alternative coarse gain calibration - this on uses the settings from offset_calibration and - uses only one scanline - */ -/* - with offset and coarse calibration we only want to get our input range into - a reasonable shape. the fine calibration of the upper and lower bounds will - be done with shading. - */ -static SANE_Status -gl841_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi) -{ - int num_pixels; - int total_size; - int i, j, channels; - SANE_Status status = SANE_STATUS_GOOD; - int max[3]; - float gain[3]; - int val; - int lines=1; - int move; - - DBG(DBG_proc, "%s: dpi=%d\n", __func__, dpi); - - /* feed to white strip if needed */ - if (dev->model->y_offset_calib>0) - { - move = SANE_UNFIX (dev->model->y_offset_calib); - move = (move * (dev->motor.base_ydpi)) / MM_PER_INCH; - DBG(DBG_io, "%s: move=%d lines\n", __func__, move); - status = gl841_feed(dev, move); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to feed: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - /* coarse gain calibration is allways done in color mode */ - channels = 3; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = (sensor.sensor_pixels*dev->settings.xres) / sensor.optical_res; - params.lines = lines; - params.depth = 16; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_USE_OPTICAL_RES; - - status = gl841_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - RIE(sanei_genesys_bulk_write_register(dev, regs)); - - num_pixels = dev->current_setup.pixels; - - total_size = num_pixels * channels * 2 * lines; /* colors * bytes_per_color * scan lines */ - - std::vector<uint8_t> line(total_size); - - RIE(gl841_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl841_gain.pnm", line.data(), 16, channels, num_pixels, lines); - - /* average high level for each channel and compute gain - to reach the target code - we only use the central half of the CCD data */ - for (j = 0; j < channels; j++) - { - max[j] = 0; - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * num_pixels + 1] * 256 + - line[i * 2 + j * 2 * num_pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - - if (val > max[j]) - max[j] = val; - } - - gain[j] = 65535.0/max[j]; - - uint8_t out_gain = 0; - - if (dev->model->dac_type == DAC_CANONLIDE35 || - dev->model->dac_type == DAC_WOLFSON_XP300 || - dev->model->dac_type == DAC_WOLFSON_DSM600) - { - gain[j] *= 0.69;/*seems we don't get the real maximum. empirically derived*/ - if (283 - 208/gain[j] > 255) - out_gain = 255; - else if (283 - 208/gain[j] < 0) - out_gain = 0; - else - out_gain = 283 - 208/gain[j]; - } - else if (dev->model->dac_type == DAC_CANONLIDE80) - { - out_gain = gain[j]*12; - } - dev->frontend.set_gain(j, out_gain); - - DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], - out_gain); - } - - for (j = 0; j < channels; j++) - { - if(gain[j] > 10) - { - DBG (DBG_error0, "**********************************************\n"); - DBG (DBG_error0, "**********************************************\n"); - DBG (DBG_error0, "**** ****\n"); - DBG (DBG_error0, "**** Extremely low Brightness detected. ****\n"); - DBG (DBG_error0, "**** Check the scanning head is ****\n"); - DBG (DBG_error0, "**** unlocked and moving. ****\n"); - DBG (DBG_error0, "**** ****\n"); - DBG (DBG_error0, "**********************************************\n"); - DBG (DBG_error0, "**********************************************\n"); - return SANE_STATUS_JAMMED; - } - - } - - if (dev->model->is_cis) { - uint8_t gain0 = dev->frontend.get_gain(0); - if (gain0 > dev->frontend.get_gain(1)) { - gain0 = dev->frontend.get_gain(1); - } - if (gain0 > dev->frontend.get_gain(2)) { - gain0 = dev->frontend.get_gain(2); - } - dev->frontend.set_gain(0, gain0); - dev->frontend.set_gain(1, gain0); - dev->frontend.set_gain(2, gain0); - } - - if (channels == 1) { - dev->frontend.set_gain(0, dev->frontend.get_gain(1)); - dev->frontend.set_gain(2, dev->frontend.get_gain(1)); - } - - DBG(DBG_info, "%s: gain=(%d,%d,%d)\n", __func__, - dev->frontend.get_gain(0), - dev->frontend.get_gain(1), - dev->frontend.get_gain(2)); - - RIE (gl841_stop_action (dev)); - - gl841_slow_back_home(dev, SANE_TRUE); - - DBGCOMPLETED; - return status; -} - -/* - * wait for lamp warmup by scanning the same line until difference - * between 2 scans is below a threshold - */ -static SANE_Status -gl841_init_regs_for_warmup (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * local_reg, - int *channels, int *total_size) -{ - int num_pixels = (int) (4 * 300); - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s\n", __func__); - - *local_reg = dev->reg; - -/* okay.. these should be defaults stored somewhere */ - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - dev->frontend.set_offset(0, 0x80); - dev->frontend.set_offset(1, 0x80); - dev->frontend.set_offset(2, 0x80); - - SetupParams params; - params.xres = sensor.optical_res; - params.yres = dev->settings.yres; - params.startx = sensor.dummy_pixel; - params.starty = 0; - params.pixels = num_pixels; - params.lines = 1; - params.depth = 16; - params.channels = *channels; - params.scan_method = dev->settings.scan_method; - if (*channels == 3) { - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - } else { - params.scan_mode = ScanColorMode::GRAY; - } - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_USE_OPTICAL_RES; - - status = gl841_init_scan_regs(dev, sensor, local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - num_pixels = dev->current_setup.pixels; - - *total_size = num_pixels * 3 * 2 * 1; /* colors * bytes_per_color * scan lines */ - - RIE(sanei_genesys_bulk_write_register(dev, *local_reg)); - - return status; -} - - -/* - * this function moves head without scanning, forward, then backward - * so that the head goes to park position. - * as a by-product, also check for lock - */ -static SANE_Status -sanei_gl841_repark_head (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s\n", __func__); - - status = gl841_feed(dev,232); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to feed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* toggle motor flag, put an huge step number and redo move backward */ - status = gl841_slow_back_home (dev, SANE_TRUE); - DBG(DBG_proc, "%s: completed\n", __func__); - return status; -} - -static bool -gl841_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Calibration_Cache *cache, - int for_overwrite) -{ -#ifdef HAVE_SYS_TIME_H - struct timeval time; -#endif - - DBGSTART; - - /* calibration cache not working yet for this model */ - if (dev->model->ccd_type == CCD_PLUSTEK_3600) - { - return false; - } - - gl841_calculate_current_setup (dev, sensor); - - DBG(DBG_proc, "%s: checking\n", __func__); - - if (dev->current_setup.ccd_size_divisor != cache->used_setup.ccd_size_divisor) - return false; - - /* a cache entry expires after 30 minutes for non sheetfed scanners */ - /* this is not taken into account when overwriting cache entries */ -#ifdef HAVE_SYS_TIME_H - if(for_overwrite == SANE_FALSE) - { - gettimeofday (&time, NULL); - if ((time.tv_sec - cache->last_calibration > 30 * 60) - && (dev->model->is_sheetfed == SANE_FALSE)) - { - DBG(DBG_proc, "%s: expired entry, non compatible cache\n", __func__); - return false; - } - } -#endif - - DBGCOMPLETED; - return true; -} - -/* - * initialize ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home - */ -static SANE_Status -gl841_init (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - size_t size; - - DBG_INIT (); - DBGSTART; - - dev->scanhead_position_in_steps = 0; - - /* Check if the device has already been initialized and powered up */ - if (dev->already_initialized) - { - RIE (sanei_genesys_get_status (dev, &val)); - if (val & REG41_PWRBIT) - { - DBG(DBG_info, "%s: already initialized\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - } - - dev->dark_average_data.clear(); - dev->white_average_data.clear(); - - dev->settings.color_filter = ColorFilter::RED; - - /* ASIC reset */ - RIE (sanei_genesys_write_register (dev, 0x0e, 0x01)); - RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); - - /* Set default values for registers */ - gl841_init_registers (dev); - - /* Write initial registers */ - RIE(sanei_genesys_bulk_write_register(dev, dev->reg)); - - /* Test ASIC and RAM */ - if (!(dev->model->flags & GENESYS_FLAG_LAZY_INIT)) - { - RIE (sanei_gl841_asic_test (dev)); - } - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - /* Set analog frontend */ - RIE (gl841_set_fe(dev, sensor, AFE_INIT)); - - /* Move home */ - RIE (gl841_slow_back_home (dev, SANE_TRUE)); - - /* Init shading data */ - RIE (sanei_genesys_init_shading_data(dev, sensor, sensor.sensor_pixels)); - - /* ensure head is correctly parked, and check lock */ - if (dev->model->flags & GENESYS_FLAG_REPARK) - { - status = sanei_gl841_repark_head (dev); - if (status != SANE_STATUS_GOOD) - { - if (status == SANE_STATUS_INVAL) - DBG(DBG_error0, "Your scanner is locked. Please move the lock switch to the unlocked " - "position\n"); - else - DBG(DBG_error, "%s: sanei_gl841_repark_head failed: %s\n", __func__, - sane_strstatus(status)); - return status; - } - } - - /* send gamma tables */ - status = gl841_send_gamma_table(dev, sensor); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send initial gamma tables: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* initial calibration reg values */ - Genesys_Register_Set& regs = dev->calib_reg; - regs = dev->reg; - - SetupParams params; - params.xres = 300; - params.yres = 300; - params.startx = 0; - params.starty = 0; - params.pixels = (16 * 300) / sensor.optical_res; - params.lines = 1; - params.depth = 16; - params.channels = 3; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_USE_OPTICAL_RES; - - status = gl841_init_scan_regs(dev, sensor, ®s, params); - - RIE(sanei_genesys_bulk_write_register(dev, regs)); - - size = dev->current_setup.pixels * 3 * 2 * 1; /* colors * bytes_per_color * scan lines */ - - std::vector<uint8_t> line(size); - - DBG(DBG_info, "%s: starting dummy data reading\n", __func__); - RIE(gl841_begin_scan(dev, sensor, ®s, SANE_TRUE)); - - sanei_usb_set_timeout(1000);/* 1 second*/ - -/*ignore errors. next read will succeed*/ - sanei_genesys_read_data_from_scanner(dev, line.data(), size); - - sanei_usb_set_timeout(30 * 1000);/* 30 seconds*/ - - RIE (gl841_end_scan(dev, ®s, SANE_TRUE)); - - regs = dev->reg; - - /* Set powersaving (default = 15 minutes) */ - RIE (gl841_set_powersaving (dev, 15)); - dev->already_initialized = SANE_TRUE; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl841_update_hardware_sensors (Genesys_Scanner * s) -{ - /* do what is needed to get a new set of events, but try to not lose - any of them. - */ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - if (s->dev->model->gpo_type == GPO_CANONLIDE35 - || s->dev->model->gpo_type == GPO_CANONLIDE80) - { - RIE(sanei_genesys_read_register(s->dev, REG6D, &val)); - s->buttons[BUTTON_SCAN_SW].write((val & 0x01) == 0); - s->buttons[BUTTON_FILE_SW].write((val & 0x02) == 0); - s->buttons[BUTTON_EMAIL_SW].write((val & 0x04) == 0); - s->buttons[BUTTON_COPY_SW].write((val & 0x08) == 0); - } - - if (s->dev->model->gpo_type == GPO_XP300 || - s->dev->model->gpo_type == GPO_DP665 || - s->dev->model->gpo_type == GPO_DP685) - { - RIE(sanei_genesys_read_register(s->dev, REG6D, &val)); - - s->buttons[BUTTON_PAGE_LOADED_SW].write((val & 0x01) == 0); - s->buttons[BUTTON_SCAN_SW].write((val & 0x02) == 0); - } - - return status; -} - -/** @brief search for a full width black or white strip. - * This function searches for a black or white stripe across the scanning area. - * When searching backward, the searched area must completely be of the desired - * color since this area will be used for calibration which scans forward. - * @param dev scanner device - * @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward - * @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip - * @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not - */ -static SANE_Status -gl841_search_strip(Genesys_Device * dev, const Genesys_Sensor& sensor, - SANE_Bool forward, SANE_Bool black) -{ - unsigned int pixels, lines, channels; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - size_t size; - int steps, depth, dpi; - unsigned int pass, count, found, x, y, length; - char title[80]; - GenesysRegister *r; - uint8_t white_level=90; /**< default white level to detect white dots */ - uint8_t black_level=60; /**< default black level to detect black dots */ - - DBG(DBG_proc, "%s %s %s\n", __func__, black ? "black" : "white", forward ? "forward" : "reverse"); - - /* use maximum gain when doing forward white strip detection - * since we don't have calibrated the sensor yet */ - if(!black && forward) - { - dev->frontend.set_gain(0, 0xff); - dev->frontend.set_gain(1, 0xff); - dev->frontend.set_gain(2, 0xff); - } - - gl841_set_fe(dev, sensor, AFE_SET); - status = gl841_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* set up for a gray scan at lowest dpi */ - dpi = 9600; - for (x = 0; x < MAX_RESOLUTIONS; x++) - { - if (dev->model->xdpi_values[x] > 0 && dev->model->xdpi_values[x] < dpi) - dpi = dev->model->xdpi_values[x]; - } - channels = 1; - - /* shading calibation is done with dev->motor.base_ydpi */ - /* lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; */ - lines = (10*dpi)/MM_PER_INCH; - - depth = 8; - pixels = (sensor.sensor_pixels * dpi) / sensor.optical_res; - size = pixels * channels * lines * (depth / 8); - std::vector<uint8_t> data(size); - - /* 20 cm max length for calibration sheet */ - length = ((200 * dpi) / MM_PER_INCH)/lines; - - dev->scanhead_position_in_steps = 0; - - local_reg = dev->reg; - - SetupParams params; - params.xres = dpi; - params.yres = dpi; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_GAMMA; - - status = gl841_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup for scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* set up for reverse or forward */ - r = sanei_genesys_get_address(&local_reg, 0x02); - if (forward) - r->value &= ~4; - else - r->value |= 4; - - - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl841_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl841_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl841_stop_action failed\n", __func__); - return status; - } - - pass = 0; - if (DBG_LEVEL >= DBG_data) - { - sprintf(title, "gl841_search_strip_%s_%s%02u.pnm", black ? "black" : "white", - forward ? "fwd" : "bwd", pass); - sanei_genesys_write_pnm_file(title, data.data(), depth, channels, pixels, lines); - } - - /* loop until strip is found or maximum pass number done */ - found = 0; - while (pass < length && !found) - { - status = sanei_genesys_bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* now start scan */ - status = gl841_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error,"%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner (dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "g%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl841_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl841_stop_action failed\n", __func__); - return status; - } - - if (DBG_LEVEL >= DBG_data) - { - sprintf(title, "gl841_search_strip_%s_%s%02u.pnm", - black ? "black" : "white", forward ? "fwd" : "bwd", pass); - sanei_genesys_write_pnm_file(title, data.data(), depth, channels, pixels, lines); - } - - /* search data to find black strip */ - /* when searching forward, we only need one line of the searched color since we - * will scan forward. But when doing backward search, we need all the area of the - * same color */ - if (forward) - { - for (y = 0; y < lines && !found; y++) - { - count = 0; - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > white_level) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < black_level) - { - count++; - } - } - - /* at end of line, if count >= 3%, line is not fully of the desired color - * so we must go to next line of the buffer */ - /* count*100/pixels < 3 */ - if ((count * 100) / pixels < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, - pass, y); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - } - else /* since calibration scans are done forward, we need the whole area - to be of the required color when searching backward */ - { - count = 0; - for (y = 0; y < lines; y++) - { - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > white_level) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < black_level) - { - count++; - } - } - } - - /* at end of area, if count >= 3%, area is not fully of the desired color - * so we must go to next buffer */ - if ((count * 100) / (pixels * lines) < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - pass++; - } - - if (found) - { - status = SANE_STATUS_GOOD; - DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); - } - else - { - status = SANE_STATUS_UNSUPPORTED; - DBG(DBG_info, "%s: %s strip not found\n", __func__, black ? "black" : "white"); - } - - DBG(DBG_proc, "%s: completed\n", __func__); - return status; -} - -/** - * Send shading calibration data. The buffer is considered to always hold values - * for all the channels. - */ -static -SANE_Status -gl841_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint32_t length, x, factor, pixels, i; - uint32_t lines, channels; - uint16_t dpiset, dpihw, strpixel ,endpixel, beginpixel; - uint8_t *ptr,*src; - - DBGSTART; - DBG(DBG_io2, "%s: writing %d bytes of shading data\n", __func__, size); - - /* old method if no SHDAREA */ - if((dev->reg.find_reg(0x01).value & REG01_SHDAREA) == 0) - { - /* start address */ - status = sanei_genesys_set_buffer_address (dev, 0x0000); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* shading data whole line */ - status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, data, size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading table: %s\n", __func__, - sane_strstatus(status)); - return status; - } - DBGCOMPLETED; - return status; - } - - /* data is whole line, we extract only the part for the scanned area */ - length = (uint32_t) (size / 3); - sanei_genesys_get_double(&dev->reg,REG_STRPIXEL,&strpixel); - sanei_genesys_get_double(&dev->reg,REG_ENDPIXEL,&endpixel); - DBG(DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d\n", __func__, strpixel, endpixel, - endpixel-strpixel); - - /* compute deletion/average factor */ - sanei_genesys_get_double(&dev->reg,REG_DPISET,&dpiset); - dpihw = gl841_get_dpihw(dev); - unsigned ccd_size_divisor = dev->current_setup.ccd_size_divisor; - factor=dpihw/dpiset; - DBG(DBG_io2, "%s: dpihw=%d, dpiset=%d, ccd_size_divisor=%d, factor=%d\n", __func__, dpihw, dpiset, - ccd_size_divisor, factor); - - /* binary data logging */ - if(DBG_LEVEL>=DBG_data) - { - dev->binary=fopen("binary.pnm","wb"); - sanei_genesys_get_triple(&dev->reg, REG_LINCNT, &lines); - channels=dev->current_setup.channels; - if(dev->binary!=NULL) - { - fprintf(dev->binary,"P5\n%d %d\n%d\n",(endpixel-strpixel)/factor*channels,lines/channels,255); - } - } - - /* turn pixel value into bytes 2x16 bits words */ - strpixel*=2*2; /* 2 words of 2 bytes */ - endpixel*=2*2; - pixels=endpixel-strpixel; - - /* shading pixel begin is start pixel minus start pixel during shading - * calibration. Currently only cases handled are full and half ccd resolution. - */ - beginpixel = sensor.CCD_start_xoffset / ccd_size_divisor; - beginpixel += sensor.dummy_pixel + 1; - DBG(DBG_io2, "%s: ORIGIN PIXEL=%d\n", __func__, beginpixel); - beginpixel = (strpixel-beginpixel*2*2)/factor; - DBG(DBG_io2, "%s: BEGIN PIXEL=%d\n", __func__, beginpixel/4); - - DBG(DBG_io2, "%s: using chunks of %d bytes (%d shading data pixels)\n", __func__, length, - length/4); - std::vector<uint8_t> buffer(pixels, 0); - - /* write actual shading data contigously - * channel by channel, starting at addr 0x0000 - * */ - for(i=0;i<3;i++) - { - /* copy data to work buffer and process it */ - /* coefficent destination */ - ptr=buffer.data(); - - /* iterate on both sensor segment, data has been averaged, - * so is in the right order and we only have to copy it */ - for(x=0;x<pixels;x+=4) - { - /* coefficient source */ - src=data+x+beginpixel+i*length; - ptr[0]=src[0]; - ptr[1]=src[1]; - ptr[2]=src[2]; - ptr[3]=src[3]; - - /* next shading coefficient */ - ptr+=4; - } - - /* 0x5400 alignment for LIDE80 internal memory */ - RIE(sanei_genesys_set_buffer_address(dev, 0x5400*i)); - RIE(dev->model->cmd_set->bulk_write_data(dev, 0x3c, buffer.data(), pixels)); - } - - DBGCOMPLETED; - - return status; -} - - -/** the gl841 command set */ -static Genesys_Command_Set gl841_cmd_set = { - "gl841-generic", /* the name of this set */ - - [](Genesys_Device* dev) -> bool { (void) dev; return true; }, - - gl841_init, - gl841_init_regs_for_warmup, - gl841_init_regs_for_coarse_calibration, - gl841_init_regs_for_shading, - gl841_init_regs_for_scan, - - gl841_get_filter_bit, - gl841_get_lineart_bit, - gl841_get_bitset_bit, - gl841_get_gain4_bit, - gl841_get_fast_feed_bit, - gl841_test_buffer_empty_bit, - gl841_test_motor_flag_bit, - - gl841_set_fe, - gl841_set_powersaving, - gl841_save_power, - - gl841_begin_scan, - gl841_end_scan, - - gl841_send_gamma_table, - - gl841_search_start_position, - - gl841_offset_calibration, - gl841_coarse_gain_calibration, - gl841_led_calibration, - - NULL, - gl841_slow_back_home, - NULL, - - sanei_genesys_bulk_write_register, - sanei_genesys_bulk_write_data, - sanei_genesys_bulk_read_data, - - gl841_update_hardware_sensors, - - gl841_load_document, - gl841_detect_document_end, - gl841_eject_document, - gl841_search_strip, - - gl841_is_compatible_calibration, - NULL, - gl841_send_shading_data, - gl841_calculate_current_setup, - NULL -}; - -SANE_Status -sanei_gl841_init_cmd_set (Genesys_Device * dev) -{ - dev->model->cmd_set = &gl841_cmd_set; - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_gl841.h b/backend/genesys_gl841.h deleted file mode 100644 index 3dbfc80..0000000 --- a/backend/genesys_gl841.h +++ /dev/null @@ -1,265 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2011-2013 Stéphane Voltz <stef.dev@free.fr> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#include "genesys.h" - -/* Individual bits */ -#define REG01 0x01 -#define REG01_CISSET 0x80 -#define REG01_DOGENB 0x40 -#define REG01_DVDSET 0x20 -#define REG01_M16DRAM 0x08 -#define REG01_DRAMSEL 0x04 -#define REG01_SHDAREA 0x02 -#define REG01_SCAN 0x01 - -#define REG02 0x02 -#define REG02_NOTHOME 0x80 -#define REG02_ACDCDIS 0x40 -#define REG02_AGOHOME 0x20 -#define REG02_MTRPWR 0x10 -#define REG02_FASTFED 0x08 -#define REG02_MTRREV 0x04 -#define REG02_HOMENEG 0x02 -#define REG02_LONGCURV 0x01 - -#define REG03_LAMPDOG 0x80 -#define REG03_AVEENB 0x40 -#define REG03_XPASEL 0x20 -#define REG03_LAMPPWR 0x10 -#define REG03_LAMPTIM 0x0f - -#define REG04_LINEART 0x80 -#define REG04_BITSET 0x40 -#define REG04_AFEMOD 0x30 -#define REG04_FILTER 0x0c -#define REG04_FESET 0x03 - -#define REG04S_AFEMOD 4 - -#define REG05_DPIHW 0xc0 -#define REG05_DPIHW_600 0x00 -#define REG05_DPIHW_1200 0x40 -#define REG05_DPIHW_2400 0x80 -#define REG05_MTLLAMP 0x30 -#define REG05_GMMENB 0x08 -#define REG05_MTLBASE 0x03 - -#define REG06_SCANMOD 0xe0 -#define REG06S_SCANMOD 5 -#define REG06_PWRBIT 0x10 -#define REG06_GAIN4 0x08 -#define REG06_OPTEST 0x07 - -#define REG07_SRAMSEL 0x08 -#define REG07_FASTDMA 0x04 -#define REG07_DMASEL 0x02 -#define REG07_DMARDWR 0x01 - -#define REG08_DECFLAG 0x40 -#define REG08_GMMFFR 0x20 -#define REG08_GMMFFG 0x10 -#define REG08_GMMFFB 0x08 -#define REG08_GMMZR 0x04 -#define REG08_GMMZG 0x02 -#define REG08_GMMZB 0x01 - -#define REG09_MCNTSET 0xc0 -#define REG09_CLKSET 0x30 -#define REG09_BACKSCAN 0x08 -#define REG09_ENHANCE 0x04 -#define REG09_SHORTTG 0x02 -#define REG09_NWAIT 0x01 - -#define REG09S_MCNTSET 6 -#define REG09S_CLKSET 4 - - -#define REG0A_SRAMBUF 0x01 - -#define REG0D 0x0d -#define REG0D_CLRLNCNT 0x01 - -#define REG16_CTRLHI 0x80 -#define REG16_TOSHIBA 0x40 -#define REG16_TGINV 0x20 -#define REG16_CK1INV 0x10 -#define REG16_CK2INV 0x08 -#define REG16_CTRLINV 0x04 -#define REG16_CKDIS 0x02 -#define REG16_CTRLDIS 0x01 - -#define REG17_TGMODE 0xc0 -#define REG17_TGMODE_NO_DUMMY 0x00 -#define REG17_TGMODE_REF 0x40 -#define REG17_TGMODE_XPA 0x80 -#define REG17_TGW 0x3f -#define REG17S_TGW 0 - -#define REG18_CNSET 0x80 -#define REG18_DCKSEL 0x60 -#define REG18_CKTOGGLE 0x10 -#define REG18_CKDELAY 0x0c -#define REG18_CKSEL 0x03 - -#define REG1A_MANUAL3 0x02 -#define REG1A_MANUAL1 0x01 -#define REG1A_CK4INV 0x08 -#define REG1A_CK3INV 0x04 -#define REG1A_LINECLP 0x02 - -#define REG1C_TGTIME 0x07 - -#define REG1D_CK4LOW 0x80 -#define REG1D_CK3LOW 0x40 -#define REG1D_CK1LOW 0x20 -#define REG1D_TGSHLD 0x1f -#define REG1DS_TGSHLD 0 - - -#define REG1E 0x1e -#define REG1E_WDTIME 0xf0 -#define REG1ES_WDTIME 4 -#define REG1E_LINESEL 0x0f -#define REG1ES_LINESEL 0 - -#define REG_EXPR 0x10 -#define REG_EXPG 0x12 -#define REG_EXPB 0x14 -#define REG_STEPNO 0x21 -#define REG_FWDSTEP 0x22 -#define REG_BWDSTEP 0x23 -#define REG_FASTNO 0x24 -#define REG_LINCNT 0x25 -#define REG_DPISET 0x2c -#define REG_STRPIXEL 0x30 -#define REG_ENDPIXEL 0x32 -#define REG_LPERIOD 0x38 - -#define REG40_HISPDFLG 0x04 -#define REG40_MOTMFLG 0x02 -#define REG40_DATAENB 0x01 - -#define REG41_PWRBIT 0x80 -#define REG41_BUFEMPTY 0x40 -#define REG41_FEEDFSH 0x20 -#define REG41_SCANFSH 0x10 -#define REG41_HOMESNR 0x08 -#define REG41_LAMPSTS 0x04 -#define REG41_FEBUSY 0x02 -#define REG41_MOTORENB 0x01 - -#define REG58_VSMP 0xf8 -#define REG58S_VSMP 3 -#define REG58_VSMPW 0x07 -#define REG58S_VSMPW 0 - -#define REG59_BSMP 0xf8 -#define REG59S_BSMP 3 -#define REG59_BSMPW 0x07 -#define REG59S_BSMPW 0 - -#define REG5A_ADCLKINV 0x80 -#define REG5A_RLCSEL 0x40 -#define REG5A_CDSREF 0x30 -#define REG5AS_CDSREF 4 -#define REG5A_RLC 0x0f -#define REG5AS_RLC 0 - -#define REG5E_DECSEL 0xe0 -#define REG5ES_DECSEL 5 -#define REG5E_STOPTIM 0x1f -#define REG5ES_STOPTIM 0 - -#define REG60_ZIMOD 0x1f -#define REG61_Z1MOD 0xff -#define REG62_Z1MOD 0xff - -#define REG63_Z2MOD 0x1f -#define REG64_Z2MOD 0xff -#define REG65_Z2MOD 0xff - -#define REG67_STEPSEL 0xc0 -#define REG67_FULLSTEP 0x00 -#define REG67_HALFSTEP 0x40 -#define REG67_QUATERSTEP 0x80 -#define REG67_MTRPWM 0x3f - -#define REG68_FSTPSEL 0xc0 -#define REG68_FULLSTEP 0x00 -#define REG68_HALFSTEP 0x40 -#define REG68_QUATERSTEP 0x80 -#define REG68_FASTPWM 0x3f - -#define REG6B_MULTFILM 0x80 -#define REG6B_GPOM13 0x40 -#define REG6B_GPOM12 0x20 -#define REG6B_GPOM11 0x10 -#define REG6B_GPO18 0x02 -#define REG6B_GPO17 0x01 - -#define REG6B 0x6b - -#define REG6C 0x6c -#define REG6C_GPIOH 0xff -#define REG6C_GPIOL 0xff - -#define REG6D 0x6d -#define REG6E 0x6e -#define REG6F 0x6f - -#define REG87_LEDADD 0x04 - -#define INITREG(adr,val) {dev->reg.init_reg(adr, val); } - -/** - * prototypes declaration in case of unit testing - */ - -static -int gl841_exposure_time(Genesys_Device *dev, const Genesys_Sensor& sensor, - float slope_dpi, - int scan_step_type, - int start, - int used_pixels, - int *scan_power_mode); diff --git a/backend/genesys_gl843.cc b/backend/genesys_gl843.cc deleted file mode 100644 index a72dc5a..0000000 --- a/backend/genesys_gl843.cc +++ /dev/null @@ -1,4415 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> - - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#define DEBUG_DECLARE_ONLY - -#include "genesys_gl843.h" - -#include <string> -#include <vector> - -/**************************************************************************** - Low level function - ****************************************************************************/ - -/* ------------------------------------------------------------------------ */ -/* Read and write RAM, registers and AFE */ -/* ------------------------------------------------------------------------ */ - -/* Set address for writing data */ -static SANE_Status -gl843_set_buffer_address (Genesys_Device * dev, uint32_t addr) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_io, "%s: setting address to 0x%05x\n", __func__, addr & 0xffff); - - status = sanei_genesys_write_register (dev, 0x5b, ((addr >> 8) & 0xff)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while writing high byte: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = sanei_genesys_write_register (dev, 0x5c, (addr & 0xff)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while writing low byte: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_io, "%s: completed\n", __func__); - - return status; -} - -/** - * writes a block of data to RAM - * @param dev USB device - * @param addr RAM address to write to - * @param size size of the chunk of data - * @param data pointer to the data to write - */ -static SANE_Status -write_data (Genesys_Device * dev, uint32_t addr, uint32_t size, - uint8_t * data) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - - status = gl843_set_buffer_address (dev, addr); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while setting address for bulk write data: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* write actual data */ - status = sanei_genesys_bulk_write_data(dev, 0x28, data, size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while writing bulk write data: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* set back address to 0 */ - status = gl843_set_buffer_address (dev, 0); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed setting to default RAM address: %s\n", __func__, - sane_strstatus(status)); - return status; - } - DBGCOMPLETED; - return status; -} - -/**************************************************************************** - Mid level functions - ****************************************************************************/ - -static SANE_Bool -gl843_get_fast_feed_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG02); - if (r && (r->value & REG02_FASTFED)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl843_get_filter_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_FILTER)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl843_get_lineart_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_LINEART)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl843_get_bitset_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_BITSET)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl843_get_gain4_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG06); - if (r && (r->value & REG06_GAIN4)) - return SANE_TRUE; - return SANE_FALSE; -} - -/** - * compute the step multiplier used - */ -static int -gl843_get_step_multiplier (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - int value = 1; - - r = sanei_genesys_get_address (regs, REG9D); - if (r != NULL) - { - switch (r->value & 0x0c) - { - case 0x04: - value = 2; - break; - case 0x08: - value = 4; - break; - default: - value = 1; - } - } - DBG(DBG_io, "%s: step multiplier is %d\n", __func__, value); - return value; -} - -static SANE_Bool -gl843_test_buffer_empty_bit (SANE_Byte val) -{ - if (val & REG41_BUFEMPTY) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl843_test_motor_flag_bit (SANE_Byte val) -{ - if (val & REG41_MOTORENB) - return SANE_TRUE; - return SANE_FALSE; -} - -/** copy sensor specific settings */ -static void -gl843_setup_sensor (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, int dpi,int flags) -{ - (void) dpi; - (void) flags; - - DBGSTART; - - for (const auto& custom_reg : sensor.custom_regs) { - regs->set8(custom_reg.address, custom_reg.value); - } - if (!(dev->model->flags & GENESYS_FLAG_FULL_HWDPI_MODE)) { - regs->set8(0x7d, 0x90); - } - - DBGCOMPLETED; -} - - -/** @brief set all registers to default values . - * This function is called only once at the beginning and - * fills register startup values for registers reused across scans. - * Those that are rarely modified or not modified are written - * individually. - * @param dev device structure holding register set to initialize - */ -static void -gl843_init_registers (Genesys_Device * dev) -{ - // Within this function SENSOR_DEF marker documents that a register is part - // of the sensors definition and the actual value is set in - // gl843_setup_sensor(). - - DBGSTART; - - dev->reg.clear(); - - /* default to KV-SS080 */ - SETREG (0xa2, 0x0f); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0xa2, 0x1f); - } - SETREG (0x01, 0x00); - SETREG (0x02, 0x78); - SETREG (0x03, 0x1f); - SETREG (0x04, 0x10); - - // fine tune upon device description - SETREG (0x05, 0x80); - if (dev->model->model_id == MODEL_HP_SCANJET_G4010 || - dev->model->model_id == MODEL_HP_SCANJET_G4050 || - dev->model->model_id == MODEL_HP_SCANJET_4850C) - { - SETREG (0x05, 0x08); - } - - dev->reg.find_reg(0x05).value &= ~REG05_DPIHW; - switch (sanei_genesys_find_sensor_any(dev).optical_res) - { - case 600: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_600; - break; - case 1200: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_1200; - break; - case 2400: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_2400; - break; - case 4800: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_4800; - break; - } - - // TODO: on 8600F the windows driver turns off GAIN4 which is recommended - SETREG (0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */ - SETREG (0x08, 0x00); - SETREG (0x09, 0x00); - SETREG (0x0a, 0x00); - - // This register controls clock and RAM settings and is further modified in - // gl843_boot - SETREG (0x0b, 0x6a); - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x0b, 0x89); - } - - // EXPR[0:15], EXPG[0:15], EXPB[0:15]: Exposure time settings. - SETREG(0x10, 0x00); // SENSOR_DEF - SETREG(0x11, 0x00); // SENSOR_DEF - SETREG(0x12, 0x00); // SENSOR_DEF - SETREG(0x13, 0x00); // SENSOR_DEF - SETREG(0x14, 0x00); // SENSOR_DEF - SETREG(0x15, 0x00); // SENSOR_DEF - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - dev->reg.set16(REG_EXPR, 0x9c40); - dev->reg.set16(REG_EXPG, 0x9c40); - dev->reg.set16(REG_EXPB, 0x9c40); - } - // CCD signal settings. - SETREG(0x16, 0x33); // SENSOR_DEF - SETREG(0x17, 0x1c); // SENSOR_DEF - SETREG(0x18, 0x10); // SENSOR_DEF - - // EXPDMY[0:7]: Exposure time of dummy lines. - SETREG(0x19, 0x2a); // SENSOR_DEF - - // Various CCD clock settings. - SETREG(0x1a, 0x04); // SENSOR_DEF - SETREG(0x1b, 0x00); // SENSOR_DEF - SETREG(0x1c, 0x20); // SENSOR_DEF - SETREG(0x1d, 0x04); // SENSOR_DEF - - SETREG (0x1e, 0x10); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x1e, 0x20); - } - - SETREG (0x1f, 0x01); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x1f, 0xff); - } - - SETREG (0x20, 0x10); - SETREG (0x21, 0x04); - SETREG (0x22, 0x01); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x22, 0xc8); - } - - SETREG (0x23, 0x01); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x23, 0xc8); - } - - SETREG (0x24, 0x04); - SETREG (0x25, 0x00); - SETREG (0x26, 0x00); - SETREG (0x27, 0x00); - SETREG (0x2c, 0x02); - SETREG (0x2d, 0x58); - // BWHI[0:7]: high level of black and white threshold - SETREG (0x2e, 0x80); - // BWLOW[0:7]: low level of black and white threshold - SETREG (0x2f, 0x80); - SETREG (0x30, 0x00); - SETREG (0x31, 0x14); - SETREG (0x32, 0x27); - SETREG (0x33, 0xec); - - // DUMMY: CCD dummy and optically black pixel count - SETREG (0x34, 0x24); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x34, 0x14); - } - - // MAXWD: If available buffer size is less than 2*MAXWD words, then - // "buffer full" state will be set. - SETREG (0x35, 0x00); - SETREG (0x36, 0xff); - SETREG (0x37, 0xff); - - // LPERIOD: Line period or exposure time for CCD or CIS. - SETREG(0x38, 0x55); // SENSOR_DEF - SETREG(0x39, 0xf0); // SENSOR_DEF - - // FEEDL[0:24]: The number of steps of motor movement. - SETREG(0x3d, 0x00); - SETREG (0x3e, 0x00); - SETREG (0x3f, 0x01); - - // Latch points for high and low bytes of R, G and B channels of AFE. If - // multiple clocks per pixel are consumed, then the setting defines during - // which clock the corresponding value will be read. - // RHI[0:4]: The latch point for high byte of R channel. - // RLOW[0:4]: The latch point for low byte of R channel. - // GHI[0:4]: The latch point for high byte of G channel. - // GLOW[0:4]: The latch point for low byte of G channel. - // BHI[0:4]: The latch point for high byte of B channel. - // BLOW[0:4]: The latch point for low byte of B channel. - SETREG(0x52, 0x01); // SENSOR_DEF - SETREG(0x53, 0x04); // SENSOR_DEF - SETREG(0x54, 0x07); // SENSOR_DEF - SETREG(0x55, 0x0a); // SENSOR_DEF - SETREG(0x56, 0x0d); // SENSOR_DEF - SETREG(0x57, 0x10); // SENSOR_DEF - - // VSMP[0:4]: The position of the image sampling pulse for AFE in cycles. - // VSMPW[0:2]: The length of the image sampling pulse for AFE in cycles. - SETREG(0x58, 0x1b); // SENSOR_DEF - - SETREG(0x59, 0x00); // SENSOR_DEF - SETREG(0x5a, 0x40); // SENSOR_DEF - - // 0x5b-0x5c: GMMADDR[0:15] address for gamma or motor tables download - // SENSOR_DEF - - // DECSEL[0:2]: The number of deceleratino steps after touching home sensor - // STOPTIM[0:4]: The stop duration between change of directions in - // backtracking - SETREG (0x5e, 0x23); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x5e, 0x1f); - } - - // FMOVDEC: The number of deceleration steps in table 5 for auto-go-home - SETREG (0x5f, 0x01); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x5f, 0xf0); - } - - // Z1MOD[0:20] - SETREG (0x60, 0x00); - SETREG (0x61, 0x00); - SETREG (0x62, 0x00); - - // Z2MOD[0:20] - SETREG (0x63, 0x00); - SETREG (0x64, 0x00); - SETREG (0x65, 0x00); - - // STEPSEL[0:1]. Motor movement step mode selection for tables 1-3 in - // scanning mode. - // MTRPWM[0:5]. Motor phase PWM duty cycle setting for tables 1-3 - SETREG (0x67, 0x7f); - // FSTPSEL[0:1]: Motor movement step mode selection for tables 4-5 in - // command mode. - // FASTPWM[5:0]: Motor phase PWM duty cycle setting for tables 4-5 - SETREG (0x68, 0x7f); - - // FSHDEC[0:7]: The number of deceleration steps after scanning is finished - // (table 3) - SETREG (0x69, 0x01); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x69, 64); - } - - // FMOVNO[0:7] The number of acceleration or deceleration steps for fast - // moving (table 4) - SETREG (0x6a, 0x04); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x69, 64); - } - - // GPIO-related register bits - SETREG (0x6b, 0x30); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x6b, 0x72); - } - - // 0x6c, 0x6d, 0x6e, 0x6f are set according to gpio tables. See - // gl843_init_gpio. - - // RSH[0:4]: The position of rising edge of CCD RS signal in cycles - // RSL[0:4]: The position of falling edge of CCD RS signal in cycles - // CPH[0:4]: The position of rising edge of CCD CP signal in cycles. - // CPL[0:4]: The position of falling edge of CCD CP signal in cycles - SETREG(0x70, 0x01); // SENSOR_DEF - SETREG(0x71, 0x03); // SENSOR_DEF - SETREG (0x72, 0x04); - SETREG (0x73, 0x05); - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x70, 0x00); - SETREG(0x71, 0x02); - SETREG(0x72, 0x02); - SETREG(0x73, 0x04); - } - - // CK1MAP[0:17], CK3MAP[0:17], CK4MAP[0:17]: CCD clock bit mapping setting. - SETREG(0x74, 0x00); // SENSOR_DEF - SETREG(0x75, 0x00); // SENSOR_DEF - SETREG(0x76, 0x3c); // SENSOR_DEF - SETREG(0x77, 0x00); // SENSOR_DEF - SETREG(0x78, 0x00); // SENSOR_DEF - SETREG(0x79, 0x9f); // SENSOR_DEF - SETREG(0x7a, 0x00); // SENSOR_DEF - SETREG(0x7b, 0x00); // SENSOR_DEF - SETREG(0x7c, 0x55); // SENSOR_DEF - - // various AFE settings - SETREG(0x7d, 0x00); - - // GPOLED[x]: LED vs GPIO settings - SETREG(0x7e, 0x00); - - // BSMPDLY, VSMPDLY - // LEDCNT[0:1]: Controls led blinking and its period - SETREG (0x7f, 0x00); - - // VRHOME, VRMOVE, VRBACK, VRSCAN: Vref settings of the motor driver IC for - // moving in various situations. - SETREG (0x80, 0x00); - - if (dev->model->model_id != MODEL_CANON_CANOSCAN_4400F) - { - // NOTE: Historical code. None of the following 6 registers are - // documented in the datasheet. Their default value is 0, so probably it's - // not a bad idea to leave this here. - SETREG (0x81, 0x00); - SETREG (0x82, 0x00); - SETREG (0x83, 0x00); - SETREG (0x84, 0x00); - SETREG (0x85, 0x00); - SETREG (0x86, 0x00); - } - - SETREG (0x87, 0x00); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x87, 0x02); - } - - // MTRPLS[0:7]: The width of the ADF motor trigger signal pulse. - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x94, 0xff); - } - - // 0x95-0x97: SCANLEN[0:19]: Controls when paper jam bit is set in sheetfed - // scanners. - - // ONDUR[0:15]: The duration of PWM ON phase for LAMP control - // OFFDUR[0:15]: The duration of PWM OFF phase for LAMP control - // both of the above are in system clocks - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x98, 0x00); - SETREG(0x99, 0x00); - SETREG(0x9a, 0x00); - SETREG(0x9b, 0x00); - } - - // RMADLY[0:1], MOTLAG, CMODE, STEPTIM, MULDMYLN, IFRS - SETREG(0x9d, 0x04); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0x9d, 0x08); // additionally sets the multiplier for slope tables - } - - - // SEL3INV, TGSTIME[0:2], TGWTIME[0:2] - SETREG (0x9e, 0x00); // SENSOR_DEF - - // RFHSET[0:4]: Refresh time of SDRAM in units of 2us - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0xa2, 0x1f); - } - - // 0xa6-0xa9: controls gpio, see gl843_gpio_init - - // GPOM9, MULSTOP[0-2], NODECEL, TB3TB1, TB5TB2, FIX16CLK. - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0xab, 0x00); - } - - // VRHOME[3:2], VRMOVE[3:2], VRBACK[3:2]: Vref setting of the motor driver IC - // for various situations. - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - SETREG(0xac, 0x00); - } - - if (dev->model->model_id != MODEL_CANON_CANOSCAN_8400F) - { - SETREG (0x0c, 0x00); - SETREG (0x94, 0xff); - SETREG (0xab, 0x50); - } - - if (dev->model->model_id != MODEL_CANON_CANOSCAN_4400F - && dev->model->model_id != MODEL_CANON_CANOSCAN_8400F) - { - SETREG (0xaa, 0x00); - } - - /* G4050 values */ - if (dev->model->model_id == MODEL_HP_SCANJET_G4010 || - dev->model->model_id == MODEL_HP_SCANJET_G4050 || - dev->model->model_id == MODEL_HP_SCANJET_4850C) - { - SETREG (0x03, 0x1d); - SETREG (0x06, 0xd0); /* SCANMOD=110, PWRBIT and no GAIN4 */ - SETREG (0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */ - SETREG (0x0a, 0x18); - SETREG (0x0b, 0x69); - - /* CIS exposure is used for XPA lamp movement */ - SETREG (0x10, 0x2c); - SETREG (0x11, 0x09); - SETREG (0x12, 0x22); - SETREG (0x13, 0xb8); - SETREG (0x14, 0x10); - SETREG (0x15, 0xf0); - - SETREG (0x6b, 0xf4); - - SETREG (0x70, 0x00); - SETREG (0x71, 0x02); - SETREG (0x72, 0x00); - SETREG (0x73, 0x00); - - SETREG (0x80, 0x50); - SETREG (0x9d, 0x08); - SETREG (0xab, 0x40); - - /* XXX STEF XXX TODO move to set for scan */ - SETREG (0x98, 0x03); - SETREG (0x99, 0x30); - SETREG (0x9a, 0x01); - SETREG (0x9b, 0x80); - SETREG (0xac, 0x00); - } - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_4400F) - { - SETREG (0x06, 0xf0); /* SCANMOD=111, PWRBIT and no GAIN4 */ - SETREG (0x0b, 0x69); /* 16M only */ - SETREG (0x1e, 0x20); - SETREG (0x22, 0xc8); - SETREG (0x23, 0xc8); - SETREG (0x5e, 0x3f); - SETREG (0x5f, 0xf0); - SETREG (0x6b, 0x72); - SETREG (0x72, 0x01); - SETREG (0x73, 0x03); - SETREG (0x80, 0x0c); - SETREG (0x87, 0x02); /* MCLOCK -> CK4MAP */ - SETREG (0x9d, 0x08); /* STEPTIM=2 */ - SETREG (0xa2, 0x1f); - SETREG (0xab, 0x00); - sanei_genesys_set_double(&dev->reg,REG_EXPR,0x9c40); - sanei_genesys_set_double(&dev->reg,REG_EXPG,0x9c40); - sanei_genesys_set_double(&dev->reg,REG_EXPB,0x9c40); - } - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8400F) - { - SETREG (0x03, 0x1c); - SETREG (0x06, 0xd0); /* SCANMOD=110, PWRBIT and no GAIN4 */ - SETREG (0x0a, 0x10); - SETREG (0x22, 0x50); - SETREG (0x23, 0x50); - SETREG (0x5e, 0x85); - SETREG (0x6b, 0xb1); - SETREG (0x1e, 0xa0); - SETREG (0x72, 0x03); - SETREG (0x73, 0x04); - SETREG (0x7d, 0x20); - SETREG (0x80, 0x28); - SETREG (0x87, 0x02); /* MCLOCK -> CK4MAP */ - SETREG (0x9d, 0x08); /* STEPTIM=2 */ - } - - dev->calib_reg = dev->reg; - - DBGCOMPLETED; -} - -/* Send slope table for motor movement - slope_table in machine byte order - */ -static SANE_Status -gl843_send_slope_table (Genesys_Device * dev, int table_nr, - uint16_t * slope_table, int steps) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - char msg[10000]; - - DBG(DBG_proc, "%s (table_nr = %d, steps = %d)\n", __func__, table_nr, steps); - - std::vector<uint8_t> table(steps * 2); - for (i = 0; i < steps; i++) - { - table[i * 2] = slope_table[i] & 0xff; - table[i * 2 + 1] = slope_table[i] >> 8; - } - - if (DBG_LEVEL >= DBG_io) - { - sprintf (msg, "write slope %d (%d)=", table_nr, steps); - for (i = 0; i < steps; i++) - { - sprintf (msg+strlen(msg), "%d", slope_table[i]); - } - DBG(DBG_io, "%s: %s\n", __func__, msg); - } - - - /* slope table addresses are fixed : 0x4000, 0x4800, 0x5000, 0x5800, 0x6000 */ - /* XXX STEF XXX USB 1.1 ? sanei_genesys_write_0x8c (dev, 0x0f, 0x14); */ - status = write_data (dev, 0x4000 + 0x800 * table_nr, steps * 2, table.data()); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: write data failed writing slope table %d (%s)\n", __func__, table_nr, - sane_strstatus(status)); - } - - DBGCOMPLETED; - return status; -} - - -/* Set values of analog frontend */ -static SANE_Status -gl843_set_fe (Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - int i; - - DBG(DBG_proc, "%s (%s)\n", __func__, set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set == - AFE_POWER_SAVE ? "powersave" : "huh?"); - - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - dev->frontend = dev->frontend_initial; - } - - /* check analog frontend type */ - // FIXME: looks like we write to that register with initial data - RIE (sanei_genesys_read_register (dev, REG04, &val)); - if ((val & REG04_FESET) != 0x00) - { - /* for now there is no support for AD fe */ - DBG(DBG_proc, "%s(): unsupported frontend type %d\n", __func__, - dev->reg.find_reg(0x04).value & REG04_FESET); - return SANE_STATUS_UNSUPPORTED; - } - - DBG(DBG_proc, "%s(): frontend reset complete\n", __func__); - - for (i = 1; i <= 3; i++) - { - // FIXME: BUG: we should initialize dev->frontend before first use. Right now it's - // initialized during genesys_coarse_calibration() - if (dev->frontend.regs.empty()) { - status = sanei_genesys_fe_write_data(dev, i, 0x00); - } else { - status = sanei_genesys_fe_write_data(dev, i, dev->frontend.regs.get_value(0x00 + i)); - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing reg[%d] failed: %s\n", __func__, i, sane_strstatus(status)); - return status; - } - } - for (const auto& reg : sensor.custom_fe_regs) { - status = sanei_genesys_fe_write_data(dev, reg.address, reg.value); - if (status != SANE_STATUS_GOOD) { - DBG(DBG_error, "%s: writing reg[%d] failed: %s\n", __func__, i, sane_strstatus(status)); - return status; - } - } - - for (i = 0; i < 3; i++) - { - // FIXME: BUG: see above - if (dev->frontend.regs.empty()) { - status = sanei_genesys_fe_write_data(dev, 0x20 + i, 0x00); - } else { - status = sanei_genesys_fe_write_data(dev, 0x20 + i, dev->frontend.get_offset(i)); - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing offset[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - - if (dev->model->ccd_type == CCD_KVSS080) - { - for (i = 0; i < 3; i++) - { - // FIXME: BUG: see above - if (dev->frontend.regs.empty()) { - status = sanei_genesys_fe_write_data(dev, 0x24 + i, 0x00); - } else { - status = sanei_genesys_fe_write_data(dev, 0x24 + i, - dev->frontend.regs.get_value(0x24 + i)); - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing sign[%d] failed: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - } - - for (i = 0; i < 3; i++) - { - // FIXME: BUG: see above - if (dev->frontend.regs.empty()) { - status = sanei_genesys_fe_write_data(dev, 0x28 + i, 0x00); - } else { - status = sanei_genesys_fe_write_data(dev, 0x28 + i, dev->frontend.get_gain(i)); - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: writing gain[%d] failed: %s\n", __func__, i, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -static SANE_Status -gl843_init_motor_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int exposure, - float scan_yres, - int scan_step_type, - unsigned int scan_lines, - unsigned int scan_dummy, - unsigned int feed_steps, - int scan_power_mode, - unsigned int flags) -{ - SANE_Status status = SANE_STATUS_GOOD; - int use_fast_fed, coeff; - unsigned int lincnt; - uint16_t scan_table[1024]; - uint16_t fast_table[1024]; - int scan_steps,fast_steps, fast_step_type; - unsigned int feedl,factor,dist; - GenesysRegister *r; - uint32_t z1, z2; - - DBGSTART; - DBG(DBG_info, "%s : exposure=%d, scan_yres=%g, scan_step_type=%d, scan_lines=%d, scan_dummy=%d, " - "feed_steps=%d, scan_power_mode=%d, flags=%x\n", __func__, exposure, scan_yres, - scan_step_type, scan_lines, scan_dummy, feed_steps, scan_power_mode, flags); - - /* get step multiplier */ - factor = gl843_get_step_multiplier (reg); - - use_fast_fed = 0; - - if((scan_yres>=300 && feed_steps>900) || (flags & MOTOR_FLAG_FEED)) - use_fast_fed=1; - - lincnt=scan_lines; - sanei_genesys_set_triple(reg,REG_LINCNT,lincnt); - DBG(DBG_io, "%s: lincnt=%d\n", __func__, lincnt); - - /* compute register 02 value */ - r = sanei_genesys_get_address (reg, REG02); - r->value = 0x00; - sanei_genesys_set_motor_power(*reg, true); - - if (use_fast_fed) - r->value |= REG02_FASTFED; - else - r->value &= ~REG02_FASTFED; - - /* in case of automatic go home, move until home sensor */ - if (flags & MOTOR_FLAG_AUTO_GO_HOME) - r->value |= REG02_AGOHOME | REG02_NOTHOME; - - /* disable backtracking */ - if ((flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE) - ||(scan_yres>=2400) - ||(scan_yres>=sensor.optical_res)) - r->value |= REG02_ACDCDIS; - - /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - scan_yres, - exposure, - dev->motor.base_ydpi, - scan_step_type, - factor, - dev->model->motor_type, - gl843_motors); - RIE(gl843_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps*factor)); - RIE(gl843_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps*factor)); - - /* STEPNO */ - r = sanei_genesys_get_address (reg, REG_STEPNO); - r->value = scan_steps; - - /* FSHDEC */ - r = sanei_genesys_get_address (reg, REG_FSHDEC); - r->value = scan_steps; - - /* fast table */ - fast_step_type=0; - if(scan_step_type<=fast_step_type) - { - fast_step_type=scan_step_type; - } - sanei_genesys_slope_table(fast_table, - &fast_steps, - sanei_genesys_get_lowest_ydpi(dev), - exposure, - dev->motor.base_ydpi, - fast_step_type, - factor, - dev->model->motor_type, - gl843_motors); - RIE(gl843_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps*factor)); - RIE(gl843_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps*factor)); - RIE(gl843_send_slope_table (dev, HOME_TABLE, fast_table, fast_steps*factor)); - - /* FASTNO */ - r = sanei_genesys_get_address (reg, REG_FASTNO); - r->value = fast_steps; - - /* FMOVNO */ - r = sanei_genesys_get_address (reg, REG_FMOVNO); - r->value = fast_steps; - - /* substract acceleration distance from feedl */ - feedl=feed_steps; - feedl<<=scan_step_type; - - dist = scan_steps; - if (use_fast_fed) - { - dist += fast_steps*2; - } - DBG(DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); - - /* get sure when don't insane value : XXX STEF XXX in this case we should - * fall back to single table move */ - if(dist<feedl) - feedl -= dist; - else - feedl = 1; - - sanei_genesys_set_triple(reg,REG_FEEDL,feedl); - DBG(DBG_io, "%s: feedl=%d\n", __func__, feedl); - - /* doesn't seem to matter that much */ - sanei_genesys_calculate_zmode2 (use_fast_fed, - exposure, - scan_table, - scan_steps, - feedl, - scan_steps, - &z1, - &z2); - if(scan_yres>600) - { - z1=0; - z2=0; - } - - sanei_genesys_set_triple(reg,REG_Z1MOD,z1); - DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); - - sanei_genesys_set_triple(reg,REG_Z2MOD,z2); - DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); - - r = sanei_genesys_get_address (reg, REG1E); - r->value &= 0xf0; /* 0 dummy lines */ - r->value |= scan_dummy; /* dummy lines */ - - r = sanei_genesys_get_address (reg, REG67); - r->value = 0x3f | (scan_step_type << REG67S_STEPSEL); - - r = sanei_genesys_get_address (reg, REG68); - r->value = 0x3f | (scan_step_type << REG68S_FSTPSEL); - - /* steps for STOP table */ - r = sanei_genesys_get_address (reg, REG_FMOVDEC); - r->value = fast_steps; - - /* Vref XXX STEF XXX : optical divider or step type ? */ - r = sanei_genesys_get_address (reg, 0x80); - if (!(dev->model->flags & GENESYS_FLAG_FULL_HWDPI_MODE)) - { - r->value = 0x50; - coeff=sensor.optical_res/sanei_genesys_compute_dpihw(dev, sensor, scan_yres); - if (dev->model->motor_type == MOTOR_KVSS080) - { - if(coeff>=1) - { - r->value |= 0x05; - } - } - else { - switch(coeff) - { - case 4: - r->value |= 0x0a; - break; - case 2: - r->value |= 0x0f; - break; - case 1: - r->value |= 0x0f; - break; - } - } - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/** @brief setup optical related registers - * start and pixels are expressed in optical sensor resolution coordinate - * space. - * @param dev device to use - * @param reg registers to set up - * @param exposure exposure time to use - * @param used_res scanning resolution used, may differ from - * scan's one - * @param start logical start pixel coordinate - * @param pixels logical number of pixels to use - * @param channels number of color channles used (1 or 3) - * @param depth bit depth of the scan (1, 8 or 16 bits) - * @param ccd_size_divisor SANE_TRUE specifies how much x coordinates must be shrunk - * @param color_filter to choose the color channel used in gray scans - * @param flags to drive specific settings such no calibration, XPA use ... - * @return SANE_STATUS_GOOD if OK - */ -static SANE_Status -gl843_init_optical_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int exposure, - int used_res, - unsigned int start, - unsigned int pixels, - int channels, - int depth, - unsigned ccd_size_divisor, - ColorFilter color_filter, - int flags) -{ - unsigned int words_per_line; - unsigned int startx, endx, used_pixels; - unsigned int dpiset, dpihw, factor; - unsigned int bytes; - unsigned int tgtime; /**> exposure time multiplier */ - unsigned int cksel; /**> clock per system pixel time in capturing image */ - GenesysRegister *r; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s : exposure=%d, used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, " - "ccd_size_divisor=%d, flags=%x\n", __func__, exposure, used_res, start, pixels, channels, - depth, ccd_size_divisor, flags); - - /* tgtime */ - tgtime = exposure / 65536 + 1; - DBG(DBG_io2, "%s: tgtime=%d\n", __func__, tgtime); - - /* to manage high resolution device while keeping good - * low resolution scanning speed, we make hardware dpi vary */ - dpihw=sanei_genesys_compute_dpihw(dev, sensor, used_res); - factor=sensor.optical_res/dpihw; - DBG(DBG_io2, "%s: dpihw=%d (factor=%d)\n", __func__, dpihw, factor); - - /* sensor parameters */ - gl843_setup_sensor (dev, sensor, reg, dpihw, flags); - - /* resolution is divided according to CKSEL which is known once sensor is set up */ - r = sanei_genesys_get_address (reg, REG18); - cksel= (r->value & REG18_CKSEL)+1; - DBG(DBG_io2, "%s: cksel=%d\n", __func__, cksel); - dpiset = used_res * cksel; - - /* start and end coordinate in optical dpi coordinates */ - startx = (start + sensor.dummy_pixel)/cksel; - - used_pixels=pixels/cksel; - endx = startx + used_pixels; - - /* pixel coordinate factor correction when used dpihw is not maximal one */ - startx/=factor; - endx/=factor; - used_pixels=endx-startx; - - /* in case of stagger we have to start at an odd coordinate */ - if ((flags & OPTICAL_FLAG_STAGGER) - &&((startx & 1)==0)) - { - startx++; - endx++; - } - - status = gl843_set_fe(dev, sensor, AFE_SET); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* enable shading */ - r = sanei_genesys_get_address (reg, REG01); - r->value &= ~REG01_SCAN; - if ((flags & OPTICAL_FLAG_DISABLE_SHADING) || (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) - { - r->value &= ~REG01_DVDSET; - } - else - { - r->value |= REG01_DVDSET; - } - if(dpihw>600) - { - r->value |= REG01_SHDAREA; - } - else - { - r->value &= ~REG01_SHDAREA; - } - - r = sanei_genesys_get_address (reg, REG03); - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - r->value |= REG03_AVEENB; - else { - r->value &= ~REG03_AVEENB; - } - - // FIXME: we probably don't need to set exposure to registers at this point. It was this way - // before a refactor. - sanei_genesys_set_lamp_power(dev, sensor, *reg, !(flags & OPTICAL_FLAG_DISABLE_LAMP)); - - /* select XPA */ - r->value &= ~REG03_XPASEL; - if (flags & OPTICAL_FLAG_USE_XPA) - { - r->value |= REG03_XPASEL; - } - reg->state.is_xpa_on = flags & OPTICAL_FLAG_USE_XPA; - - /* BW threshold */ - r = sanei_genesys_get_address (reg, REG2E); - r->value = dev->settings.threshold; - r = sanei_genesys_get_address (reg, REG2F); - r->value = dev->settings.threshold; - - /* monochrome / color scan */ - r = sanei_genesys_get_address (reg, REG04); - switch (depth) - { - case 1: - r->value &= ~REG04_BITSET; - r->value |= REG04_LINEART; - break; - case 8: - r->value &= ~(REG04_LINEART | REG04_BITSET); - break; - case 16: - r->value &= ~REG04_LINEART; - r->value |= REG04_BITSET; - break; - } - - r->value &= ~(REG04_FILTER | REG04_AFEMOD); - if (channels == 1) - { - switch (color_filter) - { - case ColorFilter::RED: - r->value |= 0x14; - break; - case ColorFilter::BLUE: - r->value |= 0x1c; - break; - case ColorFilter::GREEN: - r->value |= 0x18; - break; - default: - break; // should not happen - } - } - else - r->value |= 0x10; /* mono */ - - /* register 05 */ - r = sanei_genesys_get_address (reg, REG05); - - /* set up dpihw */ - r->value &= ~REG05_DPIHW; - switch(dpihw) - { - case 600: - r->value |= REG05_DPIHW_600; - break; - case 1200: - r->value |= REG05_DPIHW_1200; - break; - case 2400: - r->value |= REG05_DPIHW_2400; - break; - case 4800: - r->value |= REG05_DPIHW_4800; - break; - } - - /* enable gamma tables */ - if (flags & OPTICAL_FLAG_DISABLE_GAMMA) - r->value &= ~REG05_GMMENB; - else - r->value |= REG05_GMMENB; - - sanei_genesys_set_double(reg, REG_DPISET, dpiset * ccd_size_divisor); - DBG(DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset * ccd_size_divisor); - - sanei_genesys_set_double(reg, REG_STRPIXEL, startx); - sanei_genesys_set_double(reg, REG_ENDPIXEL, endx); - - /* words(16bit) before gamma, conversion to 8 bit or lineart */ - words_per_line = (used_pixels * dpiset) / dpihw; - bytes = depth / 8; - if (depth == 1) - { - words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0); - } - else - { - words_per_line *= bytes; - } - - dev->wpl = words_per_line; - dev->bpl = words_per_line; - - DBG(DBG_io2, "%s: used_pixels=%d\n", __func__, used_pixels); - DBG(DBG_io2, "%s: pixels =%d\n", __func__, pixels); - DBG(DBG_io2, "%s: depth =%d\n", __func__, depth); - DBG(DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long) dev->bpl); - DBG(DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long)dev->len); - DBG(DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long)dev->dist); - - words_per_line *= channels; - - /* MAXWD is expressed in 2 words unit */ - /* nousedspace = (mem_bank_range * 1024 / 256 -1 ) * 4; */ - sanei_genesys_set_triple(reg,REG_MAXWD,(words_per_line)>>1); - DBG(DBG_io2, "%s: words_per_line used=%d\n", __func__, words_per_line); - - sanei_genesys_set_double(reg,REG_LPERIOD,exposure/tgtime); - DBG(DBG_io2, "%s: exposure used=%d\n", __func__, exposure/tgtime); - - r = sanei_genesys_get_address (reg, REG_DUMMY); - r->value = sensor.dummy_pixel; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -struct ScanSession { - SetupParams params; - - // whether the session setup has been computed via gl843_compute_session() - bool computed = false; - - // whether CCD operates as half-resolution or full resolution at a specific resolution - unsigned ccd_size_divisor = 1; - - // the optical resolution of the scanner. - unsigned optical_resolution = 0; - - // the number of pixels at the optical resolution. - unsigned optical_pixels = 0; - - // the number of bytes in the output of a single line directly from scanner - unsigned optical_line_bytes = 0; - - // the resolution of the output data. - unsigned output_resolution = 0; - - // the number of pixels in output data - unsigned output_pixels = 0; - - // the number of bytes in the output of a single line - unsigned output_line_bytes = 0; - - // the number of lines in the output of the scanner. This must be larger than the user - // requested number due to line staggering and color channel shifting. - unsigned output_line_count = 0; - - // the number of staggered lines (i.e. lines that overlap during scanning due to line being - // thinner than the CCD element) - unsigned num_staggered_lines = 0; - - // the number of lines that color channels shift due to different physical positions of - // different color channels - unsigned max_color_shift_lines = 0; - - void assert_computed() const - { - if (!computed) { - throw std::runtime_error("ScanSession is not computed"); - } - } -}; - -static unsigned align_int_up(unsigned num, unsigned alignment) -{ - unsigned mask = alignment - 1; - if (num & mask) - num = (num & ~mask) + alignment; - return num; -} - -// computes physical parameters for specific scan setup -static void gl843_compute_session(Genesys_Device* dev, ScanSession& s, - const Genesys_Sensor& sensor) -{ - s.params.assert_valid(); - s.ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(s.params.xres); - - s.optical_resolution = sensor.optical_res / s.ccd_size_divisor; - - if (s.params.flags & SCAN_FLAG_USE_OPTICAL_RES) { - s.output_resolution = s.optical_resolution; - } else { - // resolution is choosen from a fixed list and can be used directly - // unless we have ydpi higher than sensor's maximum one - if (s.params.xres > s.optical_resolution) - s.output_resolution = s.optical_resolution; - else - s.output_resolution = s.params.xres; - } - - // compute rounded up number of optical pixels - s.optical_pixels = (s.params.pixels * s.optical_resolution) / s.params.xres; - if (s.optical_pixels * s.params.xres < s.params.pixels * s.optical_resolution) - s.optical_pixels++; - - // ensure the number of optical pixels is divisible by 2. - // In quarter-CCD mode optical_pixels is 4x larger than the actual physical number - s.optical_pixels = align_int_up(s.optical_pixels, 2 * s.ccd_size_divisor); - - s.output_pixels = - (s.optical_pixels * s.output_resolution) / s.optical_resolution; - - // Note: staggering is not applied for calibration. Staggering starts at 2400 dpi - s.num_staggered_lines = 0; - if ((s.params.yres > 1200) && - ((s.params.flags & SCAN_FLAG_IGNORE_LINE_DISTANCE) == 0) && - (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - { - s.num_staggered_lines = (4 * s.params.yres) / dev->motor.base_ydpi; - } - - s.max_color_shift_lines = sanei_genesys_compute_max_shift(dev, s.params.channels, - s.params.yres, s.params.flags); - - s.output_line_count = s.params.lines + s.max_color_shift_lines + s.num_staggered_lines; - - s.optical_line_bytes = (s.optical_pixels * s.params.channels * s.params.depth) / 8; - s.output_line_bytes = (s.output_pixels * s.params.channels * s.params.depth) / 8; - s.computed = true; -} - -/* set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -static SANE_Status gl843_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sensor, - Genesys_Register_Set* reg, - ScanSession& session) -{ - session.assert_computed(); - - int start; - int move; - unsigned int oflags, mflags; /**> optical and motor flags */ - int exposure; - - int slope_dpi = 0; - int dummy = 0; - int scan_step_type = 1; - int scan_power_mode = 0; - size_t requested_buffer_size, read_buffer_size; - - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, session.params); - - DBG(DBG_info, "%s : stagger=%d lines\n", __func__, session.num_staggered_lines); - - /* we enable true gray for cis scanners only, and just when doing - * scan since color calibration is OK for this mode - */ - oflags = 0; - if (session.params.flags & SCAN_FLAG_DISABLE_SHADING) - oflags |= OPTICAL_FLAG_DISABLE_SHADING; - if (session.params.flags & SCAN_FLAG_DISABLE_GAMMA) - oflags |= OPTICAL_FLAG_DISABLE_GAMMA; - if (session.params.flags & SCAN_FLAG_DISABLE_LAMP) - oflags |= OPTICAL_FLAG_DISABLE_LAMP; - if (session.params.flags & SCAN_FLAG_CALIBRATION) - oflags |= OPTICAL_FLAG_DISABLE_DOUBLE; - if (session.num_staggered_lines) - oflags |= OPTICAL_FLAG_STAGGER; - if (session.params.flags & SCAN_FLAG_USE_XPA) - oflags |= OPTICAL_FLAG_USE_XPA; - - - /* compute scan parameters values */ - /* pixels are allways given at full optical resolution */ - /* use detected left margin and fixed value */ - /* start */ - start = session.params.startx; - - dummy = 0; - /* dummy = 1; XXX STEF XXX */ - - /* slope_dpi */ - /* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */ - if (dev->model->is_cis) - slope_dpi = session.params.yres * session.params.channels; - else - slope_dpi = session.params.yres; - slope_dpi = slope_dpi * (1 + dummy); - - /* scan_step_type */ - exposure = sensor.exposure_lperiod; - if (exposure < 0) { - throw std::runtime_error("Exposure not defined in sensor definition"); - } - scan_step_type = sanei_genesys_compute_step_type(gl843_motors, dev->model->motor_type, exposure); - - DBG(DBG_info, "%s : exposure=%d pixels\n", __func__, exposure); - DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, scan_step_type); - - /*** optical parameters ***/ - /* in case of dynamic lineart, we use an internal 8 bit gray scan - * to generate 1 lineart data */ - if (session.params.flags & SCAN_FLAG_DYNAMIC_LINEART) { - session.params.depth = 8; - } - - /* no 16 bit gamma for this ASIC */ - if (session.params.depth == 16) - { - session.params.flags |= SCAN_FLAG_DISABLE_GAMMA; - oflags |= OPTICAL_FLAG_DISABLE_GAMMA; - } - - /* now _LOGICAL_ optical values used are known, setup registers */ - status = gl843_init_optical_regs_scan (dev, sensor, - reg, - exposure, - session.output_resolution, - start, - session.optical_pixels, - session.params.channels, - session.params.depth, - session.ccd_size_divisor, - session.params.color_filter, - oflags); - if (status != SANE_STATUS_GOOD) - return status; - - /*** motor parameters ***/ - - /* it seems base_dpi of the G4050 motor is changed above 600 dpi*/ - if (dev->model->motor_type == MOTOR_G4050 && session.params.yres>600) - { - dev->ld_shift_r = (dev->model->ld_shift_r*3800)/dev->motor.base_ydpi; - dev->ld_shift_g = (dev->model->ld_shift_g*3800)/dev->motor.base_ydpi; - dev->ld_shift_b = (dev->model->ld_shift_b*3800)/dev->motor.base_ydpi; - } - else - { - dev->ld_shift_r = dev->model->ld_shift_r; - dev->ld_shift_g = dev->model->ld_shift_g; - dev->ld_shift_b = dev->model->ld_shift_b; - } - - /* add tl_y to base movement */ - move = session.params.starty; - DBG(DBG_info, "%s: move=%d steps\n", __func__, move); - - - mflags=0; - if(session.params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) - mflags|=MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; - if(session.params.flags & SCAN_FLAG_FEEDING) - mflags|=MOTOR_FLAG_FEED; - if (session.params.flags & SCAN_FLAG_USE_XPA) - mflags |= MOTOR_FLAG_USE_XPA; - - status = gl843_init_motor_regs_scan (dev, sensor, - reg, - exposure, - slope_dpi, - scan_step_type, - dev->model->is_cis ? session.output_line_count * session.params.channels - : session.output_line_count, - dummy, - move, - scan_power_mode, - mflags); - if (status != SANE_STATUS_GOOD) - return status; - - /* since we don't have sheetfed scanners to handle, - * use huge read buffer */ - /* TODO find the best size according to settings */ - requested_buffer_size = 16 * session.output_line_bytes; - - read_buffer_size = - 2 * requested_buffer_size + - (session.max_color_shift_lines + session.num_staggered_lines) * session.optical_line_bytes; - - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); - - dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); - - dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); - - dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * session.params.pixels * session.params.channels * - session.params.depth) / 8); - - dev->read_bytes_left = session.output_line_bytes * session.output_line_count; - - DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); - dev->read_active = SANE_TRUE; - - dev->current_setup.params = session.params; - dev->current_setup.pixels = session.output_pixels; - DBG(DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); - dev->current_setup.lines = session.output_line_count; - dev->current_setup.depth = session.params.depth; - dev->current_setup.channels = session.params.channels; - dev->current_setup.exposure_time = exposure; - dev->current_setup.xres = session.output_resolution; - dev->current_setup.yres = session.params.yres; - dev->current_setup.ccd_size_divisor = session.ccd_size_divisor; - dev->current_setup.stagger = session.num_staggered_lines; - dev->current_setup.max_shift = session.max_color_shift_lines + session.num_staggered_lines; - - dev->total_bytes_read = 0; - if (session.params.depth == 1) { - dev->total_bytes_to_read = ((session.params.pixels * session.params.lines) / 8 + - (((session.params.pixels * session.params.lines) % 8) ? 1 : 0)) * - session.params.channels; - } else { - dev->total_bytes_to_read = session.params.pixels * session.params.lines * - session.params.channels * (session.params.depth / 8); - } - - DBG(DBG_info, "%s: total bytes to send = %lu\n", __func__, (u_long) dev->total_bytes_to_read); - - DBG(DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; -} - -static void -gl843_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int depth; - int start; - - int used_res; - int used_pixels; - unsigned int lincnt; - int exposure; - int stagger; - - int max_shift; - - int optical_res; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - unsigned ccd_size_divisor = sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - /* start */ - if(dev->settings.scan_method==ScanMethod::TRANSPARENCY) - start = SANE_UNFIX (dev->model->x_offset_ta); - else - start = SANE_UNFIX (dev->model->x_offset); - - start /= ccd_size_divisor; - - start += dev->settings.tl_x; - start = (start * sensor.optical_res) / MM_PER_INCH; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; // not used - params.starty = 0; // not used - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = 0; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - - /* optical_res */ - optical_res = sensor.optical_res / ccd_size_divisor; - - /* stagger */ - if (ccd_size_divisor == 1 && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG(DBG_info, "%s: stagger=%d lines\n", __func__, stagger); - - if (params.xres <= (unsigned) optical_res) { - used_res = params.xres; - } else { - used_res = optical_res; - } - - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - - /* compute correct pixels number */ - used_pixels = (params.pixels * optical_res) / params.xres; - DBG(DBG_info, "%s: used_pixels=%d\n", __func__, used_pixels); - - /* exposure */ - exposure = sensor.exposure_lperiod; - if (exposure < 0) { - throw std::runtime_error("Exposure not defined in sensor definition"); - } - DBG(DBG_info, "%s : exposure=%d pixels\n", __func__, exposure); - - /* it seems base_dpi of the G4050 motor is changed above 600 dpi*/ - if (dev->model->motor_type == MOTOR_G4050 && params.yres>600) - { - dev->ld_shift_r = (dev->model->ld_shift_r*3800)/dev->motor.base_ydpi; - dev->ld_shift_g = (dev->model->ld_shift_g*3800)/dev->motor.base_ydpi; - dev->ld_shift_b = (dev->model->ld_shift_b*3800)/dev->motor.base_ydpi; - } - else - { - dev->ld_shift_r = dev->model->ld_shift_r; - dev->ld_shift_g = dev->model->ld_shift_g; - dev->ld_shift_b = dev->model->ld_shift_b; - } - - /* scanned area must be enlarged by max color shift needed */ - max_shift = sanei_genesys_compute_max_shift(dev, params.channels, params.yres, 0); - - /* lincnt */ - lincnt = params.lines + max_shift + stagger; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; - DBG(DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = ccd_size_divisor; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - - DBG(DBG_proc, "%s: completed\n", __func__); -} - -/** - * for fast power saving methods only, like disabling certain amplifiers - * @param dev device to use - * @param enable true to set inot powersaving - * */ -static SANE_Status -gl843_save_power (Genesys_Device * dev, SANE_Bool enable) -{ - uint8_t val; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s: enable = %d\n", __func__, enable); - if (dev == NULL) - return SANE_STATUS_INVAL; - - /* switch KV-SS080 lamp off */ - if (dev->model->gpo_type == GPO_KVSS080) - { - RIE(sanei_genesys_read_register (dev, REG6C, &val)); - if(enable) - val &= 0xef; - else - val |= 0x10; - RIE(sanei_genesys_write_register(dev,REG6C,val)); - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl843_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ ) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (delay = %d)\n", __func__, delay); - if (dev == NULL) - return SANE_STATUS_INVAL; - - DBGCOMPLETED; - return status; -} - -static SANE_Status -gl843_start_action (Genesys_Device * dev) -{ - return sanei_genesys_write_register (dev, 0x0f, 0x01); -} - -static SANE_Status -gl843_stop_action_no_move(Genesys_Device* dev, Genesys_Register_Set* reg) -{ - uint8_t val = sanei_genesys_read_reg_from_set(reg, REG01); - val &= ~REG01_SCAN; - sanei_genesys_set_reg_from_set(reg, REG01, val); - SANE_Status ret = sanei_genesys_write_register(dev, REG01, val); - sanei_genesys_sleep_ms(100); - return ret; -} - -static SANE_Status -gl843_stop_action (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val40, val; - unsigned int loop; - - DBG(DBG_proc, "%s\n", __func__); - - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - val40 = 0; - status = sanei_genesys_read_register (dev, REG40, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBG(DBG_proc, "%s: completed\n", __func__); - return status; - } - - /* only stop action if needed */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)) - { - DBG(DBG_info, "%s: already stopped\n", __func__); - DBG(DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; - } - - /* ends scan 646 */ - val = dev->reg.get8(REG01); - val &= ~REG01_SCAN; - dev->reg.set8(REG01, val); - status = sanei_genesys_write_register (dev, REG01, val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register 01: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_sleep_ms(100); - - loop = 10; - while (loop > 0) - { - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - val40 = 0; - status = sanei_genesys_read_register (dev, 0x40, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* if scanner is in command mode, we are done */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG) - && !(val & REG41_MOTORENB)) - { - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - sanei_genesys_sleep_ms(100); - loop--; - } - - DBGCOMPLETED; - return SANE_STATUS_IO_ERROR; -} - -static SANE_Status -gl843_get_paper_sensor (Genesys_Device * dev, SANE_Bool * paper_loaded) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - status = sanei_genesys_read_register (dev, REG6D, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read gpio: %s\n", __func__, sane_strstatus(status)); - return status; - } - *paper_loaded = (val & 0x1) == 0; - return SANE_STATUS_GOOD; - - return SANE_STATUS_INVAL; -} - -static SANE_Status -gl843_eject_document (Genesys_Device * dev) -{ - DBG(DBG_proc, "%s: not implemented \n", __func__); - if (dev == NULL) - return SANE_STATUS_INVAL; - return SANE_STATUS_GOOD; -} - - -static SANE_Status -gl843_load_document (Genesys_Device * dev) -{ - DBG(DBG_proc, "%s: not implemented \n", __func__); - if (dev == NULL) - return SANE_STATUS_INVAL; - return SANE_STATUS_GOOD; -} - -/** - * detects end of document and adjust current scan - * to take it into account - * used by sheetfed scanners - */ -static SANE_Status -gl843_detect_document_end (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - SANE_Bool paper_loaded; - unsigned int scancnt = 0; - int flines, channels, depth, bytes_remain, sublines, - bytes_to_flush, lines, sub_bytes, tmp, read_bytes_left; - DBG(DBG_proc, "%s: begin\n", __func__); - - RIE (gl843_get_paper_sensor (dev, &paper_loaded)); - - /* sheetfed scanner uses home sensor as paper present */ - if ((dev->document == SANE_TRUE) && !paper_loaded) - { - DBG(DBG_info, "%s: no more document\n", __func__); - dev->document = SANE_FALSE; - - channels = dev->current_setup.channels; - depth = dev->current_setup.depth; - read_bytes_left = (int) dev->read_bytes_left; - DBG(DBG_io, "%s: read_bytes_left=%d\n", __func__, read_bytes_left); - - /* get lines read */ - try { - status = sanei_genesys_read_scancnt(dev, &scancnt); - } catch (...) { - flines = 0; - } - if (status != SANE_STATUS_GOOD) - { - flines = 0; - } - else - { - /* compute number of line read */ - tmp = (int) dev->total_bytes_read; - if (depth == 1 || dev->settings.scan_mode == ScanColorMode::LINEART) - flines = tmp * 8 / dev->settings.pixels / channels; - else - flines = tmp / (depth / 8) / dev->settings.pixels / channels; - - /* number of scanned lines, but no read yet */ - flines = scancnt - flines; - - DBG(DBG_io, "%s: %d scanned but not read lines\n", __func__, flines); - } - - /* adjust number of bytes to read - * we need to read the final bytes which are word per line * number of last lines - * to have doc leaving feeder */ - lines = - (SANE_UNFIX (dev->model->post_scan) * dev->current_setup.yres) / - MM_PER_INCH + flines; - DBG(DBG_io, "%s: adding %d line to flush\n", __func__, lines); - - /* number of bytes to read from scanner to get document out of it after - * end of document dectected by hardware sensor */ - bytes_to_flush = lines * dev->wpl; - - /* if we are already close to end of scan, flushing isn't needed */ - if (bytes_to_flush < read_bytes_left) - { - /* we take all these step to work around an overflow on some plateforms */ - tmp = (int) dev->total_bytes_read; - DBG (DBG_io, "%s: tmp=%d\n", __func__, tmp); - bytes_remain = (int) dev->total_bytes_to_read; - DBG(DBG_io, "%s: bytes_remain=%d\n", __func__, bytes_remain); - bytes_remain = bytes_remain - tmp; - DBG(DBG_io, "%s: bytes_remain=%d\n", __func__, bytes_remain); - - /* remaining lines to read by frontend for the current scan */ - if (depth == 1 || dev->settings.scan_mode == ScanColorMode::LINEART) - { - flines = bytes_remain * 8 / dev->settings.pixels / channels; - } - else - flines = bytes_remain / (depth / 8) - / dev->settings.pixels / channels; - DBG(DBG_io, "%s: flines=%d\n", __func__, flines); - - if (flines > lines) - { - /* change the value controlling communication with the frontend : - * total bytes to read is current value plus the number of remaining lines - * multiplied by bytes per line */ - sublines = flines - lines; - - if (depth == 1 || dev->settings.scan_mode == ScanColorMode::LINEART) - sub_bytes = - ((dev->settings.pixels * sublines) / 8 + - (((dev->settings.pixels * sublines) % 8) ? 1 : 0)) * - channels; - else - sub_bytes = - dev->settings.pixels * sublines * channels * (depth / 8); - - dev->total_bytes_to_read -= sub_bytes; - - /* then adjust the physical bytes to read */ - if (read_bytes_left > sub_bytes) - { - dev->read_bytes_left -= sub_bytes; - } - else - { - dev->total_bytes_to_read = dev->total_bytes_read; - dev->read_bytes_left = 0; - } - - DBG(DBG_io, "%s: sublines=%d\n", __func__, sublines); - DBG(DBG_io, "%s: subbytes=%d\n", __func__, sub_bytes); - DBG(DBG_io, "%s: total_bytes_to_read=%lu\n", __func__, - (unsigned long) dev->total_bytes_to_read); - DBG(DBG_io, "%s: read_bytes_left=%d\n", __func__, read_bytes_left); - } - } - else - { - DBG(DBG_io, "%s: no flushing needed\n", __func__); - } - } - - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; -} - -// enables or disables XPA slider motor -static SANE_Status gl843_set_xpa_motor_power(Genesys_Device *dev, bool set) -{ - uint8_t val; - SANE_Status status=SANE_STATUS_GOOD; - - DBGSTART; - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) { - - if (set) { - RIE(sanei_genesys_read_register(dev, REG6C, &val)); - val &= ~REG6C_GPIO14; - if (dev->current_setup.xres >= 2400) { - val |= REG6C_GPIO10; - } - RIE(sanei_genesys_write_register(dev, REG6C, val)); - - RIE(sanei_genesys_read_register(dev, REGA6, &val)); - val |= REGA6_GPIO17; - RIE(sanei_genesys_write_register(dev, REGA6,val)); - } else { - RIE(sanei_genesys_read_register(dev, REG6C, &val)); - val |= REG6C_GPIO14; - val &= ~REG6C_GPIO10; - RIE(sanei_genesys_write_register(dev, REG6C, val)); - - RIE(sanei_genesys_read_register(dev, REGA6, &val)); - val &= ~REGA6_GPIO17; - RIE(sanei_genesys_write_register(dev, REGA6,val)); - } - DBGCOMPLETED; - return status; - } - - if (dev->model->model_id == MODEL_HP_SCANJET_G4050) { - - if (set) { - /* set MULTFILM et GPOADF */ - RIE (sanei_genesys_read_register (dev, REG6B, &val)); - val |=REG6B_MULTFILM|REG6B_GPOADF; - RIE (sanei_genesys_write_register (dev, REG6B, val)); - - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - val &= ~REG6C_GPIO15; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - - /* Motor power ? No move at all without this one */ - RIE (sanei_genesys_read_register (dev, REGA6, &val)); - val |= REGA6_GPIO20; - RIE (sanei_genesys_write_register(dev,REGA6,val)); - - RIE (sanei_genesys_read_register (dev, REGA8, &val)); - val &= ~REGA8_GPO27; - RIE (sanei_genesys_write_register (dev, REGA8, val)); - - RIE (sanei_genesys_read_register (dev, REGA9, &val)); - val |= REGA9_GPO32|REGA9_GPO31; - RIE (sanei_genesys_write_register (dev, REGA9, val)); - } else { - /* unset GPOADF */ - RIE (sanei_genesys_read_register (dev, REG6B, &val)); - val &= ~REG6B_GPOADF; - RIE (sanei_genesys_write_register (dev, REG6B, val)); - - RIE (sanei_genesys_read_register (dev, REGA8, &val)); - val |= REGA8_GPO27; - RIE (sanei_genesys_write_register (dev, REGA8, val)); - - RIE (sanei_genesys_read_register (dev, REGA9, &val)); - val &= ~REGA9_GPO31; - RIE (sanei_genesys_write_register (dev, REGA9, val)); - } - DBGCOMPLETED; - return status; - } - - DBGCOMPLETED; - return status; -} - - -/** @brief light XPA lamp - * toggle gpios to switch off regular lamp and light on the - * XPA light - * @param dev device to set up - */ -static SANE_Status gl843_set_xpa_lamp_power(Genesys_Device *dev, bool set) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val = 0; - DBGSTART; - - if (set) { - RIE(sanei_genesys_read_register(dev, REGA6, &val)); - - // cut regular lamp power - val &= ~(REGA6_GPIO24 | REGA6_GPIO23); - - // set XPA lamp power - val |= REGA6_GPIO22 | REGA6_GPIO21 | REGA6_GPIO19; - - RIE(sanei_genesys_write_register(dev, REGA6, val)); - - RIE(sanei_genesys_read_register(dev, REGA7, &val)); - val|=REGA7_GPOE24; /* lamp 1 off GPOE 24 */ - val|=REGA7_GPOE23; /* lamp 2 off GPOE 23 */ - val|=REGA7_GPOE22; /* full XPA lamp power */ - RIE(sanei_genesys_write_register(dev, REGA7, val)); - } else { - RIE(sanei_genesys_read_register(dev, REGA6, &val)); - - // switch on regular lamp - val |= REGA6_GPIO23; - - // no XPA lamp power (2 bits for level: __11 ____) - val &= ~(REGA6_GPIO22 | REGA6_GPIO21); - - RIE(sanei_genesys_write_register(dev, REGA6, val)); - } - - DBGCOMPLETED; - return status; -} - -/* Send the low-level scan command */ -static SANE_Status -gl843_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SANE_Bool start_motor) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - uint16_t dpiset, dpihw; - - DBGSTART; - - /* get back the target dpihw */ - sanei_genesys_get_double (reg, REG_DPISET, &dpiset); - dpihw = sanei_genesys_compute_dpihw(dev, sensor, dpiset); - - /* set up GPIO for scan */ - switch(dev->model->gpo_type) - { - /* KV case */ - case GPO_KVSS080: - RIE (sanei_genesys_write_register (dev, REGA9, 0x00)); - RIE (sanei_genesys_write_register (dev, REGA6, 0xf6)); - /* blinking led */ - RIE (sanei_genesys_write_register (dev, 0x7e, 0x04)); - break; - case GPO_G4050: - RIE (sanei_genesys_write_register (dev, REGA7, 0xfe)); - RIE (sanei_genesys_write_register (dev, REGA8, 0x3e)); - RIE (sanei_genesys_write_register (dev, REGA9, 0x06)); - switch (dpihw) - { - case 1200: - case 2400: - case 4800: - RIE (sanei_genesys_write_register (dev, REG6C, 0x60)); - RIE (sanei_genesys_write_register (dev, REGA6, 0x46)); - break; - default: /* 600 dpi case */ - RIE (sanei_genesys_write_register (dev, REG6C, 0x20)); - RIE (sanei_genesys_write_register (dev, REGA6, 0x44)); - } - - if (reg->state.is_xpa_on && reg->state.is_lamp_on) { - RIE(gl843_set_xpa_lamp_power(dev, true)); - } - - if (reg->state.is_xpa_on) { - dev->needs_home_ta = SANE_TRUE; - RIE(gl843_set_xpa_motor_power(dev, true)); - } - - /* blinking led */ - RIE (sanei_genesys_write_register (dev, REG7E, 0x01)); - break; - case GPO_CS8600F: - if (reg->state.is_xpa_on) { - dev->needs_home_ta = SANE_TRUE; - RIE(gl843_set_xpa_motor_power(dev, true)); - } - break; - case GPO_CS4400F: - case GPO_CS8400F: - default: - break; - } - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register - (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - - /* enable scan and motor */ - RIE (sanei_genesys_read_register (dev, REG01, &val)); - val |= REG01_SCAN; - RIE (sanei_genesys_write_register (dev, REG01, val)); - - if (start_motor) - { - RIE (sanei_genesys_write_register (dev, REG0F, 1)); - } - else - { - RIE (sanei_genesys_write_register (dev, REG0F, 0)); - } - - DBGCOMPLETED; - return status; -} - - -/* Send the stop scan command */ -static SANE_Status -gl843_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (check_stop = %d)\n", __func__, check_stop); - if (reg == NULL) - return SANE_STATUS_INVAL; - - /* post scan gpio */ - RIE(sanei_genesys_write_register(dev,0x7e,0x00)); - - // turn off XPA lamp if needed - // BUG: the if condition below probably shouldn't be enabled when XPA is off - if (reg->state.is_xpa_on || reg->state.is_lamp_on) { - gl843_set_xpa_lamp_power(dev, false); - } - - if (dev->model->is_sheetfed == SANE_TRUE) - { - status = SANE_STATUS_GOOD; - } - else /* flat bed scanners */ - { - status = gl843_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - return status; -} - -/** @brief park XPA lamp - * park the XPA lamp if needed - */ -static SANE_Status gl843_park_xpa_lamp (Genesys_Device * dev) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - uint8_t val; - int loop = 0; - - DBGSTART; - - /* copy scan settings */ - local_reg = dev->reg; - - /* set a huge feedl and reverse direction */ - sanei_genesys_set_triple(&local_reg,REG_FEEDL,0xbdcd); - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - - /* set up for reverse and no scan */ - r = sanei_genesys_get_address (&local_reg, REG02); - r->value |= REG02_MTRREV; - r = sanei_genesys_get_address (&local_reg, REG01); - r->value &= ~REG01_SCAN; - - /* write to scanner and start action */ - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - RIE(gl843_set_xpa_motor_power(dev, true)); - try { - status = gl843_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl843_stop_action(dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl843_stop_action (dev); - /* restore original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - while (loop < 600) /* do not wait longer then 60 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io2) - { - sanei_genesys_print_status (val); - } - - if (val & REG41_HOMESNR) /* home sensor */ - { - DBG(DBG_info, "%s: reached home position\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - - gl843_set_xpa_motor_power(dev, false); - dev->needs_home_ta = SANE_FALSE; - - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* we are not parked here.... should we fail ? */ - DBG(DBG_info, "%s: XPA lamp is not parked\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief Moves the slider to the home (top) position slowly - * */ -static SANE_Status -gl843_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - uint8_t val; - float resolution; - int loop = 0; - - DBG(DBG_proc, "%s (wait_until_home = %d)\n", __func__, wait_until_home); - - if (dev->needs_home_ta) { - RIE(gl843_park_xpa_lamp(dev)); - } - - /* regular slow back home */ - dev->scanhead_position_in_steps = 0; - - /* first read gives HOME_SENSOR true */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_sleep_ms(100); - - /* second is reliable */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - if (val & HOMESNR) /* is sensor at home? */ - { - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - local_reg = dev->reg; - resolution=sanei_genesys_get_lowest_ydpi(dev); - - const auto& sensor = sanei_genesys_find_sensor(dev, resolution); - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = 100; - session.params.starty = 40000; - session.params.pixels = 100; - session.params.lines = 100; - session.params.depth = 8; - session.params.channels = 1; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::LINEART; - session.params.color_filter = dev->settings.color_filter; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - gl843_compute_session(dev, session, sensor); - - status = gl843_init_scan_regs(dev, sensor, &local_reg, session); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - - /* set up for reverse and no scan */ - r = sanei_genesys_get_address(&local_reg, REG02); - r->value |= REG02_MTRREV; - r = sanei_genesys_get_address(&local_reg, REG01); - r->value &= ~REG01_SCAN; - - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - try { - status = gl843_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl843_stop_action(dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl843_stop_action (dev); - /* restore original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - if (wait_until_home) - { - - while (loop < 300) /* do not wait longer then 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io2) - { - sanei_genesys_print_status (val); - } - - if (val & REG41_HOMESNR) /* home sensor */ - { - DBG(DBG_info, "%s: reached home position\n", __func__); - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl843_stop_action (dev); - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels - area at 600 dpi from very top of scanner */ -static SANE_Status -gl843_search_start_position (Genesys_Device * dev) -{ - int size; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - int steps; - - int pixels = 600; - int dpi = 300; - - DBG(DBG_proc, "%s\n", __func__); - - local_reg = dev->reg; - - /* sets for a 200 lines * 600 pixels */ - /* normal scan with no shading */ - - // FIXME: the current approach of doing search only for one resolution does not work on scanners - // whith employ different sensors with potentially different settings. - auto& sensor = sanei_genesys_find_sensor_for_write(dev, dpi); - - ScanSession session; - session.params.xres = dpi; - session.params.yres = dpi; - session.params.startx = 0; - session.params.starty = 0; // we should give a small offset here - ~60 steps - session.params.pixels = 600; - session.params.lines = dev->model->search_lines; - session.params.depth = 8; - session.params.channels = 1; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::GRAY; - session.params.color_filter = ColorFilter::GREEN; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; - gl843_compute_session(dev, session, sensor); - - status = gl843_init_scan_regs(dev, sensor, &local_reg, session); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk setup registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* send to scanner */ - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - size = dev->read_bytes_left; - - std::vector<uint8_t> data(size); - - status = gl843_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - RIE(gl843_stop_action_no_move(dev, &local_reg)); - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl843_search_position.pnm", data.data(), 8, 1, pixels, - dev->model->search_lines); - - status = gl843_end_scan(dev, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* update regs to copy ASIC internal state */ - dev->reg = local_reg; - - status = - sanei_genesys_search_reference_point (dev, sensor, data.data(), 0, dpi, pixels, - dev->model->search_lines); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set search reference point: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - return SANE_STATUS_GOOD; -} - -/* - * sets up register for coarse gain calibration - * todo: check it for scanners using it */ -static SANE_Status -gl843_init_regs_for_coarse_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t channels; - uint8_t cksel; - - DBGSTART; - cksel = (regs.find_reg(0x18).value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */ - - /* set line size */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) { - flags |= SCAN_FLAG_USE_XPA; - } - - ScanSession session; - session.params.xres = dev->settings.xres; - session.params.yres = dev->settings.yres; - session.params.startx = 0; - session.params.starty = 0; - session.params.pixels = sensor.optical_res / cksel; // XXX STEF XXX dpi instead of pixels! - session.params.lines = 20; - session.params.depth = 16; - session.params.channels = channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = dev->settings.scan_mode; - session.params.color_filter = dev->settings.color_filter; - session.params.flags = flags; - gl843_compute_session(dev, session, sensor); - - status = gl843_init_scan_regs(dev, sensor, ®s, session); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_set_motor_power(regs, false); - - DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, - sensor.optical_res / cksel, dev->settings.xres); - - status = dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief moves the slider to steps at motor base dpi - * @param dev device to work on - * @param steps number of steps to move - * */ -static SANE_Status -gl843_feed (Genesys_Device * dev, unsigned int steps) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - float resolution; - uint8_t val; - - DBGSTART; - - /* prepare local registers */ - local_reg = dev->reg; - - resolution=sanei_genesys_get_lowest_ydpi(dev); - - const auto& sensor = sanei_genesys_find_sensor(dev, resolution); - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = 0; - session.params.starty = steps; - session.params.pixels = 100; - session.params.lines = 3; - session.params.depth = 8; - session.params.channels = 3; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - gl843_compute_session(dev, session, sensor); - - status = gl843_init_scan_regs(dev, sensor, &local_reg, session); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT)); - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRMCNT)); - - /* set up for no scan */ - r = sanei_genesys_get_address(&local_reg, REG01); - r->value &= ~REG01_SCAN; - - /* send registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - try { - status = gl843_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl843_stop_action(dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl843_stop_action (dev); - - /* restore original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - /* wait until feed count reaches the required value, but do not - * exceed 30s */ - do - { - status = sanei_genesys_get_status (dev, &val); - } - while (status == SANE_STATUS_GOOD && !(val & FEEDFSH)); - - // looks like the scanner locks up if we scan immediately after feeding - sanei_genesys_sleep_ms(100); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status gl843_move_to_ta (Genesys_Device * dev); - -/* init registers for shading calibration */ -/* shading calibration is done at dpihw */ -static SANE_Status -gl843_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - int move, resolution, dpihw, factor; - uint16_t strpixel; - - DBGSTART; - - /* initial calibration reg values */ - regs = dev->reg; - - dev->calib_channels = 3; - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) - dev->calib_lines = dev->model->shading_ta_lines; - else - dev->calib_lines = dev->model->shading_lines; - dpihw = sanei_genesys_compute_dpihw_calibration(dev, sensor, dev->settings.xres); - factor=sensor.optical_res/dpihw; - resolution=dpihw; - - const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, - dev->settings.scan_method); - - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY && - dev->model->model_id == MODEL_CANON_CANOSCAN_8600F && - dev->settings.xres == 4800) - { - float offset = SANE_UNFIX(dev->model->x_offset_ta); - offset /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); - offset = (offset * calib_sensor.optical_res) / MM_PER_INCH; - - unsigned size = SANE_UNFIX(dev->model->x_size_ta); - size /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); - size = (size * calib_sensor.optical_res) / MM_PER_INCH; - - dev->calib_pixels_offset = offset; - dev->calib_pixels = size; - } - else - { - dev->calib_pixels_offset = 0; - dev->calib_pixels = calib_sensor.sensor_pixels / factor; - } - - dev->calib_resolution = resolution; - - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) - { - // note: move_to_ta() function has already been called and the sensor is at the - // transparency adapter - move = 0; // already at dev->model->y_offset_calib_ta implicitly - flags |= SCAN_FLAG_USE_XPA; - } - else - move = SANE_UNFIX(dev->model->y_offset_calib); - - move = (move * resolution) / MM_PER_INCH; - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = dev->calib_pixels_offset; - session.params.starty = move; - session.params.pixels = dev->calib_pixels; - session.params.lines = dev->calib_lines; - session.params.depth = 16; - session.params.channels = dev->calib_channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = dev->settings.scan_mode; - session.params.color_filter = dev->settings.color_filter; - session.params.flags = flags; - gl843_compute_session(dev, session, calib_sensor); - - status = gl843_init_scan_regs(dev, calib_sensor, ®s, session); - - // the pixel number may be updated to conform to scanner constraints - dev->calib_pixels = dev->current_setup.pixels; - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - dev->calib_total_bytes_to_read = dev->read_bytes_left; - - dev->scanhead_position_in_steps += dev->calib_lines + move; - sanei_genesys_get_double(®s,REG_STRPIXEL,&strpixel); - DBG(DBG_info, "%s: STRPIXEL=%d\n", __func__, strpixel); - - status = dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief set up registers for the actual scan - */ -static SANE_Status -gl843_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int flags; - int depth; - float move; - int move_dpi; - float start; - - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - move_dpi = dev->motor.base_ydpi; - - flags = 0; - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) - { - // note: move_to_ta() function has already been called and the sensor is at the - // transparency adapter - move = SANE_UNFIX(dev->model->y_offset_ta) - SANE_UNFIX(dev->model->y_offset_calib_ta); - flags |= SCAN_FLAG_USE_XPA; - } - else - move = SANE_UNFIX(dev->model->y_offset); - - move += dev->settings.tl_y; - move = (move * move_dpi) / MM_PER_INCH; - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - /* start */ - if(dev->settings.scan_method==ScanMethod::TRANSPARENCY) - start = SANE_UNFIX (dev->model->x_offset_ta); - else - start = SANE_UNFIX (dev->model->x_offset); - - start /= sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres); - start += dev->settings.tl_x; - start = (start * sensor.optical_res) / MM_PER_INCH; - - /* enable emulated lineart from gray data */ - if(dev->settings.scan_mode == ScanColorMode::LINEART - && dev->settings.dynamic_lineart) - { - flags |= SCAN_FLAG_DYNAMIC_LINEART; - } - - ScanSession session; - session.params.xres = dev->settings.xres; - session.params.yres = dev->settings.yres; - session.params.startx = start; - session.params.starty = move; - session.params.pixels = dev->settings.pixels; - session.params.lines = dev->settings.lines; - session.params.depth = depth; - session.params.channels = channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = dev->settings.scan_mode; - session.params.color_filter = dev->settings.color_filter; - session.params.flags = flags; - gl843_compute_session(dev, session, sensor); - - status = gl843_init_scan_regs(dev, sensor, &dev->reg, session); - - if (status != SANE_STATUS_GOOD) - return status; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** - * This function sends gamma tables to ASIC - */ -static SANE_Status -gl843_send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor) -{ - int size; - SANE_Status status = SANE_STATUS_GOOD; - int i; - - DBGSTART; - - size = 256; - - /* allocate temporary gamma tables: 16 bits words, 3 channels */ - std::vector<uint8_t> gamma(size * 2 * 3); - - std::vector<uint16_t> rgamma = get_gamma_table(dev, sensor, GENESYS_RED); - std::vector<uint16_t> ggamma = get_gamma_table(dev, sensor, GENESYS_GREEN); - std::vector<uint16_t> bgamma = get_gamma_table(dev, sensor, GENESYS_BLUE); - - // copy sensor specific's gamma tables - for (i = 0; i < size; i++) { - gamma[i * 2 + size * 0 + 0] = rgamma[i] & 0xff; - gamma[i * 2 + size * 0 + 1] = (rgamma[i] >> 8) & 0xff; - gamma[i * 2 + size * 2 + 0] = ggamma[i] & 0xff; - gamma[i * 2 + size * 2 + 1] = (ggamma[i] >> 8) & 0xff; - gamma[i * 2 + size * 4 + 0] = bgamma[i] & 0xff; - gamma[i * 2 + size * 4 + 1] = (bgamma[i] >> 8) & 0xff; - } - - /* send address */ - status = gl843_set_buffer_address (dev, 0x0000); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* send data */ - status = sanei_genesys_bulk_write_data(dev, 0x28, gamma.data(), size * 2 * 3); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send gamma table: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; -} - -/* this function does the led calibration by scanning one line of the calibration - area below scanner's top on white strip. - --needs working coarse/gain -*/ -static SANE_Status -gl843_led_calibration (Genesys_Device * dev, Genesys_Sensor& sensor, Genesys_Register_Set& regs) -{ - int num_pixels; - int total_size; - int used_res; - int i, j; - SANE_Status status = SANE_STATUS_GOOD; - int val; - int channels, depth; - int avg[3], avga, avge; - int turn; - uint16_t expr, expg, expb; - - SANE_Bool acceptable = SANE_FALSE; - - DBG(DBG_proc, "%s\n", __func__); - - /* offset calibration is always done in color mode */ - channels = 3; - depth = 16; - used_res = sensor.optical_res; - - auto& calib_sensor = sanei_genesys_find_sensor_for_write(dev, used_res, - dev->settings.scan_method); - num_pixels = - (calib_sensor.sensor_pixels * used_res) / calib_sensor.optical_res; - - /* initial calibration reg values */ - regs = dev->reg; - - ScanSession session; - session.params.xres = used_res; - session.params.yres = dev->motor.base_ydpi; - session.params.startx = 0; - session.params.starty = 0; - session.params.pixels = num_pixels; - session.params.lines = 1; - session.params.depth = depth; - session.params.channels = channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - session.params.color_filter = dev->settings.color_filter; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - gl843_compute_session(dev, session, calib_sensor); - - status = gl843_init_scan_regs(dev, calib_sensor, ®s, session); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - total_size = dev->read_bytes_left; - - std::vector<uint8_t> line(total_size); - -/* - we try to get equal bright leds here: - - loop: - average per color - adjust exposure times - */ - - expr = calib_sensor.exposure.red; - expg = calib_sensor.exposure.green; - expb = calib_sensor.exposure.blue; - - turn = 0; - - do - { - - calib_sensor.exposure.red = expr; - calib_sensor.exposure.green = expg; - calib_sensor.exposure.blue = expb; - - sanei_genesys_set_exposure(regs, calib_sensor.exposure); - - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - DBG(DBG_info, "%s: starting first line reading\n", __func__); - RIE (gl843_begin_scan(dev, calib_sensor, ®s, SANE_TRUE)); - RIE (sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - RIE(gl843_stop_action_no_move(dev, ®s)); - - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl843_led_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, line.data(), depth, channels, num_pixels, 1); - } - - acceptable = SANE_TRUE; - - for (j = 0; j < channels; j++) - { - avg[j] = 0; - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * num_pixels + 1] * 256 + - line[i * 2 + j * 2 * num_pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - avg[j] += val; - } - - avg[j] /= num_pixels; - } - - DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); - - acceptable = SANE_TRUE; - - if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 || - avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 || - avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95) - acceptable = SANE_FALSE; - - if (!acceptable) - { - avga = (avg[0] + avg[1] + avg[2]) / 3; - expr = (expr * avga) / avg[0]; - expg = (expg * avga) / avg[1]; - expb = (expb * avga) / avg[2]; -/* - keep the resulting exposures below this value. - too long exposure drives the ccd into saturation. - we may fix this by relying on the fact that - we get a striped scan without shading, by means of - statistical calculation -*/ - avge = (expr + expg + expb) / 3; - - /* don't overflow max exposure */ - if (avge > 3000) - { - expr = (expr * 2000) / avge; - expg = (expg * 2000) / avge; - expb = (expb * 2000) / avge; - } - if (avge < 50) - { - expr = (expr * 50) / avge; - expg = (expg * 50) / avge; - expb = (expb * 50) / avge; - } - - } - - RIE (gl843_stop_action (dev)); - - turn++; - - } - while (!acceptable && turn < 100); - - DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, expr, expg, expb); - - sensor.exposure = calib_sensor.exposure; - - gl843_slow_back_home (dev, SANE_TRUE); - - DBG(DBG_proc, "%s: completed\n", __func__); - return status; -} - - - -/** - * average dark pixels of a 8 bits scan of a given channel - */ -static int -dark_average_channel (uint8_t * data, unsigned int pixels, unsigned int lines, - unsigned int channels, unsigned int black, int channel) -{ - unsigned int i, j, k, count; - unsigned int avg[3]; - uint8_t val; - - /* computes average values on black margin */ - for (k = 0; k < channels; k++) - { - avg[k] = 0; - count = 0; - // FIXME: start with the second line because the black pixels often have noise on the first - // line; the cause is probably incorrectly cleaned up previous scan - for (i = 1; i < lines; i++) - { - for (j = 0; j < black; j++) - { - val = data[i * channels * pixels + j*channels + k]; - avg[k] += val; - count++; - } - } - if (count) - avg[k] /= count; - DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); - } - DBG(DBG_info, "%s: average = %d\n", __func__, avg[channel]); - return avg[channel]; -} - -/** @brief calibrate AFE offset - * Iterate doing scans at target dpi until AFE offset if correct. One - * color line is scanned at a time. Scanning head doesn't move. - * @param dev device to calibrate - */ -static SANE_Status -gl843_offset_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - unsigned int channels, bpp; - int pass, total_size, i, resolution, lines; - int topavg[3], bottomavg[3], avg[3]; - int top[3], bottom[3], black_pixels, pixels, factor, dpihw; - - DBGSTART; - - /* offset calibration is always done in color mode */ - channels = 3; - lines = 8; - bpp = 8; - - /* compute divider factor to compute final pixels number */ - dpihw = sanei_genesys_compute_dpihw_calibration(dev, sensor, dev->settings.xres); - factor = sensor.optical_res / dpihw; - resolution = dpihw; - - const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, - dev->settings.scan_method); - - int target_pixels = calib_sensor.sensor_pixels / factor; - int start_pixel = 0; - black_pixels = calib_sensor.black_pixels / factor; - - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY && - dev->model->model_id == MODEL_CANON_CANOSCAN_8600F && - dev->settings.xres == 4800) - { - start_pixel = SANE_UNFIX(dev->model->x_offset_ta); - start_pixel /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); - start_pixel = (start_pixel * calib_sensor.optical_res) / MM_PER_INCH; - - target_pixels = SANE_UNFIX(dev->model->x_size_ta); - target_pixels /= calib_sensor.get_ccd_size_divisor_for_dpi(resolution); - target_pixels = (target_pixels * calib_sensor.optical_res) / MM_PER_INCH; - } - - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) - { - flags |= SCAN_FLAG_USE_XPA; - } - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = start_pixel; - session.params.starty = 0; - session.params.pixels = target_pixels; - session.params.lines = lines; - session.params.depth = bpp; - session.params.channels = channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - session.params.color_filter = ColorFilter::RED; - session.params.flags = flags; - gl843_compute_session(dev, session, calib_sensor); - pixels = session.output_pixels; - - DBG(DBG_io, "%s: dpihw =%d\n", __func__, dpihw); - DBG(DBG_io, "%s: factor =%d\n", __func__, factor); - DBG(DBG_io, "%s: resolution =%d\n", __func__, resolution); - DBG(DBG_io, "%s: pixels =%d\n", __func__, pixels); - DBG(DBG_io, "%s: black_pixels=%d\n", __func__, black_pixels); - status = gl843_init_scan_regs(dev, calib_sensor, ®s, session); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_set_motor_power(regs, false); - - /* allocate memory for scans */ - total_size = dev->read_bytes_left; - - std::vector<uint8_t> first_line(total_size); - std::vector<uint8_t> second_line(total_size); - - /* init gain and offset */ - for (i = 0; i < 3; i++) - { - bottom[i] = 10; - dev->frontend.set_offset(i, bottom[i]); - dev->frontend.set_gain(i, 0); - } - RIE(gl843_set_fe(dev, calib_sensor, AFE_SET)); - - /* scan with obttom AFE settings */ - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting first line reading\n", __func__); - RIE(gl843_begin_scan(dev, calib_sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size)); - RIE(gl843_stop_action_no_move(dev, ®s)); - - if (DBG_LEVEL >= DBG_data) - { - char fn[40]; - snprintf(fn, 40, "gl843_bottom_offset_%03d_%03d_%03d.pnm", - bottom[0], bottom[1], bottom[2]); - sanei_genesys_write_pnm_file(fn, first_line.data(), bpp, channels, pixels, lines); - } - - for (i = 0; i < 3; i++) - { - bottomavg[i] = dark_average_channel(first_line.data(), pixels, lines, channels, black_pixels, i); - DBG(DBG_io2, "%s: bottom avg %d=%d\n", __func__, i, bottomavg[i]); - } - - /* now top value */ - for (i = 0; i < 3; i++) - { - top[i] = 255; - dev->frontend.set_offset(i, top[i]); - } - RIE(gl843_set_fe(dev, calib_sensor, AFE_SET)); - - /* scan with top AFE values */ - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl843_begin_scan(dev, calib_sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size)); - RIE(gl843_stop_action_no_move(dev, ®s)); - - for (i = 0; i < 3; i++) - { - topavg[i] = dark_average_channel(second_line.data(), pixels, lines, channels, black_pixels, i); - DBG(DBG_io2, "%s: top avg %d=%d\n", __func__, i, topavg[i]); - } - - pass = 0; - - std::vector<uint8_t> debug_image; - size_t debug_image_lines = 0; - std::string debug_image_info; - - /* loop until acceptable level */ - while ((pass < 32) - && ((top[0] - bottom[0] > 1) - || (top[1] - bottom[1] > 1) || (top[2] - bottom[2] > 1))) - { - pass++; - - /* settings for new scan */ - for (i = 0; i < 3; i++) - { - if (top[i] - bottom[i] > 1) - { - dev->frontend.set_offset(i, (top[i] + bottom[i]) / 2); - } - } - RIE(gl843_set_fe(dev, calib_sensor, AFE_SET)); - - /* scan with no move */ - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl843_begin_scan(dev, calib_sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size)); - RIE(gl843_stop_action_no_move(dev, ®s)); - - if (DBG_LEVEL >= DBG_data) - { - char title[100]; - snprintf(title, 100, "lines: %d pixels_per_line: %d offsets[0..2]: %d %d %d\n", - lines, pixels, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - debug_image_info += title; - std::copy(second_line.begin(), second_line.end(), std::back_inserter(debug_image)); - debug_image_lines += lines; - } - - for (i = 0; i < 3; i++) - { - avg[i] = dark_average_channel(second_line.data(), pixels, lines, channels, black_pixels, i); - DBG(DBG_info, "%s: avg[%d]=%d offset=%d\n", __func__, i, avg[i], - dev->frontend.get_offset(i)); - } - - /* compute new boundaries */ - for (i = 0; i < 3; i++) - { - if (topavg[i] >= avg[i]) - { - topavg[i] = avg[i]; - top[i] = dev->frontend.get_offset(i); - } - else - { - bottomavg[i] = avg[i]; - bottom[i] = dev->frontend.get_offset(i); - } - } - } - - if (DBG_LEVEL >= DBG_data) - { - sanei_genesys_write_file("gl843_offset_all_desc.txt", - (uint8_t*) debug_image_info.data(), debug_image_info.size()); - sanei_genesys_write_pnm_file("gl843_offset_all.pnm", - debug_image.data(), bpp, channels, pixels, debug_image_lines); - } - - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* alternative coarse gain calibration - this on uses the settings from offset_calibration and - uses only one scanline - */ -/* - with offset and coarse calibration we only want to get our input range into - a reasonable shape. the fine calibration of the upper and lower bounds will - be done with shading. - */ -static SANE_Status -gl843_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi) -{ - int pixels, factor, dpihw; - int total_size; - int i, j, channels; - SANE_Status status = SANE_STATUS_GOOD; - int max[3]; - float coeff; - int val, lines; - int resolution; - int bpp; - - DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi); - dpihw=sanei_genesys_compute_dpihw_calibration(dev, sensor, dpi); - factor=sensor.optical_res/dpihw; - - /* coarse gain calibration is always done in color mode */ - channels = 3; - - /* follow CKSEL */ - if (dev->model->ccd_type == CCD_KVSS080) - { - if(dev->settings.xres<sensor.optical_res) - { - coeff=0.9; - } - else - { - coeff=1.0; - } - } - else - { - coeff=1.0; - } - resolution=dpihw; - lines=10; - bpp=8; - int target_pixels = sensor.sensor_pixels / factor; - - int flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - if (dev->settings.scan_method == ScanMethod::TRANSPARENCY) - { - flags |= SCAN_FLAG_USE_XPA; - } - - const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, - dev->settings.scan_method); - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = 0; - session.params.starty = 0; - session.params.pixels = target_pixels; - session.params.lines = lines; - session.params.depth = bpp; - session.params.channels = channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - session.params.color_filter = dev->settings.color_filter; - session.params.flags = flags; - gl843_compute_session(dev, session, calib_sensor); - pixels = session.output_pixels; - - try { - status = gl843_init_scan_regs(dev, calib_sensor, ®s, session); - } catch (...) { - try { - sanei_genesys_set_motor_power(regs, false); - } catch (...) {} - throw; - } - - sanei_genesys_set_motor_power(regs, false); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - total_size = dev->read_bytes_left; - - std::vector<uint8_t> line(total_size); - - RIE(gl843_set_fe(dev, calib_sensor, AFE_SET)); - RIE(gl843_begin_scan(dev, calib_sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, line.data(), total_size)); - RIE(gl843_stop_action_no_move(dev, ®s)); - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl843_gain.pnm", line.data(), bpp, channels, pixels, lines); - - /* average value on each channel */ - for (j = 0; j < channels; j++) - { - max[j] = 0; - // FIXME: start from the second line because the first line often has artifacts. Probably - // caused by unclean cleanup of previous scans - for (i = pixels/4 + pixels; i < (pixels*3/4) + pixels; i++) - { - if(bpp==16) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * pixels + 1] * 256 + - line[i * 2 + j * 2 * pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - } - else - { - if (dev->model->is_cis) - val = line[i + j * pixels]; - else - val = line[i * channels + j]; - } - - max[j] += val; - } - max[j] = max[j] / (pixels/2); - - /* the flow of data through the frontend ADC is as follows (see e.g. VM8192 datasheet) - input - -> apply offset (o = i + 260mV * (DAC[7:0]-127.5)/127.5) -> - -> apply gain (o = i * 208/(283-PGA[7:0]) - -> ADC - - Here we have some input data that was acquired with zero gain (PGA==0). - We want to compute gain such that the output would approach full ADC range (controlled by - gain_white_ref). - - We want to solve the following for {PGA}: - - {input} * 208 / (283 - 0) = {output} - {input} * 208 / (283 - {PGA}) = {target output} - - The solution is the following equation: - - {PGA} = 283 * (1 - {output} / {target output}) - */ - float gain = ((float) max[j] / (calib_sensor.gain_white_ref*coeff)); - int code = 283 * (1 - gain); - if (code > 255) - code = 255; - else if (code < 0) - code = 0; - dev->frontend.set_gain(j, code); - - DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain, - code); - } - - if (dev->model->is_cis) { - uint8_t gain0 = dev->frontend.get_gain(0); - if (gain0 > dev->frontend.get_gain(1)) { - gain0 = dev->frontend.get_gain(1); - } - if (gain0 > dev->frontend.get_gain(2)) { - gain0 = dev->frontend.get_gain(2); - } - dev->frontend.set_gain(0, gain0); - dev->frontend.set_gain(1, gain0); - dev->frontend.set_gain(2, gain0); - } - - if (channels == 1) { - dev->frontend.set_gain(0, dev->frontend.get_gain(1)); - dev->frontend.set_gain(2, dev->frontend.get_gain(1)); - } - - RIE (gl843_stop_action (dev)); - - status=gl843_slow_back_home (dev, SANE_TRUE); - - DBGCOMPLETED; - return status; -} - -/* - * wait for lamp warmup by scanning the same line until difference - * between 2 scans is below a threshold - */ -static SANE_Status -gl843_init_regs_for_warmup (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - int *channels, int *total_size) -{ - int num_pixels; - SANE_Status status = SANE_STATUS_GOOD; - int dpihw; - int resolution; - int factor; - - DBGSTART; - if (dev == NULL || reg == NULL || channels == NULL || total_size == NULL) - return SANE_STATUS_INVAL; - - /* setup scan */ - *channels=3; - resolution=600; - dpihw=sanei_genesys_compute_dpihw_calibration(dev, sensor, resolution); - resolution=dpihw; - - const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, - dev->settings.scan_method); - factor = calib_sensor.optical_res/dpihw; - num_pixels = calib_sensor.sensor_pixels/(factor*2); - *total_size = num_pixels * 3 * 1; - - *reg = dev->reg; - - ScanSession session; - session.params.xres = resolution; - session.params.yres = resolution; - session.params.startx = num_pixels/2; - session.params.starty = 0; - session.params.pixels = num_pixels; - session.params.lines = 1; - session.params.depth = 8; - session.params.channels = *channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - session.params.color_filter = dev->settings.color_filter; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - gl843_compute_session(dev, session, calib_sensor); - - status = gl843_init_scan_regs(dev, calib_sensor, reg, session); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - sanei_genesys_set_motor_power(*reg, false); - RIE(dev->model->cmd_set->bulk_write_register(dev, *reg)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** - * set up GPIO/GPOE for idle state -WRITE GPIO[17-21]= GPIO19 -WRITE GPOE[17-21]= GPOE21 GPOE20 GPOE19 GPOE18 -genesys_write_register(0xa8,0x3e) -GPIO(0xa8)=0x3e - */ -static SANE_Status -gl843_init_gpio (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - int idx; - - DBGSTART; - - RIE (sanei_genesys_write_register (dev, REG6E, dev->gpo.enable[0])); - RIE (sanei_genesys_write_register (dev, REG6F, dev->gpo.enable[1])); - RIE (sanei_genesys_write_register (dev, REG6C, dev->gpo.value[0])); - RIE (sanei_genesys_write_register (dev, REG6D, dev->gpo.value[1])); - - idx=0; - while(dev->model->gpo_type != gpios[idx].gpo_type && gpios[idx].gpo_type!=0) - { - idx++; - } - if (gpios[idx].gpo_type!=0) - { - RIE (sanei_genesys_write_register (dev, REGA6, gpios[idx].ra6)); - RIE (sanei_genesys_write_register (dev, REGA7, gpios[idx].ra7)); - RIE (sanei_genesys_write_register (dev, REGA8, gpios[idx].ra8)); - RIE (sanei_genesys_write_register (dev, REGA9, gpios[idx].ra9)); - } - else - { - status=SANE_STATUS_INVAL; - } - - DBGCOMPLETED; - return status; -} - - -/* * - * initialize ASIC from power on condition - */ -static SANE_Status -gl843_boot (Genesys_Device * dev, SANE_Bool cold) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - DBGSTART; - - if(cold) - { - RIE (sanei_genesys_write_register (dev, 0x0e, 0x01)); - RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); - } - - if(dev->usb_mode == 1) - { - val = 0x14; - } - else - { - val = 0x11; - } - RIE (sanei_genesys_write_0x8c (dev, 0x0f, val)); - - /* test CHKVER */ - RIE (sanei_genesys_read_register (dev, REG40, &val)); - if (val & REG40_CHKVER) - { - RIE (sanei_genesys_read_register (dev, 0x00, &val)); - DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); - } - - /* Set default values for registers */ - gl843_init_registers (dev); - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - // turns on vref control for maximum current of the motor driver - RIE(sanei_genesys_write_register (dev, REG6B, 0x72)); - } - else - { - RIE(sanei_genesys_write_register (dev, REG6B, 0x02)); - } - - /* Write initial registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, dev->reg)); - - // Enable DRAM by setting a rising edge on bit 3 of reg 0x0b - val = dev->reg.find_reg(0x0b).value & REG0B_DRAMSEL; - val = (val | REG0B_ENBDRAM); - RIE (sanei_genesys_write_register (dev, REG0B, val)); - dev->reg.find_reg(0x0b).value = val; - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - RIE (sanei_genesys_write_0x8c (dev, 0x10, 0xc8)); - } - else - { - RIE (sanei_genesys_write_0x8c (dev, 0x10, 0xb4)); - } - - /* CLKSET */ - int clock_freq = REG0B_48MHZ; - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - clock_freq = REG0B_60MHZ; - - val = (dev->reg.find_reg(0x0b).value & ~REG0B_CLKSET) | clock_freq; - - RIE (sanei_genesys_write_register (dev, REG0B, val)); - dev->reg.find_reg(0x0b).value = val; - - /* prevent further writings by bulk write register */ - dev->reg.remove_reg(0x0b); - - if (dev->model->model_id != MODEL_CANON_CANOSCAN_8600F) - { - // set up end access - // FIXME: this is overwritten in gl843_init_gpio - sanei_genesys_write_register(dev, REGA7, 0x04); - sanei_genesys_write_register(dev, REGA9, 0x00); - } - - /* set RAM read address */ - RIE (sanei_genesys_write_register (dev, REG29, 0x00)); - RIE (sanei_genesys_write_register (dev, REG2A, 0x00)); - RIE (sanei_genesys_write_register (dev, REG2B, 0x00)); - - /* setup gpio */ - RIE (gl843_init_gpio (dev)); - - gl843_feed (dev, 300); - sanei_genesys_sleep_ms(100); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* * - * initialize backend and ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home - */ -static SANE_Status -gl843_init (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG_INIT (); - DBGSTART; - - status=sanei_genesys_asic_init(dev, 0); - - DBGCOMPLETED; - return status; -} - -static SANE_Status -gl843_update_hardware_sensors (Genesys_Scanner * s) -{ - /* do what is needed to get a new set of events, but try to not lose - any of them. - */ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - RIE (sanei_genesys_read_register (s->dev, REG6D, &val)); - - switch (s->dev->model->gpo_type) - { - case GPO_KVSS080: - s->buttons[BUTTON_SCAN_SW].write((val & 0x04) == 0); - break; - case GPO_G4050: - s->buttons[BUTTON_SCAN_SW].write((val & 0x01) == 0); - s->buttons[BUTTON_FILE_SW].write((val & 0x02) == 0); - s->buttons[BUTTON_EMAIL_SW].write((val & 0x04) == 0); - s->buttons[BUTTON_COPY_SW].write((val & 0x08) == 0); - break; - case GPO_CS4400F: - case GPO_CS8400F: - default: - break; - } - - return status; -} - -/** @brief move sensor to transparency adaptor - * Move sensor to the calibration of the transparency adapator (XPA). - * @param dev device to use - */ -static SANE_Status -gl843_move_to_ta (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - float resolution; - unsigned int feed; - - DBGSTART; - - resolution=sanei_genesys_get_lowest_ydpi(dev); - feed = 16*(SANE_UNFIX (dev->model->y_offset_calib_ta) * resolution) / MM_PER_INCH; - status = gl843_feed (dev, feed); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move to XPA calibration area\n", __func__); - return status; - } - - DBGCOMPLETED; - return status; -} - - -/** @brief search for a full width black or white strip. - * This function searches for a black or white stripe across the scanning area. - * When searching backward, the searched area must completely be of the desired - * color since this area will be used for calibration which scans forward. - * @param dev scanner device - * @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward - * @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip - * @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not - */ -static SANE_Status -gl843_search_strip (Genesys_Device * dev, const Genesys_Sensor& sensor, - SANE_Bool forward, SANE_Bool black) -{ - unsigned int pixels, lines, channels; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - size_t size; - int steps, depth, dpi; - unsigned int pass, count, found, x, y; - GenesysRegister *r; - - DBG(DBG_proc, "%s %s %s\n", __func__, black ? "black" : "white", forward ? "forward" : "reverse"); - - gl843_set_fe(dev, sensor, AFE_SET); - status = gl843_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* set up for a gray scan at lowest dpi */ - dpi = sanei_genesys_get_lowest_dpi(dev); - channels = 1; - - const auto& calib_sensor = sanei_genesys_find_sensor(dev, dpi, dev->settings.scan_method); - - /* 10 MM */ - /* lines = (10 * dpi) / MM_PER_INCH; */ - /* shading calibation is done with dev->motor.base_ydpi */ - lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; - depth = 8; - pixels = (calib_sensor.sensor_pixels * dpi) / calib_sensor.optical_res; - - dev->scanhead_position_in_steps = 0; - - local_reg = dev->reg; - - ScanSession session; - session.params.xres = dpi; - session.params.yres = dpi; - session.params.startx = 0; - session.params.starty = 0; - session.params.pixels = pixels; - session.params.lines = lines; - session.params.depth = depth; - session.params.channels = channels; - session.params.scan_method = dev->settings.scan_method; - session.params.scan_mode = ScanColorMode::GRAY; - session.params.color_filter = ColorFilter::RED; - session.params.flags = SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_SHADING; - gl843_compute_session(dev, session, calib_sensor); - - status = gl843_init_scan_regs(dev, calib_sensor, &local_reg, session); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup for scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - size = dev->read_bytes_left; - std::vector<uint8_t> data(size); - - /* set up for reverse or forward */ - r = sanei_genesys_get_address(&local_reg, REG02); - if (forward) - r->value &= ~REG02_MTRREV; - else - r->value |= REG02_MTRREV; - - - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl843_begin_scan(dev, calib_sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl843_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl843_stop_action failed\n", __func__); - return status; - } - - pass = 0; - if (DBG_LEVEL >= DBG_data) - { - char fn[40]; - snprintf(fn, 40, "gl843_search_strip_%s_%s%02d.pnm", - black ? "black" : "white", forward ? "fwd" : "bwd", (int)pass); - sanei_genesys_write_pnm_file(fn, data.data(), depth, channels, pixels, lines); - } - - /* loop until strip is found or maximum pass number done */ - found = 0; - while (pass < 20 && !found) - { - status = - dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* now start scan */ - status = gl843_begin_scan(dev, calib_sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl843_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl843_stop_action failed\n", __func__); - return status; - } - - if (DBG_LEVEL >= DBG_data) - { - char fn[40]; - snprintf(fn, 40, "gl843_search_strip_%s_%s%02d.pnm", - black ? "black" : "white", forward ? "fwd" : "bwd", (int)pass); - sanei_genesys_write_pnm_file(fn, data.data(), depth, channels, pixels, lines); - } - - /* search data to find black strip */ - /* when searching forward, we only need one line of the searched color since we - * will scan forward. But when doing backward search, we need all the area of the - * same color */ - if (forward) - { - for (y = 0; y < lines && !found; y++) - { - count = 0; - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > 90) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < 60) - { - count++; - } - } - - /* at end of line, if count >= 3%, line is not fully of the desired color - * so we must go to next line of the buffer */ - /* count*100/pixels < 3 */ - if ((count * 100) / pixels < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, - pass, y); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - } - else /* since calibration scans are done forward, we need the whole area - to be of the required color when searching backward */ - { - count = 0; - for (y = 0; y < lines; y++) - { - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > 90) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < 60) - { - count++; - } - } - } - - /* at end of area, if count >= 3%, area is not fully of the desired color - * so we must go to next buffer */ - if ((count * 100) / (pixels * lines) < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - pass++; - } - if (found) - { - status = SANE_STATUS_GOOD; - DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); - } - else - { - status = SANE_STATUS_UNSUPPORTED; - DBG(DBG_info, "%s: %s strip not found\n", __func__, black ? "black" : "white"); - } - - DBG(DBG_proc, "%s: completed\n", __func__); - return status; -} - -/** - * Send shading calibration data. The buffer is considered to always hold values - * for all the channels. - */ -static SANE_Status -gl843_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint32_t final_size, length, i; - uint8_t *buffer; - int count,offset; - unsigned int cksel; - GenesysRegister *r; - uint16_t dpiset, strpixel, endpixel, startx, factor; - - DBGSTART; - - offset=0; - length=size; - r = sanei_genesys_get_address(&dev->reg, REG01); - if(r->value & REG01_SHDAREA) - { - /* recompute STRPIXEL used shading calibration so we can - * compute offset within data for SHDAREA case */ - r = sanei_genesys_get_address(&dev->reg, REG18); - cksel= (r->value & REG18_CKSEL)+1; - sanei_genesys_get_double(&dev->reg,REG_DPISET,&strpixel); - sanei_genesys_get_double(&dev->reg,REG_DPISET,&dpiset); - factor=sensor.optical_res/sanei_genesys_compute_dpihw(dev, sensor, dpiset); - - /* start coordinate in optical dpi coordinates */ - startx = (sensor.dummy_pixel / cksel) / factor; - - /* current scan coordinates */ - sanei_genesys_get_double(&dev->reg,REG_STRPIXEL,&strpixel); - sanei_genesys_get_double(&dev->reg,REG_ENDPIXEL,&endpixel); - - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - int optical_res = sensor.optical_res / dev->current_setup.ccd_size_divisor; - int dpiset_real = dpiset / dev->current_setup.ccd_size_divisor; - int half_ccd_factor = optical_res / - sanei_genesys_compute_dpihw_calibration(dev, sensor, dpiset_real); - strpixel /= half_ccd_factor; - endpixel /= half_ccd_factor; - } - - /* 16 bit words, 2 words per color, 3 color channels */ - offset=(strpixel-startx)*2*2*3; - length=(endpixel-strpixel)*2*2*3; - DBG(DBG_info, "%s: STRPIXEL=%d, ENDPIXEL=%d, startx=%d\n", __func__, strpixel, endpixel, - startx); - } - - /* compute and allocate size for final data */ - final_size = ((length+251) / 252) * 256; - DBG(DBG_io, "%s: final shading size=%04x (length=%d)\n", __func__, final_size, length); - std::vector<uint8_t> final_data(final_size, 0); - - /* copy regular shading data to the expected layout */ - buffer = final_data.data(); - count = 0; - - /* loop over calibration data */ - for (i = 0; i < length; i++) - { - buffer[count] = data[offset+i]; - count++; - if ((count % (256*2)) == (252*2)) - { - count += 4*2; - } - } - - /* send data */ - status = sanei_genesys_set_buffer_address (dev, 0); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set buffer address: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = dev->model->cmd_set->bulk_write_data (dev, 0x3c, final_data.data(), count); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to send shading table: %s\n", __func__, sane_strstatus(status)); - } - - DBGCOMPLETED; - return status; -} - - -/** the gl843 command set */ -static Genesys_Command_Set gl843_cmd_set = { - "gl843-generic", /* the name of this set */ - - [](Genesys_Device* dev) -> bool { (void) dev; return true; }, - - gl843_init, - gl843_init_regs_for_warmup, - gl843_init_regs_for_coarse_calibration, - gl843_init_regs_for_shading, - gl843_init_regs_for_scan, - - gl843_get_filter_bit, - gl843_get_lineart_bit, - gl843_get_bitset_bit, - gl843_get_gain4_bit, - gl843_get_fast_feed_bit, - gl843_test_buffer_empty_bit, - gl843_test_motor_flag_bit, - - gl843_set_fe, - gl843_set_powersaving, - gl843_save_power, - - gl843_begin_scan, - gl843_end_scan, - - gl843_send_gamma_table, - - gl843_search_start_position, - - gl843_offset_calibration, - gl843_coarse_gain_calibration, - gl843_led_calibration, - - NULL, - gl843_slow_back_home, - NULL, - - sanei_genesys_bulk_write_register, - sanei_genesys_bulk_write_data, - sanei_genesys_bulk_read_data, - - gl843_update_hardware_sensors, - - gl843_load_document, - gl843_detect_document_end, - gl843_eject_document, - gl843_search_strip, - - sanei_genesys_is_compatible_calibration, - gl843_move_to_ta, - gl843_send_shading_data, - gl843_calculate_current_setup, - gl843_boot -}; - -SANE_Status -sanei_gl843_init_cmd_set (Genesys_Device * dev) -{ - dev->model->cmd_set = &gl843_cmd_set; - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_gl843.h b/backend/genesys_gl843.h deleted file mode 100644 index 7651cc9..0000000 --- a/backend/genesys_gl843.h +++ /dev/null @@ -1,472 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#include "genesys.h" - -#define REG01 0x01 -#define REG01_CISSET 0x80 -#define REG01_DOGENB 0x40 -#define REG01_DVDSET 0x20 -#define REG01_STAGGER 0x10 -#define REG01_COMPENB 0x08 -#define REG01_TRUEGRAY 0x04 -#define REG01_SHDAREA 0x02 -#define REG01_SCAN 0x01 - -#define REG02 0x02 -#define REG02_NOTHOME 0x80 -#define REG02_ACDCDIS 0x40 -#define REG02_AGOHOME 0x20 -#define REG02_MTRPWR 0x10 -#define REG02_FASTFED 0x08 -#define REG02_MTRREV 0x04 -#define REG02_HOMENEG 0x02 -#define REG02_LONGCURV 0x01 - -#define REG03 0x03 -#define REG03_LAMPDOG 0x80 -#define REG03_AVEENB 0x40 -#define REG03_XPASEL 0x20 -#define REG03_LAMPPWR 0x10 -#define REG03_LAMPTIM 0x0f - -#define REG04 0x04 -#define REG04_LINEART 0x80 -#define REG04_BITSET 0x40 -#define REG04_AFEMOD 0x30 -#define REG04_FILTER 0x0c -#define REG04_FESET 0x03 - -#define REG04S_AFEMOD 4 - -#define REG05 0x05 -#define REG05_DPIHW 0xc0 -#define REG05_DPIHW_600 0x00 -#define REG05_DPIHW_1200 0x40 -#define REG05_DPIHW_2400 0x80 -#define REG05_DPIHW_4800 0xc0 -#define REG05_MTLLAMP 0x30 -#define REG05_GMMENB 0x08 -#define REG05_MTLBASE 0x03 - -#define REG06 0x06 -#define REG06_SCANMOD 0xe0 -#define REG06S_SCANMOD 5 -#define REG06_PWRBIT 0x10 -#define REG06_GAIN4 0x08 -#define REG06_OPTEST 0x07 - -#define REG07_LAMPSIM 0x80 - -#define REG08_DECFLAG 0x40 -#define REG08_GMMFFR 0x20 -#define REG08_GMMFFG 0x10 -#define REG08_GMMFFB 0x08 -#define REG08_GMMZR 0x04 -#define REG08_GMMZG 0x02 -#define REG08_GMMZB 0x01 - -#define REG09_MCNTSET 0xc0 -#define REG09_EVEN1ST 0x20 -#define REG09_BLINE1ST 0x10 -#define REG09_BACKSCAN 0x08 -#define REG09_ENHANCE 0x04 -#define REG09_SHORTTG 0x02 -#define REG09_NWAIT 0x01 - -#define REG09S_MCNTSET 6 -#define REG09S_CLKSET 4 - -#define REG0B 0x0b -#define REG0B_DRAMSEL 0x07 -#define REG0B_ENBDRAM 0x08 -#define REG0B_ENBDRAM 0x08 -#define REG0B_RFHDIS 0x10 -#define REG0B_CLKSET 0xe0 -#define REG0B_24MHZ 0x00 -#define REG0B_30MHZ 0x20 -#define REG0B_40MHZ 0x40 -#define REG0B_48MHZ 0x60 -#define REG0B_60MHZ 0x80 - -#define REG0D 0x0d -#define REG0D_JAMPCMD 0x80 -#define REG0D_DOCCMD 0x40 -#define REG0D_CCDCMD 0x20 -#define REG0D_FULLSTP 0x10 -#define REG0D_SEND 0x08 -#define REG0D_CLRMCNT 0x04 -#define REG0D_CLRDOCJM 0x02 -#define REG0D_CLRLNCNT 0x01 - -#define REG0F 0x0f - -#define REG_EXPR 0x10 -#define REG_EXPG 0x12 -#define REG_EXPB 0x14 - -#define REG16_CTRLHI 0x80 -#define REG16_TOSHIBA 0x40 -#define REG16_TGINV 0x20 -#define REG16_CK1INV 0x10 -#define REG16_CK2INV 0x08 -#define REG16_CTRLINV 0x04 -#define REG16_CKDIS 0x02 -#define REG16_CTRLDIS 0x01 - -#define REG17_TGMODE 0xc0 -#define REG17_TGMODE_NO_DUMMY 0x00 -#define REG17_TGMODE_REF 0x40 -#define REG17_TGMODE_XPA 0x80 -#define REG17_TGW 0x3f -#define REG17S_TGW 0 - -#define REG18 0x18 -#define REG18_CNSET 0x80 -#define REG18_DCKSEL 0x60 -#define REG18_CKTOGGLE 0x10 -#define REG18_CKDELAY 0x0c -#define REG18_CKSEL 0x03 - -#define REG_EXPDMY 0x19 - -#define REG1A_TGLSW2 0x80 -#define REG1A_TGLSW1 0x40 -#define REG1A_MANUAL3 0x02 -#define REG1A_MANUAL1 0x01 -#define REG1A_CK4INV 0x08 -#define REG1A_CK3INV 0x04 -#define REG1A_LINECLP 0x02 - -#define REG1C 0x1c -#define REG1C_TGTIME 0x07 - -#define REG1D_CK4LOW 0x80 -#define REG1D_CK3LOW 0x40 -#define REG1D_CK1LOW 0x20 -#define REG1D_TGSHLD 0x1f -#define REG1DS_TGSHLD 0 - - -#define REG1E 0x1e -#define REG1E_WDTIME 0xf0 -#define REG1ES_WDTIME 4 -#define REG1E_LINESEL 0x0f -#define REG1ES_LINESEL 0 - -#define REG21 0x21 -#define REG_STEPNO 0x21 -#define REG_FWDSTEP 0x22 -#define REG_BWDSTEP 0x23 -#define REG_FASTNO 0x24 -#define REG_LINCNT 0x25 - -#define REG29 0x29 -#define REG2A 0x2a -#define REG2B 0x2b -#define REG_DPISET 0x2c -#define REG2E 0x2e -#define REG2F 0x2f - -#define REG_STRPIXEL 0x30 -#define REG_ENDPIXEL 0x32 -#define REG_DUMMY 0x34 -#define REG_MAXWD 0x35 -#define REG_LPERIOD 0x38 -#define REG_FEEDL 0x3d - -#define REG40 0x40 -#define REG40_DOCSNR 0x80 -#define REG40_ADFSNR 0x40 -#define REG40_COVERSNR 0x20 -#define REG40_CHKVER 0x10 -#define REG40_DOCJAM 0x08 -#define REG40_HISPDFLG 0x04 -#define REG40_MOTMFLG 0x02 -#define REG40_DATAENB 0x01 - -#define REG41_PWRBIT 0x80 -#define REG41_BUFEMPTY 0x40 -#define REG41_FEEDFSH 0x20 -#define REG41_SCANFSH 0x10 -#define REG41_HOMESNR 0x08 -#define REG41_LAMPSTS 0x04 -#define REG41_FEBUSY 0x02 -#define REG41_MOTORENB 0x01 - -#define REG58_VSMP 0xf8 -#define REG58S_VSMP 3 -#define REG58_VSMPW 0x07 -#define REG58S_VSMPW 0 - -#define REG59_BSMP 0xf8 -#define REG59S_BSMP 3 -#define REG59_BSMPW 0x07 -#define REG59S_BSMPW 0 - -#define REG5A_ADCLKINV 0x80 -#define REG5A_RLCSEL 0x40 -#define REG5A_CDSREF 0x30 -#define REG5AS_CDSREF 4 -#define REG5A_RLC 0x0f -#define REG5AS_RLC 0 - -#define REG5E 0x5e -#define REG5E_DECSEL 0xe0 -#define REG5ES_DECSEL 5 -#define REG5E_STOPTIM 0x1f -#define REG5ES_STOPTIM 0 - -#define REG_FMOVDEC 0x5f - -#define REG60 0x60 -#define REG60_Z1MOD 0x1f -#define REG61 0x61 -#define REG61_Z1MOD 0xff -#define REG62 0x62 -#define REG62_Z1MOD 0xff - -#define REG63 0x63 -#define REG63_Z2MOD 0x1f -#define REG64 0x64 -#define REG64_Z2MOD 0xff -#define REG65 0x65 -#define REG65_Z2MOD 0xff - -#define REG67 0x67 - -#define REG68 0x68 - -#define REG67S_STEPSEL 6 -#define REG67_STEPSEL 0xc0 -#define REG67_FULLSTEP 0x00 -#define REG67_HALFSTEP 0x20 -#define REG67_EIGHTHSTEP 0x60 -#define REG67_16THSTEP 0x80 - -#define REG68S_FSTPSEL 6 -#define REG68_FSTPSEL 0xc0 -#define REG68_FULLSTEP 0x00 -#define REG68_HALFSTEP 0x20 -#define REG68_EIGHTHSTEP 0x60 -#define REG68_16THSTEP 0x80 - -#define REG_FSHDEC 0x69 -#define REG_FMOVNO 0x6a - -#define REG6B 0x6b -#define REG6B_MULTFILM 0x80 -#define REG6B_GPOM13 0x40 -#define REG6B_GPOM12 0x20 -#define REG6B_GPOM11 0x10 -#define REG6B_GPOCK4 0x08 -#define REG6B_GPOCP 0x04 -#define REG6B_GPOLEDB 0x02 -#define REG6B_GPOADF 0x01 - -#define REG6C 0x6c -#define REG6C_GPIO16 0x80 -#define REG6C_GPIO15 0x40 -#define REG6C_GPIO14 0x20 -#define REG6C_GPIO13 0x10 -#define REG6C_GPIO12 0x08 -#define REG6C_GPIO11 0x04 -#define REG6C_GPIO10 0x02 -#define REG6C_GPIO9 0x01 -#define REG6C_GPIOH 0xff -#define REG6C_GPIOL 0xff - -#define REG_Z1MOD 0x60 -#define REG_Z2MOD 0x63 - -#define REG6D 0x6d -#define REG6E 0x6e -#define REG6F 0x6f - -#define REG_CK1MAP 0x74 -#define REG_CK3MAP 0x77 -#define REG_CK4MAP 0x7a - -#define REG7E 0x7e - -#define REG9D 0x9d -#define REG9DS_STEPTIM 2 - -#define REG87_LEDADD 0x04 - -#define REGA6 0xa6 -#define REGA6_GPIO24 0x80 -#define REGA6_GPIO23 0x40 -#define REGA6_GPIO22 0x20 -#define REGA6_GPIO21 0x10 -#define REGA6_GPIO20 0x08 -#define REGA6_GPIO19 0x04 -#define REGA6_GPIO18 0x02 -#define REGA6_GPIO17 0x01 -#define REGA7 0xa7 -#define REGA7_GPOE24 0x80 -#define REGA7_GPOE23 0x40 -#define REGA7_GPOE22 0x20 -#define REGA7_GPOE21 0x10 -#define REGA7_GPOE20 0x08 -#define REGA7_GPOE19 0x04 -#define REGA7_GPOE18 0x02 -#define REGA7_GPOE17 0x01 -#define REGA8 0xa8 -#define REGA8_GPOE27 0x20 -#define REGA8_GPOE26 0x10 -#define REGA8_GPOE25 0x08 -#define REGA8_GPO27 0x04 -#define REGA8_GPO26 0x02 -#define REGA8_GPO25 0x01 -#define REGA9 0xa9 -#define REGA9_GPO33 0x20 -#define REGA9_GPO32 0x10 -#define REGA9_GPO31 0x08 -#define REGA9_GPO30 0x04 -#define REGA9_GPO29 0x02 -#define REGA9_GPO28 0x01 - -#define SCAN_TABLE 0 /* table 1 at 0x4000 */ -#define BACKTRACK_TABLE 1 /* table 2 at 0x4800 */ -#define STOP_TABLE 2 /* table 3 at 0x5000 */ -#define FAST_TABLE 3 /* table 4 at 0x5800 */ -#define HOME_TABLE 4 /* table 5 at 0x6000 */ - -#define SCAN_FLAG_SINGLE_LINE 0x001 -#define SCAN_FLAG_DISABLE_SHADING 0x002 -#define SCAN_FLAG_DISABLE_GAMMA 0x004 -#define SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE 0x008 -#define SCAN_FLAG_IGNORE_LINE_DISTANCE 0x010 -#define SCAN_FLAG_USE_OPTICAL_RES 0x020 -#define SCAN_FLAG_DISABLE_LAMP 0x040 -#define SCAN_FLAG_DYNAMIC_LINEART 0x080 - -#define SETREG(adr,val) { dev->reg.init_reg(adr, val); } - -typedef struct -{ - SANE_Int gpo_type; - uint8_t ra6; - uint8_t ra7; - uint8_t ra8; - uint8_t ra9; -} Gpio_layout; - -static Gpio_layout gpios[]={ - /* G4050 */ - { - GPO_G4050, 0x08, 0x1e, 0x3e, 0x06 - }, - /* KV-SS080 */ - { - GPO_KVSS080, 0x06, 0x0f, 0x00, 0x08 - }, - /* 4400F */ - { - GPO_CS4400F, 0x00, 0xff, 0x07, 0x00 - }, - /* 8400F */ - { - GPO_CS8400F, 0x00, 0x03, 0x00, 0x02 - }, - { - GPO_CS8600F, 0x00, 0xff, 0x00, 0x00, - }, - /* end marker */ - { - 0, 0, 0, 0, 0 - }, -}; - - -static uint32_t kvss080[]={44444, 34188, 32520, 29630, 26666, 24242, 22222, 19048, 16666, 15686, 14814, 14034, 12402, 11110, 8888, 7618, 6666, 5926, 5228, 4678, 4172, 3682, 3336, 3074, 2866, 2702, 2566, 2450, 2352, 2266, 2188, 2118, 2056, 2002, 1950, 1904, 1860, 1820, 1784, 1748, 1716, 1684, 1656, 1628, 1600, 1576, 1552, 1528, 1506, 1486, 1466, 1446, 1428, 1410, 1394, 1376, 1360, 1346, 1330, 1316, 1302, 1288, 1276, 1264, 1250, 1238, 1228, 1216, 1206, 1194, 1184, 1174, 1164, 1154, 1146, 1136, 1128, 1120, 1110, 1102, 1094, 1088, 1080, 1072, 1064, 1058, 1050, 1044, 1038, 1030, 1024, 1018, 1012, 1006, 1000, 994, 988, 984, 978, 972, 968, 962, 958, 952, 948, 942, 938, 934, 928, 924, 920, 916, 912, 908, 904, 900, 896, 892, 888, 884, 882, 878, 874, 870, 868, 864, 860, 858, 854, 850, 848, 844, 842, 838, 836, 832, 830, 826, 824, 822, 820, 816, 814, 812, 808, 806, 804, 802, 800, 796, 794, 792, 790, 788, 786, 784, 782, 778, 776, 774, 772, 770, 768, 766, 764, 762, 760, 758, 756, 754, 752, 750, 750, 748, 746, 744, 742, 740, 738, 736, 734, 734, 732, 730, 728, 726, 724, 724, 722, 720, 718, 716, 716, 714, 712, 710, 710, 708, 706, 704, 704, 702, 700, 698, 698, 696, 694, 694, 692, 690, 690, 688, 686, 686, 684, 682, 682, 680, 678, 678, 676, 674, 674, 672, 672, 670, 668, 668, 666, 666, 664, 662, 662, 660, 660, 658, 656, 656, 654, 654, 652, 652, 650, 650, 648, 646, 646, 644, 644, 642, 642, 640, 640, 638, 638, 636, 636, 636, 634, 634, 632, 632, 630, 630, 628, 628, 626, 626, 624, 624, 624, 622, 622, 620, 620, 618, 618, 618, 616, 616, 614, 614, 612, 612, 612, 610, 610, 608, 608, 608, 606, 606, 606, 604, 604, 602, 602, 602, 600, 600, 600, 598, 598, 596, 596, 596, 594, 594, 594, 592, 592, 592, 590, 590, 590, 588, 588, 588, 586, 586, 586, 584, 584, 584, 582, 582, 582, 590, 590, 590, 588, 588, 588, 586, 586, 586, 584, 584, 584, 582, 582, 582, 580, 580, 580, 578, 578, 578, 576, 576, 576, 576, 574, 574, 574, 572, 572, 572, 570, 570, 570, 568, 568, 568, 568, 566, 566, 566, 564, 564, 564, 562, 562, 562, 562, 560, 560, 560, 558, 558, 558, 558, 556, 556, 556, 554, 554, 554, 552, 552, 552, 552, 550, 550, 550, 548, 548, 548, 548, 546, 546, 546, 546, 544, 544, 544, 542, 542, 542, 542, 540, 540, 540, 538, 538, 538, 538, 536, 536, 536, 536, 534, 534, 534, 534, 532, 532, 532, 530, 530, 530, 530, 528, 528, 528, 528, 526, 526, 526, 526, 524, 524, 524, 524, 522, 522, 522, 522, 520, 520, 520, 520, 518, 518, 518, 516, 516, 516, 516, 514, 514, 514, 514, 514, 512, 512, 512, 512, 510, 510, 510, 510, 508, 508, 508, 508, 506, 506, 506, 506, 504, 504, 504, 504, 502, 502, 502, 502, 500, 500, 500, 500, 0}; -static uint32_t g4050_fast[]={7842,5898,4384,4258,4152,4052,3956,3864,3786,3714,3632,3564,3498,3444,3384,3324,3276,3228,3174,3128,3086,3044,3002,2968,2930,2892,2860,2824,2794,2760,2732,2704,2676,2650,2618,2594,2568,2548,2524,2500,2478,2454,2436,2414,2392,2376,2354,2338,2318,2302,2282,2266,2252,2232,2218,2202,2188,2174,2160,2142,2128,2116,2102,2088,2076,2062,2054,2040,2028,2020,2014,2008,2004,2002,2002,2002,1946,1882,1826,1770,1716,1662,1612,1568,1526,1488,1454,1422,1390,1362,1336,1310,1288,1264,1242,1222,1204,1184,1166,1150,1134,1118,1104,1090,1076,1064,1050,1038,1026,1016,1004,994,984,972,964,954,944,936,928,920,910,902,896,888,880,874,866,860,854,848,840,834,828,822,816,812,806,800,796,790,784,780,776,770,766,760,756,752,748,744,740,736,732,728,724,720,716,712,708,704,702,698,694,690,688,684,682,678,674,672,668,666,662,660,656,654,650,648,646,644,640,638,636,632,630,628,624,622,620,618,616,614,610,608,606,604,602,600,598,596,594,592,590,588,586,584,582,580,578,576,574,572,570,568,566,564,564,562,560,558,556,554,552,552,550,548,546,546,544,542,540,538,538,536,534,532,532,530,528,528,526,524,522,522,520,518,518,516,514,514,512,512,510,508,508,506,504,504,502,502,500,498,498,496,496,494,494,492,490,490,488,488,486,486,484,484,482,480,480,478,478,476,476,474,474,472,472,470,470,468,468,468,466,466,464,464,462,462,460,460,458,458,456,456,456,454,454,452,452,450,450,450,448,448,446,446,444,444,444,442,442,440,440,440,438,438,438,436,436,434,434,434,432,432,432,430,430,428,428,428,426,426,426,424,424,424,422,422,422,420,420,420,418,418,418,416,416,416,414,414,414,412,412,412,410,410,410,408,408,408,406,406,406,404,404,404,404,402,402,402,400,400,400,400,398,398,398,396,396,396,396,394,394,394,392,392,392,392,390,390,390,388,388,388,388,386,386,386,386,384,384,384,384,382,382,382,382,380,380,380,380,378,378,378,378,376,376,376,376,376,374,374,374,374,374,372,372,372,372,372,370,370,370,370,370,368,368,368,368,368,366,366,366,366,366,364,364,364,364,364,364,362,362,362,362,362,360,360,360,360,360,360,358,358,358,358,358,358,356,356,356,356,356,356,354,354,354,354,354,352,352,352,352,352,352,350,350,350,350,350,350,350,348,348,348,348,348,348,346,346,346,346,346,346,344,344,344,344,344,344,344,342,342,342,342,342,342,340,340,340,340,340,340,340,338,338,338,338,338,338,338,336,336,336,336,336,336,336,334,334,334,334,334,334,334,332,332,332,332,332,332,332,332,330,330,330,330,330,330,330,328,328,328,328,328,328,328,328,326,326,326,326,326,326,326,324,324,324,324,324,324,324,324,322,322,322,322,322,322,322,322,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320, 0}; -static uint32_t g4050_high[]={28032,28032,28032,28032,28032,28032,28032,28032, 27668,27024,26479,25975,25402,24926,24465,24087,23667,23248,22912,22576,22198,21877,21583,21289,20996,20758,20492,20226,20002,19751,19541,19303,19107,18911,18715,18534,18310,18142,17960,17820,17652,17485,17331,17163,17037,16883,16729,16617,16463,16352,16212,16100,15960,15848,15750,15610,15512,15400,15302,15204,15107,14981,14883,14799,14701,14603,14519,14421,14365,14267,14183,14127,14085,14043,14016,14002,14002,14002,13610,13162,12771,12379,12001,11624,11274,10966,10672,10407,10169,9945,9721,9525,9344,9162,9008,8840,8686,8546,8420,8280,8155,8043,7931,7819,7721,7623,7525,7441,7343,7259,7175,7105,7021,6952,6882,6798,6742,6672,6602,6546,6490,6434,6364,6308,6266,6210,6154,6112,6056,6014,5972,5930,5874,5833,5791,5749,5707,5679,5637,5595,5567,5525,5483,5455,5427,5385,5357,5315,5287,5259,5231,5203,5175,5147,5119,5091,5063,5035,5007,4979,4951,4923,4909,4881,4853,4825,4811,4783,4769,4741,4713,4699,4672,4658,4630,4616,4588,4574,4546,4532,4518,4504,4476,4462,4448,4420,4406,4392,4364,4350,4336,4322,4308,4294,4266,4252,4238,4224,4210,4196,4182,4168,4154,4140,4126,4112,4098,4084,4070,4056,4042,4028,4014,4000,3986,3972,3958,3944,3944,3930,3916,3902,3888,3874,3860,3860,3846,3832,3818,3818,3804,3790,3776,3762,3762,3748,3734,3720,3720,3706,3692,3692,3678,3664,3650,3650,3636,3622,3622,3608,3594,3594,3580,3580,3566,3552,3552,3538,3524,3524,3510,3510,3497,3483,3483,3469,3469,3455,3455,3441,3427,3427,3413,3413,3399,3399,3385,3385,3371,3357,3357,3343,3343,3329,3329,3315,3315,3301,3301,3287,3287,3273,3273,3273,3259,3259,3245,3245,3231,3231,3217,3217,3203,3203,3189,3189,3189,3175,3175,3161,3161,3147,3147,3147,3133,3133,3119,3119,3105,3105,3105,3091,3091,3077,3077,3077,3063,3063,3063,3049,3049,3035,3035,3035,3021,3021,3021,3007,3007,2993,2993,2993,2979,2979,2979,2965,2965,2965,2951,2951,2951,2937,2937,2937,2923,2923,2923,2909,2909,2909,2895,2895,2895,2881,2881,2881,2867,2867,2867,2853,2853,2853,2839,2839,2839,2825,2825,2825,2825,2811,2811,2811,2797,2797,2797,2797,2783,2783,2783,2769,2769,2769,2769,2755,2755,2755,2741,2741,2741,2741,2727,2727,2727,2713,2713,2713,2713,2699,2699,2699,2699,2685,2685,2685,2685,2671,2671,2671,2671,2657,2657,2657,2657,2643,2643,2643,2643,2629,2629,2629,2629,2629,2615,2615,2615,2615,2615,2601,2601,2601,2601,2601,2587,2587,2587,2587,2587,2573,2573,2573,2573,2573,2559,2559,2559,2559,2559,2545,2545,2545,2545,2545,2545,2531,2531,2531,2531,2531,2517,2517,2517,2517,2517,2517,2503,2503,2503,2503,2503,2503,2489,2489,2489,2489,2489,2489,2475,2475,2475,2475,2475,2461,2461,2461,2461,2461,2461,2447,2447,2447,2447,2447,2447,2447,2433,2433,2433,2433,2433,2433,2419,2419,2419,2419,2419,2419,2405,2405,2405,2405,2405,2405,2405,2391,2391,2391,2391,2391,2391,2377,2377,2377,2377,2377,2377,2377,2363,2363,2363,2363,2363,2363,2363,2349,2349,2349,2349,2349,2349,2349,2336,2336,2336,2336,2336,2336,2336,2322,2322,2322,2322,2322,2322,2322,2322,2308,2308,2308,2308,2308,2308,2308,2294,2294,2294,2294,2294,2294,2294,2294,2280,2280,2280,2280,2280,2280,2280,2266,2266,2266,2266,2266,2266,2266,2266,2252,2252,2252,2252,2252,2252,2252,2252,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238,2238, 0}; -static uint32_t g4050_max[]={42752,42752,42752,42752,42752,42752,42752,42752, 41824,31456,23381,22709,22144,21610,21098,20608,20192,19808,19370,19008,18656,18368,18048,17728,17472,17216,16928,16682,16458,16234,16010,15829,15626,15424,15253,15061,14901,14720,14570,14421,14272,14133,13962,13834,13696,13589,13461,13333,13216,13088,12992,12874,12757,12672,12554,12469,12362,12277,12170,12085,12010,11904,11829,11744,11669,11594,11520,11424,11349,11285,11210,11136,11072,10997,10954,10880,10816,10773,10741,10709,10688,10677,10677,10677,10378,10037,9738,9440,9152,8864,8597,8362,8138,7936,7754,7584,7413,7264,7125,6986,6869,6741,6624,6517,6421,6314,6218,6133,6048,5962,5888,5813,5738,5674,5600,5536,5472,5418,5354,5301,5248,5184,5141,5088,5034,4992,4949,4906,4853,4810,4778,4736,4693,4661,4618,4586,4554,4522,4480,4448,4416,4384,4352,4330,4298,4266,4245,4213,4181,4160,4138,4106,4085,4053,4032,4010,3989,3968,3946,3925,3904,3882,3861,3840,3818,3797,3776,3754,3744,3722,3701,3680,3669,3648,3637,3616,3594,3584,3562,3552,3530,3520,3498,3488,3466,3456,3445,3434,3413,3402,3392,3370,3360,3349,3328,3317,3306,3296,3285,3274,3253,3242,3232,3221,3210,3200,3189,3178,3168,3157,3146,3136,3125,3114,3104,3093,3082,3072,3061,3050,3040,3029,3018,3008,3008,2997,2986,2976,2965,2954,2944,2944,2933,2922,2912,2912,2901,2890,2880,2869,2869,2858,2848,2837,2837,2826,2816,2816,2805,2794,2784,2784,2773,2762,2762,2752,2741,2741,2730,2730,2720,2709,2709,2698,2688,2688,2677,2677,2666,2656,2656,2645,2645,2634,2634,2624,2613,2613,2602,2602,2592,2592,2581,2581,2570,2560,2560,2549,2549,2538,2538,2528,2528,2517,2517,2506,2506,2496,2496,2496,2485,2485,2474,2474,2464,2464,2453,2453,2442,2442,2432,2432,2432,2421,2421,2410,2410,2400,2400,2400,2389,2389,2378,2378,2368,2368,2368,2357,2357,2346,2346,2346,2336,2336,2336,2325,2325,2314,2314,2314,2304,2304,2304,2293,2293,2282,2282,2282,2272,2272,2272,2261,2261,2261,2250,2250,2250,2240,2240,2240,2229,2229,2229,2218,2218,2218,2208,2208,2208,2197,2197,2197,2186,2186,2186,2176,2176,2176,2165,2165,2165,2154,2154,2154,2154,2144,2144,2144,2133,2133,2133,2133,2122,2122,2122,2112,2112,2112,2112,2101,2101,2101,2090,2090,2090,2090,2080,2080,2080,2069,2069,2069,2069,2058,2058,2058,2058,2048,2048,2048,2048,2037,2037,2037,2037,2026,2026,2026,2026,2016,2016,2016,2016,2005,2005,2005,2005,2005,1994,1994,1994,1994,1994,1984,1984,1984,1984,1984,1973,1973,1973,1973,1973,1962,1962,1962,1962,1962,1952,1952,1952,1952,1952,1941,1941,1941,1941,1941,1941,1930,1930,1930,1930,1930,1920,1920,1920,1920,1920,1920,1909,1909,1909,1909,1909,1909,1898,1898,1898,1898,1898,1898,1888,1888,1888,1888,1888,1877,1877,1877,1877,1877,1877,1866,1866,1866,1866,1866,1866,1866,1856,1856,1856,1856,1856,1856,1845,1845,1845,1845,1845,1845,1834,1834,1834,1834,1834,1834,1834,1824,1824,1824,1824,1824,1824,1813,1813,1813,1813,1813,1813,1813,1802,1802,1802,1802,1802,1802,1802,1792,1792,1792,1792,1792,1792,1792,1781,1781,1781,1781,1781,1781,1781,1770,1770,1770,1770,1770,1770,1770,1770,1760,1760,1760,1760,1760,1760,1760,1749,1749,1749,1749,1749,1749,1749,1749,1738,1738,1738,1738,1738,1738,1738,1728,1728,1728,1728,1728,1728,1728,1728,1717,1717,1717,1717,1717,1717,1717,1717,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,1706,0}; -static uint32_t g4050_xpa[]={9422,5978,4736,4028,3560,3220,2914,2756,2588,2448,2328,2224,2132,2052,1978,1914,1854,1800,1752,1706,1664,1626,1588,1554,1522,1492,1464,1438,1412,1388,1366,1344,1324,1304,1284,1268,1250,1232,1218,1202,1188,1172,1160,1146,1134,1120,1110,1098,1086,1076,1066,1056,1046,1036,1026,1018,1008,1000,992,984,976,968,960,952,946,938,932,924,918,912,906,898,892,888,882,876,870,864,860,854,848,844,838,834,828,824,820,814,810,806,802,798,794,790,786,782,778,774,770,766,762,758,754,752,748,744,740,738,734,730,728,724,722,718,716,712,710,706,704,700,698,696,692,690,686,684,682,678,676,674,672,668,666,664,662,660,656,654,652,650,648,646,644,642,638,636,634,632,630,628,626,624,622,620,618,616,614,612,612,610,608,606,604,602,600,598,596,594,594,592,590,588,586,584,584,582,580,578,576,576,574,572,570,570,568,566,564,564,562,560,560,558,556,554,554,552,550,550,548,546,546,544,542,542,540,540,538,536,536,534,532,532,530,530,528,526,526,524,524,522,522,520,518,518,516,516,514,514,512,512,510,508,508,506,506,504,504,502,502,500,500,498,498,496,496,494,494,492,492,492,490,490,488,488,486,486,484,484,482,482,480,480,480,478,478,476,476,474,474,474,472,472,470,470,468,468,468,466,466,464,464,464,462,462,462,460,460,458,458,458,456,456,454,454,454,452,452,452,450,450,450,448,448,446,446,446,444,444,444,442,442,442,440,440,440,438,438,438,436,436,436,434,434,434,432,432,432,430,430,430,430,428,428,428,426,426,426,424,424,424,424,422,422,422,420,420,420,418,418,418,418,416,416,416,414,414,414,414,412,412,412,412,410,410,410,408,408,408,408,406,406,406,406,404,404,404,404,402,402,402,402,400,400,400,400,398,398,398,398,396,396,396,396,394,394,394,394,392,392,392,392,392,390,390,390,390,388,388,388,388,386,386,386,386,386,384,384,384,384,384,382,382,382,382,380,380,380,380,380,378,378,378,378,378,376,376,376,376,376,374,374,374,374,374,372,372,372,372,372,370,370,370,370,370,368,368,368,368,368,366,366,366,366,366,364,364,364,364,364,364,362,362,362,362,362,360,360,360,360,360,360,358,358,358,358,358,358,356,356,356,356,356,354,354,354,354,354,354,352,352,352,352,352,352,350,350,350,350,350,350,350,348,348,348,348,348,348,346,346,346,346,346,346,344,344,344,344,344,344,344,342,342,342,342,342,342,340,340,340,340,340,340,340,338,338,338,338,338,338,338,336,336,336,336,336,336,336,334,334,334,334,334,334,334,332,332,332,332,332,332,332,330,330,330,330,330,330,330,330,328,328,328,328,328,328,328,326,326,326,326,326,326,326,326,324,324,324,324,324,324,324,324,322,322,322,322,322,322,322,322,320,320,320,320,320,320,320,320,318,318,318,318,318,318,318,318,318,316,316,316,316,316,316,316,316,314,314,314,314,314,314,314,314,314,312,312,312,312,312,312,312,312,312,310,310,310,310,310,310,310,310,310,308,308,308,308,308,308,308,308,308,306,306,306,306,306,306,306,306,306,306,304,304,304,304,304,304,304,304,304,302,302,302,302,302,302,302,302,302,302,300,300,300,300,300,300,300,300,300,300,298,298,298,298,298,298,298,298,298,298,298,296,296,296,296,296,296,296,296,296,296,294,294,294,294,294,294,294,294,294,294,294,292,292,292,292,292,292,292,292,292,292,292,290,290,290,290,290,290,290,290,290,290,290,288,288,288,288,288,288,288,288,288,288,288,288,286,286,286,286,286,286,286,286,286,286,286,286,284,284,284,284,284,284,284,284,284,284,284,284,282,282,282,282,282,282,282,282,282,282,282,282,280,280,280,280,280,280,280,280,280,280,280,280,280,278,278,278,278,278,278,278,278,278,278,278,278,278,276,276,276,276,276,276,276,276,276,276,276,276,276,274,274,274,274,274,274,274,274,274,274,274,274,274,274,272,272,272,272,272,272,272,272,272,272,272,272,272,272,270,270,270,270,270,270,270,270,270,270,270,270,270,270,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,0}; -static uint32_t cs4400f_fast[]={49152, 49152, 31144, 23652, 19538, 16822, 14908, 13442, 12288, 11356, 10590, 9922, 9362, 8886, 8456, 8064, 7728, 7418, 7148, 6882, 6664, 6446, 6252, 6060, 5890, 5740, 5586, 5450, 5322, 5198, 5080, 4968, 4868, 4766, 4674, 4584, 4500, 4418, 4338, 4262, 4194, 4122, 4058, 3996, 3932, 3874, 3816, 3766, 3712, 3662, 3610, 3566, 3518, 3474, 3430, 3388, 3350, 3310, 3272, 3236, 3200, 3164, 3130, 3096, 3062, 3032, 3000, 2972, 2942, 2914, 2884, 2858, 2832, 2806, 2780, 2756, 2732, 2708, 2686, 2662, 2640, 2618, 2596, 2576, 2554, 2536, 2516, 2496, 2478, 2458, 2440, 2422, 2404, 2388, 2370, 2354, 2338, 2320, 2306, 2290, 2276, 2258, 2244, 2230, 2216, 2202, 2188, 2174, 2162, 2148, 2134, 2122, 2108, 2096, 2084, 2072, 2060, 2048, 2036, 2026, 2014, 2002, 1992, 1982, 1970, 1960, 1950, 1940, 1928, 1920, 1908, 1900, 1890, 1880, 1872, 1862, 1852, 1844, 1834, 1826, 1818, 1808, 1800, 1792, 1784, 1776, 1768, 1760, 1752, 1742, 1736, 1728, 1720, 1712, 1704, 1698, 1690, 1684, 1676, 1670, 1662, 1656, 1648, 1642, 1634, 1628, 1622, 1616, 1608, 1602, 1596, 1590, 1584, 1578, 1572, 1566, 1560, 1554, 1548, 1542, 1536, 1532, 1526, 1520, 1514, 1508, 1504, 1498, 1492, 1488, 1482, 1478, 1472, 1466, 1462, 1456, 1452, 1446, 1442, 1438, 1432, 1428, 1424, 1418, 1414, 1410, 1404, 1400, 1396, 1390, 1386, 1382, 1378, 1374, 1370, 1364, 1360, 1356, 1352, 1348, 1344, 1340, 1336, 1332, 1328, 1324, 1320, 1316, 1312, 1308, 1304, 1302, 1298, 1294, 1290, 1286, 1282, 1278, 1276, 1272, 1268, 1264, 1262, 1258, 1254, 1250, 1248, 1244, 1240, 1238, 1234, 1230, 1228, 1224, 1222, 1218, 1214, 1212, 1208, 1206, 1202, 1200, 1196, 1194, 1190, 1186, 1184, 1182, 1178, 1176, 1172, 1170, 1166, 1164, 1162, 1158, 1156, 1152, 1150, 1148, 1144, 1142, 1138, 1136, 1134, 1130, 1128, 1126, 1122, 1120, 1118, 1116, 1112, 1110, 1108, 1106, 1102, 1100, 1098, 1096, 1092, 1090, 1088, 1086, 1082, 1080, 1078, 1076, 1074, 1072, 1068, 1066, 1064, 1062, 1060, 1058, 1056, 1054, 1052, 1048, 1046, 1044, 1042, 1040, 1038, 1036, 1034, 1032, 1030, 1028, 1026, 1024, 1022, 1020, 1018, 1016, 1014, 1012, 1010, 1008, 1006, 1004, 1002, 1000, 998, 996, 994, 992, 990, 988, 986, 984, 982, 980, 978, 976, 974, 972, 972, 970, 968, 966, 964, 962, 960, 958, 956, 956, 954, 952, 950, 948, 946, 944, 944, 942, 940, 938, 936, 934, 934, 932, 930, 928, 926, 926, 924, 922, 920, 918, 918, 916, 914, 912, 912, 910, 908, 906, 904, 904, 902, 900, 898, 898, 896, 894, 892, 892, 890, 888, 888, 886, 884, 882, 882, 880, 878, 878, 876, 874, 874, 872, 870, 868, 868, 866, 864, 864, 862, 860, 860, 858, 856, 856, 854, 852, 852, 850, 848, 848, 846, 846, 844, 842, 842, 840, 838, 838, 836, 834, 834, 832, 832, 830, 828, 828, 826, 826, 824, 822, 822, 820, 820, 818, 816, 816, 814, 814, 812, 812, 810, 808, 808, 806, 806, 804, 802, 802, 800, 800, 798, 798, 796, 796, 794, 792, 792, 790, 790, 788, 788, 786, 786, 784, 784, 782, 782, 780, 780, 778, 778, 776, 774, 774, 772, 772, 770, 770, 768, 768, 766, 766, 764, 764, 762, 762, 760, 760, 758, 758, 758, 756, 756, 754, 754, 752, 752, 750, 750, 748, 748, 746, 746, 744, 744, 742, 742, 740, 740, 738, 738, 738, 736, 736, 734, 734, 732, 732, 730, 730, 730, 728, 728, 726, 726, 724, 724, 722, 722, 722, 720, 720, 718, 718, 718, 716, 716, 714, 714, 712, 712, 712, 710, 710, 708, 708, 708, 706, 706, 704, 704, 702, 702, 702, 700, 700, 698, 698, 698, 696, 696, 694, 694, 694, 692, 692, 692, 690, 690, 688, 688, 688, 686, 686, 684, 684, 684, 682, 682, 682, 680, 680, 680, 678, 678, 676, 676, 676, 674, 674, 674, 672, 672, 670, 670, 670, 668, 668, 668, 666, 666, 666, 664, 664, 664, 662, 662, 660, 660, 660, 658, 658, 658, 656, 656, 656, 654, 654, 654, 652, 652, 652, 650, 650, 650, 648, 648, 648, 646, 646, 646, 644, 644, 644, 642, 642, 642, 640, 640, 640, 640, 638, 638, 638, 636, 636, 636, 634, 634, 634, 632, 632, 632, 630, 630, 630, 630, 628, 628, 628, 626, 626, 626, 624, 624, 624, 624, 622, 622, 622, 620, 620, 620, 618, 618, 618, 618, 616, 616, 616, 614, 614, 614, 614, 612, 612, 612, 610, 610, 610, 610, 608, 608, 608, 606, 606, 606, 606, 604, 604, 604, 604, 602, 602, 602, 600, 600, 600, 600, 598, 598, 598, 598, 596, 596, 596, 594, 594, 594, 594, 592, 592, 592, 592, 590, 590, 590, 590, 588, 588, 588, 586, 586, 586, 586, 584, 584, 584, 584, 582, 582, 582, 582, 580, 580, 580, 580, 578, 578, 578, 578, 576, 576, 576, 576, 574, 574, 574, 574, 574, 572, 572, 572, 572, 570, 570, 570, 570, 568, 568, 568, 568, 566, 566, 566, 566, 564, 564, 564, 564, 564, 562, 562, 562, 562, 560, 560, 560, 560, 558, 558, 558, 558, 558, 556, 556, 556, 556, 554, 554, 554, 554, 554, 552, 552, 552, 552, 550, 550, 550, 550, 550, 548, 548, 548, 548, 546, 546, 546, 546, 546, 544, 544, 544, 544, 544, 542, 542, 542, 542, 540, 540, 540, 540, 540, 538, 538, 538, 538, 538, 536, 536, 536, 536, 536, 534, 534, 534, 534, 534, 532, 532, 532, 532, 532, 530, 530, 530, 530, 530, 528, 528, 528, 528, 528, 526, 526, 526, 526, 526, 524, 524, 524, 524, 524, 522, 522, 522, 522, 522, 520, 520, 520, 520, 520, 520, 518, 518, 518, 518, 518, 516, 516, 516, 516, 516, 514, 514, 514, 514, 514, 514, 512, 512, 512, 512, 512, 510, 510, 510, 510, 510, 510, 508, 508, 508, 508, 508, 506, 506, 506, 506, 506, 506, 504, 504, 504, 504, 504, 502, 502, 502, 502, 502, 502, 500, 500, 500, 500, 500, 500, 498, 498, 498, 498, 498, 498, 496, 496, 496, 496, 496, 496, 494, 494, 494, 494, 494, 494, 492, 492, 492, 492, 492, 492, 490, 490, 490, 490, 490, 490, 488, 488, 488, 488, 488, 488, 486, 486, 486, 486, 486, 486, 484, 484, 484, 484, 484, 484, 484, 0, 0, 0, 0, 0}; -static uint32_t cs8400f_fast[]={8743, 8205, 7017, 6201, 4938, 4016, 3371, 2966, 2682, 2469, 2296, 2159, 2041, 1942, 1857, 1782, 1716, 1656, 1602, 1554, 1510, 1470, 1432, 1398, 1366, 1336, 1309, 1282, 1258, 1235, 1213, 1193, 1173, 1154, 1137, 1120, 1104, 1089, 1074, 1060, 1047, 1034, 1022, 1010, 998, 987, 976, 966, 956, 946, 937, 928, 919, 911, 902, 894, 887, 879, 872, 864, 858, 851, 844, 838, 832, 825, 819, 814, 808, 802, 797, 792, 786, 781, 776, 771, 766, 762, 757, 753, 748, 744, 740, 736, 731, 728, 724, 720, 716, 712, 709, 705, 701, 698, 695, 691, 688, 685, 682, 679, 675, 672, 669, 666, 664, 661, 658, 655, 652, 650, 647, 644, 642, 639, 637, 634, 632, 629, 627, 625, 622, 620, 618, 616, 613, 611, 609, 607, 605, 603, 601, 599, 597, 595, 593, 591, 589, 587, 585, 583, 581, 580, 578, 576, 574, 573, 571, 569, 567, 566, 564, 563, 561, 559, 558, 556, 555, 553, 552, 550, 549, 547, 546, 544, 543, 542, 540, 539, 537, 536, 535, 533, 532, 531, 529, 528, 527, 526, 524, 523, 522, 521, 519, 518, 517, 516, 515, 514, 512, 511, 510, 509, 508, 507, 506, 505, 504, 502, 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, 488, 487, 486, 485, 484, 483, 482, 481, 480, 479, 478, 477, 477, 476, 475, 474, 473, 472, 472, 471, 470, 469, 468, 467, 467, 466, 465, 464, 464, 463, 462, 461, 460, 460, 459, 458, 457, 457, 456, 455, 454, 454, 453, 452, 452, 451, 450, 449, 449, 448, 448, 447, 446, 446, 445, 444, 444, 443, 442, 442, 441, 440, 440, 439, 438, 438, 437, 437, 436, 435, 435, 434, 434, 433, 432, 432, 431, 431, 430, 429, 429, 428, 428, 427, 427, 426, 425, 425, 424, 424, 423, 423, 422, 422, 421, 421, 420, 420, 419, 419, 418, 417, 417, 416, 416, 416, 415, 414, 414, 414, 413, 412, 412, 412, 411, 411, 410, 410, 409, 409, 408, 408, 407, 407, 406, 406, 406, 405, 405, 404, 404, 403, 403, 402, 402, 402, 401, 401, 400, 400, 399, 399, 398, 398, 398, 397, 397, 396, 396, 396, 395, 395, 394, 394, 394, 393, 393, 392, 392, 392, 391, 391, 391, 390, 390, 389, 389, 389, 388, 388, 387, 387, 387, 386, 386, 385, 385, 385, 384, 384, 384, 383, 383, 383, 382, 382, 382, 381, 381, 381, 380, 380, 380, 379, 379, 379, 378, 378, 378, 377, 377, 377, 376, 376, 376, 375, 375, 375, 374, 374, 374, 373, 373, 373, 372, 372, 372, 371, 371, 371, 370, 370, 370, 370, 369, 369, 369, 368, 368, 368, 368, 367, 367, 367, 367, 366, 366, 366, 365, 365, 365, 365, 364, 364, 364, 363, 363, 363, 363, 362, 362, 362, 362, 361, 361, 361, 360, 360, 360, 360, 359, 359, 359, 358, 358, 358, 358, 357, 357, 357, 356, 356, 356, 356, 355, 355, 355, 355, 354, 354, 354, 354, 354, 353, 353, 353, 353, 352, 352, 352, 352, 352, 351, 351, 351, 351, 350, 350, 350, 350, 350, 349, 349, 349, 349, 348, 348, 348, 348, 348, 347, 347, 347, 347, 346, 346, 346, 346, 346, 345, 345, 345, 345, 344, 344, 344, 344, 344, 343, 343, 343, 343, 342, 342, 342, 342, 342, 341, 341, 341, 341, 340, 340, 340, 340, 340, 339, 339, 339, 339, 338, 338, 338, 338, 338, 337, 337, 337, 337, 337, 337, 336, 336, 336, 336, 336, 336, 335, 335, 335, 335, 335, 335, 334, 334, 334, 334, 334, 334, 333, 333, 333, 333, 333, 333, 332, 332, 332, 332, 332, 332, 331, 331, 331, 331, 331, 331, 330, 330, 330, 330, 330, 330, 329, 329, 329, 329, 329, 329, 328, 328, 328, 328, 328, 328, 327, 327, 327, 327, 327, 327, 326, 326, 326, 326, 326, 326, 325, 325, 325, 325, 325, 325, 324, 324, 324, 324, 324, 324, 323, 323, 323, 323, 323, 323, 322, 322, 322, 322, 322, 322, 321, 321, 321, 321, 321, 321, 320, 320, 320, 320, 320, 320, 319, 319, 319, 319, 319, 319, 318, 318, 318, 318, 318, 318, 317, 317, 317, 317, 317, 317, 316, 316, 316, 316, 316, 316, 315, 315, 315, 315, 315, 315, 314, 314, 314, 314, 314, 314, 313, 313, 313, 313, 313, 313, 312, 312, 312, 312, 312, 312, 311, 311, 311, 311, 311, 311, 310, 310, 310, 310, 310, 310, 309, 309, 309, 309, 309, 309, 308, 308, 308, 308, 308, 308, 307, 307, 307, 307, 307, 307, 306, 306, 306, 306, 306, 306, 305, 305, 305, 305, 305, 305, 304, 304, 304, 304, 304, 304, 303, 303, 303, 303, 303, 303, 302, 302, 302, 302, 302, 302, 302, 301, 301, 301, 301, 301, 301, 301, 301, 301, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 0, 0, 0, 0, 0 }; -static uint32_t motor_speeds_cs8600f[] = { - 54612, 54612, 34604, 26280, 21708, 18688, 16564, 14936, 13652, 12616, - 11768, 11024, 10400, 9872, 9392, 8960, 8584, 8240, 7940, 7648, - 7404, 7160, 6948, 6732, 6544, 6376, 6208, 6056, 5912, 5776, - 5644, 5520, 5408, 5292, 5192, 5092, 5000, 4908, 4820, 4736, - 4660, 4580, 4508, 4440, 4368, 4304, 4240, 4184, 4124, 4068, - 4012, 3960, 3908, 3860, 3808, 3764, 3720, 3676, 3636, 3592, - 3552, 3516, 3476, 3440, 3400, 3368, 3332, 3300, 3268, 3236, - 3204, 3176, 3148, 3116, 3088, 3060, 3036, 3008, 2984, 2956, - 2932, 2908, 2884, 2860, 2836, 2816, 2796, 2772, 2752, 2732, - 2708, 2692, 2672, 2652, 2632, 2616, 2596, 2576, 2560, 2544, - 2528, 2508, 2492, 2476, 2460, 2444, 2432, 2416, 2400, 2384, - 2372, 2356, 2344, 2328, 2316, 2304, 2288, 2276, 2260, 2252, - 2236, 2224, 2212, 2200, 2188, 2176, 2164, 2156, 2144, 2132, - 2120, 2108, 2100, 2088, 2080, 2068, 2056, 2048, 2036, 2028, - 2020, 2008, 2000, 1988, 1980, 1972, 1964, 1952, 1944, 1936, - 1928, 1920, 1912, 1900, 1892, 1884, 1876, 1868, 1860, 1856, - 1848, 1840, 1832, 1824, 1816, 1808, 1800, 1796, 1788, 1780, - 1772, 1764, 1760, 1752, 1744, 1740, 1732, 1724, 1720, 1712, - 1708, 1700, 1692, 1688, 1680, 1676, 1668, 1664, 1656, 1652, - 1644, 1640, 1636, 1628, 1624, 1616, 1612, 1608, 1600, 1596, - 1592, 1584, 1580, 1576, 1568, 1564, 1560, 1556, 1548, 1544, - 1540, 1536, 1528, 1524, 1520, 1516, 1512, 1508, 1500, 0 -}; - -/** - * database of motor profiles - */ - -static Motor_Profile gl843_motors[]={ - /* KV-SS080 */ - {MOTOR_KVSS080, 8000, 1, kvss080}, - /* G4010/G4050/CS4400F */ - {MOTOR_G4050, 8016, 1, g4050_fast}, - {MOTOR_G4050, 11640, 1, cs4400f_fast}, - {MOTOR_G4050, 15624, 1, g4050_xpa}, - {MOTOR_G4050, 42752, 2, g4050_max}, - {MOTOR_G4050, 56064, 1, g4050_high}, - /* CS8400F */ - {MOTOR_CS8400F, 7200, 0, cs8400f_fast}, - { MOTOR_CS8600F, 0x59d8, 2, motor_speeds_cs8600f }, // FIXME: if the exposure is lower then we'll select another motor - { 0, 0, 0, NULL }, -}; diff --git a/backend/genesys_gl846.cc b/backend/genesys_gl846.cc deleted file mode 100644 index c5294b8..0000000 --- a/backend/genesys_gl846.cc +++ /dev/null @@ -1,3393 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2012-2013 Stéphane Voltz <stef.dev@free.fr> - - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -/** @file - * - * This file handles GL846 and GL845 ASICs since they are really close to each other. - */ - -#define DEBUG_DECLARE_ONLY - -#include "genesys_gl846.h" - -#include <vector> - -/**************************************************************************** - Mid level functions - ****************************************************************************/ - -static SANE_Bool -gl846_get_fast_feed_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG02); - if (r && (r->value & REG02_FASTFED)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl846_get_filter_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_FILTER)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl846_get_lineart_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_LINEART)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl846_get_bitset_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_BITSET)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl846_get_gain4_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x06); - if (r && (r->value & REG06_GAIN4)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl846_test_buffer_empty_bit (SANE_Byte val) -{ - if (val & REG41_BUFEMPTY) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl846_test_motor_flag_bit (SANE_Byte val) -{ - if (val & REG41_MOTORENB) - return SANE_TRUE; - return SANE_FALSE; -} - -/** - * compute the step multiplier used - */ -static int -gl846_get_step_multiplier (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - int value = 1; - - r = sanei_genesys_get_address (regs, 0x9d); - if (r != NULL) - { - value = (r->value & 0x0f)>>1; - value = 1 << value; - } - DBG (DBG_io, "%s: step multiplier is %d\n", __func__, value); - return value; -} - -/** @brief sensor profile - * search for the database of motor profiles and get the best one. Each - * profile is at a specific dpihw. Use LiDE 110 table by default. - * @param sensor_type sensor id - * @param dpi hardware dpi for the scan - * @return a pointer to a Sensor_Profile struct - */ -static Sensor_Profile *get_sensor_profile(int sensor_type, int dpi) -{ - unsigned int i; - int idx; - - i=0; - idx=-1; - while(i<sizeof(sensors)/sizeof(Sensor_Profile)) - { - /* exact match */ - if(sensors[i].sensor_type==sensor_type && sensors[i].dpi==dpi) - { - return &(sensors[i]); - } - - /* closest match */ - if(sensors[i].sensor_type==sensor_type) - { - if(idx<0) - { - idx=i; - } - else - { - if(sensors[i].dpi>=dpi - && sensors[i].dpi<sensors[idx].dpi) - { - idx=i; - } - } - } - i++; - } - - /* default fallback */ - if(idx<0) - { - DBG (DBG_warn,"%s: using default sensor profile\n",__func__); - idx=0; - } - - return &(sensors[idx]); -} - -/**@brief compute exposure to use - * compute the sensor exposure based on target resolution - */ -static int gl846_compute_exposure(Genesys_Device *dev, int xres) -{ - Sensor_Profile* sensor_profile=get_sensor_profile(dev->model->ccd_type, xres); - return sensor_profile->exposure; -} - - -/** @brief sensor specific settings -*/ -static void gl846_setup_sensor(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, int dpi) -{ - GenesysRegister *r; - int dpihw; - uint16_t exp; - - DBGSTART; - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dpi); - - for (uint16_t addr = 0x16; addr < 0x1e; addr++) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - for (uint16_t addr = 0x52; addr < 0x52 + 9; addr++) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - /* set EXPDUMMY and CKxMAP */ - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dpi); - Sensor_Profile* sensor_profile = get_sensor_profile(dev->model->ccd_type, dpihw); - - sanei_genesys_set_reg_from_set(regs,REG_EXPDMY,(uint8_t)((sensor_profile->expdummy) & 0xff)); - - /* if no calibration has been done, set default values for exposures */ - exp = sensor.exposure.red; - if(exp==0) - { - exp=sensor_profile->expr; - } - sanei_genesys_set_double(regs,REG_EXPR,exp); - - exp = sensor.exposure.green; - if(exp==0) - { - exp=sensor_profile->expg; - } - sanei_genesys_set_double(regs,REG_EXPG,exp); - - exp = sensor.exposure.blue; - if(exp==0) - { - exp=sensor_profile->expb; - } - sanei_genesys_set_double(regs,REG_EXPB,exp); - - sanei_genesys_set_triple(regs,REG_CK1MAP,sensor_profile->ck1map); - sanei_genesys_set_triple(regs,REG_CK3MAP,sensor_profile->ck3map); - sanei_genesys_set_triple(regs,REG_CK4MAP,sensor_profile->ck4map); - - /* order of the sub-segments */ - dev->order=sensor_profile->order; - - r = sanei_genesys_get_address (regs, 0x17); - r->value = sensor_profile->r17; - - DBGCOMPLETED; -} - - -/** @brief set all registers to default values . - * This function is called only once at the beginning and - * fills register startup values for registers reused across scans. - * Those that are rarely modified or not modified are written - * individually. - * @param dev device structure holding register set to initialize - */ -static void -gl846_init_registers (Genesys_Device * dev) -{ - DBGSTART; - - dev->reg.clear(); - - SETREG (0x01,0x60); - SETREG (0x02,0x38); - SETREG (0x03,0x03); - SETREG (0x04,0x22); - SETREG (0x05,0x60); - SETREG (0x06,0x10); - SETREG (0x08,0x60); - SETREG (0x09,0x00); - SETREG (0x0a,0x00); - SETREG (0x0b,0x8b); - SETREG (0x0c,0x00); - SETREG (0x0d,0x00); - SETREG (0x10,0x00); - SETREG (0x11,0x00); - SETREG (0x12,0x00); - SETREG (0x13,0x00); - SETREG (0x14,0x00); - SETREG (0x15,0x00); - SETREG (0x16,0xbb); - SETREG (0x17,0x13); - SETREG (0x18,0x10); - SETREG (0x19,0x2a); - SETREG (0x1a,0x34); - SETREG (0x1b,0x00); - SETREG (0x1c,0x20); - SETREG (0x1d,0x06); - SETREG (0x1e,0xf0); - SETREG (0x1f,0x01); - SETREG (0x20,0x03); - SETREG (0x21,0x10); - SETREG (0x22,0x60); - SETREG (0x23,0x60); - SETREG (0x24,0x60); - SETREG (0x25,0x00); - SETREG (0x26,0x00); - SETREG (0x27,0x00); - SETREG (0x2c,0x00); - SETREG (0x2d,0x00); - SETREG (0x2e,0x80); - SETREG (0x2f,0x80); - SETREG (0x30,0x00); - SETREG (0x31,0x00); - SETREG (0x32,0x00); - SETREG (0x33,0x00); - SETREG (0x34,0x1f); - SETREG (0x35,0x00); - SETREG (0x36,0x40); - SETREG (0x37,0x00); - SETREG (0x38,0x2a); - SETREG (0x39,0xf8); - SETREG (0x3d,0x00); - SETREG (0x3e,0x00); - SETREG (0x3f,0x01); - SETREG (0x52,0x02); - SETREG (0x53,0x04); - SETREG (0x54,0x06); - SETREG (0x55,0x08); - SETREG (0x56,0x0a); - SETREG (0x57,0x00); - SETREG (0x58,0x59); - SETREG (0x59,0x31); - SETREG (0x5a,0x40); - SETREG (0x5e,0x1f); - SETREG (0x5f,0x01); - SETREG (0x60,0x00); - SETREG (0x61,0x00); - SETREG (0x62,0x00); - SETREG (0x63,0x00); - SETREG (0x64,0x00); - SETREG (0x65,0x00); - SETREG (0x67,0x7f); - SETREG (0x68,0x7f); - SETREG (0x69,0x01); - SETREG (0x6a,0x01); - SETREG (0x70,0x01); - SETREG (0x71,0x00); - SETREG (0x72,0x02); - SETREG (0x73,0x01); - SETREG (0x74,0x00); - SETREG (0x75,0x00); - SETREG (0x76,0x00); - SETREG (0x77,0x00); - SETREG (0x78,0x00); - SETREG (0x79,0x3f); - SETREG (0x7a,0x00); - SETREG (0x7b,0x09); - SETREG (0x7c,0x99); - SETREG (0x7d,0x20); - SETREG (0x7f,0x05); - SETREG (0x80,0x4f); - SETREG (0x87,0x02); - SETREG (0x94,0xff); - SETREG (0x9d,0x04); - SETREG (0x9e,0x00); - SETREG (0xa1,0xe0); - SETREG (0xa2,0x1f); - SETREG (0xab,0xc0); - SETREG (0xbb,0x00); - SETREG (0xbc,0x0f); - SETREG (0xdb,0xff); - SETREG (0xfe,0x08); - SETREG (0xff,0x02); - SETREG (0x98,0x20); - SETREG (0x99,0x00); - SETREG (0x9a,0x90); - SETREG (0x9b,0x00); - SETREG (0xf8,0x05); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - /* fine tune upon device description */ - dev->reg.find_reg(0x05).value &= ~REG05_DPIHW; - switch (sensor.optical_res) - { - case 600: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_600; - break; - case 1200: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_1200; - break; - case 2400: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_2400; - break; - case 4800: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_4800; - break; - } - - /* initalize calibration reg */ - dev->calib_reg = dev->reg; - - DBGCOMPLETED; -} - -/**@brief send slope table for motor movement - * Send slope_table in machine byte order - * @param dev device to send slope table - * @param table_nr index of the slope table in ASIC memory - * Must be in the [0-4] range. - * @param slope_table pointer to 16 bit values array of the slope table - * @param steps number of elements in the slope table - */ -static SANE_Status -gl846_send_slope_table (Genesys_Device * dev, int table_nr, - uint16_t * slope_table, int steps) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - char msg[10000]; - - DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __func__, - table_nr, steps); - - /* sanity check */ - if(table_nr<0 || table_nr>4) - { - DBG (DBG_error, "%s: invalid table number %d!\n", __func__, table_nr); - return SANE_STATUS_INVAL; - } - - std::vector<uint8_t> table(steps * 2); - for (i = 0; i < steps; i++) - { - table[i * 2] = slope_table[i] & 0xff; - table[i * 2 + 1] = slope_table[i] >> 8; - } - - if (DBG_LEVEL >= DBG_io) - { - sprintf (msg, "write slope %d (%d)=", table_nr, steps); - for (i = 0; i < steps; i++) - { - sprintf (msg+strlen(msg), "%d", slope_table[i]); - } - DBG (DBG_io, "%s: %s\n", __func__, msg); - } - - /* slope table addresses are fixed */ - status = sanei_genesys_write_ahb(dev, 0x10000000 + 0x4000 * table_nr, steps * 2, table.data()); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: write to AHB failed writing slope table %d (%s)\n", __func__, table_nr, - sane_strstatus(status)); - } - - DBGCOMPLETED; - return status; -} - -/** - * Set register values of Analog Device type frontend - * */ -static SANE_Status -gl846_set_adi_fe (Genesys_Device * dev, uint8_t set) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - uint8_t val8; - - DBGSTART; - - /* wait for FE to be ready */ - status = sanei_genesys_get_status (dev, &val8); - while (val8 & REG41_FEBUSY) - { - sanei_genesys_sleep_ms(10); - status = sanei_genesys_get_status (dev, &val8); - }; - - if (set == AFE_INIT) - { - DBG (DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - dev->frontend = dev->frontend_initial; - } - - /* write them to analog frontend */ - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to write reg0: %s\n", __func__, - sane_strstatus (status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to write reg1: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - for (i = 0; i < 3; i++) - { - status = sanei_genesys_fe_write_data(dev, 0x02 + i, dev->frontend.get_gain(i)); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to write gain %d: %s\n", __func__, i, - sane_strstatus (status)); - return status; - } - } - for (i = 0; i < 3; i++) - { - status = sanei_genesys_fe_write_data(dev, 0x05 + i, dev->frontend.get_offset(i)); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to write offset %d: %s\n", __func__, i, - sane_strstatus (status)); - return status; - } - } - - DBGCOMPLETED; - return status; -} - -static SANE_Status -gl846_homsnr_gpio(Genesys_Device *dev) -{ -uint8_t val; -SANE_Status status=SANE_STATUS_GOOD; - - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - val |= 0x41; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - - return status; -} - -/* Set values of analog frontend */ -static SANE_Status -gl846_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (%s)\n", __func__, set == AFE_INIT ? "init" : set == AFE_SET ? "set" : - set == AFE_POWER_SAVE ? "powersave" : "huh?"); - - /* route to specific analog frontend setup */ - switch (dev->reg.find_reg(0x04).value & REG04_FESET) - { - case 0x02: /* ADI FE */ - status = gl846_set_adi_fe(dev, set); - break; - default: - DBG(DBG_proc, "%s(): unsupported frontend type %d\n", __func__, - dev->reg.find_reg(0x04).value & REG04_FESET); - status = SANE_STATUS_UNSUPPORTED; - } - - DBGCOMPLETED; - return status; -} - - -/** @brief set up motor related register for scan - */ -static SANE_Status -gl846_init_motor_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int scan_exposure_time, - float scan_yres, - int scan_step_type, - unsigned int scan_lines, - unsigned int scan_dummy, - unsigned int feed_steps, - int scan_power_mode, - unsigned int flags) -{ - SANE_Status status = SANE_STATUS_GOOD; - int use_fast_fed; - unsigned int fast_dpi; - uint16_t scan_table[SLOPE_TABLE_SIZE]; - uint16_t fast_table[SLOPE_TABLE_SIZE]; - int scan_steps, fast_steps, factor; - unsigned int feedl, dist; - GenesysRegister *r; - uint32_t z1, z2; - unsigned int min_restep = 0x20; - uint8_t val; - int fast_step_type; - unsigned int ccdlmt,tgtime; - - DBGSTART; - DBG(DBG_proc, "%s : scan_exposure_time=%d, scan_yres=%g, scan_step_type=%d, scan_lines=%d, " - "scan_dummy=%d, feed_steps=%d, scan_power_mode=%d, flags=%x\n", __func__, scan_exposure_time, - scan_yres, scan_step_type, scan_lines, scan_dummy, feed_steps, scan_power_mode, flags); - - /* get step multiplier */ - factor = gl846_get_step_multiplier (reg); - - use_fast_fed=0; - /* no fast fed since feed works well */ - if(dev->settings.yres==4444 && feed_steps>100 - && ((flags & MOTOR_FLAG_FEED)==0)) - { - use_fast_fed=1; - } - DBG (DBG_io, "%s: use_fast_fed=%d\n", __func__, use_fast_fed); - - sanei_genesys_set_triple(reg, REG_LINCNT, scan_lines); - DBG (DBG_io, "%s: lincnt=%d\n", __func__, scan_lines); - - /* compute register 02 value */ - r = sanei_genesys_get_address (reg, REG02); - r->value = 0x00; - sanei_genesys_set_motor_power(*reg, true); - - if (use_fast_fed) - r->value |= REG02_FASTFED; - else - r->value &= ~REG02_FASTFED; - - if (flags & MOTOR_FLAG_AUTO_GO_HOME) - r->value |= REG02_AGOHOME | REG02_NOTHOME; - - if ((flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE) - ||(scan_yres>=sensor.optical_res)) - { - r->value |= REG02_ACDCDIS; - } - - /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - scan_yres, - scan_exposure_time, - dev->motor.base_ydpi, - scan_step_type, - factor, - dev->model->motor_type, - gl846_motors); - RIE(gl846_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps*factor)); - RIE(gl846_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps*factor)); - - /* fast table */ - fast_dpi=sanei_genesys_get_lowest_ydpi(dev); - fast_step_type=scan_step_type; - if(scan_step_type>=2) - { - fast_step_type=2; - } - - sanei_genesys_slope_table(fast_table, - &fast_steps, - fast_dpi, - scan_exposure_time, - dev->motor.base_ydpi, - fast_step_type, - factor, - dev->model->motor_type, - gl846_motors); - - /* manual override of high start value */ - fast_table[0]=fast_table[1]; - - RIE(gl846_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps*factor)); - RIE(gl846_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps*factor)); - RIE(gl846_send_slope_table (dev, HOME_TABLE, fast_table, fast_steps*factor)); - - /* correct move distance by acceleration and deceleration amounts */ - feedl=feed_steps; - if (use_fast_fed) - { - feedl<<=fast_step_type; - dist=(scan_steps+2*fast_steps)*factor; - /* TODO read and decode REGAB */ - r = sanei_genesys_get_address (reg, 0x5e); - dist += (r->value & 31); - /* FEDCNT */ - r = sanei_genesys_get_address (reg, REG_FEDCNT); - dist += r->value; - } - else - { - feedl<<=scan_step_type; - dist=scan_steps*factor; - if (flags & MOTOR_FLAG_FEED) - dist *=2; - } - DBG (DBG_io2, "%s: scan steps=%d\n", __func__, scan_steps); - DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); - - /* check for overflow */ - if(dist<feedl) - feedl -= dist; - else - feedl = 0; - - sanei_genesys_set_triple(reg,REG_FEEDL,feedl); - DBG (DBG_io ,"%s: feedl=%d\n",__func__,feedl); - - r = sanei_genesys_get_address (reg, REG0C); - ccdlmt=(r->value & REG0C_CCDLMT)+1; - - r = sanei_genesys_get_address (reg, REG1C); - tgtime=1<<(r->value & REG1C_TGTIME); - - /* hi res motor speed GPIO */ - /* - RIE (sanei_genesys_read_register (dev, REG6C, &effective)); - */ - - /* if quarter step, bipolar Vref2 */ - /* XXX STEF XXX GPIO - if (scan_step_type > 1) - { - if (scan_step_type < 3) - { - val = effective & ~REG6C_GPIO13; - } - else - { - val = effective | REG6C_GPIO13; - } - } - else - { - val = effective; - } - RIE (sanei_genesys_write_register (dev, REG6C, val)); - */ - - /* effective scan */ - /* - RIE (sanei_genesys_read_register (dev, REG6C, &effective)); - val = effective | REG6C_GPIO10; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - */ - - if(dev->model->gpo_type==GPO_IMG101) - { - if(scan_yres==sanei_genesys_compute_dpihw(dev, sensor,scan_yres)) - { - val=1; - } - else - { - val=0; - } - RIE (sanei_genesys_write_register (dev, REG7E, val)); - } - - min_restep=scan_steps/2-1; - if (min_restep < 1) - min_restep = 1; - r = sanei_genesys_get_address (reg, REG_FWDSTEP); - r->value = min_restep; - r = sanei_genesys_get_address (reg, REG_BWDSTEP); - r->value = min_restep; - - sanei_genesys_calculate_zmode2(use_fast_fed, - scan_exposure_time*ccdlmt*tgtime, - scan_table, - scan_steps*factor, - feedl, - min_restep*factor, - &z1, - &z2); - - DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); - sanei_genesys_set_triple(reg, REG60, z1 | (scan_step_type << (16+REG60S_STEPSEL))); - - DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); - sanei_genesys_set_triple(reg, REG63, z2 | (scan_step_type << (16+REG63S_FSTPSEL))); - - r = sanei_genesys_get_address (reg, 0x1e); - r->value &= 0xf0; /* 0 dummy lines */ - r->value |= scan_dummy; /* dummy lines */ - - r = sanei_genesys_get_address (reg, REG67); - r->value = 0x7f; - - r = sanei_genesys_get_address (reg, REG68); - r->value = 0x7f; - - r = sanei_genesys_get_address (reg, REG_STEPNO); - r->value = scan_steps; - - r = sanei_genesys_get_address (reg, REG_FASTNO); - r->value = scan_steps; - - r = sanei_genesys_get_address (reg, REG_FSHDEC); - r->value = scan_steps; - - r = sanei_genesys_get_address (reg, REG_FMOVNO); - r->value = fast_steps; - - r = sanei_genesys_get_address (reg, REG_FMOVDEC); - r->value = fast_steps; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/** @brief set up registers related to sensor - * Set up the following registers - 0x01 - 0x03 - 0x10-0x015 R/G/B exposures - 0x19 EXPDMY - 0x2e BWHI - 0x2f BWLO - 0x04 - 0x87 - 0x05 - 0x2c,0x2d DPISET - 0x30,0x31 STRPIXEL - 0x32,0x33 ENDPIXEL - 0x35,0x36,0x37 MAXWD [25:2] (>>2) - 0x38,0x39 LPERIOD - 0x34 DUMMY - */ -static SANE_Status -gl846_init_optical_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int exposure_time, - int used_res, - unsigned int start, - unsigned int pixels, - int channels, - int depth, - SANE_Bool half_ccd, ColorFilter color_filter, int flags) -{ - unsigned int words_per_line; - unsigned int startx, endx, used_pixels; - unsigned int dpiset, dpihw,segnb,cksel,factor; - unsigned int bytes; - GenesysRegister *r; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s : exposure_time=%d, used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, " - "half_ccd=%d, flags=%x\n", __func__, exposure_time, used_res, start, pixels, channels, depth, - half_ccd, flags); - - /* resolution is divided according to CKSEL */ - r = sanei_genesys_get_address (reg, REG18); - cksel= (r->value & REG18_CKSEL)+1; - DBG(DBG_io2, "%s: cksel=%d\n", __func__, cksel); - - /* to manage high resolution device while keeping good - * low resolution scanning speed, we make hardware dpi vary */ - dpihw=sanei_genesys_compute_dpihw(dev, sensor, used_res * cksel); - factor=sensor.optical_res/dpihw; - DBG(DBG_io2, "%s: dpihw=%d (factor=%d)\n", __func__, dpihw, factor); - - /* sensor parameters */ - Sensor_Profile* sensor_profile = get_sensor_profile(dev->model->ccd_type, dpihw); - gl846_setup_sensor(dev, sensor, reg, dpihw); - dpiset = used_res * cksel; - - /* start and end coordinate in optical dpi coordinates */ - startx = start/cksel+sensor.CCD_start_xoffset; - used_pixels=pixels/cksel; - - /* end of sensor window */ - endx = startx + used_pixels; - - /* sensors are built from 600 dpi segments for LiDE 100/200 - * and 1200 dpi for the 700F */ - if (dev->model->flags & GENESYS_FLAG_SIS_SENSOR) - { - segnb=dpihw/600; - } - else - { - segnb=1; - } - - /* compute pixel coordinate in the given dpihw space, - * taking segments into account */ - startx/=factor*segnb; - endx/=factor*segnb; - dev->len=endx-startx; - dev->dist=0; - dev->skip=0; - - /* in cas of multi-segments sensor, we have to add the witdh - * of the sensor crossed by the scan area */ - if (dev->model->flags & GENESYS_FLAG_SIS_SENSOR && segnb>1) - { - dev->dist = sensor_profile->segcnt; - } - - /* use a segcnt rounded to next even number */ - endx += ((dev->dist+1)&0xfffe)*(segnb-1); - used_pixels=endx-startx; - - status = gl846_set_fe(dev, sensor, AFE_SET); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* enable shading */ - r = sanei_genesys_get_address (reg, REG01); - r->value &= ~REG01_SCAN; - r->value |= REG01_SHDAREA; - if ((flags & OPTICAL_FLAG_DISABLE_SHADING) || - (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) - { - r->value &= ~REG01_DVDSET; - } - else - { - r->value |= REG01_DVDSET; - } - - r = sanei_genesys_get_address (reg, REG03); - r->value &= ~REG03_AVEENB; - - sanei_genesys_set_lamp_power(dev, sensor, *reg, !(flags & OPTICAL_FLAG_DISABLE_LAMP)); - - /* BW threshold */ - r = sanei_genesys_get_address (reg, 0x2e); - r->value = dev->settings.threshold; - r = sanei_genesys_get_address (reg, 0x2f); - r->value = dev->settings.threshold; - - /* monochrome / color scan */ - r = sanei_genesys_get_address (reg, REG04); - switch (depth) - { - case 1: - r->value &= ~REG04_BITSET; - r->value |= REG04_LINEART; - break; - case 8: - r->value &= ~(REG04_LINEART | REG04_BITSET); - break; - case 16: - r->value &= ~REG04_LINEART; - r->value |= REG04_BITSET; - break; - } - - r->value &= ~(REG04_FILTER | REG04_AFEMOD); - if (channels == 1) - { - switch (color_filter) - { - case ColorFilter::RED: - r->value |= 0x24; - break; - case ColorFilter::BLUE: - r->value |= 0x2c; - break; - case ColorFilter::GREEN: - r->value |= 0x28; - break; - default: - break; // should not happen - } - } - else - r->value |= 0x20; /* mono */ - - /* register 05 */ - r = sanei_genesys_get_address (reg, REG05); - - /* set up dpihw */ - r->value &= ~REG05_DPIHW; - switch(dpihw) - { - case 600: - r->value |= REG05_DPIHW_600; - break; - case 1200: - r->value |= REG05_DPIHW_1200; - break; - case 2400: - r->value |= REG05_DPIHW_2400; - break; - case 4800: - r->value |= REG05_DPIHW_4800; - break; - } - - /* enable gamma tables */ - if (flags & OPTICAL_FLAG_DISABLE_GAMMA) - r->value &= ~REG05_GMMENB; - else - r->value |= REG05_GMMENB; - - /* CIS scanners can do true gray by setting LEDADD */ - /* we set up LEDADD only when asked */ - if (dev->model->is_cis == SANE_TRUE) - { - r = sanei_genesys_get_address (reg, 0x87); - r->value &= ~REG87_LEDADD; - if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) - { - r->value |= REG87_LEDADD; - } - /* RGB weighting - r = sanei_genesys_get_address (reg, 0x01); - r->value &= ~REG01_TRUEGRAY; - if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) - { - r->value |= REG01_TRUEGRAY; - }*/ - } - - /* words(16bit) before gamma, conversion to 8 bit or lineart*/ - words_per_line = (used_pixels * dpiset) / dpihw; - bytes=depth/8; - if (depth == 1) - { - words_per_line = (words_per_line+7)/8 ; - dev->len = (dev->len >> 3) + ((dev->len & 7) ? 1 : 0); - dev->dist = (dev->dist >> 3) + ((dev->dist & 7) ? 1 : 0); - } - else - { - words_per_line *= bytes; - dev->dist *= bytes; - dev->len *= bytes; - } - - dev->bpl = words_per_line; - dev->cur=0; - dev->segnb=segnb; - dev->line_interp = 0; - - sanei_genesys_set_double(reg,REG_DPISET,dpiset); - DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); - - sanei_genesys_set_double(reg,REG_STRPIXEL,startx); - sanei_genesys_set_double(reg,REG_ENDPIXEL,endx); - DBG (DBG_io2, "%s: startx=%d\n", __func__, startx); - DBG (DBG_io2, "%s: endx =%d\n", __func__, endx); - - DBG (DBG_io2, "%s: used_pixels=%d\n", __func__, used_pixels); - DBG (DBG_io2, "%s: pixels =%d\n", __func__, pixels); - DBG (DBG_io2, "%s: depth =%d\n", __func__, depth); - DBG (DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long)dev->bpl); - DBG (DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long)dev->len); - DBG (DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long)dev->dist); - DBG (DBG_io2, "%s: dev->segnb =%lu\n", __func__, (unsigned long)dev->segnb); - - words_per_line *= channels; - dev->wpl = words_per_line; - - dev->oe_buffer.clear(); - dev->oe_buffer.alloc(dev->wpl); - - /* MAXWD is expressed in 4 words unit */ - sanei_genesys_set_triple(reg, REG_MAXWD, (words_per_line >> 2)); - DBG (DBG_io2, "%s: words_per_line used=%d\n", __func__, words_per_line); - - sanei_genesys_set_double(reg, REG_LPERIOD, exposure_time); - DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time); - - r = sanei_genesys_get_address (reg, 0x34); - r->value = sensor.dummy_pixel; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -static SANE_Status -gl846_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SetupParams& params) -{ - params.assert_valid(); - - int used_res; - int start, used_pixels; - int bytes_per_line; - int move; - unsigned int lincnt; - unsigned int oflags; /**> optical flags */ - unsigned int mflags; /**> motor flags */ - int exposure_time; - int stagger; - - int slope_dpi = 0; - int dummy = 0; - int scan_step_type = 1; - int scan_power_mode = 0; - int max_shift; - size_t requested_buffer_size, read_buffer_size; - - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - int optical_res; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - - /* we may have 2 domains for ccd: xres below or above half ccd max dpi */ - if (sensor.get_ccd_size_divisor_for_dpi(params.xres) > 1) - { - half_ccd = SANE_TRUE; - } - else - { - half_ccd = SANE_FALSE; - } - - /* optical_res */ - optical_res = sensor.optical_res; - if (half_ccd) - optical_res /= 2; - - /* stagger */ - if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG(DBG_info, "%s : stagger=%d lines\n", __func__, stagger); - - /* used_res */ - if (params.flags & SCAN_FLAG_USE_OPTICAL_RES) - { - used_res = optical_res; - } - else - { - /* resolution is choosen from a list */ - used_res = params.xres; - } - - /* compute scan parameters values */ - /* pixels are allways given at full optical resolution */ - /* use detected left margin and fixed value */ - /* start */ - /* add x coordinates */ - start = params.startx; - - if (stagger > 0) - start |= 1; - - /* compute correct pixels number */ - /* pixels */ - used_pixels = (params.pixels * optical_res) / params.xres; - - /* round up pixels number if needed */ - if (used_pixels * params.xres < params.pixels * optical_res) - used_pixels++; - - dummy = 3-params.channels; - -/* slope_dpi */ -/* cis color scan is effectively a gray scan with 3 gray lines per color - line and a FILTER of 0 */ - if (dev->model->is_cis) - slope_dpi = params.yres * params.channels; - else - slope_dpi = params.yres; - - slope_dpi = slope_dpi * (1 + dummy); - - exposure_time = gl846_compute_exposure (dev, used_res); - scan_step_type = sanei_genesys_compute_step_type(gl846_motors, dev->model->motor_type, exposure_time); - - DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, scan_step_type); - -/*** optical parameters ***/ - /* in case of dynamic lineart, we use an internal 8 bit gray scan - * to generate 1 lineart data */ - if (params.flags & SCAN_FLAG_DYNAMIC_LINEART) { - params.depth = 8; - } - - /* we enable true gray for cis scanners only, and just when doing - * scan since color calibration is OK for this mode - */ - oflags = 0; - if(params.flags & SCAN_FLAG_DISABLE_SHADING) - oflags |= OPTICAL_FLAG_DISABLE_SHADING; - if(params.flags & SCAN_FLAG_DISABLE_GAMMA) - oflags |= OPTICAL_FLAG_DISABLE_GAMMA; - if(params.flags & SCAN_FLAG_DISABLE_LAMP) - oflags |= OPTICAL_FLAG_DISABLE_LAMP; - - if (dev->model->is_cis && dev->settings.true_gray) - { - oflags |= OPTICAL_FLAG_ENABLE_LEDADD; - } - - status = gl846_init_optical_regs_scan (dev, sensor, - reg, - exposure_time, - used_res, - start, - used_pixels, - params.channels, - params.depth, - half_ccd, - params.color_filter, - oflags); - - if (status != SANE_STATUS_GOOD) - return status; - -/*** motor parameters ***/ - - /* max_shift */ - max_shift=sanei_genesys_compute_max_shift(dev,params.channels,params.yres,params.flags); - - /* lincnt */ - lincnt = params.lines + max_shift + stagger; - - /* add tl_y to base movement */ - move = params.starty; - DBG(DBG_info, "%s: move=%d steps\n", __func__, move); - - mflags=0; - if(params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) - mflags |= MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; - if(params.flags & SCAN_FLAG_FEEDING) - mflags |= MOTOR_FLAG_FEED; - - status = gl846_init_motor_regs_scan (dev, sensor, - reg, - exposure_time, - slope_dpi, - scan_step_type, - dev->model->is_cis ? lincnt * - params.channels : lincnt, dummy, move, - scan_power_mode, - mflags); - - if (status != SANE_STATUS_GOOD) - return status; - - - /*** prepares data reordering ***/ - -/* words_per_line */ - bytes_per_line = (used_pixels * used_res) / optical_res; - bytes_per_line = (bytes_per_line * params.channels * params.depth) / 8; - - requested_buffer_size = 8 * bytes_per_line; - - read_buffer_size = - 2 * requested_buffer_size + - ((max_shift + stagger) * used_pixels * params.channels * params.depth) / 8; - - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); - - dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); - - dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); - - dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * params.pixels * params.channels * params.depth) / 8); - - dev->read_bytes_left = bytes_per_line * lincnt; - - DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); - dev->read_active = SANE_TRUE; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - -/* TODO: should this be done elsewhere? */ - /* scan bytes to send to the frontend */ - /* theory : - target_size = - (params.pixels * params.lines * channels * depth) / 8; - but it suffers from integer overflow so we do the following: - - 1 bit color images store color data byte-wise, eg byte 0 contains - 8 bits of red data, byte 1 contains 8 bits of green, byte 2 contains - 8 bits of blue. - This does not fix the overflow, though. - 644mp*16 = 10gp, leading to an overflow - -- pierre - */ - - dev->total_bytes_read = 0; - if (params.depth == 1) - dev->total_bytes_to_read = - ((params.pixels * params.lines) / 8 + - (((params.pixels * params.lines) % 8) ? 1 : 0)) * - params.channels; - else - dev->total_bytes_to_read = - params.pixels * params.lines * params.channels * (params.depth / 8); - - DBG(DBG_info, "%s: total bytes to send = %lu\n", __func__, (u_long) dev->total_bytes_to_read); -/* END TODO */ - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static void -gl846_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int depth; - int start; - - int used_res; - int used_pixels; - unsigned int lincnt; - int exposure_time; - int stagger; - - int slope_dpi; - int dummy = 0; - int max_shift; - - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - int optical_res; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - /* start */ - start = SANE_UNFIX (dev->model->x_offset); - start += dev->settings.tl_x; - start = (start * sensor.optical_res) / MM_PER_INCH; - - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; // not used - params.starty = 0; // not used - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = 0; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - -/* half_ccd */ - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - if (sensor.get_ccd_size_divisor_for_dpi(params.xres) > 1) { - half_ccd = SANE_TRUE; - } else { - half_ccd = SANE_FALSE; - } - - /* optical_res */ - optical_res = sensor.optical_res; - - /* stagger */ - if (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG(DBG_info, "%s: stagger=%d lines\n", __func__, stagger); - - /* resolution is choosen from a fixed list */ - used_res = params.xres; - - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - - /* compute correct pixels number */ - used_pixels = (params.pixels * optical_res) / used_res; - dummy = 3 - params.channels; - - /* cis color scan is effectively a gray scan with 3 gray lines per color - line and a FILTER of 0 */ - if (dev->model->is_cis) { - slope_dpi = params.yres * params.channels; - } else { - slope_dpi = params.yres; - } - - slope_dpi = slope_dpi * (1 + dummy); - - exposure_time = gl846_compute_exposure (dev, used_res); - DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - - max_shift = sanei_genesys_compute_max_shift(dev, params.channels, params.yres, 0); - - /* lincnt */ - lincnt = params.lines + max_shift + stagger; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - - DBGCOMPLETED; -} - -/*for fast power saving methods only, like disabling certain amplifiers*/ -static SANE_Status -gl846_save_power (Genesys_Device * dev, SANE_Bool enable) -{ - DBG(DBG_proc, "%s: enable = %d\n", __func__, enable); - if (dev == NULL) - return SANE_STATUS_INVAL; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl846_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ ) -{ - DBG(DBG_proc, "%s (delay = %d)\n", __func__, delay); - if (dev == NULL) - return SANE_STATUS_INVAL; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl846_start_action (Genesys_Device * dev) -{ - return sanei_genesys_write_register (dev, 0x0f, 0x01); -} - -static SANE_Status -gl846_stop_action (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val40, val; - unsigned int loop; - - DBGSTART; - - /* post scan gpio : without that HOMSNR is unreliable */ - gl846_homsnr_gpio(dev); - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - status = sanei_genesys_read_register (dev, REG40, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* only stop action if needed */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)) - { - DBG(DBG_info, "%s: already stopped\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - /* ends scan */ - val = dev->reg.get8(REG01); - val &= ~REG01_SCAN; - dev->reg.set8(REG01, val); - status = sanei_genesys_write_register (dev, REG01, val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register 01: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_sleep_ms(100); - - loop = 10; - while (loop > 0) - { - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - status = sanei_genesys_read_register (dev, REG40, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* if scanner is in command mode, we are done */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG) - && !(val & REG41_MOTORENB)) - { - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - sanei_genesys_sleep_ms(100); - loop--; - } - - DBGCOMPLETED; - return SANE_STATUS_IO_ERROR; -} - -/* Send the low-level scan command */ -static SANE_Status -gl846_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SANE_Bool start_motor) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - GenesysRegister *r; - - DBGSTART; - - /* XXX STEF XXX SCAN GPIO */ - /* - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - RIE (sanei_genesys_write_register (dev, REG6C, val)); - */ - - val = REG0D_CLRLNCNT; - RIE (sanei_genesys_write_register (dev, REG0D, val)); - val = REG0D_CLRMCNT; - RIE (sanei_genesys_write_register (dev, REG0D, val)); - - RIE (sanei_genesys_read_register (dev, REG01, &val)); - val |= REG01_SCAN; - RIE (sanei_genesys_write_register (dev, REG01, val)); - r = sanei_genesys_get_address (reg, REG01); - r->value = val; - - if (start_motor) - { - RIE (sanei_genesys_write_register (dev, REG0F, 1)); - } - else - { - RIE (sanei_genesys_write_register (dev, REG0F, 0)); - } - - DBGCOMPLETED; - - return status; -} - - -/* Send the stop scan command */ -static SANE_Status -gl846_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (check_stop = %d)\n", __func__, check_stop); - if (reg == NULL) - return SANE_STATUS_INVAL; - - if (dev->model->is_sheetfed == SANE_TRUE) - { - status = SANE_STATUS_GOOD; - } - else /* flat bed scanners */ - { - status = gl846_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - return status; -} - -/* Moves the slider to the home (top) postion slowly */ -static SANE_Status -gl846_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - float resolution; - uint8_t val; - int loop = 0; - ScanColorMode scan_mode; - - DBG(DBG_proc, "%s (wait_until_home = %d)\n", __func__, wait_until_home); - - /* post scan gpio : without that HOMSNR is unreliable */ - gl846_homsnr_gpio(dev); - - /* first read gives HOME_SENSOR true */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - sanei_genesys_sleep_ms(100); - - /* second is reliable */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - /* is sensor at home? */ - if (val & HOMESNR) - { - DBG(DBG_info, "%s: already at home, completed\n", __func__); - dev->scanhead_position_in_steps = 0; - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - local_reg = dev->reg; - - resolution=sanei_genesys_get_lowest_ydpi(dev); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - /* TODO add scan_mode to the API */ - scan_mode= dev->settings.scan_mode; - dev->settings.scan_mode = ScanColorMode::LINEART; - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 100; - params.starty = 30000; - params.pixels = 100; - params.lines = 100; - params.depth = 8; - params.channels = 1; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl846_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - dev->settings.scan_mode=scan_mode; - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - - /* set up for reverse */ - r = sanei_genesys_get_address(&local_reg, REG02); - r->value |= REG02_MTRREV; - - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - try { - status = gl846_start_action(dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl846_stop_action(dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl846_stop_action (dev); - /* send original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - /* post scan gpio : without that HOMSNR is unreliable */ - gl846_homsnr_gpio(dev); - - if (wait_until_home) - { - while (loop < 300) /* do not wait longer then 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - if (val & HOMESNR) /* home sensor */ - { - DBG(DBG_info, "%s: reached home position\n", __func__); - gl846_stop_action (dev); - dev->scanhead_position_in_steps = 0; - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl846_stop_action (dev); - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels - area at 600 dpi from very top of scanner */ -static SANE_Status -gl846_search_start_position (Genesys_Device * dev) -{ - int size; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - int steps; - - int pixels = 600; - int dpi = 300; - - DBG(DBG_proc, "%s\n", __func__); - - local_reg = dev->reg; - - /* sets for a 200 lines * 600 pixels */ - /* normal scan with no shading */ - - // FIXME: the current approach of doing search only for one resolution does not work on scanners - // whith employ different sensors with potentially different settings. - auto& sensor = sanei_genesys_find_sensor_for_write(dev, dpi); - - SetupParams params; - params.xres = dpi; - params.yres = dpi; - params.startx = 0; - params.starty = 0; /*we should give a small offset here~60 steps */ - params.pixels = 600; - params.lines = dev->model->search_lines; - params.depth = 8; - params.channels = 1; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::GREEN; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl846_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* send to scanner */ - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - size = pixels * dev->model->search_lines; - - std::vector<uint8_t> data(size); - - status = gl846_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl846_search_position.pnm", data.data(), 8, 1, pixels, - dev->model->search_lines); - - status = gl846_end_scan (dev, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* update regs to copy ASIC internal state */ - dev->reg = local_reg; - -/*TODO: find out where sanei_genesys_search_reference_point - stores information, and use that correctly*/ - status = - sanei_genesys_search_reference_point (dev, sensor, data.data(), 0, dpi, pixels, - dev->model->search_lines); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set search reference point: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - return SANE_STATUS_GOOD; -} - -/* - * sets up register for coarse gain calibration - * todo: check it for scanners using it */ -static SANE_Status -gl846_init_regs_for_coarse_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t channels; - uint8_t cksel; - - DBG(DBG_proc, "%s\n", __func__); - - - cksel = (regs.find_reg(0x18).value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */ - - /* set line size */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else { - channels = 1; - } - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = sensor.optical_res / cksel; - params.lines = 20; - params.depth = 16; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl846_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, - sensor.optical_res / cksel, dev->settings.xres); - - status = dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief moves the slider to steps at motor base dpi - * @param dev device to work on - * @param steps number of steps to move in base_dpi line count - * */ -static SANE_Status -gl846_feed (Genesys_Device * dev, unsigned int steps) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - float resolution; - uint8_t val; - - DBGSTART; - DBG(DBG_io, "%s: steps=%d\n", __func__, steps); - - /* prepare local registers */ - local_reg = dev->reg; - - resolution=sanei_genesys_get_lowest_ydpi(dev); - const auto& sensor = sanei_genesys_find_sensor(dev, resolution); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = steps; - params.pixels = 100; - params.lines = 3; - params.depth = 8; - params.channels = 3; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl846_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* set exposure to zero */ - sanei_genesys_set_triple(&local_reg,REG_EXPR,0); - sanei_genesys_set_triple(&local_reg,REG_EXPG,0); - sanei_genesys_set_triple(&local_reg,REG_EXPB,0); - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT)); - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRMCNT)); - - /* set up for no scan */ - r = sanei_genesys_get_address(&local_reg, REG01); - r->value &= ~REG01_SCAN; - - /* send registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - try { - status = gl846_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl846_stop_action(dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl846_stop_action (dev); - - /* restore original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - /* wait until feed count reaches the required value, but do not - * exceed 30s */ - do - { - status = sanei_genesys_get_status (dev, &val); - } - while (status == SANE_STATUS_GOOD && !(val & FEEDFSH)); - - /* then stop scanning */ - RIE(gl846_stop_action (dev)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* init registers for shading calibration */ -static SANE_Status -gl846_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - float move; - - DBGSTART; - dev->calib_channels = 3; - - /* initial calibration reg values */ - regs = dev->reg; - - dev->calib_resolution = sanei_genesys_compute_dpihw(dev, sensor, dev->settings.xres); - dev->calib_total_bytes_to_read = 0; - dev->calib_lines = dev->model->shading_lines; - if(dev->calib_resolution==4800) - dev->calib_lines *= 2; - dev->calib_pixels = (sensor.sensor_pixels*dev->calib_resolution)/sensor.optical_res; - DBG(DBG_io, "%s: calib_lines = %d\n", __func__, (unsigned int)dev->calib_lines); - DBG(DBG_io, "%s: calib_pixels = %d\n", __func__, (unsigned int)dev->calib_pixels); - - /* this is aworkaround insufficent distance for slope - * motor acceleration TODO special motor slope for shading */ - move=1; - if(dev->calib_resolution<1200) - { - move=40; - } - - SetupParams params; - params.xres = dev->calib_resolution; - params.yres = dev->calib_resolution; - params.startx = 0; - params.starty = move; - params.pixels = dev->calib_pixels; - params.lines = dev->calib_lines; - params.depth = 16; - params.channels = dev->calib_channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl846_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* we use GENESYS_FLAG_SHADING_REPARK */ - dev->scanhead_position_in_steps = 0; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief set up registers for the actual scan - */ -static SANE_Status -gl846_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int flags; - int depth; - float move; - int move_dpi; - float start; - - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - - /* steps to move to reach scanning area: - - first we move to physical start of scanning - either by a fixed steps amount from the black strip - or by a fixed amount from parking position, - minus the steps done during shading calibration - - then we move by the needed offset whitin physical - scanning area - - assumption: steps are expressed at maximum motor resolution - - we need: - SANE_Fixed y_offset; - SANE_Fixed y_size; - SANE_Fixed y_offset_calib; - mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */ - - /* if scanner uses GENESYS_FLAG_SEARCH_START y_offset is - relative from origin, else, it is from parking position */ - - move_dpi = dev->motor.base_ydpi; - - move = SANE_UNFIX (dev->model->y_offset); - move += dev->settings.tl_y; - move = (move * move_dpi) / MM_PER_INCH; - move -= dev->scanhead_position_in_steps; - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - /* fast move to scan area */ - /* we don't move fast the whole distance since it would involve - * computing acceleration/deceleration distance for scan - * resolution. So leave a remainder for it so scan makes the final - * move tuning */ - if(channels*dev->settings.yres>=600 && move>700) - { - status = gl846_feed (dev, move-500); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move to scan area\n", __func__); - return status; - } - move=500; - } - - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - /* start */ - start = SANE_UNFIX (dev->model->x_offset); - start += dev->settings.tl_x; - start = (start * sensor.optical_res) / MM_PER_INCH; - - flags = 0; - - /* emulated lineart from gray data is required for now */ - if(dev->settings.scan_mode == ScanColorMode::LINEART - && dev->settings.dynamic_lineart) - { - flags |= SCAN_FLAG_DYNAMIC_LINEART; - } - - /* backtracking isn't handled well, so don't enable it */ - flags |= SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; - params.starty = move; - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = flags; - - status = gl846_init_scan_regs(dev, sensor, &dev->reg, params); - - if (status != SANE_STATUS_GOOD) - return status; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/** - * Send shading calibration data. The buffer is considered to always hold values - * for all the channels. - */ -static SANE_Status -gl846_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint32_t addr, length, i, x, factor, pixels; - uint32_t dpiset, dpihw, strpixel, endpixel; - uint16_t tempo; - uint32_t lines, channels; - uint8_t val,*ptr,*src; - - DBGSTART; - DBG(DBG_io2, "%s: writing %d bytes of shading data\n", __func__, size); - - /* shading data is plit in 3 (up to 5 with IR) areas - write(0x10014000,0x00000dd8) - URB 23429 bulk_out len 3544 wrote 0x33 0x10 0x.... - write(0x1003e000,0x00000dd8) - write(0x10068000,0x00000dd8) - */ - length = (uint32_t) (size / 3); - sanei_genesys_get_double(&dev->reg,REG_STRPIXEL,&tempo); - strpixel=tempo; - sanei_genesys_get_double(&dev->reg,REG_ENDPIXEL,&tempo); - endpixel=tempo; - - /* compute deletion factor */ - sanei_genesys_get_double(&dev->reg,REG_DPISET,&tempo); - dpiset=tempo; - DBG(DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d, DPISET=%d\n", __func__, strpixel, endpixel, - endpixel-strpixel, dpiset); - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dpiset); - factor=dpihw/dpiset; - DBG(DBG_io2, "%s: factor=%d\n", __func__, factor); - - if(DBG_LEVEL>=DBG_data) - { - dev->binary=fopen("binary.pnm","wb"); - sanei_genesys_get_triple(&dev->reg, REG_LINCNT, &lines); - channels=dev->current_setup.channels; - if(dev->binary!=NULL) - { - fprintf(dev->binary,"P5\n%d %d\n%d\n",(endpixel-strpixel)/factor*channels,lines/channels,255); - } - } - - pixels=endpixel-strpixel; - - /* since we're using SHDAREA, substract startx coordinate from shading */ - strpixel-=((sensor.CCD_start_xoffset*600)/sensor.optical_res); - - /* turn pixel value into bytes 2x16 bits words */ - strpixel*=2*2; - pixels*=2*2; - - std::vector<uint8_t> buffer(pixels, 0); - - DBG(DBG_io2, "%s: using chunks of %d (0x%04x) bytes\n", __func__, pixels, pixels); - - /* base addr of data has been written in reg D0-D4 in 4K word, so AHB address - * is 8192*reg value */ - - /* write actual color channel data */ - for(i=0;i<3;i++) - { - /* build up actual shading data by copying the part from the full width one - * to the one corresponding to SHDAREA */ - ptr = buffer.data(); - - /* iterate on both sensor segment */ - for(x=0;x<pixels;x+=4*factor) - { - /* coefficient source */ - src=(data+strpixel+i*length)+x; - - /* coefficient copy */ - ptr[0]=src[0]; - ptr[1]=src[1]; - ptr[2]=src[2]; - ptr[3]=src[3]; - - /* next shading coefficient */ - ptr+=4; - } - - RIE(sanei_genesys_read_register(dev, 0xd0+i, &val)); - addr = val * 8192 + 0x10000000; - status = sanei_genesys_write_ahb(dev, addr, pixels, buffer.data()); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s; write to AHB failed (%s)\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - - return status; -} - -/** @brief calibrates led exposure - * Calibrate exposure by scanning a white area until the used exposure gives - * data white enough. - * @param dev device to calibrate - */ -static SANE_Status -gl846_led_calibration (Genesys_Device * dev, Genesys_Sensor& sensor, Genesys_Register_Set& regs) -{ - int num_pixels; - int total_size; - int used_res; - int i, j; - SANE_Status status = SANE_STATUS_GOOD; - int val; - int channels, depth; - int avg[3], top[3], bottom[3]; - int turn; - uint16_t exp[3]; - float move; - SANE_Bool acceptable; - - DBGSTART; - - move = SANE_UNFIX (dev->model->y_offset_calib); - move = (move * (dev->motor.base_ydpi/4)) / MM_PER_INCH; - if(move>20) - { - RIE(gl846_feed (dev, move)); - } - DBG(DBG_io, "%s: move=%f steps\n", __func__, move); - - /* offset calibration is always done in color mode */ - channels = 3; - depth=16; - used_res=sanei_genesys_compute_dpihw(dev, sensor, dev->settings.xres); - Sensor_Profile* sensor_profile = get_sensor_profile(dev->model->ccd_type, used_res); - num_pixels = (sensor.sensor_pixels*used_res)/sensor.optical_res; - - /* initial calibration reg values */ - regs = dev->reg; - - SetupParams params; - params.xres = used_res; - params.yres = used_res; - params.startx = 0; - params.starty = 0; - params.pixels = num_pixels; - params.lines = 1; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl846_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - total_size = num_pixels * channels * (depth/8) * 1; /* colors * bytes_per_color * scan lines */ - std::vector<uint8_t> line(total_size); - - /* initial loop values and boundaries */ - exp[0]=sensor_profile->expr; - exp[1]=sensor_profile->expg; - exp[2]=sensor_profile->expb; - - bottom[0]=29000; - bottom[1]=29000; - bottom[2]=29000; - - top[0]=41000; - top[1]=51000; - top[2]=51000; - - turn = 0; - - /* no move during led calibration */ - sanei_genesys_set_motor_power(regs, false); - do - { - /* set up exposure */ - sanei_genesys_set_double(®s,REG_EXPR,exp[0]); - sanei_genesys_set_double(®s,REG_EXPG,exp[1]); - sanei_genesys_set_double(®s,REG_EXPB,exp[2]); - - /* write registers and scan data */ - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - DBG(DBG_info, "%s: starting line reading\n", __func__); - RIE(gl846_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - - /* stop scanning */ - RIE(gl846_stop_action(dev)); - - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl846_led_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, line.data(), depth, channels, num_pixels, 1); - } - - /* compute average */ - for (j = 0; j < channels; j++) - { - avg[j] = 0; - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * num_pixels + 1] * 256 + - line[i * 2 + j * 2 * num_pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - avg[j] += val; - } - - avg[j] /= num_pixels; - } - - DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); - - /* check if exposure gives average within the boundaries */ - acceptable = SANE_TRUE; - for(i=0;i<3;i++) - { - if(avg[i]<bottom[i]) - { - exp[i]=(exp[i]*bottom[i])/avg[i]; - acceptable = SANE_FALSE; - } - if(avg[i]>top[i]) - { - exp[i]=(exp[i]*top[i])/avg[i]; - acceptable = SANE_FALSE; - } - } - - turn++; - } - while (!acceptable && turn < 100); - - DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); - - /* set these values as final ones for scan */ - sanei_genesys_set_double(&dev->reg,REG_EXPR,exp[0]); - sanei_genesys_set_double(&dev->reg,REG_EXPG,exp[1]); - sanei_genesys_set_double(&dev->reg,REG_EXPB,exp[2]); - - /* store in this struct since it is the one used by cache calibration */ - sensor.exposure.red = exp[0]; - sensor.exposure.green = exp[1]; - sensor.exposure.blue = exp[2]; - - /* go back home */ - if(move>20) - { - status=gl846_slow_back_home (dev, SANE_TRUE); - } - - DBGCOMPLETED; - return status; -} - -/** - * set up GPIO/GPOE for idle state - */ -static SANE_Status -gl846_init_gpio (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - int idx=0; - - DBGSTART; - - /* search GPIO profile */ - while(gpios[idx].sensor_id!=0 && dev->model->gpo_type!=gpios[idx].sensor_id) - { - idx++; - } - if(gpios[idx].sensor_id==0) - { - DBG(DBG_error, "%s: failed to find GPIO profile for sensor_id=%d\n", __func__, - dev->model->ccd_type); - return SANE_STATUS_INVAL; - } - - RIE (sanei_genesys_write_register (dev, REGA7, gpios[idx].ra7)); - RIE (sanei_genesys_write_register (dev, REGA6, gpios[idx].ra6)); - - RIE (sanei_genesys_write_register (dev, REG6B, gpios[idx].r6b)); - RIE (sanei_genesys_write_register (dev, REG6C, gpios[idx].r6c)); - RIE (sanei_genesys_write_register (dev, REG6D, gpios[idx].r6d)); - RIE (sanei_genesys_write_register (dev, REG6E, gpios[idx].r6e)); - RIE (sanei_genesys_write_register (dev, REG6F, gpios[idx].r6f)); - - RIE (sanei_genesys_write_register (dev, REGA8, gpios[idx].ra8)); - RIE (sanei_genesys_write_register (dev, REGA9, gpios[idx].ra9)); - - DBGCOMPLETED; - return status; -} - -/** - * set memory layout by filling values in dedicated registers - */ -static SANE_Status -gl846_init_memory_layout (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - int idx = 0, i; - uint8_t val; - - DBGSTART - - /* point to per model memory layout */ - idx = 0; - while(layouts[idx].model!=NULL && strcmp(dev->model->name,layouts[idx].model)!=0) - { - if(strcmp(dev->model->name,layouts[idx].model)!=0) - idx++; - } - if(layouts[idx].model==NULL) - { - DBG(DBG_error, "%s: failed to find memory layout for model %s!\n", __func__, dev->model->name); - return SANE_STATUS_INVAL; - } - - /* CLKSET and DRAMSEL */ - val = layouts[idx].dramsel; - RIE (sanei_genesys_write_register (dev, REG0B, val)); - dev->reg.find_reg(0x0b).value = val; - - /* prevent further writings by bulk write register */ - dev->reg.remove_reg(0x0b); - - /* setup base address for shading and scanned data. */ - for(i=0;i<10;i++) - { - sanei_genesys_write_register (dev, 0xe0+i, layouts[idx].rx[i]); - } - - DBGCOMPLETED; - return status; -} - -/* * - * initialize ASIC from power on condition - */ -static SANE_Status -gl846_boot (Genesys_Device * dev, SANE_Bool cold) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - DBGSTART; - - /* reset ASIC if cold boot */ - if(cold) - { - RIE (sanei_genesys_write_register (dev, 0x0e, 0x01)); - RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); - } - - if(dev->usb_mode == 1) - { - val = 0x14; - } - else - { - val = 0x11; - } - RIE (sanei_genesys_write_0x8c (dev, 0x0f, val)); - - /* test CHKVER */ - RIE (sanei_genesys_read_register (dev, REG40, &val)); - if (val & REG40_CHKVER) - { - RIE (sanei_genesys_read_register (dev, 0x00, &val)); - DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); - } - - /* Set default values for registers */ - gl846_init_registers (dev); - - /* Write initial registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, dev->reg)); - - /* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */ - val = dev->reg.find_reg(0x0b).value & REG0B_DRAMSEL; - val = (val | REG0B_ENBDRAM); - RIE (sanei_genesys_write_register (dev, REG0B, val)); - dev->reg.find_reg(0x0b).value = val; - - /* CIS_LINE */ - if (dev->model->is_cis) - { - SETREG (0x08, REG08_CIS_LINE); - RIE (sanei_genesys_write_register (dev, 0x08, dev->reg.find_reg(0x08).value)); - } - - /* set up clocks */ - RIE (sanei_genesys_write_0x8c (dev, 0x10, 0x0e)); - RIE (sanei_genesys_write_0x8c (dev, 0x13, 0x0e)); - - /* setup gpio */ - RIE (gl846_init_gpio (dev)); - - /* setup internal memory layout */ - RIE (gl846_init_memory_layout (dev)); - - SETREG (0xf8, 0x05); - RIE (sanei_genesys_write_register (dev, 0xf8, dev->reg.find_reg(0xf8).value)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** - * initialize backend and ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home - */ -static SANE_Status gl846_init(Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG_INIT (); - DBGSTART; - - status=sanei_genesys_asic_init(dev, 0); - - DBGCOMPLETED; - return status; -} - -static SANE_Status -gl846_update_hardware_sensors (Genesys_Scanner * s) -{ - /* do what is needed to get a new set of events, but try to not lose - any of them. - */ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - uint8_t scan, file, email, copy; - switch(s->dev->model->gpo_type) - { - default: - scan=0x01; - file=0x02; - email=0x04; - copy=0x08; - } - RIE (sanei_genesys_read_register (s->dev, REG6D, &val)); - - s->buttons[BUTTON_SCAN_SW].write((val & scan) == 0); - s->buttons[BUTTON_FILE_SW].write((val & file) == 0); - s->buttons[BUTTON_EMAIL_SW].write((val & email) == 0); - s->buttons[BUTTON_COPY_SW].write((val & copy) == 0); - - return status; -} - -/** @brief search for a full width black or white strip. - * This function searches for a black or white stripe across the scanning area. - * When searching backward, the searched area must completely be of the desired - * color since this area will be used for calibration which scans forward. - * @param dev scanner device - * @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward - * @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip - * @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not - */ -static SANE_Status -gl846_search_strip(Genesys_Device * dev, const Genesys_Sensor& sensor, - SANE_Bool forward, SANE_Bool black) -{ - unsigned int pixels, lines, channels; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - size_t size; - int steps, depth, dpi; - unsigned int pass, count, found, x, y; - char title[80]; - GenesysRegister *r; - - DBG(DBG_proc, "%s %s %s\n", __func__, black ? "black" : "white", forward ? "forward" : "reverse"); - - status = gl846_set_fe(dev, sensor, AFE_SET); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl846_set_fe() failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl846_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* set up for a gray scan at lowest dpi */ - dpi = 9600; - for (x = 0; x < MAX_RESOLUTIONS; x++) - { - if (dev->model->xdpi_values[x] > 0 && dev->model->xdpi_values[x] < dpi) - dpi = dev->model->xdpi_values[x]; - } - channels = 1; - /* 10 MM */ - /* lines = (10 * dpi) / MM_PER_INCH; */ - /* shading calibation is done with dev->motor.base_ydpi */ - lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; - depth = 8; - pixels = (sensor.sensor_pixels * dpi) / sensor.optical_res; - size = pixels * channels * lines * (depth / 8); - std::vector<uint8_t> data(size); - - dev->scanhead_position_in_steps = 0; - - local_reg = dev->reg; - - SetupParams params; - params.xres = dpi; - params.yres = dpi; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = depth; - params.channels = channels; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA; - - status = gl846_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup for scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* set up for reverse or forward */ - r = sanei_genesys_get_address (&local_reg, REG02); - if (forward) - r->value &= ~REG02_MTRREV; - else - r->value |= REG02_MTRREV; - - - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl846_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl846_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl846_stop_action failed\n", __func__); - return status; - } - - pass = 0; - if (DBG_LEVEL >= DBG_data) - { - sprintf(title, "gl846_search_strip_%s_%s%02d.pnm", - black ? "black" : "white", forward ? "fwd" : "bwd", (int)pass); - sanei_genesys_write_pnm_file(title, data.data(), depth, channels, pixels, lines); - } - - /* loop until strip is found or maximum pass number done */ - found = 0; - while (pass < 20 && !found) - { - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* now start scan */ - status = gl846_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl846_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl846_stop_action failed\n", __func__); - return status; - } - - if (DBG_LEVEL >= DBG_data) - { - sprintf(title, "gl846_search_strip_%s_%s%02d.pnm", - black ? "black" : "white", forward ? "fwd" : "bwd", (int)pass); - sanei_genesys_write_pnm_file(title, data.data(), depth, channels, pixels, lines); - } - - /* search data to find black strip */ - /* when searching forward, we only need one line of the searched color since we - * will scan forward. But when doing backward search, we need all the area of the - * same color */ - if (forward) - { - for (y = 0; y < lines && !found; y++) - { - count = 0; - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > 90) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < 60) - { - count++; - } - } - - /* at end of line, if count >= 3%, line is not fully of the desired color - * so we must go to next line of the buffer */ - /* count*100/pixels < 3 */ - if ((count * 100) / pixels < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, - pass, y); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - } - else /* since calibration scans are done forward, we need the whole area - to be of the required color when searching backward */ - { - count = 0; - for (y = 0; y < lines; y++) - { - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > 90) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < 60) - { - count++; - } - } - } - - /* at end of area, if count >= 3%, area is not fully of the desired color - * so we must go to next buffer */ - if ((count * 100) / (pixels * lines) < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - pass++; - } - - if (found) - { - status = SANE_STATUS_GOOD; - DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); - } - else - { - status = SANE_STATUS_UNSUPPORTED; - DBG(DBG_info, "%s: %s strip not found\n", __func__, black ? "black" : "white"); - } - - DBGCOMPLETED; - return status; -} - -/** - * average dark pixels of a 8 bits scan - */ -static int -dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, - unsigned int channels, unsigned int black) -{ - unsigned int i, j, k, average, count; - unsigned int avg[3]; - uint8_t val; - - /* computes average value on black margin */ - for (k = 0; k < channels; k++) - { - avg[k] = 0; - count = 0; - for (i = 0; i < lines; i++) - { - for (j = 0; j < black; j++) - { - val = data[i * channels * pixels + j + k]; - avg[k] += val; - count++; - } - } - if (count) - avg[k] /= count; - DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); - } - average = 0; - for (i = 0; i < channels; i++) - average += avg[i]; - average /= channels; - DBG(DBG_info, "%s: average = %d\n", __func__, average); - return average; -} - -static SANE_Status -gl846_offset_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t reg04; - unsigned int channels, bpp; - int pass = 0, avg, total_size; - int topavg, bottomavg, resolution, lines; - int top, bottom, black_pixels, pixels; - - DBGSTART; - - /* no gain nor offset for AKM AFE */ - RIE (sanei_genesys_read_register (dev, REG04, ®04)); - if ((reg04 & REG04_FESET) == 0x02) - { - DBGCOMPLETED; - return status; - } - - /* offset calibration is always done in color mode */ - channels = 3; - resolution=sensor.optical_res; - dev->calib_pixels = sensor.sensor_pixels; - lines=1; - bpp=8; - pixels= (sensor.sensor_pixels*resolution) / sensor.optical_res; - black_pixels = (sensor.black_pixels * resolution) / sensor.optical_res; - DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = bpp; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl846_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_set_motor_power(regs, false); - - /* allocate memory for scans */ - total_size = pixels * channels * lines * (bpp/8); /* colors * bytes_per_color * scan lines */ - - std::vector<uint8_t> first_line(total_size); - std::vector<uint8_t> second_line(total_size); - - /* init gain */ - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - - /* scan with no move */ - bottom = 10; - dev->frontend.set_offset(0, bottom); - dev->frontend.set_offset(1, bottom); - dev->frontend.set_offset(2, bottom); - - RIE(gl846_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting first line reading\n", __func__); - RIE(gl846_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, first_line.data(), total_size)); - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl846_offset%03d.pnm", bottom); - sanei_genesys_write_pnm_file(fn, first_line.data(), bpp, channels, pixels, lines); - } - - bottomavg = dark_average(first_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); - - /* now top value */ - top = 255; - dev->frontend.set_offset(0, top); - dev->frontend.set_offset(1, top); - dev->frontend.set_offset(2, top); - RIE(gl846_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl846_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, second_line.data(), total_size)); - - topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); - - /* loop until acceptable level */ - while ((pass < 32) && (top - bottom > 1)) - { - pass++; - - /* settings for new scan */ - dev->frontend.set_offset(0, (top + bottom) / 2); - dev->frontend.set_offset(1, (top + bottom) / 2); - dev->frontend.set_offset(2, (top + bottom) / 2); - - /* scan with no move */ - RIE(gl846_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl846_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, second_line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl846_offset%03d.pnm", dev->frontend.get_offset(1)); - sanei_genesys_write_pnm_file(fn, second_line.data(), bpp, channels, pixels, lines); - } - - avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); - - /* compute new boundaries */ - if (topavg == avg) - { - topavg = avg; - top = dev->frontend.get_offset(1); - } - else - { - bottomavg = avg; - bottom = dev->frontend.get_offset(1); - } - } - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl846_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi) -{ - int pixels; - int total_size; - uint8_t reg04; - int i, j, channels; - SANE_Status status = SANE_STATUS_GOOD; - int max[3]; - float gain[3],coeff; - int val, code, lines; - int resolution; - int bpp; - - DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi); - - /* no gain nor offset for AKM AFE */ - RIE (sanei_genesys_read_register (dev, REG04, ®04)); - if ((reg04 & REG04_FESET) == 0x02) - { - DBGCOMPLETED; - return status; - } - - /* coarse gain calibration is always done in color mode */ - channels = 3; - - /* follow CKSEL */ - if(dev->settings.xres<sensor.optical_res) - { - coeff=0.9; - /*resolution=sensor.optical_res/2;*/ - resolution=sensor.optical_res; - } - else - { - resolution=sensor.optical_res; - coeff=1.0; - } - lines=10; - bpp=8; - pixels = (sensor.sensor_pixels * resolution) / sensor.optical_res; - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = bpp; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - try { - status = gl846_init_scan_regs(dev, sensor, ®s, params); - } catch (...) { - try { - sanei_genesys_set_motor_power(regs, false); - } catch (...) {} - throw; - } - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - RIE (dev->model->cmd_set->bulk_write_register(dev, regs)); - - total_size = pixels * channels * (16/bpp) * lines; - - std::vector<uint8_t> line(total_size); - - RIE(gl846_set_fe(dev, sensor, AFE_SET)); - RIE(gl846_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl846_gain.pnm", line.data(), bpp, channels, pixels, lines); - - /* average value on each channel */ - for (j = 0; j < channels; j++) - { - max[j] = 0; - for (i = pixels/4; i < (pixels*3/4); i++) - { - if (dev->model->is_cis) - val = line[i + j * pixels]; - else - val = line[i * channels + j]; - - max[j] += val; - } - max[j] = max[j] / (pixels/2); - - gain[j] = ((float) sensor.gain_white_ref*coeff) / max[j]; - - /* turn logical gain value into gain code, checking for overflow */ - code = 283 - 208 / gain[j]; - if (code > 255) - code = 255; - else if (code < 0) - code = 0; - dev->frontend.set_gain(j, code); - - DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], - dev->frontend.get_gain(j)); - } - - if (dev->model->is_cis) { - uint8_t gain0 = dev->frontend.get_gain(0); - if (gain0 > dev->frontend.get_gain(1)) { - gain0 = dev->frontend.get_gain(1); - } - if (gain0 > dev->frontend.get_gain(2)) { - gain0 = dev->frontend.get_gain(2); - } - dev->frontend.set_gain(0, gain0); - dev->frontend.set_gain(1, gain0); - dev->frontend.set_gain(2, gain0); - } - - RIE (gl846_stop_action (dev)); - - status=gl846_slow_back_home (dev, SANE_TRUE); - - DBGCOMPLETED; - return status; -} - - -/** the gl846 command set */ -static Genesys_Command_Set gl846_cmd_set = { - "gl846-generic", /* the name of this set */ - - nullptr, - - gl846_init, - NULL, - gl846_init_regs_for_coarse_calibration, - gl846_init_regs_for_shading, - gl846_init_regs_for_scan, - - gl846_get_filter_bit, - gl846_get_lineart_bit, - gl846_get_bitset_bit, - gl846_get_gain4_bit, - gl846_get_fast_feed_bit, - gl846_test_buffer_empty_bit, - gl846_test_motor_flag_bit, - - gl846_set_fe, - gl846_set_powersaving, - gl846_save_power, - - gl846_begin_scan, - gl846_end_scan, - - sanei_genesys_send_gamma_table, - - gl846_search_start_position, - - gl846_offset_calibration, - gl846_coarse_gain_calibration, - gl846_led_calibration, - - NULL, - gl846_slow_back_home, - NULL, - - sanei_genesys_bulk_write_register, - NULL, - sanei_genesys_bulk_read_data, - - gl846_update_hardware_sensors, - - NULL, - NULL, - NULL, - gl846_search_strip, - - sanei_genesys_is_compatible_calibration, - NULL, - gl846_send_shading_data, - gl846_calculate_current_setup, - gl846_boot -}; - -SANE_Status -sanei_gl846_init_cmd_set (Genesys_Device * dev) -{ - dev->model->cmd_set = &gl846_cmd_set; - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_gl846.h b/backend/genesys_gl846.h deleted file mode 100644 index 797c605..0000000 --- a/backend/genesys_gl846.h +++ /dev/null @@ -1,498 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2012-2013 Stéphane Voltz <stef.dev@free.fr> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#include "genesys.h" - -#define REG01 0x01 -#define REG01_CISSET 0x80 -#define REG01_DOGENB 0x40 -#define REG01_DVDSET 0x20 -#define REG01_STAGGER 0x10 -#define REG01_COMPENB 0x08 -#define REG01_TRUEGRAY 0x04 -#define REG01_SHDAREA 0x02 -#define REG01_SCAN 0x01 - -#define REG02 0x02 -#define REG02_NOTHOME 0x80 -#define REG02_ACDCDIS 0x40 -#define REG02_AGOHOME 0x20 -#define REG02_MTRPWR 0x10 -#define REG02_FASTFED 0x08 -#define REG02_MTRREV 0x04 -#define REG02_HOMENEG 0x02 -#define REG02_LONGCURV 0x01 - -#define REG03 0x03 -#define REG03_LAMPDOG 0x80 -#define REG03_AVEENB 0x40 -#define REG03_XPASEL 0x20 -#define REG03_LAMPPWR 0x10 -#define REG03_LAMPTIM 0x0f - -#define REG04 0x04 -#define REG04_LINEART 0x80 -#define REG04_BITSET 0x40 -#define REG04_AFEMOD 0x30 -#define REG04_FILTER 0x0c -#define REG04_FESET 0x03 - -#define REG04S_AFEMOD 4 - -#define REG05 0x05 -#define REG05_DPIHW 0xc0 -#define REG05_DPIHW_600 0x00 -#define REG05_DPIHW_1200 0x40 -#define REG05_DPIHW_2400 0x80 -#define REG05_DPIHW_4800 0xc0 -#define REG05_MTLLAMP 0x30 -#define REG05_GMMENB 0x08 -#define REG05_MTLBASE 0x03 - -#define REG06_SCANMOD 0xe0 -#define REG06S_SCANMOD 5 -#define REG06_PWRBIT 0x10 -#define REG06_GAIN4 0x08 -#define REG06_OPTEST 0x07 - -#define REG07_LAMPSIM 0x80 - -#define REG08_DRAM2X 0x80 -#define REG08_MPENB 0x20 -#define REG08_CIS_LINE 0x10 -#define REG08_IR1ENB 0x08 -#define REG08_IR2ENB 0x04 -#define REG08_ENB24M 0x01 - -#define REG09_MCNTSET 0xc0 -#define REG09_EVEN1ST 0x20 -#define REG09_BLINE1ST 0x10 -#define REG09_BACKSCAN 0x08 -#define REG09_ENHANCE 0x04 -#define REG09_SHORTTG 0x02 -#define REG09_NWAIT 0x01 - -#define REG09S_MCNTSET 6 -#define REG09S_CLKSET 4 - - -#define REG0A_LPWMEN 0x10 - -#define REG0B 0x0b -#define REG0B_DRAMSEL 0x07 -#define REG0B_ENBDRAM 0x08 -#define REG0B_ENBDRAM 0x08 -#define REG0B_RFHDIS 0x10 -#define REG0B_CLKSET 0xe0 -#define REG0B_24MHZ 0x00 -#define REG0B_30MHZ 0x20 -#define REG0B_40MHZ 0x40 -#define REG0B_48MHZ 0x60 -#define REG0B_60MHZ 0x80 - -#define REG0C 0x0c -#define REG0C_CCDLMT 0x0f - -#define REG0D 0x0d -#define REG0D_SCSYNC 0x40 -#define REG0D_CLRERR 0x20 -#define REG0D_FULLSTP 0x10 -#define REG0D_SEND 0x80 -#define REG0D_CLRMCNT 0x04 -#define REG0D_CLRDOCJM 0x02 -#define REG0D_CLRLNCNT 0x01 - -#define REG0F 0x0f - -#define REG16_CTRLHI 0x80 -#define REG16_TOSHIBA 0x40 -#define REG16_TGINV 0x20 -#define REG16_CK1INV 0x10 -#define REG16_CK2INV 0x08 -#define REG16_CTRLINV 0x04 -#define REG16_CKDIS 0x02 -#define REG16_CTRLDIS 0x01 - -#define REG17_TGMODE 0xc0 -#define REG17_TGMODE_NO_DUMMY 0x00 -#define REG17_TGMODE_REF 0x40 -#define REG17_TGMODE_XPA 0x80 -#define REG17_TGW 0x3f -#define REG17S_TGW 0 - -#define REG18 0x18 -#define REG18_CNSET 0x80 -#define REG18_DCKSEL 0x60 -#define REG18_CKTOGGLE 0x10 -#define REG18_CKDELAY 0x0c -#define REG18_CKSEL 0x03 - -#define REG1A_SW2SET 0x80 -#define REG1A_SW1SET 0x40 -#define REG1A_MANUAL3 0x02 -#define REG1A_MANUAL1 0x01 -#define REG1A_CK4INV 0x08 -#define REG1A_CK3INV 0x04 -#define REG1A_LINECLP 0x02 - -#define REG1C 0x1c -#define REG1C_TGTIME 0x07 - -#define REG1D_CK4LOW 0x80 -#define REG1D_CK3LOW 0x40 -#define REG1D_CK1LOW 0x20 -#define REG1D_TGSHLD 0x1f -#define REG1DS_TGSHLD 0 - - -#define REG1E_WDTIME 0xf0 -#define REG1ES_WDTIME 4 -#define REG1E_LINESEL 0x0f -#define REG1ES_LINESEL 0 - -#define REG_FEDCNT 0x1f - -#define REG24 0x1c -#define REG40 0x40 -#define REG40_DOCSNR 0x80 -#define REG40_ADFSNR 0x40 -#define REG40_COVERSNR 0x20 -#define REG40_CHKVER 0x10 -#define REG40_DOCJAM 0x08 -#define REG40_HISPDFLG 0x04 -#define REG40_MOTMFLG 0x02 -#define REG40_DATAENB 0x01 - -#define REG41_PWRBIT 0x80 -#define REG41_BUFEMPTY 0x40 -#define REG41_FEEDFSH 0x20 -#define REG41_SCANFSH 0x10 -#define REG41_HOMESNR 0x08 -#define REG41_LAMPSTS 0x04 -#define REG41_FEBUSY 0x02 -#define REG41_MOTORENB 0x01 - -#define REG58_VSMP 0xf8 -#define REG58S_VSMP 3 -#define REG58_VSMPW 0x07 -#define REG58S_VSMPW 0 - -#define REG59_BSMP 0xf8 -#define REG59S_BSMP 3 -#define REG59_BSMPW 0x07 -#define REG59S_BSMPW 0 - -#define REG5A_ADCLKINV 0x80 -#define REG5A_RLCSEL 0x40 -#define REG5A_CDSREF 0x30 -#define REG5AS_CDSREF 4 -#define REG5A_RLC 0x0f -#define REG5AS_RLC 0 - -#define REG5E_DECSEL 0xe0 -#define REG5ES_DECSEL 5 -#define REG5E_STOPTIM 0x1f -#define REG5ES_STOPTIM 0 - -#define REG60 0x60 -#define REG60_Z1MOD 0x1f -#define REG61 0x61 -#define REG61_Z1MOD 0xff -#define REG62 0x62 -#define REG62_Z1MOD 0xff - -#define REG63 0x63 -#define REG63_Z2MOD 0x1f -#define REG64 0x64 -#define REG64_Z2MOD 0xff -#define REG65 0x65 -#define REG65_Z2MOD 0xff - -#define REG60S_STEPSEL 5 -#define REG60_STEPSEL 0xe0 -#define REG60_FULLSTEP 0x00 -#define REG60_HALFSTEP 0x20 -#define REG60_EIGHTHSTEP 0x60 -#define REG60_16THSTEP 0x80 - -#define REG63S_FSTPSEL 5 -#define REG63_FSTPSEL 0xe0 -#define REG63_FULLSTEP 0x00 -#define REG63_HALFSTEP 0x20 -#define REG63_EIGHTHSTEP 0x60 -#define REG63_16THSTEP 0x80 - -#define REG67 0x67 -#define REG67_MTRPWM 0x80 - -#define REG68 0x68 -#define REG68_FASTPWM 0x80 - -#define REG6B 0x6b -#define REG6B_MULTFILM 0x80 -#define REG6B_GPOM13 0x40 -#define REG6B_GPOM12 0x20 -#define REG6B_GPOM11 0x10 -#define REG6B_GPO18 0x02 -#define REG6B_GPO17 0x01 - -#define REG6C 0x6c -#define REG6C_GPIO16 0x80 -#define REG6C_GPIO15 0x40 -#define REG6C_GPIO14 0x20 -#define REG6C_GPIO13 0x10 -#define REG6C_GPIO12 0x08 -#define REG6C_GPIO11 0x04 -#define REG6C_GPIO10 0x02 -#define REG6C_GPIO9 0x01 -#define REG6C_GPIOH 0xff -#define REG6C_GPIOL 0xff - -#define REG6D 0x6d -#define REG6E 0x6e -#define REG6F 0x6f -#define REG7E 0x7e - -#define REG87_ACYCNRLC 0x10 -#define REG87_ENOFFSET 0x08 -#define REG87_LEDADD 0x04 -#define REG87_CK4ADC 0x02 -#define REG87_AUTOCONF 0x01 - -#define REG9E 0x9e -#define REG9F 0x9f - -#define REGA6 0xa6 -#define REGA7 0xa7 -#define REGA8 0xa8 -#define REGA9 0xa9 -#define REGAB 0xab - -#define REG_EXPR 0x10 -#define REG_EXPG 0x12 -#define REG_EXPB 0x14 -#define REG_EXPDMY 0x19 -#define REG_STEPNO 0x21 -#define REG_FWDSTEP 0x22 -#define REG_BWDSTEP 0x23 -#define REG_FASTNO 0x24 -#define REG_DPISET 0x2c -#define REG_STRPIXEL 0x30 -#define REG_ENDPIXEL 0x32 -#define REG_LINCNT 0x25 -#define REG_MAXWD 0x35 -#define REG_LPERIOD 0x38 -#define REG_FEEDL 0x3d -#define REG_FMOVDEC 0x5f -#define REG_FSHDEC 0x69 -#define REG_FMOVNO 0x6a -#define REG_CK1MAP 0x74 -#define REG_CK3MAP 0x77 -#define REG_CK4MAP 0x7a - -#define REGF8 0xf8 -#define REGF8_MAXSEL 0xf0 -#define REGF8_SMAXSEL 4 -#define REGF8_MINSEL 0x0f - -#define SETREG(adr,val) { dev->reg.init_reg(adr, val); } - - -/** set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -static SANE_Status gl846_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, SetupParams& params); - -/* Send the low-level scan command */ -static SANE_Status gl846_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, SANE_Bool start_motor); - -/* Send the stop scan command */ -static SANE_Status gl846_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, SANE_Bool check_stop); - -static SANE_Status gl846_init (Genesys_Device * dev); - -/** @brief moves the slider to steps at motor base dpi - * @param dev device to work on - * @param steps number of steps to move - * */ -static SANE_Status -gl846_feed (Genesys_Device * dev, unsigned int steps); - -static SANE_Status -gl846_stop_action (Genesys_Device * dev); - -static SANE_Status -gl846_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home); - -static SANE_Status -gl846_boot (Genesys_Device * dev, SANE_Bool cold); - - - -typedef struct -{ - uint8_t sensor_id; - uint8_t r6b; - uint8_t r6c; - uint8_t r6d; - uint8_t r6e; - uint8_t r6f; - uint8_t ra6; - uint8_t ra7; - uint8_t ra8; - uint8_t ra9; -} Gpio_Profile; - -static Gpio_Profile gpios[]={ - { GPO_IMG101, 0x72, 0x1f, 0xa4, 0x13, 0xa7, 0x11, 0xff, 0x19, 0x05}, - { GPO_PLUSTEK3800, 0x30, 0x01, 0x80, 0x2d, 0x80, 0x0c, 0x8f, 0x08, 0x04}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -}; - -typedef struct -{ - const char *model; - uint8_t dramsel; - /* shading data address */ - uint8_t rd0; - uint8_t rd1; - uint8_t rd2; - /* scanned data address */ - uint8_t rx[24]; -} Memory_layout; - -static Memory_layout layouts[]={ - /* Image formula 101 */ - { - "canon-image-formula-101", - 0x8b, - 0x0a, 0x1b, 0x00, - { /* RED ODD START / RED ODD END */ - 0x00, 0xb0, 0x05, 0xe7, /* [0x00b0, 0x05e7] 1336*4000w */ - /* RED EVEN START / RED EVEN END */ - 0x05, 0xe8, 0x0b, 0x1f, /* [0x05e8, 0x0b1f] */ - /* GREEN ODD START / GREEN ODD END */ - 0x0b, 0x20, 0x10, 0x57, /* [0x0b20, 0x1057] */ - /* GREEN EVEN START / GREEN EVEN END */ - 0x10, 0x58, 0x15, 0x8f, /* [0x1058, 0x158f] */ - /* BLUE ODD START / BLUE ODD END */ - 0x15, 0x90, 0x1a, 0xc7, /* [0x1590,0x1ac7] */ - /* BLUE EVEN START / BLUE EVEN END */ - 0x1a, 0xc8, 0x1f, 0xff /* [0x1ac8,0x1fff] */ - } - }, - /* OpticBook 3800 */ - { - "plustek-opticbook-3800", - 0x2a, - 0x0a, 0x0a, 0x0a, - { /* RED ODD START / RED ODD END */ - 0x00, 0x68, 0x03, 0x00, - /* RED EVEN START / RED EVEN END */ - 0x03, 0x01, 0x05, 0x99, - /* GREEN ODD START / GREEN ODD END */ - 0x05, 0x9a, 0x08, 0x32, - /* GREEN EVEN START / GREEN EVEN END */ - 0x08, 0x33, 0x0a, 0xcb, - /* BLUE ODD START / BLUE ODD END */ - 0x0a, 0xcc, 0x0d, 0x64, - /* BLUE EVEN START / BLUE EVEN END */ - 0x0d, 0x65, 0x0f, 0xfd - } - }, - /* list terminating entry */ - { NULL, 0, 0, 0, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} } -}; - -/** @brief structure for sensor settings - * this structure describes the sensor settings to use for a given - * exposure. - */ -typedef struct { - int sensor_type; /**> sensor id */ - int dpi; /**> maximum dpi for which data are valid */ - int exposure; /**> exposure */ - int ck1map; /**> CK1MAP */ - int ck3map; /**> CK3MAP */ - int ck4map; /**> CK4MAP */ - int segcnt; /**> SEGCNT */ - int expdummy; /**> exposure dummy */ - int expr; /**> initial red exposure */ - int expg; /**> initial green exposure */ - int expb; /**> initial blue exposure */ - size_t *order; /**> order of sub-segments */ - uint8_t r17; /**> TG width */ -} Sensor_Profile; - -/** - * order of the scanned pixel - */ -static size_t order_01[]={0,1}; - -/** - * database of sensor profiles - */ -static Sensor_Profile sensors[]={ - {CCD_IMG101, 1200, 11000, 60, 159, 85, 5136, 255, 0, 0, 0, order_01 , 0x13}, - {CCD_PLUSTEK3800, 1200, 11000, 60, 159, 85, 5136, 255, 0, 0, 0, order_01 , 0x13}, -}; - -/* base motor slopes in full step unit */ -/* target=((exposure * dpi) / base_dpi)>>step_type; */ -static uint32_t img101_high[] = {22000, 22000, 22000, 18450, 15974, 14284, 13054, 12076, 11286, 10660, 10100, 9632, 9224, 8864, 8532, 8250, 7986, 7750, 7530, 7330, 7142, 6972, 6810, 6656, 6518, 6384, 6264, 6150, 6038, 5930, 5834, 5732, 5642, 5560, 5476, 5398, 5324, 5252, 5180, 5112, 5050, 4990, 4926, 4868, 4816, 4760, 4708, 4658, 4608, 4562, 4516, 4472, 4428, 4384, 4344, 4306, 4266, 4230, 4194, 4156, 4122, 4088, 4054, 4022, 3990, 3960, 3930, 3900, 3872, 3842, 3816, 3790, 3762, 3736, 3710, 3686, 3662, 3638, 3614, 3590, 3570, 3548, 3526, 3506, 3484, 3462, 3442, 3424, 3402, 3384, 3366, 3346, 3328, 3310, 3292, 3276, 3258, 3242, 3224, 3208, 3192, 3176, 3162, 3146, 3130, 3114, 3100, 3086, 3072, 3058, 3044, 3030, 3016, 3002, 2990, 2976, 2964, 2950, 2938, 2926, 2914, 2902, 2890, 2878, 2866, 2854, 2844, 2832, 2820, 2810, 2800, 2790, 2778, 2768, 2756, 2748, 2738, 2726, 2716, 2708, 2698, 2688, 2678, 2668, 2660, 2650, 2642, 2632, 2624, 2616, 2606, 2598, 2588, 2580, 2572, 2564, 2556, 2548, 2540, 2530, 2522, 2516, 2508, 2500, 2492, 2486, 2476, 2470, 2462, 2454, 2448, 2440, 2434, 2426, 2420, 2412, 2406, 2400, 2392, 2386, 2378, 2372, 2366, 2360, 2354, 2346, 2340, 2334, 2328, 2322, 2314, 2310, 2304, 2296, 2292, 2286, 2280, 2274, 2268, 2262, 2256, 2252, 2246, 2240, 2234, 2230, 2224, 2218, 2214, 2208, 2202, 2196, 2192, 2188, 2182, 2176, 2172, 2166, 2162, 2156, 2152, 2146, 2142, 2136, 2132, 2128, 2124, 2118, 2114, 2108, 2104, 2100, 2096, 2092, 2086, 2082, 2078, 2072, 2068, 2064, 2060, 2056, 2052, 2048, 2044, 2038, 2034, 2030, 2026, 2022, 2018, 2014, 2010, 2006, 2002, 1998, 1994, 1990, 1988, 1984, 1980, 1976, 1972, 1968, 1964, 1960, 1956, 1952, 1950, 1946, 1942, 1938, 1934, 1932, 1928, 1924, 1920, 1918, 1914, 1910, 1908, 1904, 1900, 1898, 1894, 1890, 1888, 1884, 1880, 1878, 1874, 1870, 1868, 1864, 1862, 1858, 1854, 1852, 1848, 1846, 1842, 1840, 1836, 1834, 1830, 1828, 1824, 1822, 1818, 1816, 1812, 1810, 1806, 1804, 1800, 1798, 1794, 1792, 1790, 1786, 1784, 1780, 1778, 1776, 1772, 1770, 1768, 1764, 1762, 1758, 1756, 1754, 1752, 1748, 1746, 1744, 1740, 1738, 1736, 1734, 1730, 1728, 1726, 1724, 1720, 1718, 1716, 1714, 1710, 1708, 1706, 1704, 1700, 1698, 1696, 1694, 1692, 1688, 1686, 1684, 1682, 1680, 1676, 1674, 1672, 1670, 1668, 1666, 1664, 1662, 1660, 1656, 1654, 1652, 1650, 1648, 1646, 1644, 1642, 1638, 1636, 1634, 1632, 1630, 1628, 1626, 1624, 1622, 1620, 1618, 1616, 1614, 1612, 1610, 1608, 1606, 1604, 1602, 1600, 1598, 1596, 1594, 1592, 1590, 1588, 1586, 1584, 1582, 1580, 1578, 1576, 1574, 1572, 1570, 1568, 1566, 1564, 1562, 1560, 1558, 1556, 1556, 1554, 1552, 1550, 1548, 1546, 1544, 1542, 1540, 1538, 1536, 1536, 1534, 1532, 1530, 1528, 1526, 1524, 1522, 1522, 1520, 1518, 1516, 1514, 1512, 1510, 1510, 1508, 1506, 1504, 1502, 1500, 1500, 1498, 1496, 1494, 1492, 1490, 1490, 1488, 1486, 1484, 1482, 1482, 1480, 1478, 1476, 1474, 1474, 1472, 1470, 1468, 1466, 1466, 1464, 1462, 1460, 1460, 1458, 1456, 1454, 1454, 1452, 1450, 1448, 1448, 1446, 1444, 1442, 1442, 1440, 1438, 1438, 1436, 1434, 1432, 1432, 1430, 1428, 1426, 1426, 1424, 1422, 1422, 1420, 1418, 1418, 1416, 1414, 1412, 1412, 1410, 1408, 1408, 1406, 1404, 1404, 1402, 1400, 1400, 1398, 1396, 1394, 1394, 1392, 1390, 1390, 1388, 1388, 1386, 1384, 1384, 1382, 1380, 1380, 1378, 1376, 1376, 1374, 1374, 1372, 1370, 1370, 1368, 1366, 1366, 1364, 1362, 1362, 1360, 1360, 1358, 1356, 1356, 1354, 1352, 1352, 1350, 1350, 1348, 1348, 1346, 1344, 1344, 1342, 1340, 1340, 1338, 1338, 1336, 1336, 1334, 1332, 1332, 1330, 1330, 1328, 1328, 1326, 1324, 1324, 1322, 1322, 1320, 1318, 1318, 1316, 1316, 1314, 1314, 1312, 1310, 1310, 1308, 1308, 1306, 1306, 1304, 1304, 1302, 1302, 1300, 1300, 1298, 1298, 1296, 1294, 1294, 1292, 1292, 1290, 1290, 1288, 1288, 1286, 1286, 1284, 1284, 1282, 1282, 1280, 1280, 1278, 1278, 1276, 1276, 1274, 1272, 1272, 1270, 1270, 1270, 1268, 1268, 1266, 1264, 1264, 1262, 1262, 1260, 1260, 1260, 1258, 1258, 1256, 1254, 1254, 1254, 1252, 1252, 1250, 1250, 1248, 1248, 1246, 1246, 1244, 1244, 1242, 1242, 1240, 1240, 1238, 1238, 1236, 1236, 1236, 1234, 1234, 1232, 1232, 1230, 1230, 1228, 1228, 1226, 1226, 1226, 1224, 1224, 1222, 1222, 1220, 1220, 1218, 1218, 1218, 1216, 1216, 1214, 1214, 1212, 1212, 1210, 1210, 1210, 1208, 1208, 1206, 1206, 1204, 1204, 1204, 1202, 1202, 1200, 1200, 1198, 1198, 1198, 1196, 1196, 1194, 1194, 1192, 1192, 1192, 1190, 1190, 1188, 1188, 1188, 1186, 1186, 1184, 1184, 1182, 1182, 1182, 1180, 1180, 1180, 1178, 1178, 1176, 1176, 1174, 1174, 1174, 1172, 1172, 1172, 1170, 1170, 1168, 1168, 1168, 1166, 1166, 1164, 1164, 1164, 1162, 1162, 1160, 1160, 1160, 1158, 1158, 1156, 1156, 1156, 1154, 1154, 1154, 1152, 1152, 1152, 1150, 1150, 1148, 1148, 1148, 1146, 1146, 1146, 1144, 1144, 1142, 1142, 1142, 1140, 1140, 1140, 1138, 1138, 1136, 1136, 1136, 1134, 1134, 1134, 1132, 1132, 1132, 1130, 1130, 1130, 1128, 1128, 1126, 1126, 1126, 1124, 1124, 1124, 1122, 1122, 1122, 1120, 1120, 1120, 1118, 1118, 1118, 1116, 1116, 1116, 1114, 1114, 1114, 1112, 1112, 1112, 1110, 1110, 1110, 1108, 1108, 1108, 1106, 1106, 1106, 1104, 1104, 1104, 1102, 1102, 1102, 1100, 1100, 1100, 1098, 1098, 1098, 1096, 1096, 1096, 1094, 1094, 1094, 1092, 1092, 1092, 1090, 1090, 1090, 1088, 1088, 1088, 1086, 1086, 1086, 1086, 1084, 1084, 1084, 1082, 1082, 1082, 1080, 1080, 1080, 1078, 1078, 1078, 1078, 1076, 1076, 1076, 1074, 1074, 1074, 1072, 1072, 1072, 1072, 1070, 1070, 1070, 1068, 1068, 1068, 1066, 1066, 1066, 1064, 1064, 1064, 1064, 1062, 1062, 1062, 1060, 1060, 1060, 1058, 1058, 1058, 1058, 1056, 1056, 1056, 1054, 1054, 1054, 1054, 1052, 1052, 1052, 1050, 1050, 1050, 1050, 1048, 1048, 1048, 1046, 1046, 1046, 1046, 1044, 1044, 1044, 1044, 1042, 1042, 1042, 1040, 1040, 1040, 1040, 1038, 1038, 1038, 1036, 1036, 1036, 1036, 1034, 1034, 1034, 1034, 1032, 1032, 1032, 1030, 1030, 1030, 1030, 1028, 1028, 1028, 1028, 1026, 1026, 1026, 1026, 1024, 1024, 1024, 1022, 1022, 1022, 1022, 1020, 1020, 1020, 1020, 1018, 1018, 1018, 1018, 1016, 1016, 1016, 1016, 1014, 1014, 1014, 1014, 1012, 1012, 1012, 1012, 1010, 1010, 1010, 1010, 1008, 1008, 1008, 1008, 1006, 1006, 1006, 1006, 1004, 1004, 1004, 1004, 1002, 1002, 1002, 1002, 1000, 1000, 1000, 1000, 0 }; - -/** - * database of motor profiles - */ - -static Motor_Profile gl846_motors[]={ - /* Image Formula 101 */ - {MOTOR_IMG101, 11000, HALF_STEP , img101_high}, - {MOTOR_PLUSTEK3800, 11000, HALF_STEP , img101_high}, - - /* end of database entry */ - {0, 0, 0, NULL}, -}; diff --git a/backend/genesys_gl847.cc b/backend/genesys_gl847.cc deleted file mode 100644 index b5748a5..0000000 --- a/backend/genesys_gl847.cc +++ /dev/null @@ -1,3517 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> - - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#define DEBUG_DECLARE_ONLY - -#include "genesys_gl847.h" - -#include <vector> - -/**************************************************************************** - Mid level functions - ****************************************************************************/ - -static SANE_Bool -gl847_get_fast_feed_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG02); - if (r && (r->value & REG02_FASTFED)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl847_get_filter_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_FILTER)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl847_get_lineart_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_LINEART)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl847_get_bitset_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, REG04); - if (r && (r->value & REG04_BITSET)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl847_get_gain4_bit (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - - r = sanei_genesys_get_address (regs, 0x06); - if (r && (r->value & REG06_GAIN4)) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl847_test_buffer_empty_bit (SANE_Byte val) -{ - if (val & REG41_BUFEMPTY) - return SANE_TRUE; - return SANE_FALSE; -} - -static SANE_Bool -gl847_test_motor_flag_bit (SANE_Byte val) -{ - if (val & REG41_MOTORENB) - return SANE_TRUE; - return SANE_FALSE; -} - -/** - * compute the step multiplier used - */ -static int -gl847_get_step_multiplier (Genesys_Register_Set * regs) -{ - GenesysRegister *r = NULL; - int value = 1; - - r = sanei_genesys_get_address (regs, 0x9d); - if (r != NULL) - { - value = (r->value & 0x0f)>>1; - value = 1 << value; - } - DBG (DBG_io, "%s: step multiplier is %d\n", __func__, value); - return value; -} - -/** @brief sensor profile - * search for the database of motor profiles and get the best one. Each - * profile is at a specific dpihw. Use LiDE 110 table by default. - * @param sensor_type sensor id - * @param dpi hardware dpi for the scan - * @return a pointer to a Sensor_Profile struct - */ -static Sensor_Profile *get_sensor_profile(int sensor_type, int dpi) -{ - unsigned int i; - int idx; - - i=0; - idx=-1; - while(i<sizeof(sensors)/sizeof(Sensor_Profile)) - { - /* exact match */ - if(sensors[i].sensor_type==sensor_type && sensors[i].dpi==dpi) - { - return &(sensors[i]); - } - - /* closest match */ - if(sensors[i].sensor_type==sensor_type) - { - if(idx<0) - { - idx=i; - } - else - { - if(sensors[i].dpi>=dpi - && sensors[i].dpi<sensors[idx].dpi) - { - idx=i; - } - } - } - i++; - } - - /* default fallback */ - if(idx<0) - { - DBG (DBG_warn,"%s: using default sensor profile\n",__func__); - idx=0; - } - - return &(sensors[idx]); -} - -/**@brief compute exposure to use - * compute the sensor exposure based on target resolution - */ -static int gl847_compute_exposure(Genesys_Device *dev, int xres) -{ - Sensor_Profile* sensor_profile=get_sensor_profile(dev->model->ccd_type, xres); - return sensor_profile->exposure; -} - - -/** @brief sensor specific settings -*/ -static void gl847_setup_sensor(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, int dpi) -{ - GenesysRegister *r; - int dpihw; - uint16_t exp; - - DBGSTART; - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dpi); - - for (uint16_t addr = 0x16; addr < 0x1e; addr++) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - for (uint16_t addr = 0x52; addr < 0x52 + 9; addr++) { - regs->set8(addr, sensor.custom_regs.get_value(addr)); - } - - /* set EXPDUMMY and CKxMAP */ - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dpi); - Sensor_Profile* sensor_profile=get_sensor_profile(dev->model->ccd_type, dpihw); - - sanei_genesys_set_reg_from_set(regs,REG_EXPDMY,(uint8_t)((sensor_profile->expdummy) & 0xff)); - - /* if no calibration has been done, set default values for exposures */ - exp = sensor.exposure.red; - if(exp==0) - { - exp=sensor_profile->expr; - } - sanei_genesys_set_double(regs,REG_EXPR,exp); - - exp = sensor.exposure.green; - if(exp==0) - { - exp=sensor_profile->expg; - } - sanei_genesys_set_double(regs,REG_EXPG,exp); - - exp = sensor.exposure.blue; - if(exp==0) - { - exp=sensor_profile->expb; - } - sanei_genesys_set_double(regs,REG_EXPB,exp); - - sanei_genesys_set_triple(regs,REG_CK1MAP,sensor_profile->ck1map); - sanei_genesys_set_triple(regs,REG_CK3MAP,sensor_profile->ck3map); - sanei_genesys_set_triple(regs,REG_CK4MAP,sensor_profile->ck4map); - - /* order of the sub-segments */ - dev->order=sensor_profile->order; - - r = sanei_genesys_get_address (regs, 0x17); - r->value = sensor_profile->r17; - - DBGCOMPLETED; -} - - -/** @brief set all registers to default values . - * This function is called only once at the beginning and - * fills register startup values for registers reused across scans. - * Those that are rarely modified or not modified are written - * individually. - * @param dev device structure holding register set to initialize - */ -static void -gl847_init_registers (Genesys_Device * dev) -{ - int lide700=0; - uint8_t val; - - DBGSTART; - /* 700F class needs some different initial settings */ - if (dev->model->model_id == MODEL_CANON_LIDE_700F) - { - lide700 = 1; - } - - dev->reg.clear(); - - SETREG (0x01, 0x82); - SETREG (0x02, 0x18); - SETREG (0x03, 0x50); - SETREG (0x04, 0x12); - SETREG (0x05, 0x80); - SETREG (0x06, 0x50); /* FASTMODE + POWERBIT */ - SETREG (0x08, 0x10); - SETREG (0x09, 0x01); - SETREG (0x0a, 0x00); - SETREG (0x0b, 0x01); - SETREG (0x0c, 0x02); - - /* LED exposures */ - SETREG (0x10, 0x00); - SETREG (0x11, 0x00); - SETREG (0x12, 0x00); - SETREG (0x13, 0x00); - SETREG (0x14, 0x00); - SETREG (0x15, 0x00); - - SETREG (0x16, 0x10); - SETREG (0x17, 0x08); - SETREG (0x18, 0x00); - - /* EXPDMY */ - SETREG (0x19, 0x50); - - SETREG (0x1a, 0x34); - SETREG (0x1b, 0x00); - SETREG (0x1c, 0x02); - SETREG (0x1d, 0x04); - SETREG (0x1e, 0x10); - SETREG (0x1f, 0x04); - SETREG (0x20, 0x02); - SETREG (0x21, 0x10); - SETREG (0x22, 0x7f); - SETREG (0x23, 0x7f); - SETREG (0x24, 0x10); - SETREG (0x25, 0x00); - SETREG (0x26, 0x00); - SETREG (0x27, 0x00); - SETREG (0x2c, 0x09); - SETREG (0x2d, 0x60); - SETREG (0x2e, 0x80); - SETREG (0x2f, 0x80); - SETREG (0x30, 0x00); - SETREG (0x31, 0x10); - SETREG (0x32, 0x15); - SETREG (0x33, 0x0e); - SETREG (0x34, 0x40); - SETREG (0x35, 0x00); - SETREG (0x36, 0x2a); - SETREG (0x37, 0x30); - SETREG (0x38, 0x2a); - SETREG (0x39, 0xf8); - SETREG (0x3d, 0x00); - SETREG (0x3e, 0x00); - SETREG (0x3f, 0x00); - SETREG (0x52, 0x03); - SETREG (0x53, 0x07); - SETREG (0x54, 0x00); - SETREG (0x55, 0x00); - SETREG (0x56, 0x00); - SETREG (0x57, 0x00); - SETREG (0x58, 0x2a); - SETREG (0x59, 0xe1); - SETREG (0x5a, 0x55); - SETREG (0x5e, 0x41); - SETREG (0x5f, 0x40); - SETREG (0x60, 0x00); - SETREG (0x61, 0x21); - SETREG (0x62, 0x40); - SETREG (0x63, 0x00); - SETREG (0x64, 0x21); - SETREG (0x65, 0x40); - SETREG (0x67, 0x80); - SETREG (0x68, 0x80); - SETREG (0x69, 0x20); - SETREG (0x6a, 0x20); - - /* CK1MAP */ - SETREG (0x74, 0x00); - SETREG (0x75, 0x00); - SETREG (0x76, 0x3c); - - /* CK3MAP */ - SETREG (0x77, 0x00); - SETREG (0x78, 0x00); - SETREG (0x79, 0x9f); - - /* CK4MAP */ - SETREG (0x7a, 0x00); - SETREG (0x7b, 0x00); - SETREG (0x7c, 0x55); - - SETREG (0x7d, 0x00); - - /* NOTE: autoconf is a non working option */ - SETREG (0x87, 0x02); - SETREG (0x9d, 0x06); - SETREG (0xa2, 0x0f); - SETREG (0xbd, 0x18); - SETREG (0xfe, 0x08); - - /* gamma[0] and gamma[256] values */ - SETREG (0xbe, 0x00); - SETREG (0xc5, 0x00); - SETREG (0xc6, 0x00); - SETREG (0xc7, 0x00); - SETREG (0xc8, 0x00); - SETREG (0xc9, 0x00); - SETREG (0xca, 0x00); - - /* LiDE 700 fixups */ - if(lide700) - { - SETREG (0x5f, 0x04); - SETREG (0x7d, 0x80); - - /* we write to these registers only once */ - val=0; - sanei_genesys_write_register (dev, REG7E, val); - sanei_genesys_write_register (dev, REG9E, val); - sanei_genesys_write_register (dev, REG9F, val); - sanei_genesys_write_register (dev, REGAB, val); - } - - /* fine tune upon device description */ - dev->reg.find_reg(0x05).value &= ~REG05_DPIHW; - switch (sanei_genesys_find_sensor_any(dev).optical_res) - { - case 600: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_600; - break; - case 1200: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_1200; - break; - case 2400: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_2400; - break; - case 4800: - dev->reg.find_reg(0x05).value |= REG05_DPIHW_4800; - break; - } - - /* initalize calibration reg */ - dev->calib_reg = dev->reg; - - DBGCOMPLETED; -} - -/**@brief send slope table for motor movement - * Send slope_table in machine byte order - * @param dev device to send slope table - * @param table_nr index of the slope table in ASIC memory - * Must be in the [0-4] range. - * @param slope_table pointer to 16 bit values array of the slope table - * @param steps number of elements in the slope table - */ -static SANE_Status -gl847_send_slope_table (Genesys_Device * dev, int table_nr, - uint16_t * slope_table, int steps) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - char msg[10000]; - - DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __func__, - table_nr, steps); - - /* sanity check */ - if(table_nr<0 || table_nr>4) - { - DBG (DBG_error, "%s: invalid table number %d!\n", __func__, table_nr); - return SANE_STATUS_INVAL; - } - - std::vector<uint8_t> table(steps * 2); - for (i = 0; i < steps; i++) - { - table[i * 2] = slope_table[i] & 0xff; - table[i * 2 + 1] = slope_table[i] >> 8; - } - - if (DBG_LEVEL >= DBG_io) - { - sprintf (msg, "write slope %d (%d)=", table_nr, steps); - for (i = 0; i < steps; i++) - { - sprintf (msg+strlen(msg), "%d", slope_table[i]); - } - DBG (DBG_io, "%s: %s\n", __func__, msg); - } - - /* slope table addresses are fixed */ - status = sanei_genesys_write_ahb(dev, 0x10000000 + 0x4000 * table_nr, steps * 2, table.data()); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: write to AHB failed writing slope table %d (%s)\n", __func__, table_nr, - sane_strstatus(status)); - } - - DBGCOMPLETED; - return status; -} - -/** - * Set register values of Analog Device type frontend - * */ -static SANE_Status -gl847_set_ad_fe (Genesys_Device * dev, uint8_t set) -{ - SANE_Status status = SANE_STATUS_GOOD; - int i; - uint8_t val8; - - DBGSTART; - - /* wait for FE to be ready */ - status = sanei_genesys_get_status (dev, &val8); - while (val8 & REG41_FEBUSY) - { - sanei_genesys_sleep_ms(10); - status = sanei_genesys_get_status (dev, &val8); - }; - - if (set == AFE_INIT) - { - DBG(DBG_proc, "%s(): setting DAC %u\n", __func__, dev->model->dac_type); - - dev->frontend = dev->frontend_initial; - } - - /* reset DAC */ - status = sanei_genesys_fe_write_data (dev, 0x00, 0x80); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write reg0: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* write them to analog frontend */ - status = sanei_genesys_fe_write_data(dev, 0x00, dev->frontend.regs.get_value(0x00)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write reg0: %s\n", __func__, sane_strstatus(status)); - return status; - } - status = sanei_genesys_fe_write_data(dev, 0x01, dev->frontend.regs.get_value(0x01)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write reg1: %s\n", __func__, sane_strstatus(status)); - return status; - } - - for (i = 0; i < 3; i++) - { - status = sanei_genesys_fe_write_data(dev, 0x02 + i, dev->frontend.get_gain(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write gain %d: %s\n", __func__, i, sane_strstatus(status)); - return status; - } - } - for (i = 0; i < 3; i++) - { - status = sanei_genesys_fe_write_data(dev, 0x05 + i, dev->frontend.get_offset(i)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write offset %d: %s\n", __func__, i, - sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - return status; -} - -static SANE_Status -gl847_homsnr_gpio(Genesys_Device *dev) -{ -uint8_t val; -SANE_Status status=SANE_STATUS_GOOD; - - if (dev->model->gpo_type == GPO_CANONLIDE700) - { - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - val &= ~REG6C_GPIO10; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - } - else - { - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - val |= REG6C_GPIO10; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - } - return status; -} - -/* Set values of analog frontend */ -static SANE_Status -gl847_set_fe(Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set) -{ - (void) sensor; - - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - DBG(DBG_proc, "%s (%s)\n", __func__, set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set == - AFE_POWER_SAVE ? "powersave" : "huh?"); - - RIE (sanei_genesys_read_register (dev, REG04, &val)); - - /* route to AD devices */ - if ((val & REG04_FESET) == 0x02) - { - return gl847_set_ad_fe (dev, set); - } - - /* for now there is no support yet for wolfson fe */ - DBG(DBG_proc, "%s(): unsupported frontend type %d\n", __func__, - dev->reg.find_reg(0x04).value & REG04_FESET); - - DBGCOMPLETED; - return SANE_STATUS_UNSUPPORTED; -} - - -/** @brief set up motor related register for scan - */ -static SANE_Status -gl847_init_motor_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int scan_exposure_time, - float scan_yres, - int scan_step_type, - unsigned int scan_lines, - unsigned int scan_dummy, - unsigned int feed_steps, - int scan_power_mode, - unsigned int flags) -{ - SANE_Status status = SANE_STATUS_GOOD; - int use_fast_fed; - unsigned int fast_dpi; - uint16_t scan_table[SLOPE_TABLE_SIZE]; - uint16_t fast_table[SLOPE_TABLE_SIZE]; - int scan_steps, fast_steps, factor; - unsigned int feedl, dist; - GenesysRegister *r; - uint32_t z1, z2; - unsigned int min_restep = 0x20; - uint8_t val, effective; - int fast_step_type; - unsigned int ccdlmt,tgtime; - - DBGSTART; - DBG(DBG_proc, "%s : scan_exposure_time=%d, can_yres=%g, scan_step_type=%d, scan_lines=%d, " - "scan_dummy=%d, feed_steps=%d, scan_power_mode=%d, flags=%x\n", __func__, scan_exposure_time, - scan_yres, scan_step_type, scan_lines, scan_dummy, feed_steps, scan_power_mode, flags); - - /* get step multiplier */ - factor = gl847_get_step_multiplier (reg); - - use_fast_fed=0; - /* no fast fed since feed works well */ - if(dev->settings.yres==4444 && feed_steps>100 - && ((flags & MOTOR_FLAG_FEED)==0)) - { - use_fast_fed=1; - } - DBG(DBG_io, "%s: use_fast_fed=%d\n", __func__, use_fast_fed); - - sanei_genesys_set_triple(reg, REG_LINCNT, scan_lines); - DBG(DBG_io, "%s: lincnt=%d\n", __func__, scan_lines); - - /* compute register 02 value */ - r = sanei_genesys_get_address (reg, REG02); - r->value = 0x00; - sanei_genesys_set_motor_power(*reg, true); - - if (use_fast_fed) - r->value |= REG02_FASTFED; - else - r->value &= ~REG02_FASTFED; - - if (flags & MOTOR_FLAG_AUTO_GO_HOME) - r->value |= REG02_AGOHOME | REG02_NOTHOME; - - if ((flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE) - ||(scan_yres>=sensor.optical_res)) - { - r->value |= REG02_ACDCDIS; - } - - /* scan and backtracking slope table */ - sanei_genesys_slope_table(scan_table, - &scan_steps, - scan_yres, - scan_exposure_time, - dev->motor.base_ydpi, - scan_step_type, - factor, - dev->model->motor_type, - gl847_motors); - RIE(gl847_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps*factor)); - RIE(gl847_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps*factor)); - - /* fast table */ - fast_dpi=sanei_genesys_get_lowest_ydpi(dev); - fast_step_type=scan_step_type; - if(scan_step_type>=2) - { - fast_step_type=2; - } - - sanei_genesys_slope_table(fast_table, - &fast_steps, - fast_dpi, - scan_exposure_time, - dev->motor.base_ydpi, - fast_step_type, - factor, - dev->model->motor_type, - gl847_motors); - - /* manual override of high start value */ - fast_table[0]=fast_table[1]; - - RIE(gl847_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps*factor)); - RIE(gl847_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps*factor)); - RIE(gl847_send_slope_table (dev, HOME_TABLE, fast_table, fast_steps*factor)); - - /* correct move distance by acceleration and deceleration amounts */ - feedl=feed_steps; - if (use_fast_fed) - { - feedl<<=fast_step_type; - dist=(scan_steps+2*fast_steps)*factor; - /* TODO read and decode REGAB */ - r = sanei_genesys_get_address (reg, 0x5e); - dist += (r->value & 31); - /* FEDCNT */ - r = sanei_genesys_get_address (reg, REG_FEDCNT); - dist += r->value; - } - else - { - feedl<<=scan_step_type; - dist=scan_steps*factor; - if (flags & MOTOR_FLAG_FEED) - dist *=2; - } - DBG(DBG_io2, "%s: scan steps=%d\n", __func__, scan_steps); - DBG(DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); - - /* check for overflow */ - if(dist<feedl) - feedl -= dist; - else - feedl = 0; - - sanei_genesys_set_triple(reg,REG_FEEDL,feedl); - DBG(DBG_io ,"%s: feedl=%d\n", __func__, feedl); - - r = sanei_genesys_get_address (reg, REG0C); - ccdlmt=(r->value & REG0C_CCDLMT)+1; - - r = sanei_genesys_get_address (reg, REG1C); - tgtime=1<<(r->value & REG1C_TGTIME); - - /* hi res motor speed GPIO */ - RIE (sanei_genesys_read_register (dev, REG6C, &effective)); - - /* if quarter step, bipolar Vref2 */ - if (scan_step_type > 1) - { - if (scan_step_type < 3) - { - val = effective & ~REG6C_GPIO13; - } - else - { - val = effective | REG6C_GPIO13; - } - } - else - { - val = effective; - } - RIE (sanei_genesys_write_register (dev, REG6C, val)); - - /* effective scan */ - RIE (sanei_genesys_read_register (dev, REG6C, &effective)); - val = effective | REG6C_GPIO10; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - - min_restep=scan_steps/2-1; - if (min_restep < 1) - min_restep = 1; - r = sanei_genesys_get_address (reg, REG_FWDSTEP); - r->value = min_restep; - r = sanei_genesys_get_address (reg, REG_BWDSTEP); - r->value = min_restep; - - sanei_genesys_calculate_zmode2(use_fast_fed, - scan_exposure_time*ccdlmt*tgtime, - scan_table, - scan_steps*factor, - feedl, - min_restep*factor, - &z1, - &z2); - - DBG(DBG_info, "%s: z1 = %d\n", __func__, z1); - sanei_genesys_set_triple(reg, REG60, z1 | (scan_step_type << (16+REG60S_STEPSEL))); - - DBG(DBG_info, "%s: z2 = %d\n", __func__, z2); - sanei_genesys_set_triple(reg, REG63, z2 | (scan_step_type << (16+REG63S_FSTPSEL))); - - r = sanei_genesys_get_address (reg, 0x1e); - r->value &= 0xf0; /* 0 dummy lines */ - r->value |= scan_dummy; /* dummy lines */ - - r = sanei_genesys_get_address (reg, REG67); - r->value = REG67_MTRPWM; - - r = sanei_genesys_get_address (reg, REG68); - r->value = REG68_FASTPWM; - - r = sanei_genesys_get_address (reg, REG_STEPNO); - r->value = scan_steps; - - r = sanei_genesys_get_address (reg, REG_FASTNO); - r->value = scan_steps; - - r = sanei_genesys_get_address (reg, REG_FSHDEC); - r->value = scan_steps; - - r = sanei_genesys_get_address (reg, REG_FMOVNO); - r->value = fast_steps; - - r = sanei_genesys_get_address (reg, REG_FMOVDEC); - r->value = fast_steps; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/** @brief set up registers related to sensor - * Set up the following registers - 0x01 - 0x03 - 0x10-0x015 R/G/B exposures - 0x19 EXPDMY - 0x2e BWHI - 0x2f BWLO - 0x04 - 0x87 - 0x05 - 0x2c,0x2d DPISET - 0x30,0x31 STRPIXEL - 0x32,0x33 ENDPIXEL - 0x35,0x36,0x37 MAXWD [25:2] (>>2) - 0x38,0x39 LPERIOD - 0x34 DUMMY - */ -static SANE_Status -gl847_init_optical_regs_scan (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, - unsigned int exposure_time, - int used_res, - unsigned int start, - unsigned int pixels, - int channels, - int depth, - SANE_Bool half_ccd, ColorFilter color_filter, int flags) -{ - unsigned int words_per_line; - unsigned int startx, endx, used_pixels; - unsigned int dpiset, dpihw,segnb,cksel,factor; - unsigned int bytes; - GenesysRegister *r; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s : exposure_time=%d, used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, " - "half_ccd=%d, flags=%x\n", __func__, exposure_time, used_res, start, pixels, channels, depth, - half_ccd, flags); - - /* resolution is divided according to CKSEL */ - r = sanei_genesys_get_address (reg, REG18); - cksel= (r->value & REG18_CKSEL)+1; - DBG(DBG_io2, "%s: cksel=%d\n", __func__, cksel); - - /* to manage high resolution device while keeping good - * low resolution scanning speed, we make hardware dpi vary */ - dpihw=sanei_genesys_compute_dpihw(dev, sensor, used_res * cksel); - factor=sensor.optical_res/dpihw; - DBG(DBG_io2, "%s: dpihw=%d (factor=%d)\n", __func__, dpihw, factor); - - /* sensor parameters */ - Sensor_Profile* sensor_profile=get_sensor_profile(dev->model->ccd_type, dpihw); - gl847_setup_sensor(dev, sensor, reg, dpihw); - dpiset = used_res * cksel; - - /* start and end coordinate in optical dpi coordinates */ - startx = start/cksel+sensor.CCD_start_xoffset; - used_pixels=pixels/cksel; - - /* end of sensor window */ - endx = startx + used_pixels; - - /* sensors are built from 600 dpi segments for LiDE 100/200 - * and 1200 dpi for the 700F */ - if (dev->model->flags & GENESYS_FLAG_SIS_SENSOR) - { - segnb=dpihw/600; - } - else - { - segnb=1; - } - - /* compute pixel coordinate in the given dpihw space, - * taking segments into account */ - startx/=factor*segnb; - endx/=factor*segnb; - dev->len=endx-startx; - dev->dist=0; - dev->skip=0; - - /* in cas of multi-segments sensor, we have to add the witdh - * of the sensor crossed by the scan area */ - if (dev->model->flags & GENESYS_FLAG_SIS_SENSOR && segnb>1) - { - dev->dist = sensor_profile->segcnt; - } - - /* use a segcnt rounded to next even number */ - endx += ((dev->dist+1)&0xfffe)*(segnb-1); - used_pixels=endx-startx; - - status = gl847_set_fe(dev, sensor, AFE_SET); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set frontend: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* enable shading */ - r = sanei_genesys_get_address (reg, REG01); - r->value &= ~REG01_SCAN; - r->value |= REG01_SHDAREA; - if ((flags & OPTICAL_FLAG_DISABLE_SHADING) || - (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) - { - r->value &= ~REG01_DVDSET; - } - else - { - r->value |= REG01_DVDSET; - } - - r = sanei_genesys_get_address (reg, REG03); - r->value &= ~REG03_AVEENB; - - sanei_genesys_set_lamp_power(dev, sensor, *reg, !(flags & OPTICAL_FLAG_DISABLE_LAMP)); - - /* BW threshold */ - r = sanei_genesys_get_address (reg, 0x2e); - r->value = dev->settings.threshold; - r = sanei_genesys_get_address (reg, 0x2f); - r->value = dev->settings.threshold; - - /* monochrome / color scan */ - r = sanei_genesys_get_address (reg, REG04); - switch (depth) - { - case 1: - r->value &= ~REG04_BITSET; - r->value |= REG04_LINEART; - break; - case 8: - r->value &= ~(REG04_LINEART | REG04_BITSET); - break; - case 16: - r->value &= ~REG04_LINEART; - r->value |= REG04_BITSET; - break; - } - - r->value &= ~(REG04_FILTER | REG04_AFEMOD); - if (channels == 1) - { - switch (color_filter) - { - - case ColorFilter::RED: - r->value |= 0x14; - break; - case ColorFilter::BLUE: - r->value |= 0x1c; - break; - case ColorFilter::GREEN: - r->value |= 0x18; - break; - default: - break; // should not happen - } - } - else - r->value |= 0x10; /* mono */ - - /* register 05 */ - r = sanei_genesys_get_address (reg, REG05); - - /* set up dpihw */ - r->value &= ~REG05_DPIHW; - switch(dpihw) - { - case 600: - r->value |= REG05_DPIHW_600; - break; - case 1200: - r->value |= REG05_DPIHW_1200; - break; - case 2400: - r->value |= REG05_DPIHW_2400; - break; - case 4800: - r->value |= REG05_DPIHW_4800; - break; - } - - /* enable gamma tables */ - if (flags & OPTICAL_FLAG_DISABLE_GAMMA) - r->value &= ~REG05_GMMENB; - else - r->value |= REG05_GMMENB; - - /* CIS scanners can do true gray by setting LEDADD */ - /* we set up LEDADD only when asked */ - if (dev->model->is_cis == SANE_TRUE) - { - r = sanei_genesys_get_address (reg, 0x87); - r->value &= ~REG87_LEDADD; - if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) - { - r->value |= REG87_LEDADD; - } - /* RGB weighting - r = sanei_genesys_get_address (reg, 0x01); - r->value &= ~REG01_TRUEGRAY; - if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) - { - r->value |= REG01_TRUEGRAY; - }*/ - } - - /* words(16bit) before gamma, conversion to 8 bit or lineart*/ - words_per_line = (used_pixels * dpiset) / dpihw; - bytes=depth/8; - if (depth == 1) - { - words_per_line = (words_per_line+7)/8 ; - dev->len = (dev->len >> 3) + ((dev->len & 7) ? 1 : 0); - dev->dist = (dev->dist >> 3) + ((dev->dist & 7) ? 1 : 0); - } - else - { - words_per_line *= bytes; - dev->dist *= bytes; - dev->len *= bytes; - } - - dev->bpl = words_per_line; - dev->cur=0; - dev->segnb=segnb; - dev->line_interp = 0; - - sanei_genesys_set_double(reg,REG_DPISET,dpiset); - DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); - - sanei_genesys_set_double(reg,REG_STRPIXEL,startx); - sanei_genesys_set_double(reg,REG_ENDPIXEL,endx); - DBG (DBG_io2, "%s: startx=%d\n", __func__, startx); - DBG (DBG_io2, "%s: endx =%d\n", __func__, endx); - - DBG (DBG_io2, "%s: used_pixels=%d\n", __func__, used_pixels); - DBG (DBG_io2, "%s: pixels =%d\n", __func__, pixels); - DBG (DBG_io2, "%s: depth =%d\n", __func__, depth); - DBG (DBG_io2, "%s: dev->bpl =%lu\n", __func__, (unsigned long)dev->bpl); - DBG (DBG_io2, "%s: dev->len =%lu\n", __func__, (unsigned long)dev->len); - DBG (DBG_io2, "%s: dev->dist =%lu\n", __func__, (unsigned long)dev->dist); - DBG (DBG_io2, "%s: dev->segnb =%lu\n", __func__, (unsigned long)dev->segnb); - - words_per_line *= channels; - dev->wpl = words_per_line; - - dev->oe_buffer.clear(); - dev->oe_buffer.alloc(dev->wpl); - - /* MAXWD is expressed in 4 words unit */ - sanei_genesys_set_triple(reg, REG_MAXWD, (words_per_line >> 2)); - DBG(DBG_io2, "%s: words_per_line used=%d\n", __func__, words_per_line); - - sanei_genesys_set_double(reg, REG_LPERIOD, exposure_time); - DBG(DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time); - - r = sanei_genesys_get_address (reg, 0x34); - r->value = sensor.dummy_pixel; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -static SANE_Status -gl847_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SetupParams& params) - -{ - params.assert_valid(); - - int used_res; - int start, used_pixels; - int bytes_per_line; - int move; - unsigned int lincnt; - unsigned int oflags; /**> optical flags */ - unsigned int mflags; /**> motor flags */ - int exposure_time; - int stagger; - - int slope_dpi = 0; - int dummy = 0; - int scan_step_type = 1; - int scan_power_mode = 0; - int max_shift; - size_t requested_buffer_size, read_buffer_size; - - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - int optical_res; - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - - /* we may have 2 domains for ccd: xres below or above half ccd max dpi */ - if (sensor.get_ccd_size_divisor_for_dpi(params.xres) > 1) - { - half_ccd = SANE_TRUE; - } - else - { - half_ccd = SANE_FALSE; - } - - /* optical_res */ - optical_res = sensor.optical_res; - if (half_ccd) - optical_res /= 2; - - /* stagger */ - if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG(DBG_info, "%s : stagger=%d lines\n", __func__, stagger); - - /* used_res */ - if (params.flags & SCAN_FLAG_USE_OPTICAL_RES) - { - used_res = optical_res; - } - else - { - /* resolution is choosen from a list */ - used_res = params.xres; - } - - /* compute scan parameters values */ - /* pixels are allways given at full optical resolution */ - /* use detected left margin and fixed value */ - /* start */ - /* add x coordinates */ - start = params.startx; - - if (stagger > 0) - start |= 1; - - /* compute correct pixels number */ - /* pixels */ - used_pixels = (params.pixels * optical_res) / params.xres; - - /* round up pixels number if needed */ - if (used_pixels * params.xres < params.pixels * optical_res) - used_pixels++; - - dummy = 3-params.channels; - -/* slope_dpi */ -/* cis color scan is effectively a gray scan with 3 gray lines per color - line and a FILTER of 0 */ - if (dev->model->is_cis) - slope_dpi = params.yres * params.channels; - else - slope_dpi = params.yres; - - slope_dpi = slope_dpi * (1 + dummy); - - exposure_time = gl847_compute_exposure (dev, used_res); - scan_step_type = sanei_genesys_compute_step_type(gl847_motors, dev->model->motor_type, exposure_time); - - DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - DBG(DBG_info, "%s : scan_step_type=%d\n", __func__, scan_step_type); - -/*** optical parameters ***/ - /* in case of dynamic lineart, we use an internal 8 bit gray scan - * to generate 1 lineart data */ - if (params.flags & SCAN_FLAG_DYNAMIC_LINEART) { - params.depth = 8; - } - - /* we enable true gray for cis scanners only, and just when doing - * scan since color calibration is OK for this mode - */ - oflags = 0; - if(params.flags & SCAN_FLAG_DISABLE_SHADING) - oflags |= OPTICAL_FLAG_DISABLE_SHADING; - if(params.flags & SCAN_FLAG_DISABLE_GAMMA) - oflags |= OPTICAL_FLAG_DISABLE_GAMMA; - if(params.flags & SCAN_FLAG_DISABLE_LAMP) - oflags |= OPTICAL_FLAG_DISABLE_LAMP; - - if (dev->model->is_cis && dev->settings.true_gray) - { - oflags |= OPTICAL_FLAG_ENABLE_LEDADD; - } - - status = gl847_init_optical_regs_scan (dev, sensor, - reg, - exposure_time, - used_res, - start, - used_pixels, - params.channels, - params.depth, - half_ccd, - params.color_filter, - oflags); - - if (status != SANE_STATUS_GOOD) - return status; - -/*** motor parameters ***/ - - /* max_shift */ - max_shift=sanei_genesys_compute_max_shift(dev,params.channels,params.yres,params.flags); - - /* lincnt */ - lincnt = params.lines + max_shift + stagger; - - /* add tl_y to base movement */ - move = params.starty; - DBG(DBG_info, "%s: move=%d steps\n", __func__, move); - - mflags=0; - if(params.flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) - mflags |= MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; - if(params.flags & SCAN_FLAG_FEEDING) - mflags |= MOTOR_FLAG_FEED; - - status = gl847_init_motor_regs_scan (dev, sensor, - reg, - exposure_time, - slope_dpi, - scan_step_type, - dev->model->is_cis ? lincnt * - params.channels : lincnt, dummy, move, - scan_power_mode, - mflags); - - if (status != SANE_STATUS_GOOD) - return status; - - - /*** prepares data reordering ***/ - -/* words_per_line */ - bytes_per_line = (used_pixels * used_res) / optical_res; - bytes_per_line = (bytes_per_line * params.channels * params.depth) / 8; - - requested_buffer_size = 8 * bytes_per_line; - - read_buffer_size = - 2 * requested_buffer_size + - ((max_shift + stagger) * used_pixels * params.channels * params.depth) / 8; - - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); - - dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); - - dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); - - dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * params.pixels * params.channels * params.depth) / 8); - - dev->read_bytes_left = bytes_per_line * lincnt; - - DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); - dev->read_active = SANE_TRUE; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - -/* TODO: should this be done elsewhere? */ - /* scan bytes to send to the frontend */ - /* theory : - target_size = - (params.pixels * params.lines * channels * depth) / 8; - but it suffers from integer overflow so we do the following: - - 1 bit color images store color data byte-wise, eg byte 0 contains - 8 bits of red data, byte 1 contains 8 bits of green, byte 2 contains - 8 bits of blue. - This does not fix the overflow, though. - 644mp*16 = 10gp, leading to an overflow - -- pierre - */ - - dev->total_bytes_read = 0; - if (params.depth == 1) - dev->total_bytes_to_read = - ((params.pixels * params.lines) / 8 + - (((params.pixels * params.lines) % 8) ? 1 : 0)) * - params.channels; - else - dev->total_bytes_to_read = - params.pixels * params.lines * params.channels * (params.depth / 8); - - DBG(DBG_info, "%s: total bytes to send = %lu\n", __func__, (u_long) dev->total_bytes_to_read); -/* END TODO */ - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static void -gl847_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int depth; - int start; - - int used_res; - int used_pixels; - unsigned int lincnt; - int exposure_time; - int stagger; - - int slope_dpi = 0; - int dummy = 0; - int max_shift; - - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - int optical_res; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - /* start */ - start = SANE_UNFIX (dev->model->x_offset); - start += dev->settings.tl_x; - start = (start * sensor.optical_res) / MM_PER_INCH; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; // not used - params.starty = 0; // not used - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = 0; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, params); - -/* half_ccd */ - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - if (sensor.get_ccd_size_divisor_for_dpi(params.xres) > 1) { - half_ccd = SANE_TRUE; - } else { - half_ccd = SANE_FALSE; - } - - /* optical_res */ - optical_res = sensor.optical_res; - - /* stagger */ - if (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE) - stagger = (4 * params.yres) / dev->motor.base_ydpi; - else - stagger = 0; - DBG(DBG_info, "%s: stagger=%d lines\n", __func__, stagger); - - /* resolution is choosen from a fixed list */ - used_res = params.xres; - - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - - /* compute correct pixels number */ - used_pixels = (params.pixels * optical_res) / used_res; - dummy = 3 - params.channels; - - /* slope_dpi */ - /* cis color scan is effectively a gray scan with 3 gray lines per color - line and a FILTER of 0 */ - if (dev->model->is_cis) { - slope_dpi = params.yres * params.channels; - } else { - slope_dpi = params.yres; - } - - slope_dpi = slope_dpi * (1 + dummy); - - exposure_time = gl847_compute_exposure (dev, used_res); - DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - - /* max_shift */ - max_shift = sanei_genesys_compute_max_shift(dev, params.channels, params.yres, 0); - - /* lincnt */ - lincnt = params.lines + max_shift + stagger; - - dev->current_setup.params = params; - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; - dev->current_setup.lines = lincnt; - dev->current_setup.depth = params.depth; - dev->current_setup.channels = params.channels; - dev->current_setup.exposure_time = exposure_time; - dev->current_setup.xres = used_res; - dev->current_setup.yres = params.yres; - dev->current_setup.ccd_size_divisor = half_ccd ? 2 : 1; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; - - DBGCOMPLETED; -} - -/*for fast power saving methods only, like disabling certain amplifiers*/ -static SANE_Status -gl847_save_power (Genesys_Device * dev, SANE_Bool enable) -{ - DBG(DBG_proc, "%s: enable = %d\n", __func__, enable); - if (dev == NULL) - return SANE_STATUS_INVAL; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl847_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ ) -{ - DBG(DBG_proc, "%s (delay = %d)\n", __func__, delay); - if (dev == NULL) - return SANE_STATUS_INVAL; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl847_start_action (Genesys_Device * dev) -{ - return sanei_genesys_write_register (dev, 0x0f, 0x01); -} - -static SANE_Status -gl847_stop_action (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val40, val; - unsigned int loop; - - DBGSTART; - - /* post scan gpio : without that HOMSNR is unreliable */ - gl847_homsnr_gpio(dev); - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - status = sanei_genesys_read_register (dev, REG40, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* only stop action if needed */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)) - { - DBG(DBG_info, "%s: already stopped\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - /* ends scan */ - val = dev->reg.get8(REG01); - val &= ~REG01_SCAN; - sanei_genesys_set_reg_from_set(&dev->reg, REG01, val); - status = sanei_genesys_write_register (dev, REG01, val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to write register 01: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_sleep_ms(100); - - loop = 10; - while (loop > 0) - { - status = sanei_genesys_get_status (dev, &val); - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - status = sanei_genesys_read_register (dev, REG40, &val40); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* if scanner is in command mode, we are done */ - if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG) - && !(val & REG41_MOTORENB)) - { - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - sanei_genesys_sleep_ms(100); - loop--; - } - - DBGCOMPLETED; - return SANE_STATUS_IO_ERROR; -} - -/* Send the low-level scan command */ -static SANE_Status -gl847_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Register_Set * reg, - SANE_Bool start_motor) -{ - (void) sensor; - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - GenesysRegister *r; - - DBGSTART; - - /* clear GPIO 10 */ - if (dev->model->gpo_type != GPO_CANONLIDE700) - { - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - val &= ~REG6C_GPIO10; - RIE (sanei_genesys_write_register (dev, REG6C, val)); - } - - val = REG0D_CLRLNCNT; - RIE (sanei_genesys_write_register (dev, REG0D, val)); - val = REG0D_CLRMCNT; - RIE (sanei_genesys_write_register (dev, REG0D, val)); - - RIE (sanei_genesys_read_register (dev, REG01, &val)); - val |= REG01_SCAN; - RIE (sanei_genesys_write_register (dev, REG01, val)); - r = sanei_genesys_get_address (reg, REG01); - r->value = val; - - if (start_motor) - { - RIE (sanei_genesys_write_register (dev, REG0F, 1)); - } - else - { - RIE (sanei_genesys_write_register (dev, REG0F, 0)); - } - - DBGCOMPLETED; - - return status; -} - - -/* Send the stop scan command */ -static SANE_Status -gl847_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, - SANE_Bool check_stop) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_proc, "%s (check_stop = %d)\n", __func__, check_stop); - if (reg == NULL) - return SANE_STATUS_INVAL; - - if (dev->model->is_sheetfed == SANE_TRUE) - { - status = SANE_STATUS_GOOD; - } - else /* flat bed scanners */ - { - status = gl847_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - return status; -} - -/** rewind scan - * Move back by the same amount of distance than previous scan. - * @param dev device to rewind - * @returns SANE_STATUS_GOOD on success - */ -#if 0 /* disabled to fix #7 */ -static -SANE_Status gl847_rewind(Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t byte; - - DBGSTART; - - /* set motor reverse */ - RIE (sanei_genesys_read_register (dev, 0x02, &byte)); - byte |= 0x04; - RIE (sanei_genesys_write_register(dev, 0x02, byte)); - - /* and start scan, then wait completion */ - RIE (gl847_begin_scan (dev, dev->reg, SANE_TRUE)); - do - { - sanei_genesys_sleep_ms(100); - RIE (sanei_genesys_read_register (dev, REG40, &byte)); - } - while(byte & REG40_MOTMFLG); - RIE (gl847_end_scan (dev, dev->reg, SANE_TRUE)); - - /* restore direction */ - RIE (sanei_genesys_read_register (dev, 0x02, &byte)); - byte &= 0xfb; - RIE (sanei_genesys_write_register(dev, 0x02, byte)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} -#endif - -/** Park head - * Moves the slider to the home (top) position slowly - * @param dev device to park - * @param wait_until_home true to make the function waiting for head - * to be home before returning, if fals returne immediately - * @returns SANE_STATUS_GOO on success */ -static -SANE_Status -gl847_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - float resolution; - uint8_t val; - int loop = 0; - ScanColorMode scan_mode; - - DBG(DBG_proc, "%s (wait_until_home = %d)\n", __func__, wait_until_home); - - /* post scan gpio : without that HOMSNR is unreliable */ - gl847_homsnr_gpio(dev); - - /* first read gives HOME_SENSOR true */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - sanei_genesys_sleep_ms(100); - - /* second is reliable */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, sane_strstatus(status)); - return status; - } - if (DBG_LEVEL >= DBG_io) - { - sanei_genesys_print_status (val); - } - - /* is sensor at home? */ - if (val & HOMESNR) - { - DBG(DBG_info, "%s: already at home, completed\n", __func__); - dev->scanhead_position_in_steps = 0; - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - - local_reg = dev->reg; - - resolution=sanei_genesys_get_lowest_ydpi(dev); - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - /* TODO add scan_mode to the API */ - scan_mode = dev->settings.scan_mode; - dev->settings.scan_mode = ScanColorMode::LINEART; - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 100; - params.starty = 30000; - params.pixels = 100; - params.lines = 100; - params.depth = 8; - params.channels = 1; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl847_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - dev->settings.scan_mode = scan_mode; - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - - /* set up for reverse */ - r = sanei_genesys_get_address (&local_reg, REG02); - r->value |= REG02_MTRREV; - - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - try { - status = gl847_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl847_stop_action(dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl847_stop_action (dev); - /* send original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - /* post scan gpio : without that HOMSNR is unreliable */ - gl847_homsnr_gpio(dev); - - if (wait_until_home) - { - while (loop < 300) /* do not wait longer then 30 seconds */ - { - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - if (val & HOMESNR) /* home sensor */ - { - DBG(DBG_info, "%s: reached home position\n", __func__); - gl847_stop_action (dev); - dev->scanhead_position_in_steps = 0; - DBGCOMPLETED; - return SANE_STATUS_GOOD; - } - sanei_genesys_sleep_ms(100); - ++loop; - } - - /* when we come here then the scanner needed too much time for this, so we better stop the motor */ - gl847_stop_action (dev); - DBG(DBG_error, "%s: timeout while waiting for scanhead to go home\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - DBG(DBG_info, "%s: scanhead is still moving\n", __func__); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels - area at 600 dpi from very top of scanner */ -static SANE_Status -gl847_search_start_position (Genesys_Device * dev) -{ - int size; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - int steps; - - int pixels = 600; - int dpi = 300; - - DBG(DBG_proc, "%s\n", __func__); - - local_reg = dev->reg; - - /* sets for a 200 lines * 600 pixels */ - /* normal scan with no shading */ - - // FIXME: the current approach of doing search only for one resolution does not work on scanners - // whith employ different sensors with potentially different settings. - auto& sensor = sanei_genesys_find_sensor_for_write(dev, dpi); - - SetupParams params; - params.xres = dpi; - params.yres = dpi; - params.startx = 0; - params.starty = 0; /*we should give a small offset here~60 steps */ - params.pixels = 600; - params.lines = dev->model->search_lines; - params.depth = 8; - params.channels = 1; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::GREEN; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl847_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* send to scanner */ - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - size = pixels * dev->model->search_lines; - - std::vector<uint8_t> data(size); - - status = gl847_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl847_search_position.pnm", data.data(), 8, 1, pixels, - dev->model->search_lines); - - status = gl847_end_scan(dev, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to end scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* update regs to copy ASIC internal state */ - dev->reg = local_reg; - -/*TODO: find out where sanei_genesys_search_reference_point - stores information, and use that correctly*/ - status = - sanei_genesys_search_reference_point(dev, sensor, data.data(), 0, dpi, pixels, - dev->model->search_lines); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set search reference point: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - return SANE_STATUS_GOOD; -} - -/* - * sets up register for coarse gain calibration - * todo: check it for scanners using it */ -static SANE_Status -gl847_init_regs_for_coarse_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t channels; - uint8_t cksel; - - DBG(DBG_proc, "%s\n", __func__); - - - cksel = (regs.find_reg(0x18).value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */ - - /* set line size */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else { - channels = 1; - } - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = 0; - params.starty = 0; - params.pixels = sensor.optical_res / cksel; - params.lines = 20; - params.depth = 16; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl847_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_info, "%s: optical sensor res: %d dpi, actual res: %d\n", __func__, - sensor.optical_res / cksel, dev->settings.xres); - - status = - dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief moves the slider to steps at motor base dpi - * @param dev device to work on - * @param steps number of steps to move in base_dpi line count - * */ -static SANE_Status -gl847_feed (Genesys_Device * dev, unsigned int steps) -{ - Genesys_Register_Set local_reg; - SANE_Status status = SANE_STATUS_GOOD; - GenesysRegister *r; - float resolution; - uint8_t val; - - DBGSTART; - DBG(DBG_io, "%s: steps=%d\n", __func__, steps); - - local_reg = dev->reg; - - resolution=sanei_genesys_get_lowest_ydpi(dev); - const auto& sensor = sanei_genesys_find_sensor(dev, resolution); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = steps; - params.pixels = 100; - params.lines = 3; - params.depth = 8; - params.channels = 3; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_FEEDING | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl847_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus(status)); - DBGCOMPLETED; - return status; - } - - /* set exposure to zero */ - sanei_genesys_set_triple(&local_reg,REG_EXPR,0); - sanei_genesys_set_triple(&local_reg,REG_EXPG,0); - sanei_genesys_set_triple(&local_reg,REG_EXPB,0); - - /* clear scan and feed count */ - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT)); - RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRMCNT)); - - /* set up for no scan */ - r = sanei_genesys_get_address(&local_reg, REG01); - r->value &= ~REG01_SCAN; - - /* send registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, local_reg)); - - try { - status = gl847_start_action (dev); - } catch (...) { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - try { - gl847_stop_action(dev); - } catch (...) {} - try { - // restore original registers - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - } catch (...) {} - throw; - } - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus(status)); - gl847_stop_action (dev); - - /* restore original registers */ - dev->model->cmd_set->bulk_write_register(dev, dev->reg); - return status; - } - - /* wait until feed count reaches the required value, but do not - * exceed 30s */ - do - { - status = sanei_genesys_get_status (dev, &val); - } - while (status == SANE_STATUS_GOOD && !(val & FEEDFSH)); - - /* then stop scanning */ - RIE(gl847_stop_action (dev)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/* init registers for shading calibration */ -static SANE_Status -gl847_init_regs_for_shading(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - float move; - - DBGSTART; - dev->calib_channels = 3; - - /* initial calibration reg values */ - regs = dev->reg; - - dev->calib_resolution = sanei_genesys_compute_dpihw(dev, sensor, dev->settings.xres); - dev->calib_total_bytes_to_read = 0; - dev->calib_lines = dev->model->shading_lines; - if(dev->calib_resolution==4800) - dev->calib_lines *= 2; - dev->calib_pixels = (sensor.sensor_pixels*dev->calib_resolution)/sensor.optical_res; - DBG(DBG_io, "%s: calib_lines = %d\n", __func__, (int)dev->calib_lines); - DBG(DBG_io, "%s: calib_pixels = %d\n", __func__, (int)dev->calib_pixels); - - /* this is aworkaround insufficent distance for slope - * motor acceleration TODO special motor slope for shading */ - move=1; - if(dev->calib_resolution<1200) - { - move=40; - } - - SetupParams params; - params.xres = dev->calib_resolution; - params.yres = dev->calib_resolution; - params.startx = 0; - params.starty = move; - params.pixels = dev->calib_pixels; - params.lines = dev->calib_lines; - params.depth = 16; - params.channels = dev->calib_channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl847_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = dev->model->cmd_set->bulk_write_register(dev, regs); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* we use GENESYS_FLAG_SHADING_REPARK */ - dev->scanhead_position_in_steps = 0; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** @brief set up registers for the actual scan - */ -static SANE_Status -gl847_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int channels; - int flags; - int depth; - float move; - int move_dpi; - float start; - - SANE_Status status = SANE_STATUS_GOOD; - - DBG(DBG_info, "%s ", __func__); - debug_dump(DBG_info, dev->settings); - - /* channels */ - if (dev->settings.scan_mode == ScanColorMode::COLOR_SINGLE_PASS) - channels = 3; - else - channels = 1; - - /* depth */ - depth = dev->settings.depth; - if (dev->settings.scan_mode == ScanColorMode::LINEART) - depth = 1; - - - /* steps to move to reach scanning area: - - first we move to physical start of scanning - either by a fixed steps amount from the black strip - or by a fixed amount from parking position, - minus the steps done during shading calibration - - then we move by the needed offset whitin physical - scanning area - - assumption: steps are expressed at maximum motor resolution - - we need: - SANE_Fixed y_offset; - SANE_Fixed y_size; - SANE_Fixed y_offset_calib; - mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */ - - /* if scanner uses GENESYS_FLAG_SEARCH_START y_offset is - relative from origin, else, it is from parking position */ - - move_dpi = dev->motor.base_ydpi; - - move = SANE_UNFIX (dev->model->y_offset); - move += dev->settings.tl_y; - move = (move * move_dpi) / MM_PER_INCH; - move -= dev->scanhead_position_in_steps; - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - /* fast move to scan area */ - /* we don't move fast the whole distance since it would involve - * computing acceleration/deceleration distance for scan - * resolution. So leave a remainder for it so scan makes the final - * move tuning */ - if(channels*dev->settings.yres>=600 && move>700) - { - status = gl847_feed (dev, move-500); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to move to scan area\n", __func__); - return status; - } - move=500; - } - - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - DBG(DBG_info, "%s: move=%f steps\n", __func__, move); - - /* start */ - start = SANE_UNFIX (dev->model->x_offset); - start += dev->settings.tl_x; - start = (start * sensor.optical_res) / MM_PER_INCH; - - flags = 0; - - /* emulated lineart from gray data is required for now */ - if(dev->settings.scan_mode == ScanColorMode::LINEART - && dev->settings.dynamic_lineart) - { - flags |= SCAN_FLAG_DYNAMIC_LINEART; - } - - /* backtracking isn't handled well, so don't enable it */ - flags |= SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; - - SetupParams params; - params.xres = dev->settings.xres; - params.yres = dev->settings.yres; - params.startx = start; - params.starty = move; - params.pixels = dev->settings.pixels; - params.lines = dev->settings.lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = dev->settings.scan_mode; - params.color_filter = dev->settings.color_filter; - params.flags = flags; - - status = gl847_init_scan_regs(dev, sensor, &dev->reg, params); - - if (status != SANE_STATUS_GOOD) - return status; - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - - -/** - * Send shading calibration data. The buffer is considered to always hold values - * for all the channels. - */ -static SANE_Status -gl847_send_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint32_t addr, length, i, x, factor, pixels; - uint32_t dpiset, dpihw, strpixel, endpixel; - uint16_t tempo; - uint32_t lines, channels; - uint8_t val,*ptr,*src; - - DBGSTART; - DBG(DBG_io2, "%s: writing %d bytes of shading data\n", __func__, size); - - /* shading data is plit in 3 (up to 5 with IR) areas - write(0x10014000,0x00000dd8) - URB 23429 bulk_out len 3544 wrote 0x33 0x10 0x.... - write(0x1003e000,0x00000dd8) - write(0x10068000,0x00000dd8) - */ - length = (uint32_t) (size / 3); - sanei_genesys_get_double(&dev->reg,REG_STRPIXEL,&tempo); - strpixel=tempo; - sanei_genesys_get_double(&dev->reg,REG_ENDPIXEL,&tempo); - endpixel=tempo; - - /* compute deletion factor */ - sanei_genesys_get_double(&dev->reg,REG_DPISET,&tempo); - dpiset=tempo; - DBG(DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d, DPISET=%d\n", __func__, strpixel, endpixel, - endpixel-strpixel, dpiset); - dpihw=sanei_genesys_compute_dpihw(dev, sensor, dpiset); - factor=dpihw/dpiset; - DBG(DBG_io2, "%s: factor=%d\n", __func__, factor); - - if(DBG_LEVEL>=DBG_data) - { - dev->binary=fopen("binary.pnm","wb"); - sanei_genesys_get_triple(&dev->reg, REG_LINCNT, &lines); - channels=dev->current_setup.channels; - if(dev->binary!=NULL) - { - fprintf(dev->binary,"P5\n%d %d\n%d\n",(endpixel-strpixel)/factor*channels,lines/channels,255); - } - } - - pixels=endpixel-strpixel; - - /* since we're using SHDAREA, substract startx coordinate from shading */ - strpixel-=((sensor.CCD_start_xoffset*600)/sensor.optical_res); - - /* turn pixel value into bytes 2x16 bits words */ - strpixel*=2*2; - pixels*=2*2; - - std::vector<uint8_t> buffer(pixels, 0); - - DBG(DBG_io2, "%s: using chunks of %d (0x%04x) bytes\n", __func__, pixels, pixels); - - /* base addr of data has been written in reg D0-D4 in 4K word, so AHB address - * is 8192*reg value */ - - /* write actual color channel data */ - for(i=0;i<3;i++) - { - /* build up actual shading data by copying the part from the full width one - * to the one corresponding to SHDAREA */ - ptr = buffer.data(); - - /* iterate on both sensor segment */ - for(x=0;x<pixels;x+=4*factor) - { - /* coefficient source */ - src=(data+strpixel+i*length)+x; - - /* coefficient copy */ - ptr[0]=src[0]; - ptr[1]=src[1]; - ptr[2]=src[2]; - ptr[3]=src[3]; - - /* next shading coefficient */ - ptr+=4; - } - - RIE (sanei_genesys_read_register (dev, 0xd0+i, &val)); - addr = val * 8192 + 0x10000000; - status = sanei_genesys_write_ahb(dev, addr, pixels, buffer.data()); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s; write to AHB failed (%s)\n", __func__, sane_strstatus(status)); - return status; - } - } - - DBGCOMPLETED; - - return status; -} - -/** @brief calibrates led exposure - * Calibrate exposure by scanning a white area until the used exposure gives - * data white enough. - * @param dev device to calibrate - */ -static SANE_Status -gl847_led_calibration (Genesys_Device * dev, Genesys_Sensor& sensor, Genesys_Register_Set& regs) -{ - int num_pixels; - int total_size; - int used_res; - int i, j; - SANE_Status status = SANE_STATUS_GOOD; - int val; - int channels, depth; - int avg[3], top[3], bottom[3]; - int turn; - uint16_t exp[3]; - float move; - SANE_Bool acceptable; - - DBGSTART; - - move = SANE_UNFIX (dev->model->y_offset_calib); - move = (move * (dev->motor.base_ydpi/4)) / MM_PER_INCH; - if(move>20) - { - RIE(gl847_feed (dev, move)); - } - DBG(DBG_io, "%s: move=%f steps\n", __func__, move); - - /* offset calibration is always done in color mode */ - channels = 3; - depth=16; - used_res=sanei_genesys_compute_dpihw(dev, sensor, dev->settings.xres); - Sensor_Profile* sensor_profile=get_sensor_profile(dev->model->ccd_type, used_res); - num_pixels = (sensor.sensor_pixels*used_res)/sensor.optical_res; - - /* initial calibration reg values */ - regs = dev->reg; - - SetupParams params; - params.xres = used_res; - params.yres = used_res; - params.startx = 0; - params.starty = 0; - params.pixels = num_pixels; - params.lines = 1; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl847_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - total_size = num_pixels * channels * (depth/8) * 1; /* colors * bytes_per_color * scan lines */ - std::vector<uint8_t> line(total_size); - - /* initial loop values and boundaries */ - exp[0]=sensor_profile->expr; - exp[1]=sensor_profile->expg; - exp[2]=sensor_profile->expb; - - bottom[0]=29000; - bottom[1]=29000; - bottom[2]=29000; - - top[0]=41000; - top[1]=51000; - top[2]=51000; - - turn = 0; - - /* no move during led calibration */ - sanei_genesys_set_motor_power(regs, false); - do - { - /* set up exposure */ - sanei_genesys_set_double(®s,REG_EXPR,exp[0]); - sanei_genesys_set_double(®s,REG_EXPG,exp[1]); - sanei_genesys_set_double(®s,REG_EXPB,exp[2]); - - /* write registers and scan data */ - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - DBG(DBG_info, "%s: starting line reading\n", __func__); - RIE(gl847_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - - /* stop scanning */ - RIE(gl847_stop_action (dev)); - - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl847_led_%02d.pnm", turn); - sanei_genesys_write_pnm_file(fn, line.data(), depth, channels, num_pixels, 1); - } - - /* compute average */ - for (j = 0; j < channels; j++) - { - avg[j] = 0; - for (i = 0; i < num_pixels; i++) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * num_pixels + 1] * 256 + - line[i * 2 + j * 2 * num_pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - avg[j] += val; - } - - avg[j] /= num_pixels; - } - - DBG(DBG_info, "%s: average: %d,%d,%d\n", __func__, avg[0], avg[1], avg[2]); - - /* check if exposure gives average within the boundaries */ - acceptable = SANE_TRUE; - for(i=0;i<3;i++) - { - if(avg[i]<bottom[i]) - { - exp[i]=(exp[i]*bottom[i])/avg[i]; - acceptable = SANE_FALSE; - } - if(avg[i]>top[i]) - { - exp[i]=(exp[i]*top[i])/avg[i]; - acceptable = SANE_FALSE; - } - } - - turn++; - } - while (!acceptable && turn < 100); - - DBG(DBG_info, "%s: acceptable exposure: %d,%d,%d\n", __func__, exp[0], exp[1], exp[2]); - - /* set these values as final ones for scan */ - sanei_genesys_set_double(&dev->reg,REG_EXPR,exp[0]); - sanei_genesys_set_double(&dev->reg,REG_EXPG,exp[1]); - sanei_genesys_set_double(&dev->reg,REG_EXPB,exp[2]); - - /* store in this struct since it is the one used by cache calibration */ - sensor.exposure.red = exp[0]; - sensor.exposure.green = exp[1]; - sensor.exposure.blue = exp[2]; - - /* go back home */ - if(move>20) - { - status=gl847_slow_back_home (dev, SANE_TRUE); - } - - DBGCOMPLETED; - return status; -} - -/** - * set up GPIO/GPOE for idle state - */ -static SANE_Status -gl847_init_gpio (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - int idx=0; - - DBGSTART; - - /* search GPIO profile */ - while(gpios[idx].sensor_id!=0 && dev->model->gpo_type!=gpios[idx].sensor_id) - { - idx++; - } - if(gpios[idx].sensor_id==0) - { - DBG(DBG_error, "%s: failed to find GPIO profile for sensor_id=%d\n", __func__, - dev->model->ccd_type); - return SANE_STATUS_INVAL; - } - - RIE (sanei_genesys_write_register (dev, REGA7, gpios[idx].ra7)); - RIE (sanei_genesys_write_register (dev, REGA6, gpios[idx].ra6)); - - RIE (sanei_genesys_write_register (dev, REG6E, gpios[idx].r6e)); - RIE (sanei_genesys_write_register (dev, REG6C, 0x00)); - - RIE (sanei_genesys_write_register (dev, REG6B, gpios[idx].r6b)); - RIE (sanei_genesys_write_register (dev, REG6C, gpios[idx].r6c)); - RIE (sanei_genesys_write_register (dev, REG6D, gpios[idx].r6d)); - RIE (sanei_genesys_write_register (dev, REG6E, gpios[idx].r6e)); - RIE (sanei_genesys_write_register (dev, REG6F, gpios[idx].r6f)); - - RIE (sanei_genesys_write_register (dev, REGA8, gpios[idx].ra8)); - RIE (sanei_genesys_write_register (dev, REGA9, gpios[idx].ra9)); - - DBGCOMPLETED; - return status; -} - -/** - * set memory layout by filling values in dedicated registers - */ -static SANE_Status -gl847_init_memory_layout (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - int idx = 0; - uint8_t val; - - DBG(DBG_proc, "%s\n" , __func__); - - /* point to per model memory layout */ - idx = 0; - if (dev->model->model_id == MODEL_CANON_LIDE_100) - { - idx = 0; - } - if (dev->model->model_id == MODEL_CANON_LIDE_200) - { - idx = 1; - } - if (dev->model->model_id == MODEL_CANON_CANOSCAN_5600F) - { - idx = 2; - } - if (dev->model->model_id == MODEL_CANON_LIDE_700F) - { - idx = 3; - } - - /* CLKSET nd DRAMSEL */ - val = layouts[idx].dramsel; - RIE (sanei_genesys_write_register (dev, REG0B, val)); - dev->reg.find_reg(0x0b).value = val; - - /* prevent further writings by bulk write register */ - dev->reg.remove_reg(0x0b); - - /* setup base address for shading data. */ - /* values must be multiplied by 8192=0x4000 to give address on AHB */ - /* R-Channel shading bank0 address setting for CIS */ - sanei_genesys_write_register (dev, 0xd0, layouts[idx].rd0); - /* G-Channel shading bank0 address setting for CIS */ - sanei_genesys_write_register (dev, 0xd1, layouts[idx].rd1); - /* B-Channel shading bank0 address setting for CIS */ - sanei_genesys_write_register (dev, 0xd2, layouts[idx].rd2); - - /* setup base address for scanned data. */ - /* values must be multiplied by 1024*2=0x0800 to give address on AHB */ - /* R-Channel ODD image buffer 0x0124->0x92000 */ - /* size for each buffer is 0x16d*1k word */ - sanei_genesys_write_register (dev, 0xe0, layouts[idx].re0); - sanei_genesys_write_register (dev, 0xe1, layouts[idx].re1); - /* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/ - sanei_genesys_write_register (dev, 0xe2, layouts[idx].re2); - sanei_genesys_write_register (dev, 0xe3, layouts[idx].re3); - - /* R-Channel EVEN image buffer 0x0292 */ - sanei_genesys_write_register (dev, 0xe4, layouts[idx].re4); - sanei_genesys_write_register (dev, 0xe5, layouts[idx].re5); - /* R-Channel EVEN image buffer end-address 0x03ff*/ - sanei_genesys_write_register (dev, 0xe6, layouts[idx].re6); - sanei_genesys_write_register (dev, 0xe7, layouts[idx].re7); - - /* same for green, since CIS, same addresses */ - sanei_genesys_write_register (dev, 0xe8, layouts[idx].re0); - sanei_genesys_write_register (dev, 0xe9, layouts[idx].re1); - sanei_genesys_write_register (dev, 0xea, layouts[idx].re2); - sanei_genesys_write_register (dev, 0xeb, layouts[idx].re3); - sanei_genesys_write_register (dev, 0xec, layouts[idx].re4); - sanei_genesys_write_register (dev, 0xed, layouts[idx].re5); - sanei_genesys_write_register (dev, 0xee, layouts[idx].re6); - sanei_genesys_write_register (dev, 0xef, layouts[idx].re7); - -/* same for blue, since CIS, same addresses */ - sanei_genesys_write_register (dev, 0xf0, layouts[idx].re0); - sanei_genesys_write_register (dev, 0xf1, layouts[idx].re1); - sanei_genesys_write_register (dev, 0xf2, layouts[idx].re2); - sanei_genesys_write_register (dev, 0xf3, layouts[idx].re3); - sanei_genesys_write_register (dev, 0xf4, layouts[idx].re4); - sanei_genesys_write_register (dev, 0xf5, layouts[idx].re5); - sanei_genesys_write_register (dev, 0xf6, layouts[idx].re6); - sanei_genesys_write_register (dev, 0xf7, layouts[idx].re7); - - DBGCOMPLETED; - return status; -} - -/* * - * initialize ASIC from power on condition - */ -static SANE_Status -gl847_boot (Genesys_Device * dev, SANE_Bool cold) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - - DBGSTART; - - /* reset ASIC if cold boot */ - if(cold) - { - RIE (sanei_genesys_write_register (dev, 0x0e, 0x01)); - RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); - } - - /* test CHKVER */ - RIE (sanei_genesys_read_register (dev, REG40, &val)); - if (val & REG40_CHKVER) - { - RIE (sanei_genesys_read_register (dev, 0x00, &val)); - DBG(DBG_info, "%s: reported version for genesys chip is 0x%02x\n", __func__, val); - } - - /* Set default values for registers */ - gl847_init_registers (dev); - - /* Write initial registers */ - RIE (dev->model->cmd_set->bulk_write_register(dev, dev->reg)); - - /* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */ - val = dev->reg.find_reg(0x0b).value & REG0B_DRAMSEL; - val = (val | REG0B_ENBDRAM); - RIE (sanei_genesys_write_register (dev, REG0B, val)); - dev->reg.find_reg(0x0b).value = val; - - /* CIS_LINE */ - SETREG (0x08, REG08_CIS_LINE); - RIE (sanei_genesys_write_register (dev, 0x08, dev->reg.find_reg(0x08).value)); - - /* set up end access */ - RIE (sanei_genesys_write_0x8c (dev, 0x10, 0x0b)); - RIE (sanei_genesys_write_0x8c (dev, 0x13, 0x0e)); - - /* setup gpio */ - RIE (gl847_init_gpio (dev)); - - /* setup internal memory layout */ - RIE (gl847_init_memory_layout (dev)); - - SETREG (0xf8, 0x01); - RIE (sanei_genesys_write_register (dev, 0xf8, dev->reg.find_reg(0xf8).value)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** - * initialize backend and ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home - */ -static SANE_Status gl847_init (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - - DBG_INIT (); - DBGSTART; - - status=sanei_genesys_asic_init(dev, 0); - - DBGCOMPLETED; - return status; -} - -static SANE_Status -gl847_update_hardware_sensors (Genesys_Scanner * s) -{ - /* do what is needed to get a new set of events, but try to not lose - any of them. - */ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - uint8_t scan, file, email, copy; - switch(s->dev->model->gpo_type) - { - case GPO_CANONLIDE700: - scan=0x04; - file=0x02; - email=0x01; - copy=0x08; - break; - default: - scan=0x01; - file=0x02; - email=0x04; - copy=0x08; - } - RIE (sanei_genesys_read_register (s->dev, REG6D, &val)); - - s->buttons[BUTTON_SCAN_SW].write((val & scan) == 0); - s->buttons[BUTTON_FILE_SW].write((val & file) == 0); - s->buttons[BUTTON_EMAIL_SW].write((val & email) == 0); - s->buttons[BUTTON_COPY_SW].write((val & copy) == 0); - - return status; -} - -/** @brief search for a full width black or white strip. - * This function searches for a black or white stripe across the scanning area. - * When searching backward, the searched area must completely be of the desired - * color since this area will be used for calibration which scans forward. - * @param dev scanner device - * @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward - * @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip - * @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not - */ -static SANE_Status -gl847_search_strip (Genesys_Device * dev, const Genesys_Sensor& sensor, - SANE_Bool forward, SANE_Bool black) -{ - unsigned int pixels, lines, channels; - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set local_reg; - size_t size; - int steps, depth, dpi; - unsigned int pass, count, found, x, y; - char title[80]; - GenesysRegister *r; - - DBG(DBG_proc, "%s %s %s\n", __func__, black ? "black" : "white", forward ? "forward" : "reverse"); - - gl847_set_fe(dev, sensor, AFE_SET); - status = gl847_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to stop: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* set up for a gray scan at lowest dpi */ - dpi = 9600; - for (x = 0; x < MAX_RESOLUTIONS; x++) - { - if (dev->model->xdpi_values[x] > 0 && dev->model->xdpi_values[x] < dpi) - dpi = dev->model->xdpi_values[x]; - } - channels = 1; - /* 10 MM */ - /* lines = (10 * dpi) / MM_PER_INCH; */ - /* shading calibation is done with dev->motor.base_ydpi */ - lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; - depth = 8; - pixels = (sensor.sensor_pixels * dpi) / sensor.optical_res; - size = pixels * channels * lines * (depth / 8); - std::vector<uint8_t> data(size); - dev->scanhead_position_in_steps = 0; - - local_reg = dev->reg; - - SetupParams params; - params.xres = dpi; - params.yres = dpi; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = depth; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::GRAY; - params.color_filter = ColorFilter::RED; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA; - - status = gl847_init_scan_regs(dev, sensor, &local_reg, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup for scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* set up for reverse or forward */ - r = sanei_genesys_get_address(&local_reg, REG02); - if (forward) - r->value &= ~REG02_MTRREV; - else - r->value |= REG02_MTRREV; - - - status = dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl847_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl847_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl847_stop_action failed\n", __func__); - return status; - } - - pass = 0; - if (DBG_LEVEL >= DBG_data) - { - sprintf(title, "gl847_search_strip_%s_%s%02d.pnm", - black ? "black" : "white", forward ? "fwd" : "bwd", (int)pass); - sanei_genesys_write_pnm_file(title, data.data(), depth, channels, pixels, lines); - } - - /* loop until strip is found or maximum pass number done */ - found = 0; - while (pass < 20 && !found) - { - status = - dev->model->cmd_set->bulk_write_register(dev, local_reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: Failed to bulk write registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* now start scan */ - status = gl847_begin_scan(dev, sensor, &local_reg, SANE_TRUE); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to begin scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - /* waits for valid data */ - do - sanei_genesys_test_buffer_empty (dev, &steps); - while (steps); - - /* now we're on target, we can read data */ - status = sanei_genesys_read_data_from_scanner(dev, data.data(), size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); - return status; - } - - status = gl847_stop_action (dev); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: gl847_stop_action failed\n", __func__); - return status; - } - - if (DBG_LEVEL >= DBG_data) - { - sprintf(title, "gl847_search_strip_%s_%s%02d.pnm", - black ? "black" : "white", forward ? "fwd" : "bwd", (int)pass); - sanei_genesys_write_pnm_file(title, data.data(), depth, channels, pixels, lines); - } - - /* search data to find black strip */ - /* when searching forward, we only need one line of the searched color since we - * will scan forward. But when doing backward search, we need all the area of the - * same color */ - if (forward) - { - for (y = 0; y < lines && !found; y++) - { - count = 0; - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > 90) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < 60) - { - count++; - } - } - - /* at end of line, if count >= 3%, line is not fully of the desired color - * so we must go to next line of the buffer */ - /* count*100/pixels < 3 */ - if ((count * 100) / pixels < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__, - pass, y); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - } - else /* since calibration scans are done forward, we need the whole area - to be of the required color when searching backward */ - { - count = 0; - for (y = 0; y < lines; y++) - { - /* count of white/black pixels depending on the color searched */ - for (x = 0; x < pixels; x++) - { - /* when searching for black, detect white pixels */ - if (black && data[y * pixels + x] > 90) - { - count++; - } - /* when searching for white, detect black pixels */ - if (!black && data[y * pixels + x] < 60) - { - count++; - } - } - } - - /* at end of area, if count >= 3%, area is not fully of the desired color - * so we must go to next buffer */ - if ((count * 100) / (pixels * lines) < 3) - { - found = 1; - DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass); - } - else - { - DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count, - (100 * count) / pixels); - } - } - pass++; - } - - if (found) - { - status = SANE_STATUS_GOOD; - DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white"); - } - else - { - status = SANE_STATUS_UNSUPPORTED; - DBG(DBG_info, "%s: %s strip not found\n", __func__, black ? "black" : "white"); - } - - DBGCOMPLETED; - return status; -} - -/** - * average dark pixels of a 8 bits scan - */ -static int -dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, - unsigned int channels, unsigned int black) -{ - unsigned int i, j, k, average, count; - unsigned int avg[3]; - uint8_t val; - - /* computes average value on black margin */ - for (k = 0; k < channels; k++) - { - avg[k] = 0; - count = 0; - for (i = 0; i < lines; i++) - { - for (j = 0; j < black; j++) - { - val = data[i * channels * pixels + j + k]; - avg[k] += val; - count++; - } - } - if (count) - avg[k] /= count; - DBG(DBG_info, "%s: avg[%d] = %d\n", __func__, k, avg[k]); - } - average = 0; - for (i = 0; i < channels; i++) - average += avg[i]; - average /= channels; - DBG(DBG_info, "%s: average = %d\n", __func__, average); - return average; -} - -static SANE_Status -gl847_offset_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t reg04; - unsigned int channels, bpp; - int pass = 0, avg, total_size; - int topavg, bottomavg, resolution, lines; - int top, bottom, black_pixels, pixels; - - DBGSTART; - - /* no gain nor offset for AKM AFE */ - RIE (sanei_genesys_read_register (dev, REG04, ®04)); - if ((reg04 & REG04_FESET) == 0x02) - { - DBGCOMPLETED; - return status; - } - - /* offset calibration is always done in color mode */ - channels = 3; - resolution=sensor.optical_res; - dev->calib_pixels = sensor.sensor_pixels; - lines=1; - bpp=8; - pixels= (sensor.sensor_pixels*resolution) / sensor.optical_res; - black_pixels = (sensor.black_pixels * resolution) / sensor.optical_res; - DBG(DBG_io2, "%s: black_pixels=%d\n", __func__, black_pixels); - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = bpp; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - status = gl847_init_scan_regs(dev, sensor, ®s, params); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - sanei_genesys_set_motor_power(regs, false); - - /* allocate memory for scans */ - total_size = pixels * channels * lines * (bpp/8); /* colors * bytes_per_color * scan lines */ - - std::vector<uint8_t> first_line(total_size); - std::vector<uint8_t> second_line(total_size); - - /* init gain */ - dev->frontend.set_gain(0, 0); - dev->frontend.set_gain(1, 0); - dev->frontend.set_gain(2, 0); - - /* scan with no move */ - bottom = 10; - dev->frontend.set_offset(0, bottom); - dev->frontend.set_offset(1, bottom); - dev->frontend.set_offset(2, bottom); - - RIE(gl847_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting first line reading\n", __func__); - RIE(gl847_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size)); - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl847_offset%03d.pnm", bottom); - sanei_genesys_write_pnm_file(fn, first_line.data(), bpp, channels, pixels, lines); - } - - bottomavg = dark_average (first_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_io2, "%s: bottom avg=%d\n", __func__, bottomavg); - - /* now top value */ - top = 255; - dev->frontend.set_offset(0, top); - dev->frontend.set_offset(1, top); - dev->frontend.set_offset(2, top); - RIE(gl847_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl847_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, second_line.data(), total_size)); - - topavg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_io2, "%s: top avg=%d\n", __func__, topavg); - - /* loop until acceptable level */ - while ((pass < 32) && (top - bottom > 1)) - { - pass++; - - /* settings for new scan */ - dev->frontend.set_offset(0, (top + bottom) / 2); - dev->frontend.set_offset(1, (top + bottom) / 2); - dev->frontend.set_offset(2, (top + bottom) / 2); - - /* scan with no move */ - RIE(gl847_set_fe(dev, sensor, AFE_SET)); - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - DBG(DBG_info, "%s: starting second line reading\n", __func__); - RIE(gl847_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner (dev, second_line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) - { - char fn[30]; - snprintf(fn, 30, "gl847_offset%03d.pnm", dev->frontend.get_offset(1)); - sanei_genesys_write_pnm_file(fn, second_line.data(), bpp, channels, pixels, lines); - } - - avg = dark_average(second_line.data(), pixels, lines, channels, black_pixels); - DBG(DBG_info, "%s: avg=%d offset=%d\n", __func__, avg, dev->frontend.get_offset(1)); - - /* compute new boundaries */ - if (topavg == avg) - { - topavg = avg; - top = dev->frontend.get_offset(1); - } - else - { - bottomavg = avg; - bottom = dev->frontend.get_offset(1); - } - } - DBG(DBG_info, "%s: offset=(%d,%d,%d)\n", __func__, - dev->frontend.get_offset(0), - dev->frontend.get_offset(1), - dev->frontend.get_offset(2)); - - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -static SANE_Status -gl847_coarse_gain_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi) -{ - int pixels; - int total_size; - uint8_t reg04; - int i, j, channels; - SANE_Status status = SANE_STATUS_GOOD; - int max[3]; - float gain[3],coeff; - int val, code, lines; - int resolution; - int bpp; - - DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi); - - /* no gain nor offset for AKM AFE */ - RIE (sanei_genesys_read_register (dev, REG04, ®04)); - if ((reg04 & REG04_FESET) == 0x02) - { - DBGCOMPLETED; - return status; - } - - /* coarse gain calibration is always done in color mode */ - channels = 3; - - /* follow CKSEL */ - if(dev->settings.xres<sensor.optical_res) - { - coeff=0.9; - /*resolution=sensor.optical_res/2; */ - resolution=sensor.optical_res; - } - else - { - resolution=sensor.optical_res; - coeff=1.0; - } - lines=10; - bpp=8; - pixels = (sensor.sensor_pixels * resolution) / sensor.optical_res; - - SetupParams params; - params.xres = resolution; - params.yres = resolution; - params.startx = 0; - params.starty = 0; - params.pixels = pixels; - params.lines = lines; - params.depth = bpp; - params.channels = channels; - params.scan_method = dev->settings.scan_method; - params.scan_mode = ScanColorMode::COLOR_SINGLE_PASS; - params.color_filter = dev->settings.color_filter; - params.flags = SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE; - - try { - status = gl847_init_scan_regs(dev, sensor, ®s, params); - } catch (...) { - try { - sanei_genesys_set_motor_power(regs, false); - } catch (...) {} - throw; - } - - sanei_genesys_set_motor_power(regs, false); - - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); - return status; - } - - RIE(dev->model->cmd_set->bulk_write_register(dev, regs)); - - total_size = pixels * channels * (16/bpp) * lines; - - std::vector<uint8_t> line(total_size); - - RIE(gl847_set_fe(dev, sensor, AFE_SET)); - RIE(gl847_begin_scan(dev, sensor, ®s, SANE_TRUE)); - RIE(sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); - - if (DBG_LEVEL >= DBG_data) - sanei_genesys_write_pnm_file("gl847_gain.pnm", line.data(), bpp, channels, pixels, lines); - - /* average value on each channel */ - for (j = 0; j < channels; j++) - { - max[j] = 0; - for (i = pixels/4; i < (pixels*3/4); i++) - { - if(bpp==16) - { - if (dev->model->is_cis) - val = - line[i * 2 + j * 2 * pixels + 1] * 256 + - line[i * 2 + j * 2 * pixels]; - else - val = - line[i * 2 * channels + 2 * j + 1] * 256 + - line[i * 2 * channels + 2 * j]; - } - else - { - if (dev->model->is_cis) - val = line[i + j * pixels]; - else - val = line[i * channels + j]; - } - - max[j] += val; - } - max[j] = max[j] / (pixels/2); - - gain[j] = ((float) sensor.gain_white_ref*coeff) / max[j]; - - /* turn logical gain value into gain code, checking for overflow */ - code = 283 - 208 / gain[j]; - if (code > 255) - code = 255; - else if (code < 0) - code = 0; - dev->frontend.set_gain(j, code); - - DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], - dev->frontend.get_gain(j)); - } - - if (dev->model->is_cis) { - uint8_t gain0 = dev->frontend.get_gain(0); - if (gain0 > dev->frontend.get_gain(1)) { - gain0 = dev->frontend.get_gain(1); - } - if (gain0 > dev->frontend.get_gain(2)) { - gain0 = dev->frontend.get_gain(2); - } - dev->frontend.set_gain(0, gain0); - dev->frontend.set_gain(1, gain0); - dev->frontend.set_gain(2, gain0); - } - - if (channels == 1) { - dev->frontend.set_gain(0, dev->frontend.get_gain(1)); - dev->frontend.set_gain(2, dev->frontend.get_gain(1)); - } - - RIE (gl847_stop_action (dev)); - - status=gl847_slow_back_home (dev, SANE_TRUE); - - DBGCOMPLETED; - return status; -} - - -/** the gl847 command set */ -static Genesys_Command_Set gl847_cmd_set = { - "gl847-generic", /* the name of this set */ - - nullptr, - - gl847_init, - NULL, /*gl847_init_regs_for_warmup*/ - gl847_init_regs_for_coarse_calibration, - gl847_init_regs_for_shading, - gl847_init_regs_for_scan, - - gl847_get_filter_bit, - gl847_get_lineart_bit, - gl847_get_bitset_bit, - gl847_get_gain4_bit, - gl847_get_fast_feed_bit, - gl847_test_buffer_empty_bit, - gl847_test_motor_flag_bit, - - gl847_set_fe, - gl847_set_powersaving, - gl847_save_power, - - gl847_begin_scan, - gl847_end_scan, - - sanei_genesys_send_gamma_table, - - gl847_search_start_position, - - gl847_offset_calibration, - gl847_coarse_gain_calibration, - gl847_led_calibration, - - NULL, - gl847_slow_back_home, - NULL, /* disable gl847_rewind, see #7 */ - - sanei_genesys_bulk_write_register, - NULL, - sanei_genesys_bulk_read_data, - - gl847_update_hardware_sensors, - - NULL, /* no known gl847 sheetfed scanner */ - NULL, /* no known gl847 sheetfed scanner */ - NULL, /* no known gl847 sheetfed scanner */ - gl847_search_strip, - - sanei_genesys_is_compatible_calibration, - NULL, - gl847_send_shading_data, - gl847_calculate_current_setup, - gl847_boot -}; - -SANE_Status -sanei_gl847_init_cmd_set (Genesys_Device * dev) -{ - dev->model->cmd_set = &gl847_cmd_set; - return SANE_STATUS_GOOD; -} diff --git a/backend/genesys_gl847.h b/backend/genesys_gl847.h deleted file mode 100644 index 7af9c36..0000000 --- a/backend/genesys_gl847.h +++ /dev/null @@ -1,510 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#include "genesys.h" - -#define REG01 0x01 -#define REG01_CISSET 0x80 -#define REG01_DOGENB 0x40 -#define REG01_DVDSET 0x20 -#define REG01_STAGGER 0x10 -#define REG01_COMPENB 0x08 -#define REG01_TRUEGRAY 0x04 -#define REG01_SHDAREA 0x02 -#define REG01_SCAN 0x01 - -#define REG02 0x02 -#define REG02_NOTHOME 0x80 -#define REG02_ACDCDIS 0x40 -#define REG02_AGOHOME 0x20 -#define REG02_MTRPWR 0x10 -#define REG02_FASTFED 0x08 -#define REG02_MTRREV 0x04 -#define REG02_HOMENEG 0x02 -#define REG02_LONGCURV 0x01 - -#define REG03 0x03 -#define REG03_LAMPDOG 0x80 -#define REG03_AVEENB 0x40 -#define REG03_XPASEL 0x20 -#define REG03_LAMPPWR 0x10 -#define REG03_LAMPTIM 0x0f - -#define REG04 0x04 -#define REG04_LINEART 0x80 -#define REG04_BITSET 0x40 -#define REG04_AFEMOD 0x30 -#define REG04_FILTER 0x0c -#define REG04_FESET 0x03 - -#define REG04S_AFEMOD 4 - -#define REG05 0x05 -#define REG05_DPIHW 0xc0 -#define REG05_DPIHW_600 0x00 -#define REG05_DPIHW_1200 0x40 -#define REG05_DPIHW_2400 0x80 -#define REG05_DPIHW_4800 0xc0 -#define REG05_MTLLAMP 0x30 -#define REG05_GMMENB 0x08 -#define REG05_MTLBASE 0x03 - -#define REG06_SCANMOD 0xe0 -#define REG06S_SCANMOD 5 -#define REG06_PWRBIT 0x10 -#define REG06_GAIN4 0x08 -#define REG06_OPTEST 0x07 - -#define REG07_LAMPSIM 0x80 - -#define REG08_DRAM2X 0x80 -#define REG08_MPENB 0x20 -#define REG08_CIS_LINE 0x10 -#define REG08_IR1ENB 0x08 -#define REG08_IR2ENB 0x04 -#define REG08_ENB24M 0x01 - -#define REG09_MCNTSET 0xc0 -#define REG09_EVEN1ST 0x20 -#define REG09_BLINE1ST 0x10 -#define REG09_BACKSCAN 0x08 -#define REG09_ENHANCE 0x04 -#define REG09_SHORTTG 0x02 -#define REG09_NWAIT 0x01 - -#define REG09S_MCNTSET 6 -#define REG09S_CLKSET 4 - - -#define REG0A_LPWMEN 0x10 - -#define REG0B 0x0b -#define REG0B_DRAMSEL 0x07 -#define REG0B_ENBDRAM 0x08 -#define REG0B_ENBDRAM 0x08 -#define REG0B_RFHDIS 0x10 -#define REG0B_CLKSET 0xe0 -#define REG0B_24MHZ 0x00 -#define REG0B_30MHZ 0x20 -#define REG0B_40MHZ 0x40 -#define REG0B_48MHZ 0x60 -#define REG0B_60MHZ 0x80 - -#define REG0C 0x0c -#define REG0C_CCDLMT 0x0f - -#define REG0D 0x0d -#define REG0D_FULLSTP 0x10 -#define REG0D_SEND 0x80 -#define REG0D_CLRMCNT 0x04 -#define REG0D_CLRDOCJM 0x02 -#define REG0D_CLRLNCNT 0x01 - -#define REG0F 0x0f - -#define REG16_CTRLHI 0x80 -#define REG16_TOSHIBA 0x40 -#define REG16_TGINV 0x20 -#define REG16_CK1INV 0x10 -#define REG16_CK2INV 0x08 -#define REG16_CTRLINV 0x04 -#define REG16_CKDIS 0x02 -#define REG16_CTRLDIS 0x01 - -#define REG17_TGMODE 0xc0 -#define REG17_TGMODE_NO_DUMMY 0x00 -#define REG17_TGMODE_REF 0x40 -#define REG17_TGMODE_XPA 0x80 -#define REG17_TGW 0x3f -#define REG17S_TGW 0 - -#define REG18 0x18 -#define REG18_CNSET 0x80 -#define REG18_DCKSEL 0x60 -#define REG18_CKTOGGLE 0x10 -#define REG18_CKDELAY 0x0c -#define REG18_CKSEL 0x03 - -#define REG1A_SW2SET 0x80 -#define REG1A_SW1SET 0x40 -#define REG1A_MANUAL3 0x02 -#define REG1A_MANUAL1 0x01 -#define REG1A_CK4INV 0x08 -#define REG1A_CK3INV 0x04 -#define REG1A_LINECLP 0x02 - -#define REG1C 0x1c -#define REG1C_TGTIME 0x07 - -#define REG1D_CK4LOW 0x80 -#define REG1D_CK3LOW 0x40 -#define REG1D_CK1LOW 0x20 -#define REG1D_TGSHLD 0x1f -#define REG1DS_TGSHLD 0 - - -#define REG1E_WDTIME 0xf0 -#define REG1ES_WDTIME 4 -#define REG1E_LINESEL 0x0f -#define REG1ES_LINESEL 0 - -#define REG_FEDCNT 0x1f - -#define REG24 0x1c -#define REG40 0x40 -#define REG40_CHKVER 0x10 -#define REG40_HISPDFLG 0x04 -#define REG40_MOTMFLG 0x02 -#define REG40_DATAENB 0x01 - -#define REG41_PWRBIT 0x80 -#define REG41_BUFEMPTY 0x40 -#define REG41_FEEDFSH 0x20 -#define REG41_SCANFSH 0x10 -#define REG41_HOMESNR 0x08 -#define REG41_LAMPSTS 0x04 -#define REG41_FEBUSY 0x02 -#define REG41_MOTORENB 0x01 - -#define REG58_VSMP 0xf8 -#define REG58S_VSMP 3 -#define REG58_VSMPW 0x07 -#define REG58S_VSMPW 0 - -#define REG59_BSMP 0xf8 -#define REG59S_BSMP 3 -#define REG59_BSMPW 0x07 -#define REG59S_BSMPW 0 - -#define REG5A_ADCLKINV 0x80 -#define REG5A_RLCSEL 0x40 -#define REG5A_CDSREF 0x30 -#define REG5AS_CDSREF 4 -#define REG5A_RLC 0x0f -#define REG5AS_RLC 0 - -#define REG5E_DECSEL 0xe0 -#define REG5ES_DECSEL 5 -#define REG5E_STOPTIM 0x1f -#define REG5ES_STOPTIM 0 - -#define REG60 0x60 -#define REG60_Z1MOD 0x1f -#define REG61 0x61 -#define REG61_Z1MOD 0xff -#define REG62 0x62 -#define REG62_Z1MOD 0xff - -#define REG63 0x63 -#define REG63_Z2MOD 0x1f -#define REG64 0x64 -#define REG64_Z2MOD 0xff -#define REG65 0x65 -#define REG65_Z2MOD 0xff - -#define REG60S_STEPSEL 5 -#define REG60_STEPSEL 0xe0 -#define REG60_FULLSTEP 0x00 -#define REG60_HALFSTEP 0x20 -#define REG60_EIGHTHSTEP 0x60 -#define REG60_16THSTEP 0x80 - -#define REG63S_FSTPSEL 5 -#define REG63_FSTPSEL 0xe0 -#define REG63_FULLSTEP 0x00 -#define REG63_HALFSTEP 0x20 -#define REG63_EIGHTHSTEP 0x60 -#define REG63_16THSTEP 0x80 - -#define REG67 0x67 -#define REG67_MTRPWM 0x80 - -#define REG68 0x68 -#define REG68_FASTPWM 0x80 - -#define REG6B 0x6b -#define REG6B_MULTFILM 0x80 -#define REG6B_GPOM13 0x40 -#define REG6B_GPOM12 0x20 -#define REG6B_GPOM11 0x10 -#define REG6B_GPO18 0x02 -#define REG6B_GPO17 0x01 - -#define REG6C 0x6c -#define REG6C_GPIO16 0x80 -#define REG6C_GPIO15 0x40 -#define REG6C_GPIO14 0x20 -#define REG6C_GPIO13 0x10 -#define REG6C_GPIO12 0x08 -#define REG6C_GPIO11 0x04 -#define REG6C_GPIO10 0x02 -#define REG6C_GPIO9 0x01 -#define REG6C_GPIOH 0xff -#define REG6C_GPIOL 0xff - -#define REG6D 0x6d -#define REG6E 0x6e -#define REG6F 0x6f -#define REG7E 0x7e - -#define REG87_LEDADD 0x04 - -#define REG9E 0x9e -#define REG9F 0x9f - -#define REGA6 0xa6 -#define REGA7 0xa7 -#define REGA8 0xa8 -#define REGA9 0xa9 -#define REGAB 0xab - -#define REG_EXPR 0x10 -#define REG_EXPG 0x12 -#define REG_EXPB 0x14 -#define REG_EXPDMY 0x19 -#define REG_STEPNO 0x21 -#define REG_FWDSTEP 0x22 -#define REG_BWDSTEP 0x23 -#define REG_FASTNO 0x24 -#define REG_DPISET 0x2c -#define REG_STRPIXEL 0x30 -#define REG_ENDPIXEL 0x32 -#define REG_LINCNT 0x25 -#define REG_MAXWD 0x35 -#define REG_LPERIOD 0x38 -#define REG_FEEDL 0x3d -#define REG_FMOVDEC 0x5f -#define REG_FSHDEC 0x69 -#define REG_FMOVNO 0x6a -#define REG_CK1MAP 0x74 -#define REG_CK3MAP 0x77 -#define REG_CK4MAP 0x7a - -#define SETREG(adr,val) { dev->reg.init_reg(adr, val); } - -/** set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -static SANE_Status gl847_init_scan_regs(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, SetupParams& params); - -/* Send the low-level scan command */ -static SANE_Status gl847_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set * reg, SANE_Bool start_motor); - -/* Send the stop scan command */ -static SANE_Status gl847_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, SANE_Bool check_stop); - -static SANE_Status gl847_init (Genesys_Device * dev); - -/** @brief moves the slider to steps at motor base dpi - * @param dev device to work on - * @param steps number of steps to move - * */ -static SANE_Status -gl847_feed (Genesys_Device * dev, unsigned int steps); - -typedef struct -{ - uint8_t sensor_id; - uint8_t r6b; - uint8_t r6c; - uint8_t r6d; - uint8_t r6e; - uint8_t r6f; - uint8_t ra6; - uint8_t ra7; - uint8_t ra8; - uint8_t ra9; -} Gpio_Profile; - -static Gpio_Profile gpios[]={ - { GPO_CANONLIDE200, 0x02, 0xf9, 0x20, 0xff, 0x00, 0x04, 0x04, 0x00, 0x00}, - { GPO_CANONLIDE700, 0x06, 0xdb, 0xff, 0xff, 0x80, 0x15, 0x07, 0x20, 0x10}, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, -}; - -typedef struct -{ - uint8_t dramsel; - uint8_t rd0; - uint8_t rd1; - uint8_t rd2; - uint8_t re0; - uint8_t re1; - uint8_t re2; - uint8_t re3; - uint8_t re4; - uint8_t re5; - uint8_t re6; - uint8_t re7; -} Memory_layout; - -static Memory_layout layouts[]={ - /* LIDE 100 */ - { - 0x29, - 0x0a, 0x15, 0x20, - 0x00, 0xac, 0x02, 0x55, 0x02, 0x56, 0x03, 0xff - }, - /* LIDE 200 */ - { - 0x29, - 0x0a, 0x1f, 0x34, - 0x01, 0x24, 0x02, 0x91, 0x02, 0x92, 0x03, 0xff - }, - /* 5600F */ - { - 0x29, - 0x0a, 0x1f, 0x34, - 0x01, 0x24, 0x02, 0x91, 0x02, 0x92, 0x03, 0xff - }, - /* LIDE 700F */ - { - 0x2a, - 0x0a, 0x33, 0x5c, - 0x02, 0x14, 0x09, 0x09, 0x09, 0x0a, 0x0f, 0xff - } -}; - -/** @brief structure for sensor settings - * this structure describes the sensor settings to use for a given - * exposure. - */ -typedef struct { - int sensor_type; /**> sensor id */ - int dpi; /**> maximum dpi for which data are valid */ - int exposure; /**> exposure */ - int ck1map; /**> CK1MAP */ - int ck3map; /**> CK3MAP */ - int ck4map; /**> CK4MAP */ - int segcnt; /**> SEGCNT */ - int expdummy; /**> exposure dummy */ - int expr; /**> initial red exposure */ - int expg; /**> initial green exposure */ - int expb; /**> initial blue exposure */ - size_t *order; /**> order of sub-segments */ - uint8_t r17; /**> TG width */ -} Sensor_Profile; - -static size_t order_01[]={0,1}; -static size_t order_0213[]={0,2,1,3}; -static size_t order_0246[]={0,2,4,6,1,3,5,7}; - -static size_t new_order[]={0,1,2,3}; -static size_t order_0145[]={0,1,4,5,2,3,6,7}; - -/** - * database of sensor profiles - */ -static Sensor_Profile sensors[]={ - {CIS_CANONLIDE100, 200, 2848, 60, 159, 85, 5136, 255, 410, 275, 203, NULL , 0x0a}, - {CIS_CANONLIDE100, 300, 1424, 60, 159, 85, 5136, 255, 410, 275, 203, NULL , 0x0a}, - {CIS_CANONLIDE100, 600, 1432, 60, 159, 85, 5136, 255, 410, 275, 203, NULL , 0x0a}, - {CIS_CANONLIDE100, 1200, 2712, 60, 159, 85, 5136, 255, 746, 478, 353, order_01 , 0x08}, - {CIS_CANONLIDE100, 2400, 5280, 60, 159, 85, 5136, 255, 1417, 909, 643, order_0213, 0x06}, - /* - {CIS_CANONLIDE200, 150, 2848, 240, 636, 340, 5144, 0, 255, 637, 637, 637}, - {CIS_CANONLIDE200, 300, 1424, 240, 636, 340, 5144, 0, 255, 637, 637, 637}, - */ - {CIS_CANONLIDE200, 200, 2848, 60, 159, 85, 5136, 255, 410, 275, 203, NULL , 0x0a}, - {CIS_CANONLIDE200, 300, 1424, 60, 159, 85, 5136, 255, 410, 275, 203, NULL , 0x0a}, - {CIS_CANONLIDE200, 600, 1432, 60, 159, 85, 5136, 255, 410, 275, 203, NULL , 0x0a}, - {CIS_CANONLIDE200, 1200, 2712, 60, 159, 85, 5136, 255, 746, 478, 353, order_01 , 0x08}, - {CIS_CANONLIDE200, 2400, 5280, 60, 159, 85, 5136, 255, 1417, 909, 643, order_0213, 0x06}, - {CIS_CANONLIDE200, 4800, 10416, 60, 159, 85, 5136, 255, 2692, 1728, 1221, order_0246, 0x04}, - - /* LiDE 700F */ - {CIS_CANONLIDE700, 150, 2848, 135, 249, 85, 5187, 255, 465, 310, 239, NULL , 0x0c}, - {CIS_CANONLIDE700, 300, 1424, 135, 249, 85, 5187, 255, 465, 310, 239, NULL , 0x0c}, - {CIS_CANONLIDE700, 600, 1504, 135, 249, 85, 5187, 255, 465, 310, 239, NULL , 0x0c}, - {CIS_CANONLIDE700, 1200, 2696, 135, 249, 85, 5187, 255, 1464, 844, 555, order_01 , 0x0a}, - {CIS_CANONLIDE700, 2400, 10576, 135, 249, 85, 5187, 255, 2798, 1558, 972, new_order , 0x08}, - {CIS_CANONLIDE700, 4800, 10576, 135, 249, 85, 5187, 255, 2798, 1558, 972, order_0145, 0x06}, -}; - -/* base motor sopes in full step unit */ -/* target=((exposure * dpi) / base_dpi)>>step_type; */ -static uint32_t lide200_base[] = { 46876, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2343, 2336, 2329, 2322, 2314, 2307, 2300,2292,2285,2278,2271,2263,2256,2249,2241,2234,2227,2219,2212,2205,2198,2190,2183,2176,2168,2161,2154,2146,2139,2132,2125,2117,2110,2103,2095,2088,2081,2073,2066,2059,2052,2044,2037,2030,2022,2015,2008,2001,1993,1986,1979,1971,1964,1957,1949,1942,1935,1928,1920,1913,1906,1898,1891,1884,1876,1869,1862,1855,1847,1840,1833,1825,1818,1811,1803,1796,1789,1782,1774,1767,1760,1752,1745,1738,1731,1723,1716,1709,1701,1694,1687,1679,1672,1665,1658,1650,1643,1636,1628,1621,1614,1606,1599,1592,1585,1577,1570,1563,1555,1548,1541,1533,1526,1519,1512,1504,1497,1490,1482,1475,1468,1461,1453,1446,1439,1431,1424,1417,1409,1402,1395,1388,1380,1373,1366,1358,1351,1344,1336,1329,1322,1315,1307,1300,1293,1285,1278,1271,1263,1256,1249,1242,1234,1227,1220,1212,1205,1198,1191,1183,1176,1169,1161,1154,1147,1139,1132,1125,1118,1110,1103,1096,1088,1081,1074,1066,1059,1052,1045,1037,1030,1023,1015,1008,1001,993,986,979,972,964,957,950,942,935,928,921,913,906,899,891,884,877,869,862,855,848,840,833,826,818,811,804,796,789,782,775,767,760,753,745,738,731,723,716,709,702,694,687,680,672,665,658,651,643,636,629,621,614,607,599,592,585,578,570,563,556,534,534, 0}; -static uint32_t lide200_medium[] = { 46876, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136, 8136,2343, 2336, 2329, 2322, 2314, 2307, 2300,2292,2285,2278,2271,2263,2256,2249,2241,2234,2227,2219,2212,2205,2198,2190,2183,2176,2168,2161,2154,2146,2139,2132,2125,2117,2110,2103,2095,2088,2081,2073,2066,2059,2052,2044,2037,2030,2022,2015,2008,2001,1993,1986,1979,1971,1964,1957,1949,1942,1935,1928,1920,1913,1906,1898,1891,1884,1876,1869,1862,1855,1847,1840,1833,1825,1818,1811,1803,1796,1789,1782,1774,1767,1760,1752,1745,1738,1731,1723,1716,1709,1701,1694,1687,1679,1672,1665,1658,1650,1643,1636,1628,1621,1614,1606,1599,1592,1585,1577,1570,1563,1555,1548,1541,1533,1526,1519,1512,1504,1497,1490,1482,1475,1468,1461,1453,1446,1439,1431,1424,1417,1409,1402,1395,1388,1380,1373,1366,1358,1351,1344,1336,1329,1322,1315,1307,1300,1293,1285,1278,1271,1263,1256,1249,1242,1234,1227,1220,1212,1205,1198,1191,1183,1176,1169,1161,1154,1147,1139,1132,1125,1118,1110,1103,1096,1088,1081,1074,1066,1059,1052,1045,1037,1030,1023,1015,1008,1001,993,986,979,972,964,957,950,942,935,928,921,913,906,899,891,884,877,869,862,855,848,840,833,826,818,811,804,796,789,782,775,767,760,753,745,738,731,723,716,709,702,694,687,680,672,665,658,651,643,636,629,621,614,607,599,592,585,578,570,563,556,534,534, 0}; -static uint32_t lide200_high[] = { 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 31680, 2219,2212,2205,2198,2190,2183,2176,2168,2161,2154,2146,2139,2132,2125,2117,2110,2103,2095,2088,2081,2073,2066,2059,2052,2044,2037,2030,2022,2015,2008,2001,1993,1986,1979,1971,1964,1957,1949,1942,1935,1928,1920,1913,1906,1898,1891,1884,1876,1869,1862,1855,1847,1840,1833,1825,1818,1811,1803,1796,1789,1782,1774,1767,1760,1752,1745,1738,1731,1723,1716,1709,1701,1694,1687,1679,1672,1665,1658,1650,1643,1636,1628,1621,1614,1606,1599,1592,1585,1577,1570,1563,1555,1548,1541,1533,1526,1519,1512,1504,1497,1490,1482,1475,1468,1461,1453,1446,1439,1431,1424,1417,1409,1402,1395,1388,1380,1373,1366,1358,1351,1344,1336,1329,1322,1315,1307,1300,1293,1285,1278,1271,1263,1256,1249,1242,1234,1227,1220,1212,1205,1198,1191,1183,1176,1169,1161,1154,1147,1139,1132,1125,1118,1110,1103,1096,1088,1081,1074,1066,1059,1052,1045,1037,1030,1023,1015,1008,1001,993,986,979,972,964,957,950,942,935,928,921,913,906,899,891,884,877,869,862,855,848,840,833,826,818,811,804,796,789,782,775,767,760,753,745,738,731,723,716,709,702,694,687,680,672,665,658,651,643,636,629,621,614,607,599,592,585,578,570,563,556,534,534, 0}; -static uint32_t lide700_medium[] = { 46876,2342,2342,2342,2342,2342,2342,2342,2342,2302,2286,2274,2266,2258,2252,2244,2240,2234,2228,2224,2218,2216,2210,2208,2202,2200,2194,2192,2190,2186,2182,2180,2176,2174,2172,2170,2166,2162,2160,2156,2154,2152,2150,2150,2146,2144,2142,2140,2136,2134,2132,2130,2130,2128,2124,2122,2120,2120,2118,2116,2112,2112,2110,2108,2106,2106,2104,2102,2102,2098,2096,2094,2094,2092,2090,2090,2086,2084,2084,2082,2082,2080,2078,2078,2076,2074,2074,2070,2070,2068,2066,2066,2064,2064,2062,2062,2060,2058,2058,2054,2054,2052,2052,2050,2050,2048,2048,2046,2046,2044,2042,2042,2040,2040,2038,2038,2034,2034,2032,2032,2030,2030,2028,2028,2026,2026,2022,2022}; -static uint32_t lide700_high[] = { 46876,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864,15864}; -/* 5190 trop - * 5186 pas assez - */ -/* -static uint32_t lide200_max[] = { 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 124992, 2219,2212,2205,2198,2190,2183,2176,2168,2161,2154,2146,2139,2132,2125,2117,2110,2103,2095,2088,2081,2073,2066,2059,2052,2044,2037,2030,2022,2015,2008,2001,1993,1986,1979,1971,1964,1957,1949,1942,1935,1928,1920,1913,1906,1898,1891,1884,1876,1869,1862,1855,1847,1840,1833,1825,1818,1811,1803,1796,1789,1782,1774,1767,1760,1752,1745,1738,1731,1723,1716,1709,1701,1694,1687,1679,1672,1665,1658,1650,1643,1636,1628,1621,1614,1606,1599,1592,1585,1577,1570,1563,1555,1548,1541,1533,1526,1519,1512,1504,1497,1490,1482,1475,1468,1461,1453,1446,1439,1431,1424,1417,1409,1402,1395,1388,1380,1373,1366,1358,1351,1344,1336,1329,1322,1315,1307,1300,1293,1285,1278,1271,1263,1256,1249,1242,1234,1227,1220,1212,1205,1198,1191,1183,1176,1169,1161,1154,1147,1139,1132,1125,1118,1110,1103,1096,1088,1081,1074,1066,1059,1052,1045,1037,1030,1023,1015,1008,1001,993,986,979,972,964,957,950,942,935,928,921,913,906,899,891,884,877,869,862,855,848,840,833,826,818,811,804,796,789,782,775,767,760,753,745,738,731,723,716,709,702,694,687,680,672,665,658,651,643,636,629,621,614,607,599,592,585,578,570,563,556,534,534, 0}; -*/ - -/** - * database of motor profiles - */ - -static Motor_Profile gl847_motors[]={ - /* LiDE 100 */ - {MOTOR_CANONLIDE100, 2848, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE100, 1424, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE100, 1432, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE100, 2712, QUARTER_STEP, lide200_medium}, - {MOTOR_CANONLIDE100, 5280, EIGHTH_STEP , lide200_high}, - - /* LiDE 200 */ - {MOTOR_CANONLIDE200, 2848, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE200, 1424, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE200, 1432, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE200, 2712, QUARTER_STEP, lide200_medium}, - {MOTOR_CANONLIDE200, 5280, EIGHTH_STEP , lide200_high}, - {MOTOR_CANONLIDE200, 10416, EIGHTH_STEP , lide200_high}, - - /* LiDE 700F */ - {MOTOR_CANONLIDE700, 2848, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE700, 1424, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE700, 1504, HALF_STEP , lide200_base}, - {MOTOR_CANONLIDE700, 2696, HALF_STEP , lide700_medium}, /* 2696 , 2838 */ - {MOTOR_CANONLIDE700, 10576, EIGHTH_STEP, lide700_high}, - - /* end of database entry */ - {0, 0, 0, NULL}, -}; diff --git a/backend/genesys_low.cc b/backend/genesys_low.cc deleted file mode 100644 index 097375f..0000000 --- a/backend/genesys_low.cc +++ /dev/null @@ -1,2059 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2010-2013 Stéphane Voltz <stef.dev@free.fr> - - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#define DEBUG_DECLARE_ONLY - -#include "genesys_low.h" -#include "assert.h" - -#include <vector> - - -Genesys_Device::~Genesys_Device() -{ - clear(); - - if (file_name != nullptr) - free(file_name); -} - -void Genesys_Device::clear() -{ - read_buffer.clear(); - lines_buffer.clear(); - shrink_buffer.clear(); - out_buffer.clear(); - binarize_buffer.clear(); - local_buffer.clear(); - - calib_file.clear(); - - calibration_cache.clear(); - - white_average_data.clear(); - dark_average_data.clear(); -} - -/* ------------------------------------------------------------------------ */ -/* functions calling ASIC specific functions */ -/* ------------------------------------------------------------------------ */ - -/** - * setup the hardware dependent functions - */ -SANE_Status -sanei_genesys_init_cmd_set (Genesys_Device * dev) -{ - DBG_INIT (); - switch (dev->model->asic_type) - { - case GENESYS_GL646: - return sanei_gl646_init_cmd_set (dev); - case GENESYS_GL841: - return sanei_gl841_init_cmd_set (dev); - case GENESYS_GL843: - return sanei_gl843_init_cmd_set (dev); - case GENESYS_GL845: /* since only a few reg bits differs - we handle both together */ - case GENESYS_GL846: - return sanei_gl846_init_cmd_set (dev); - case GENESYS_GL847: - return sanei_gl847_init_cmd_set (dev); - case GENESYS_GL124: - return sanei_gl124_init_cmd_set (dev); - default: - return SANE_STATUS_INVAL; - } -} - -/* ------------------------------------------------------------------------ */ -/* General IO and debugging functions */ -/* ------------------------------------------------------------------------ */ - -SANE_Status sanei_genesys_write_file(const char *filename, uint8_t * data, size_t length) -{ - FILE *out; - - out = fopen (filename, "w"); - if (!out) { - DBG(DBG_error, "%s: could nor open %s for writing: %s\n", __func__, filename, - strerror(errno)); - return SANE_STATUS_INVAL; - } - fwrite(data, 1, length, out); - fclose(out); - - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; -} - -/* Write data to a pnm file (e.g. calibration). For debugging only */ -/* data is RGB or grey, with little endian byte order */ -SANE_Status -sanei_genesys_write_pnm_file (const char *filename, uint8_t * data, int depth, - int channels, int pixels_per_line, int lines) -{ - FILE *out; - int count; - - DBG(DBG_info, "%s: depth=%d, channels=%d, ppl=%d, lines=%d\n", __func__,depth, channels, - pixels_per_line, lines); - - out = fopen (filename, "w"); - if (!out) - { - DBG(DBG_error, "%s: could nor open %s for writing: %s\n", __func__, filename, - strerror(errno)); - return SANE_STATUS_INVAL; - } - if(depth==1) - { - fprintf (out, "P4\n%d\n%d\n", pixels_per_line, lines); - } - else - { - fprintf (out, "P%c\n%d\n%d\n%d\n", channels == 1 ? '5' : '6', - pixels_per_line, lines, (int) pow (2, depth) - 1); - } - if (channels == 3) - { - for (count = 0; count < (pixels_per_line * lines * 3); count++) - { - if (depth == 16) - fputc (*(data + 1), out); - fputc (*(data++), out); - if (depth == 16) - data++; - } - } - else - { - if (depth==1) - { - pixels_per_line/=8; - } - for (count = 0; count < (pixels_per_line * lines); count++) - { - switch (depth) - { - case 8: - fputc (*(data + count), out); - break; - case 16: - fputc (*(data + 1), out); - fputc (*(data), out); - data += 2; - break; - default: - fputc(data[count], out); - break; - } - } - } - fclose (out); - - DBG(DBG_proc, "%s: finished\n", __func__); - return SANE_STATUS_GOOD; -} - -/* ------------------------------------------------------------------------ */ -/* Read and write RAM, registers and AFE */ -/* ------------------------------------------------------------------------ */ - -extern unsigned sanei_genesys_get_bulk_max_size(Genesys_Device * dev) -{ - /* Genesys supports 0xFE00 maximum size in general, wheraus GL646 supports - 0xFFC0. We use 0xF000 because that's the packet limit in the Linux usbmon - USB capture stack. By default it limits packet size to b_size / 5 where - b_size is the size of the ring buffer. By default it's 300*1024, so the - packet is limited 61440 without any visibility to acquiring software. - */ - if (dev->model->asic_type == GENESYS_GL124 || - dev->model->asic_type == GENESYS_GL846 || - dev->model->asic_type == GENESYS_GL847) { - return 0xeff0; - } - return 0xf000; -} - -void sanei_genesys_bulk_read_data_send_header(Genesys_Device* dev, size_t len) -{ - DBG_HELPER(dbg); - - uint8_t outdata[8]; - if (dev->model->asic_type == GENESYS_GL124 || - dev->model->asic_type == GENESYS_GL846 || - dev->model->asic_type == GENESYS_GL847) - { - // hard coded 0x10000000 address - outdata[0] = 0; - outdata[1] = 0; - outdata[2] = 0; - outdata[3] = 0x10; - } else if (dev->model->asic_type == GENESYS_GL841 || - dev->model->asic_type == GENESYS_GL843) { - outdata[0] = BULK_IN; - outdata[1] = BULK_RAM; - outdata[2] = VALUE_BUFFER & 0xff; - outdata[3] = (VALUE_BUFFER >> 8) & 0xff; - } else { - outdata[0] = BULK_IN; - outdata[1] = BULK_RAM; - outdata[2] = 0x00; - outdata[3] = 0x00; - } - - /* data size to transfer */ - outdata[4] = (len & 0xff); - outdata[5] = ((len >> 8) & 0xff); - outdata[6] = ((len >> 16) & 0xff); - outdata[7] = ((len >> 24) & 0xff); - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x00, - sizeof(outdata), outdata); -} - -SANE_Status sanei_genesys_bulk_read_data(Genesys_Device * dev, uint8_t addr, uint8_t* data, - size_t len) -{ - DBG_HELPER(dbg); - - // currently supported: GL646, GL841, GL843, GL846, GL847, GL124 - size_t size, target; - uint8_t *buffer; - - unsigned is_addr_used = 1; - unsigned has_header_before_each_chunk = 0; - if (dev->model->asic_type == GENESYS_GL124 || - dev->model->asic_type == GENESYS_GL846 || - dev->model->asic_type == GENESYS_GL847) - { - is_addr_used = 0; - has_header_before_each_chunk = 1; - } - - if (is_addr_used) { - DBG(DBG_io, "%s: requesting %lu bytes from 0x%02x addr\n", __func__, (u_long) len, addr); - } else { - DBG(DBG_io, "%s: requesting %lu bytes\n", __func__, (u_long) len); - } - - if (len == 0) - return SANE_STATUS_GOOD; - - if (is_addr_used) { - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, 0x00, - 1, &addr); - } - - target = len; - buffer = data; - - size_t max_in_size = sanei_genesys_get_bulk_max_size(dev); - - if (!has_header_before_each_chunk) { - sanei_genesys_bulk_read_data_send_header(dev, len); - } - - // loop until computed data size is read - while (target) { - if (target > max_in_size) { - size = max_in_size; - } else { - size = target; - } - - if (has_header_before_each_chunk) { - sanei_genesys_bulk_read_data_send_header(dev, size); - } - - DBG(DBG_io2, "%s: trying to read %lu bytes of data\n", __func__, (u_long) size); - - dev->usb_dev.bulk_read(data, &size); - - DBG(DBG_io2, "%s: read %lu bytes, %lu remaining\n", __func__, - (u_long) size, (u_long) (target - size)); - - target -= size; - data += size; - } - - if (DBG_LEVEL >= DBG_data && dev->binary!=NULL) { - fwrite(buffer, len, 1, dev->binary); - } - - return SANE_STATUS_GOOD; -} - -SANE_Status sanei_genesys_bulk_write_data(Genesys_Device * dev, uint8_t addr, uint8_t* data, - size_t len) -{ - DBG_HELPER(dbg); - - // supported: GL646, GL841, GL843 - size_t size; - uint8_t outdata[8]; - - DBG(DBG_io, "%s writing %lu bytes\n", __func__, (u_long) len); - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, - 1, &addr); - - - size_t max_out_size = sanei_genesys_get_bulk_max_size(dev); - - while (len) { - if (len > max_out_size) - size = max_out_size; - else - size = len; - - if (dev->model->asic_type == GENESYS_GL841) { - outdata[0] = BULK_OUT; - outdata[1] = BULK_RAM; - outdata[2] = VALUE_BUFFER & 0xff; - outdata[3] = (VALUE_BUFFER >> 8) & 0xff; - } else { - outdata[0] = BULK_OUT; - outdata[1] = BULK_RAM; - outdata[2] = 0x00; - outdata[3] = 0x00; - } - - outdata[4] = (size & 0xff); - outdata[5] = ((size >> 8) & 0xff); - outdata[6] = ((size >> 16) & 0xff); - outdata[7] = ((size >> 24) & 0xff); - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x00, - sizeof(outdata), outdata); - - dev->usb_dev.bulk_write(data, &size); - - DBG(DBG_io2, "%s: wrote %lu bytes, %lu remaining\n", __func__, (u_long) size, - (u_long) (len - size)); - - len -= size; - data += size; - } - - return SANE_STATUS_GOOD; -} - -/** @brief write to one high (addr >= 0x100) register - * write to a register which address is higher than 0xff. - * @param dev opened device to write to - * @param reg LSB of register address - * @param val value to write - */ -SANE_Status -sanei_genesys_write_hregister (Genesys_Device * dev, uint16_t reg, uint8_t val) -{ - DBG_HELPER(dbg); - - uint8_t buffer[2]; - - buffer[0]=reg & 0xff; - buffer[1]=val; - - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, 0x100 | VALUE_SET_REGISTER, INDEX, - 2, buffer); - - DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, reg, val); - - return SANE_STATUS_GOOD; -} - -/** @brief read from one high (addr >= 0x100) register - * Read to a register which address is higher than 0xff. Second byte is check to detect - * physical link errors. - * @param dev opened device to read from - * @param reg LSB of register address - * @param val value to write - */ -SANE_Status -sanei_genesys_read_hregister (Genesys_Device * dev, uint16_t reg, uint8_t * val) -{ - DBG_HELPER(dbg); - - SANE_Byte value[2]; - - dev->usb_dev.control_msg(REQUEST_TYPE_IN, REQUEST_BUFFER, 0x100 | VALUE_GET_REGISTER, - 0x22+((reg & 0xff)<<8), 2, value); - - *val=value[0]; - DBG(DBG_io2, "%s(0x%02x)=0x%02x\n", __func__, reg, *val); - - /* check usb link status */ - if((value[1] & 0xff) != 0x55) - { - DBG(DBG_error,"%s: invalid read, scanner unplugged ?\n", __func__); - return SANE_STATUS_IO_ERROR; - } - return SANE_STATUS_GOOD; -} - -/** - * Write to one GL847 ASIC register -URB 10 control 0x40 0x04 0x83 0x00 len 2 wrote 0xa6 0x04 - */ -static SANE_Status -sanei_genesys_write_gl847_register (Genesys_Device * dev, uint8_t reg, uint8_t val) -{ - DBG_HELPER(dbg); - - uint8_t buffer[2]; - - buffer[0]=reg; - buffer[1]=val; - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_SET_REGISTER, INDEX, - 2, buffer); - - DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, reg, val); - - return SANE_STATUS_GOOD; -} - -/** - * Write to one ASIC register - */ -SANE_Status -sanei_genesys_write_register (Genesys_Device * dev, uint16_t reg, uint8_t val) -{ - DBG_HELPER(dbg); - - SANE_Byte reg8; - - /* 16 bit register address space */ - if(reg>255) - { - return sanei_genesys_write_hregister(dev, reg, val); - } - - /* route to gl847 function if needed */ - if(dev->model->asic_type==GENESYS_GL847 - || dev->model->asic_type==GENESYS_GL845 - || dev->model->asic_type==GENESYS_GL846 - || dev->model->asic_type==GENESYS_GL124) - { - return sanei_genesys_write_gl847_register(dev, reg, val); - } - - reg8=reg & 0xff; - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, - 1, ®8); - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_WRITE_REGISTER, INDEX, - 1, &val); - - DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, reg, val); - - return SANE_STATUS_GOOD; -} - -/** - * @brief write command to 0x8c endpoint - * Write a value to 0x8c end point (end access), for USB firmware related operations - * Known values are 0x0f, 0x11 for USB 2.0 data transfer and 0x0f,0x14 for USB1.1 - * @param dev device to write to - * @param index index of the command - * @param val value to write - */ -SANE_Status -sanei_genesys_write_0x8c(Genesys_Device * dev, uint8_t index, uint8_t val) -{ - DBG_HELPER_ARGS(dbg, "0x%02x,0x%02x", index, val); - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_BUF_ENDACCESS, index, - 1, &val); - return SANE_STATUS_GOOD; -} - -/* read reg 0x41: - * URB 164 control 0xc0 0x04 0x8e 0x4122 len 2 read 0xfc 0x55 - */ -static SANE_Status -sanei_genesys_read_gl847_register (Genesys_Device * dev, uint16_t reg, uint8_t * val) -{ - DBG_HELPER(dbg); - SANE_Status status = SANE_STATUS_GOOD; - SANE_Byte value[2]; - - dev->usb_dev.control_msg(REQUEST_TYPE_IN, REQUEST_BUFFER, VALUE_GET_REGISTER, 0x22+(reg<<8), - 2, value); - - *val=value[0]; - DBG(DBG_io2, "%s(0x%02x)=0x%02x\n", __func__, reg, *val); - - /* check usb link status */ - if((value[1] & 0xff) != 0x55) - { - DBG(DBG_error,"%s: invalid read, scanner unplugged ?\n", __func__); - status=SANE_STATUS_IO_ERROR; - } - return status; -} - -/* Read from one register */ -SANE_Status -sanei_genesys_read_register (Genesys_Device * dev, uint16_t reg, uint8_t * val) -{ - DBG_HELPER(dbg); - - SANE_Byte reg8; - - /* 16 bit register address space */ - if(reg>255) - { - return sanei_genesys_read_hregister(dev, reg, val); - } - - /* route to gl847 function if needed */ - if(dev->model->asic_type==GENESYS_GL847 - || dev->model->asic_type==GENESYS_GL845 - || dev->model->asic_type==GENESYS_GL846 - || dev->model->asic_type==GENESYS_GL124) - return sanei_genesys_read_gl847_register(dev, reg, val); - - /* 8 bit register address space */ - reg8=(SANE_Byte)(reg& 0Xff); - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, - 1, ®8); - - *val = 0; - - dev->usb_dev.control_msg(REQUEST_TYPE_IN, REQUEST_REGISTER, VALUE_READ_REGISTER, INDEX, - 1, val); - - DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, reg, *val); - - return SANE_STATUS_GOOD; -} - -/* Set address for writing data */ -SANE_Status -sanei_genesys_set_buffer_address (Genesys_Device * dev, uint32_t addr) -{ - SANE_Status status = SANE_STATUS_GOOD; - - if(dev->model->asic_type==GENESYS_GL847 - || dev->model->asic_type==GENESYS_GL845 - || dev->model->asic_type==GENESYS_GL846 - || dev->model->asic_type==GENESYS_GL124) - { - DBG(DBG_warn, "%s: shouldn't be used for GL846+ ASICs\n", __func__); - return SANE_STATUS_GOOD; - } - - DBG(DBG_io, "%s: setting address to 0x%05x\n", __func__, addr & 0xfffffff0); - - addr = addr >> 4; - - status = sanei_genesys_write_register (dev, 0x2b, (addr & 0xff)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while writing low byte: %s\n", __func__, sane_strstatus(status)); - return status; - } - - addr = addr >> 8; - status = sanei_genesys_write_register (dev, 0x2a, (addr & 0xff)); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while writing high byte: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_io, "%s: completed\n", __func__); - - return status; -} - -/**@brief read data from analog frontend (AFE) - * @param dev device owning the AFE - * @param addr register address to read - * @param data placeholder for the result - * @return SANE_STATUS_GOOD is OK, else the error code - */ -SANE_Status -sanei_genesys_fe_read_data (Genesys_Device * dev, uint8_t addr, - uint16_t *data) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t value; - Genesys_Register_Set reg; - - - DBG(DBG_proc, "%s: start\n", __func__); - - reg.init_reg(0x50, addr); - - /* set up read address */ - status = dev->model->cmd_set->bulk_write_register(dev, reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while bulk writing registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - /* read data */ - RIE (sanei_genesys_read_register (dev, 0x46, &value)); - *data=256*value; - RIE (sanei_genesys_read_register (dev, 0x47, &value)); - *data+=value; - - DBG(DBG_io, "%s (0x%02x, 0x%04x)\n", __func__, addr, *data); - DBG(DBG_proc, "%s: completed\n", __func__); - - return status; -} - -/*@brief write data to analog frontend - * writes data to analog frontend to set it up accordingly - * to the sensor settings (exposure, timings, color, bit depth, ...) - * @param dev devie owning the AFE to write to - * @param addr AFE rister address - * @param data value to write to AFE register - **/ -SANE_Status -sanei_genesys_fe_write_data (Genesys_Device * dev, uint8_t addr, - uint16_t data) -{ - SANE_Status status = SANE_STATUS_GOOD; - Genesys_Register_Set reg(Genesys_Register_Set::SEQUENTIAL); - - DBG(DBG_io, "%s (0x%02x, 0x%04x)\n", __func__, addr, data); - - reg.init_reg(0x51, addr); - if (dev->model->asic_type == GENESYS_GL124) { - reg.init_reg(0x5d, (data / 256) & 0xff); - reg.init_reg(0x5e, data & 0xff); - } else { - reg.init_reg(0x3a, (data / 256) & 0xff); - reg.init_reg(0x3b, data & 0xff); - } - - status = dev->model->cmd_set->bulk_write_register(dev, reg); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed while bulk writing registers: %s\n", __func__, - sane_strstatus(status)); - return status; - } - - DBG(DBG_io, "%s: completed\n", __func__); - - return status; -} - -/* ------------------------------------------------------------------------ */ -/* Medium level functions */ -/* ------------------------------------------------------------------------ */ - -/** read the status register - */ -SANE_Status -sanei_genesys_get_status (Genesys_Device * dev, uint8_t * status) -{ - if(dev->model->asic_type==GENESYS_GL124) - return sanei_genesys_read_hregister(dev, 0x101, status); - return sanei_genesys_read_register (dev, 0x41, status); -} - -/** - * decodes and prints content of status register - * @param val value read from status register - */ -void sanei_genesys_print_status (uint8_t val) -{ - char msg[80]; - - sprintf (msg, "%s%s%s%s%s%s%s%s", - val & PWRBIT ? "PWRBIT " : "", - val & BUFEMPTY ? "BUFEMPTY " : "", - val & FEEDFSH ? "FEEDFSH " : "", - val & SCANFSH ? "SCANFSH " : "", - val & HOMESNR ? "HOMESNR " : "", - val & LAMPSTS ? "LAMPSTS " : "", - val & FEBUSY ? "FEBUSY " : "", - val & MOTORENB ? "MOTORENB" : ""); - DBG(DBG_info, "status=%s\n", msg); -} - -#if 0 -/* returns pixels per line from register set */ -/*candidate for moving into chip specific files?*/ -static int -genesys_pixels_per_line (Genesys_Register_Set * reg) -{ - int pixels_per_line; - - pixels_per_line = - sanei_genesys_read_reg_from_set (reg, - 0x32) * 256 + - sanei_genesys_read_reg_from_set (reg, 0x33); - pixels_per_line -= - (sanei_genesys_read_reg_from_set (reg, 0x30) * 256 + - sanei_genesys_read_reg_from_set (reg, 0x31)); - - return pixels_per_line; -} - -/* returns dpiset from register set */ -/*candidate for moving into chip specific files?*/ -static int -genesys_dpiset (Genesys_Register_Set * reg) -{ - int dpiset; - - dpiset = - sanei_genesys_read_reg_from_set (reg, - 0x2c) * 256 + - sanei_genesys_read_reg_from_set (reg, 0x2d); - - return dpiset; -} -#endif - -/** read the number of valid words in scanner's RAM - * ie registers 42-43-44 - */ -/*candidate for moving into chip specific files?*/ -SANE_Status -sanei_genesys_read_valid_words (Genesys_Device * dev, unsigned int *words) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t value; - - DBGSTART; - switch (dev->model->asic_type) - { - case GENESYS_GL124: - RIE (sanei_genesys_read_hregister (dev, 0x102, &value)); - *words = (value & 0x03); - RIE (sanei_genesys_read_hregister (dev, 0x103, &value)); - *words = *words * 256 + value; - RIE (sanei_genesys_read_hregister (dev, 0x104, &value)); - *words = *words * 256 + value; - RIE (sanei_genesys_read_hregister (dev, 0x105, &value)); - *words = *words * 256 + value; - break; - - case GENESYS_GL845: - case GENESYS_GL846: - RIE (sanei_genesys_read_register (dev, 0x42, &value)); - *words = (value & 0x02); - RIE (sanei_genesys_read_register (dev, 0x43, &value)); - *words = *words * 256 + value; - RIE (sanei_genesys_read_register (dev, 0x44, &value)); - *words = *words * 256 + value; - RIE (sanei_genesys_read_register (dev, 0x45, &value)); - *words = *words * 256 + value; - break; - - case GENESYS_GL847: - RIE (sanei_genesys_read_register (dev, 0x42, &value)); - *words = (value & 0x03); - RIE (sanei_genesys_read_register (dev, 0x43, &value)); - *words = *words * 256 + value; - RIE (sanei_genesys_read_register (dev, 0x44, &value)); - *words = *words * 256 + value; - RIE (sanei_genesys_read_register (dev, 0x45, &value)); - *words = *words * 256 + value; - break; - - default: - RIE (sanei_genesys_read_register (dev, 0x44, &value)); - *words = value; - RIE (sanei_genesys_read_register (dev, 0x43, &value)); - *words += (value * 256); - RIE (sanei_genesys_read_register (dev, 0x42, &value)); - if (dev->model->asic_type == GENESYS_GL646) - *words += ((value & 0x03) * 256 * 256); - else - *words += ((value & 0x0f) * 256 * 256); - } - - DBG(DBG_proc, "%s: %d words\n", __func__, *words); - DBGCOMPLETED; - return SANE_STATUS_GOOD; -} - -/** read the number of lines scanned - * ie registers 4b-4c-4d - */ -SANE_Status -sanei_genesys_read_scancnt (Genesys_Device * dev, unsigned int *words) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t value; - - DBG(DBG_proc, "%s: start\n", __func__); - - if (dev->model->asic_type == GENESYS_GL124) - { - RIE (sanei_genesys_read_hregister (dev, 0x10b, &value)); - *words = (value & 0x0f) << 16; - RIE (sanei_genesys_read_hregister (dev, 0x10c, &value)); - *words += (value << 8); - RIE (sanei_genesys_read_hregister (dev, 0x10d, &value)); - *words += value; - } - else - { - RIE (sanei_genesys_read_register (dev, 0x4d, &value)); - *words = value; - RIE (sanei_genesys_read_register (dev, 0x4c, &value)); - *words += (value * 256); - RIE (sanei_genesys_read_register (dev, 0x4b, &value)); - if (dev->model->asic_type == GENESYS_GL646) - *words += ((value & 0x03) * 256 * 256); - else - *words += ((value & 0x0f) * 256 * 256); - } - - DBG(DBG_proc, "%s: %d lines\n", __func__, *words); - return SANE_STATUS_GOOD; -} - -/** @brief Check if the scanner's internal data buffer is empty - * @param *dev device to test for data - * @param *empty return value - * @return empty will be set to SANE_TRUE if there is no scanned data. - **/ -SANE_Status -sanei_genesys_test_buffer_empty (Genesys_Device * dev, SANE_Bool * empty) -{ - uint8_t val = 0; - SANE_Status status = SANE_STATUS_GOOD; - - sanei_genesys_sleep_ms(1); - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: failed to read buffer status: %s\n", __func__, sane_strstatus(status)); - return status; - } - - if (dev->model->cmd_set->test_buffer_empty_bit (val)) - { - /* fix timing issue on USB3 (or just may be too fast) hardware - * spotted by John S. Weber <jweber53@gmail.com> - */ - sanei_genesys_sleep_ms(1); - DBG(DBG_io2, "%s: buffer is empty\n", __func__); - *empty = SANE_TRUE; - return SANE_STATUS_GOOD; - } - - *empty = SANE_FALSE; - - DBG(DBG_io, "%s: buffer is filled\n", __func__); - return SANE_STATUS_GOOD; -} - - -/* Read data (e.g scanned image) from scan buffer */ -SANE_Status -sanei_genesys_read_data_from_scanner (Genesys_Device * dev, uint8_t * data, - size_t size) -{ - SANE_Status status = SANE_STATUS_GOOD; - int time_count = 0; - unsigned int words = 0; - - DBG(DBG_proc, "%s (size = %lu bytes)\n", __func__, (u_long) size); - - if (size & 1) - DBG(DBG_info, "WARNING %s: odd number of bytes\n", __func__); - - /* wait until buffer not empty for up to 5 seconds */ - do - { - status = sanei_genesys_read_valid_words (dev, &words); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: checking for empty buffer failed: %s\n", __func__, - sane_strstatus(status)); - return status; - } - if (words == 0) - { - sanei_genesys_sleep_ms(10); - time_count++; - } - } - while ((time_count < 2500*2) && (words == 0)); - - if (words == 0) /* timeout, buffer does not get filled */ - { - DBG(DBG_error, "%s: timeout, buffer does not get filled\n", __func__); - return SANE_STATUS_IO_ERROR; - } - - status = dev->model->cmd_set->bulk_read_data (dev, 0x45, data, size); - if (status != SANE_STATUS_GOOD) - { - DBG(DBG_error, "%s: reading bulk data failed: %s\n", __func__, sane_strstatus(status)); - return status; - } - - DBG(DBG_proc, "%s: completed\n", __func__); - return SANE_STATUS_GOOD; -} -SANE_Status -sanei_genesys_read_feed_steps (Genesys_Device * dev, unsigned int *steps) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t value; - - DBG(DBG_proc, "%s\n", __func__); - - if (dev->model->asic_type == GENESYS_GL124) - { - RIE (sanei_genesys_read_hregister (dev, 0x108, &value)); - *steps = (value & 0x1f) << 16; - RIE (sanei_genesys_read_hregister (dev, 0x109, &value)); - *steps += (value << 8); - RIE (sanei_genesys_read_hregister (dev, 0x10a, &value)); - *steps += value; - } - else - { - RIE (sanei_genesys_read_register (dev, 0x4a, &value)); - *steps = value; - RIE (sanei_genesys_read_register (dev, 0x49, &value)); - *steps += (value * 256); - RIE (sanei_genesys_read_register (dev, 0x48, &value)); - if (dev->model->asic_type == GENESYS_GL646) - *steps += ((value & 0x03) * 256 * 256); - else if (dev->model->asic_type == GENESYS_GL841) - *steps += ((value & 0x0f) * 256 * 256); - else - *steps += ((value & 0x1f) * 256 * 256); - } - - DBG(DBG_proc, "%s: %d steps\n", __func__, *steps); - return SANE_STATUS_GOOD; -} - -void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, bool set) -{ - static const uint8_t REG03_LAMPPWR = 0x10; - - if (set) { - regs.find_reg(0x03).value |= REG03_LAMPPWR; - - if (dev->model->asic_type == GENESYS_GL841) { - sanei_genesys_set_exposure(regs, sanei_genesys_fixup_exposure(sensor.exposure)); - regs.set8(0x19, 0x50); - } - - if (dev->model->asic_type == GENESYS_GL843) { - sanei_genesys_set_exposure(regs, sensor.exposure); - } - } else { - regs.find_reg(0x03).value &= ~REG03_LAMPPWR; - - if (dev->model->asic_type == GENESYS_GL841) { - sanei_genesys_set_exposure(regs, {0x0101, 0x0101, 0x0101}); - regs.set8(0x19, 0xff); - } - - if (dev->model->asic_type == GENESYS_GL843) { - if (dev->model->model_id != MODEL_CANON_CANOSCAN_8600F) { - // BUG: datasheet says we shouldn't set exposure to zero - sanei_genesys_set_exposure(regs, {0, 0, 0}); - } - } - } - regs.state.is_lamp_on = set; -} - -void sanei_genesys_set_motor_power(Genesys_Register_Set& regs, bool set) -{ - static const uint8_t REG02_MTRPWR = 0x10; - - if (set) { - regs.find_reg(0x02).value |= REG02_MTRPWR; - } else { - regs.find_reg(0x02).value &= ~REG02_MTRPWR; - } -} - -/** - * Write to many registers at once - * Note: sequential call to write register, no effective - * bulk write implemented. - * @param dev device to write to - * @param reg pointer to an array of registers - * @param elems size of the array - */ -SANE_Status sanei_genesys_bulk_write_register(Genesys_Device * dev, Genesys_Register_Set& reg) -{ - DBG_HELPER(dbg); - - SANE_Status status = SANE_STATUS_GOOD; - - if (dev->model->asic_type == GENESYS_GL646 || - dev->model->asic_type == GENESYS_GL841) - { - uint8_t outdata[8]; - std::vector<uint8_t> buffer; - buffer.reserve(reg.size() * 2); - - /* copy registers and values in data buffer */ - for (const auto& r : reg) { - buffer.push_back(r.address); - buffer.push_back(r.value); - } - - DBG(DBG_io, "%s (elems= %lu, size = %lu)\n", __func__, (u_long) reg.size(), - (u_long) buffer.size()); - - if (dev->model->asic_type == GENESYS_GL646) { - outdata[0] = BULK_OUT; - outdata[1] = BULK_REGISTER; - outdata[2] = 0x00; - outdata[3] = 0x00; - outdata[4] = (buffer.size() & 0xff); - outdata[5] = ((buffer.size() >> 8) & 0xff); - outdata[6] = ((buffer.size() >> 16) & 0xff); - outdata[7] = ((buffer.size() >> 24) & 0xff); - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, INDEX, - sizeof(outdata), outdata); - - size_t write_size = buffer.size(); - - dev->usb_dev.bulk_write(buffer.data(), &write_size); - } else { - for (size_t i = 0; i < reg.size();) { - size_t c = reg.size() - i; - if (c > 32) /*32 is max on GL841. checked that.*/ - c = 32; - - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_SET_REGISTER, - INDEX, c * 2, buffer.data() + i * 2); - - i += c; - } - } - } else { - for (const auto& r : reg) { - status = sanei_genesys_write_register (dev, r.address, r.value); - if (status != SANE_STATUS_GOOD) - return status; - } - } - - DBG (DBG_io, "%s: wrote %lu registers\n", __func__, (u_long) reg.size()); - return status; -} - - - -/** - * writes a block of data to AHB - * @param dn USB device index - * @param usb_mode usb mode : 1 usb 1.1, 2 usb 2.0 - * @param addr AHB address to write to - * @param size size of the chunk of data - * @param data pointer to the data to write - */ -SANE_Status -sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t size, uint8_t * data) -{ - DBG_HELPER(dbg); - - uint8_t outdata[8]; - size_t written,blksize; - SANE_Status status = SANE_STATUS_GOOD; - int i; - char msg[100]="AHB="; - - outdata[0] = addr & 0xff; - outdata[1] = ((addr >> 8) & 0xff); - outdata[2] = ((addr >> 16) & 0xff); - outdata[3] = ((addr >> 24) & 0xff); - outdata[4] = (size & 0xff); - outdata[5] = ((size >> 8) & 0xff); - outdata[6] = ((size >> 16) & 0xff); - outdata[7] = ((size >> 24) & 0xff); - - if (DBG_LEVEL >= DBG_io) - { - for (i = 0; i < 8; i++) - { - sprintf (msg+strlen(msg), " 0x%02x", outdata[i]); - } - DBG (DBG_io, "%s: write(0x%08x,0x%08x)\n", __func__, addr,size); - DBG (DBG_io, "%s: %s\n", __func__, msg); - } - - // write addr and size for AHB - dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x01, 8, outdata); - - size_t max_out_size = sanei_genesys_get_bulk_max_size(dev); - - /* write actual data */ - written = 0; - do - { - if (size - written > max_out_size) - { - blksize = max_out_size; - } - else - { - blksize = size - written; - } - dev->usb_dev.bulk_write(data + written, &blksize); - - written += blksize; - } - while (written < size); - - return status; -} - - -std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor, - int color) -{ - if (!dev->gamma_override_tables[color].empty()) { - return dev->gamma_override_tables[color]; - } else { - std::vector<uint16_t> ret; - sanei_genesys_create_default_gamma_table(dev, ret, sensor.gamma[color]); - return ret; - } -} - -/** @brief generates gamma buffer to transfer - * Generates gamma table buffer to send to ASIC. Applies - * contrast and brightness if set. - * @param dev device to set up - * @param bits number of bits used by gamma - * @param max value for gamma - * @param size of the gamma table - * @param gamma allocated gamma buffer to fill - * @returns SANE_STATUS_GOOD or SANE_STATUS_NO_MEM - */ -SANE_Status sanei_genesys_generate_gamma_buffer(Genesys_Device * dev, - const Genesys_Sensor& sensor, - int bits, - int max, - int size, - uint8_t *gamma) -{ - std::vector<uint16_t> rgamma = get_gamma_table(dev, sensor, GENESYS_RED); - std::vector<uint16_t> ggamma = get_gamma_table(dev, sensor, GENESYS_GREEN); - std::vector<uint16_t> bgamma = get_gamma_table(dev, sensor, GENESYS_BLUE); - - if(dev->settings.contrast!=0 || dev->settings.brightness!=0) - { - std::vector<uint16_t> lut(65536); - sanei_genesys_load_lut((unsigned char *)lut.data(), - bits, - bits, - 0, - max, - dev->settings.contrast, - dev->settings.brightness); - for (int i = 0; i < size; i++) - { - uint16_t value=rgamma[i]; - value=lut[value]; - gamma[i * 2 + size * 0 + 0] = value & 0xff; - gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff; - - value=ggamma[i]; - value=lut[value]; - gamma[i * 2 + size * 2 + 0] = value & 0xff; - gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff; - - value=bgamma[i]; - value=lut[value]; - gamma[i * 2 + size * 4 + 0] = value & 0xff; - gamma[i * 2 + size * 4 + 1] = (value >> 8) & 0xff; - } - } - else - { - for (int i = 0; i < size; i++) - { - uint16_t value=rgamma[i]; - gamma[i * 2 + size * 0 + 0] = value & 0xff; - gamma[i * 2 + size * 0 + 1] = (value >> 8) & 0xff; - - value=ggamma[i]; - gamma[i * 2 + size * 2 + 0] = value & 0xff; - gamma[i * 2 + size * 2 + 1] = (value >> 8) & 0xff; - - value=bgamma[i]; - gamma[i * 2 + size * 4 + 0] = value & 0xff; - gamma[i * 2 + size * 4 + 1] = (value >> 8) & 0xff; - } - } - - return SANE_STATUS_GOOD; -} - - -/** @brief send gamma table to scanner - * This function sends generic gamma table (ie ones built with - * provided gamma) or the user defined one if provided by - * fontend. Used by gl846+ ASICs - * @param dev device to write to - */ -SANE_Status -sanei_genesys_send_gamma_table(Genesys_Device * dev, const Genesys_Sensor& sensor) -{ - int size; - int i; - uint8_t val; - SANE_Status status = SANE_STATUS_GOOD; - - DBGSTART; - - size = 256 + 1; - - /* allocate temporary gamma tables: 16 bits words, 3 channels */ - std::vector<uint8_t> gamma(size * 2 * 3, 255); - - RIE(sanei_genesys_generate_gamma_buffer(dev, sensor, 16, 65535, size, gamma.data())); - - /* loop sending gamma tables NOTE: 0x01000000 not 0x10000000 */ - for (i = 0; i < 3; i++) - { - /* clear corresponding GMM_N bit */ - RIE(sanei_genesys_read_register(dev, 0xbd, &val)); - val &= ~(0x01 << i); - RIE(sanei_genesys_write_register(dev, 0xbd, val)); - - /* clear corresponding GMM_F bit */ - RIE(sanei_genesys_read_register(dev, 0xbe, &val)); - val &= ~(0x01 << i); - RIE(sanei_genesys_write_register(dev, 0xbe, val)); - - // FIXME: currently the last word of each gamma table is not initialied, so to work around - // unstable data, just set it to 0 which is the most likely value of uninitialized memory - // (proper value is probably 0xff) - gamma[size * 2 * i + size * 2 - 2] = 0; - gamma[size * 2 * i + size * 2 - 1] = 0; - - /* set GMM_Z */ - RIE(sanei_genesys_write_register (dev, 0xc5+2*i, gamma[size*2*i+1])); - RIE(sanei_genesys_write_register (dev, 0xc6+2*i, gamma[size*2*i])); - - status = sanei_genesys_write_ahb(dev, 0x01000000 + 0x200 * i, (size-1) * 2, gamma.data() + i * size * 2+2); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: write to AHB failed writing table %d (%s)\n", __func__, - i, sane_strstatus (status)); - break; - } - } - - DBGCOMPLETED; - return status; -} - -/** @brief initialize device - * Initialize backend and ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home. Designed for gl846+ ASICs. - * Detects cold boot (ie first boot since device plugged) in this case - * an extensice setup up is done at hardware level. - * - * @param dev device to initialize - * @param max_regs umber of maximum used registers - * @return SANE_STATUS_GOOD in case of success - */ -SANE_Status -sanei_genesys_asic_init(Genesys_Device* dev, int /*max_regs*/) -{ - DBG_HELPER(dbg); - - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - SANE_Bool cold = SANE_TRUE; - - DBGSTART; - - // URB 16 control 0xc0 0x0c 0x8e 0x0b len 1 read 0x00 */ - dev->usb_dev.control_msg(REQUEST_TYPE_IN, REQUEST_REGISTER, VALUE_GET_REGISTER, 0x00, 1, &val); - - DBG (DBG_io2, "%s: value=0x%02x\n", __func__, val); - DBG (DBG_info, "%s: device is %s\n", __func__, (val & 0x08) ? "USB 1.0" : "USB2.0"); - if (val & 0x08) - { - dev->usb_mode = 1; - } - else - { - dev->usb_mode = 2; - } - - /* check if the device has already been initialized and powered up - * we read register 6 and check PWRBIT, if reset scanner has been - * freshly powered up. This bit will be set to later so that following - * reads can detect power down/up cycle*/ - RIE (sanei_genesys_read_register (dev, 0x06, &val)); - /* test for POWER bit */ - if (val & 0x10) - { - cold = SANE_FALSE; - } - DBG (DBG_info, "%s: device is %s\n", __func__, cold ? "cold" : "warm"); - - /* don't do anything if backend is initialized and hardware hasn't been - * replug */ - if (dev->already_initialized && !cold) - { - DBG (DBG_info, "%s: already initialized, nothing to do\n", __func__); - return SANE_STATUS_GOOD; - } - - /* set up hardware and registers */ - RIE (dev->model->cmd_set->asic_boot (dev, cold)); - - /* now hardware part is OK, set up device struct */ - dev->white_average_data.clear(); - dev->dark_average_data.clear(); - - dev->settings.color_filter = ColorFilter::RED; - - /* duplicate initial values into calibration registers */ - dev->calib_reg = dev->reg; - - const auto& sensor = sanei_genesys_find_sensor_any(dev); - - /* Set analog frontend */ - RIE (dev->model->cmd_set->set_fe(dev, sensor, AFE_INIT)); - - dev->already_initialized = SANE_TRUE; - - /* Move to home if needed */ - RIE (dev->model->cmd_set->slow_back_home (dev, SANE_TRUE)); - dev->scanhead_position_in_steps = 0; - - /* Set powersaving (default = 15 minutes) */ - RIE (dev->model->cmd_set->set_powersaving (dev, 15)); - - return status; -} - -/** - * Wait for the scanning head to park - */ -SANE_Status -sanei_genesys_wait_for_home (Genesys_Device * dev) -{ - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val; - int loop; - int max=300; - - DBGSTART; - - /* clear the parking status whatever the outcome of the function */ - dev->parking=SANE_FALSE; - - /* read initial status, if head isn't at home and motor is on - * we are parking, so we wait. - * gl847/gl124 need 2 reads for reliable results */ - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus (status)); - return status; - } - sanei_genesys_sleep_ms(10); - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus (status)); - return status; - } - - /* if at home, return */ - if(val & HOMESNR) - { - DBG (DBG_info, - "%s: already at home\n", __func__); - return status; - } - - /* loop for 30 s max, polling home sensor */ - loop = 0; - do - { - sanei_genesys_sleep_ms(100); - status = sanei_genesys_get_status (dev, &val); - if (status != SANE_STATUS_GOOD) - { - DBG (DBG_error, - "%s: failed to read home sensor: %s\n", __func__, - sane_strstatus (status)); - return status; - } - if (DBG_LEVEL >= DBG_io2) - { - sanei_genesys_print_status (val); - } - ++loop; - } - while (loop < max && !(val & HOMESNR) && status == SANE_STATUS_GOOD); - - /* if after the timeout, head is still not parked, error out */ - if(loop >= max && !(val & HOMESNR) && status == SANE_STATUS_GOOD) - { - DBG (DBG_error, "%s: failed to reach park position %ds\n", __func__, max/10); - return SANE_STATUS_IO_ERROR; - } - - DBGCOMPLETED; - return status; -} - -/**@brief compute hardware sensor dpi to use - * compute the sensor hardware dpi based on target resolution. - * A lower dpihw enable faster scans. - * @param dev device used for the scan - * @param xres x resolution of the scan - * @return the hardware dpi to use - */ -int sanei_genesys_compute_dpihw(Genesys_Device *dev, const Genesys_Sensor& sensor, int xres) -{ - /* some scanners use always hardware dpi for sensor */ - if (dev->model->flags & GENESYS_FLAG_FULL_HWDPI_MODE) - { - return sensor.optical_res; - } - - /* can't be below 600 dpi */ - if (xres <= 600) - { - return 600; - } - if (xres <= sensor.optical_res / 4) - { - return sensor.optical_res / 4; - } - if (xres <= sensor.optical_res / 2) - { - return sensor.optical_res / 2; - } - return sensor.optical_res; -} - -// sanei_genesys_compute_dpihw returns the dpihw that is written to register. -// However the number of pixels depends on half_ccd mode -int sanei_genesys_compute_dpihw_calibration(Genesys_Device *dev, const Genesys_Sensor& sensor, - int xres) -{ - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) - { - // real resolution is half of the "official" resolution - half_ccd mode - int hwres = sensor.optical_res / sensor.get_ccd_size_divisor_for_dpi(xres); - - if (xres <= hwres / 4) - { - return hwres / 4; - } - if (xres <= hwres / 2) - { - return hwres / 2; - } - return hwres; - } - - return sanei_genesys_compute_dpihw(dev, sensor, xres); -} - -/** @brief motor profile - * search for the database of motor profiles and get the best one. Each - * profile is at full step and at a reference exposure. Use first entry - * by default. - * @param motors motor profile database - * @param motor_type motor id - * @param exposure exposure time - * @return a pointer to a Motor_Profile struct - */ -Motor_Profile *sanei_genesys_get_motor_profile(Motor_Profile *motors, int motor_type, int exposure) -{ - unsigned int i; - int idx; - - i=0; - idx=-1; - while(motors[i].exposure!=0) - { - /* exact match */ - if(motors[i].motor_type==motor_type && motors[i].exposure==exposure) - { - return &(motors[i]); - } - - /* closest match */ - if(motors[i].motor_type==motor_type) - { - /* if profile exposure is higher than the required one, - * the entry is a candidate for the closest match */ - if(motors[i].exposure>=exposure) - { - if(idx<0) - { - /* no match found yet */ - idx=i; - } - else - { - /* test for better match */ - if(motors[i].exposure<motors[idx].exposure) - { - idx=i; - } - } - } - } - i++; - } - - /* default fallback */ - if(idx<0) - { - DBG (DBG_warn,"%s: using default motor profile\n",__func__); - idx=0; - } - - return &(motors[idx]); -} - -/**@brief compute motor step type to use - * compute the step type (full, half, quarter, ...) to use based - * on target resolution - * @param motors motor profile database - * @param motor_type motor id - * @param exposure sensor exposure - * @return 0 for full step - * 1 for half step - * 2 for quarter step - * 3 for eighth step - */ -int sanei_genesys_compute_step_type(Motor_Profile *motors, - int motor_type, - int exposure) -{ -Motor_Profile *profile; - - profile=sanei_genesys_get_motor_profile(motors, motor_type, exposure); - return profile->step_type; -} - -/** @brief generate slope table - * Generate the slope table to use for the scan using a reference slope - * table. - * @param slope pointer to the slope table to fill - * @param steps pointer to return used step number - * @param dpi desired motor resolution - * @param exposure exposure used - * @param base_dpi base resolution of the motor - * @param step_type step type used for scan - * @param factor shrink factor for the slope - * @param motor_type motor id - * @param motors motor profile database - */ -int sanei_genesys_slope_table(uint16_t *slope, - int *steps, - int dpi, - int exposure, - int base_dpi, - int step_type, - int factor, - int motor_type, - Motor_Profile *motors) -{ -int sum, i; -uint16_t target,current; -Motor_Profile *profile; - - /* required speed */ - target=((exposure * dpi) / base_dpi)>>step_type; - DBG (DBG_io2, "%s: exposure=%d, dpi=%d, target=%d\n", __func__, exposure, dpi, target); - - /* fill result with target speed */ - for(i=0;i<SLOPE_TABLE_SIZE;i++) - slope[i]=target; - - profile=sanei_genesys_get_motor_profile(motors, motor_type, exposure); - - /* use profile to build table */ - i=0; - sum=0; - - /* first step is always used unmodified */ - current=profile->table[0]; - - /* loop on profile copying and apply step type */ - while(profile->table[i]!=0 && current>=target) - { - slope[i]=current; - sum+=slope[i]; - i++; - current=profile->table[i]>>step_type; - } - - /* ensure last step is required speed in case profile doesn't contain it */ - if(current!=0 && current<target) - { - slope[i]=target; - sum+=slope[i]; - i++; - } - - /* range checking */ - if(profile->table[i]==0 && DBG_LEVEL >= DBG_warn && current>target) - { - DBG (DBG_warn,"%s: short slope table, failed to reach %d. target too low ?\n",__func__,target); - } - if(i<3 && DBG_LEVEL >= DBG_warn) - { - DBG (DBG_warn,"%s: short slope table, failed to reach %d. target too high ?\n",__func__,target); - } - - /* align on factor */ - while(i%factor!=0) - { - slope[i+1]=slope[i]; - sum+=slope[i]; - i++; - } - - /* ensure minimal slope size */ - while(i<2*factor) - { - slope[i+1]=slope[i]; - sum+=slope[i]; - i++; - } - - // return used steps and taken time - *steps=i/factor; - return sum; -} - -/** @brief returns the lowest possible ydpi for the device - * Parses device entry to find lowest motor dpi. - * @param dev device description - * @return lowest motor resolution - */ -int sanei_genesys_get_lowest_ydpi(Genesys_Device *dev) -{ - int min=20000; - int i=0; - - while(dev->model->ydpi_values[i]!=0) - { - if(dev->model->ydpi_values[i]<min) - { - min=dev->model->ydpi_values[i]; - } - i++; - } - return min; -} - -/** @brief returns the lowest possible dpi for the device - * Parses device entry to find lowest motor or sensor dpi. - * @param dev device description - * @return lowest motor resolution - */ -int sanei_genesys_get_lowest_dpi(Genesys_Device *dev) -{ - int min=20000; - int i=0; - - while(dev->model->ydpi_values[i]!=0) - { - if(dev->model->ydpi_values[i]<min) - { - min=dev->model->ydpi_values[i]; - } - i++; - } - i=0; - while(dev->model->xdpi_values[i]!=0) - { - if(dev->model->xdpi_values[i]<min) - { - min=dev->model->xdpi_values[i]; - } - i++; - } - return min; -} - -/** @brief check is a cache entry may be used - * Compares current settings with the cache entry and return - * SANE_TRUE if they are compatible. - * A calibration cache is compatible if color mode and x dpi match the user - * requested scan. In the case of CIS scanners, dpi isn't a criteria. - * flatbed cache entries are considred too old and then expires if they - * are older than the expiration time option, forcing calibration at least once - * then given time. */ -bool sanei_genesys_is_compatible_calibration(Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Calibration_Cache * cache, int for_overwrite) -{ -#ifdef HAVE_SYS_TIME_H - struct timeval time; -#endif - int compatible = 1, resolution; - - DBGSTART; - - if(dev->model->cmd_set->calculate_current_setup==NULL) - { - DBG (DBG_proc, "%s: no calculate_setup, non compatible cache\n", __func__); - return false; - } - - dev->model->cmd_set->calculate_current_setup(dev, sensor); - - DBG (DBG_proc, "%s: checking\n", __func__); - - /* a calibration cache is compatible if color mode and x dpi match the user - * requested scan. In the case of CIS scanners, dpi isn't a criteria */ - if (dev->model->is_cis == SANE_FALSE) - { - resolution = dev->settings.xres; - if(resolution>sensor.optical_res) - { - resolution=sensor.optical_res; - } - compatible = (resolution == ((int) cache->used_setup.xres)); - } - else - { - resolution=sanei_genesys_compute_dpihw(dev, sensor, dev->settings.xres); - compatible = (resolution == ((int) sanei_genesys_compute_dpihw(dev, sensor,cache->used_setup.xres))); - } - DBG (DBG_io, "%s: after resolution check current compatible=%d\n", __func__, compatible); - if (dev->current_setup.ccd_size_divisor != cache->used_setup.ccd_size_divisor) - { - DBG (DBG_io, "%s: half_ccd=%d, used=%d\n", __func__, - dev->current_setup.ccd_size_divisor, cache->used_setup.ccd_size_divisor); - compatible = 0; - } - if (dev->current_setup.params.scan_method != cache->used_setup.params.scan_method) - { - DBG (DBG_io, "%s: current method=%d, used=%d\n", __func__, - static_cast<unsigned>(dev->current_setup.params.scan_method), - static_cast<unsigned>(cache->used_setup.params.scan_method)); - compatible = 0; - } - if (!compatible) - { - DBG (DBG_proc, "%s: completed, non compatible cache\n", __func__); - return false; - } - - /* a cache entry expires after afetr expiration time for non sheetfed scanners */ - /* this is not taken into account when overwriting cache entries */ -#ifdef HAVE_SYS_TIME_H - if(for_overwrite == SANE_FALSE && dev->settings.expiration_time >=0) - { - gettimeofday (&time, NULL); - if ((time.tv_sec - cache->last_calibration > dev->settings.expiration_time*60) - && (dev->model->is_sheetfed == SANE_FALSE) - && (dev->settings.scan_method == ScanMethod::FLATBED)) - { - DBG (DBG_proc, "%s: expired entry, non compatible cache\n", __func__); - return false; - } - } -#endif - - DBGCOMPLETED; - return true; -} - - -/** @brief compute maximum line distance shift - * compute maximum line distance shift for the motor and sensor - * combination. Line distance shift is the distance between different - * color component of CCD sensors. Since these components aren't at - * the same physical place, they scan diffrent lines. Software must - * take this into account to accurately mix color data. - * @param dev device session to compute max_shift for - * @param channels number of color channels for the scan - * @param yres motor resolution used for the scan - * @param flags scan flags - * @return 0 or line distance shift - */ -int sanei_genesys_compute_max_shift(Genesys_Device *dev, - int channels, - int yres, - int flags) -{ - int max_shift; - - max_shift=0; - if (channels > 1 && !(flags & SCAN_FLAG_IGNORE_LINE_DISTANCE)) - { - max_shift = dev->ld_shift_r; - if (dev->ld_shift_b > max_shift) - max_shift = dev->ld_shift_b; - if (dev->ld_shift_g > max_shift) - max_shift = dev->ld_shift_g; - max_shift = (max_shift * yres) / dev->motor.base_ydpi; - } - return max_shift; -} - -/** @brief build lookup table for digital enhancements - * Function to build a lookup table (LUT), often - used by scanners to implement brightness/contrast/gamma - or by backends to speed binarization/thresholding - - offset and slope inputs are -127 to +127 - - slope rotates line around central input/output val, - 0 makes horizontal line - - pos zero neg - . x . . x - . x . . x - out . x .xxxxxxxxxxx . x - . x . . x - ....x....... ............ .......x.... - in in in - - offset moves line vertically, and clamps to output range - 0 keeps the line crossing the center of the table - - high low - . xxxxxxxx . - . x . - out x . x - . . x - ............ xxxxxxxx.... - in in - - out_min/max provide bounds on output values, - useful when building thresholding lut. - 0 and 255 are good defaults otherwise. - * @param lut pointer where to store the generated lut - * @param in_bits number of bits for in values - * @param out_bits number of bits of out values - * @param out_min minimal out value - * @param out_max maximal out value - * @param slope slope of the generated data - * @param offset offset of the generated data - */ -SANE_Status -sanei_genesys_load_lut (unsigned char * lut, - int in_bits, - int out_bits, - int out_min, - int out_max, - int slope, - int offset) -{ - SANE_Status ret = SANE_STATUS_GOOD; - int i, j; - double shift, rise; - int max_in_val = (1 << in_bits) - 1; - int max_out_val = (1 << out_bits) - 1; - uint8_t *lut_p8 = lut; - uint16_t *lut_p16 = (uint16_t *) lut; - - DBGSTART; - - /* slope is converted to rise per unit run: - * first [-127,127] to [-.999,.999] - * then to [-PI/4,PI/4] then [0,PI/2] - * then take the tangent (T.O.A) - * then multiply by the normal linear slope - * because the table may not be square, i.e. 1024x256*/ - rise = tan ((double) slope / 128 * M_PI_4 + M_PI_4) * max_out_val / max_in_val; - - /* line must stay vertically centered, so figure - * out vertical offset at central input value */ - shift = (double) max_out_val / 2 - (rise * max_in_val / 2); - - /* convert the user offset setting to scale of output - * first [-127,127] to [-1,1] - * then to [-max_out_val/2,max_out_val/2]*/ - shift += (double) offset / 127 * max_out_val / 2; - - for (i = 0; i <= max_in_val; i++) - { - j = rise * i + shift; - - /* cap data to required range */ - if (j < out_min) - { - j = out_min; - } - else if (j > out_max) - { - j = out_max; - } - - /* copy result according to bit depth */ - if (out_bits <= 8) - { - *lut_p8 = j; - lut_p8++; - } - else - { - *lut_p16 = j; - lut_p16++; - } - } - - DBGCOMPLETED; - return ret; -} - -void sanei_genesys_usleep(unsigned int useconds) -{ - usleep(useconds); -} - -void sanei_genesys_sleep_ms(unsigned int milliseconds) -{ - sanei_genesys_usleep(milliseconds * 1000); -} - -static std::unique_ptr<std::vector<std::function<void()>>> s_functions_run_at_backend_exit; - -void add_function_to_run_at_backend_exit(std::function<void()> function) -{ - if (!s_functions_run_at_backend_exit) - s_functions_run_at_backend_exit.reset(new std::vector<std::function<void()>>()); - s_functions_run_at_backend_exit->push_back(std::move(function)); -} - -void run_functions_at_backend_exit() -{ - for (auto it = s_functions_run_at_backend_exit->rbegin(); - it != s_functions_run_at_backend_exit->rend(); ++it) - { - (*it)(); - } - s_functions_run_at_backend_exit.release(); -} - -void debug_dump(unsigned level, const Genesys_Settings& settings) -{ - DBG(level, "settings:\n" - "Resolution X/Y : %u / %u dpi\n" - "Lines : %u\n" - "Pixels per line : %u\n" - "Depth : %u\n" - "Start position X/Y : %.3f/%.3f\n" - "Scan mode : %d\n\n", - settings.xres, settings.yres, - settings.lines, settings.pixels, settings.depth, - settings.tl_x, settings.tl_y, - static_cast<unsigned>(settings.scan_mode)); -} - -void debug_dump(unsigned level, const SetupParams& params) -{ - DBG(level, "settings:\n" - "Resolution X/Y : %u / %u dpi\n" - "Lines : %u\n" - "Pixels per line : %u\n" - "Depth : %u\n" - "Channels : %u\n" - "Start position X/Y : %g / %g\n" - "Scan mode : %d\n" - "Color filter : %d\n" - "Flags : %x\n", - params.xres, params.yres, - params.lines, params.pixels, - params.depth, params.channels, - params.startx, params.starty, - static_cast<unsigned>(params.scan_mode), - static_cast<unsigned>(params.color_filter), - params.flags); -} - -void debug_dump(unsigned level, const Genesys_Current_Setup& setup) -{ - DBG(level, "current_setup:\n" - "Pixels: %d\n" - "Lines: %d\n" - "Depth: %d\n" - "Channels: %d\n" - "exposure_time: %d\n" - "Resolution X/Y: %g %g\n" - "ccd_size_divisor: %d\n" - "stagger: %d\n" - "max_shift: %d\n", - setup.pixels, - setup.lines, - setup.depth, - setup.channels, - setup.exposure_time, - setup.xres, setup.yres, - setup.ccd_size_divisor, - setup.stagger, - setup.max_shift); -} diff --git a/backend/genesys_low.h b/backend/genesys_low.h deleted file mode 100644 index e750808..0000000 --- a/backend/genesys_low.h +++ /dev/null @@ -1,2042 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2003 Oliver Rauch - Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de> - Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de> - Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> - Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com> - Parts of the structs have been taken from the gt68xx backend by - Sergey Vlasov <vsu@altlinux.ru> et al. - - This file is part of the SANE package. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - - As a special exception, the authors of SANE give permission for - additional uses of the libraries contained in this release of SANE. - - The exception is that, if you link a SANE library with other files - to produce an executable, this does not by itself cause the - resulting executable to be covered by the GNU General Public - License. Your use of that executable is in no way restricted on - account of linking the SANE library code into it. - - This exception does not, however, invalidate any other reasons why - the executable file might be covered by the GNU General Public - License. - - If you submit changes to SANE to the maintainers to be included in - a subsequent release, you agree by submitting the changes that - those changes may be distributed with this exception intact. - - If you write modifications of your own for SANE, it is your choice - whether to permit this exception to apply to your modifications. - If you do not wish that, delete this exception notice. -*/ - -#ifndef GENESYS_LOW_H -#define GENESYS_LOW_H - - -#include "../include/sane/config.h" - -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <math.h> -#include <stddef.h> -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_MKDIR -#include <sys/stat.h> -#include <sys/types.h> -#endif - -#include "../include/sane/sane.h" -#include "../include/sane/sanei.h" -#include "../include/sane/saneopts.h" - -#include "../include/sane/sanei_backend.h" -#include "../include/sane/sanei_usb.h" - -#include "../include/_stdint.h" - -#include "genesys_error.h" -#include "genesys_sanei.h" -#include "genesys_serialize.h" - -#include <algorithm> -#include <array> -#include <cstring> -#include <functional> -#include <iostream> -#include <limits> -#include <memory> -#include <stdexcept> -#include <string> -#include <vector> - -#define FREE_IFNOT_NULL(x) if(x!=NULL) { free(x); x=NULL;} - -#define GENESYS_RED 0 -#define GENESYS_GREEN 1 -#define GENESYS_BLUE 2 - -/* Flags */ -#define GENESYS_FLAG_UNTESTED (1 << 0) /**< Print a warning for these scanners */ -#define GENESYS_FLAG_14BIT_GAMMA (1 << 1) /**< use 14bit Gamma table instead of 12 */ -#define GENESYS_FLAG_LAZY_INIT (1 << 2) /**< skip extensive ASIC test at init */ -#define GENESYS_FLAG_XPA (1 << 3) -#define GENESYS_FLAG_SKIP_WARMUP (1 << 4) /**< skip genesys_warmup() */ -/** @brief offset calibration flag - * signals that the scanner does offset calibration. In this case off_calibration() and - * coarse_gain_calibration() functions must be implemented - */ -#define GENESYS_FLAG_OFFSET_CALIBRATION (1 << 5) -#define GENESYS_FLAG_SEARCH_START (1 << 6) /**< do start search before scanning */ -#define GENESYS_FLAG_REPARK (1 << 7) /**< repark head (and check for lock) by - moving without scanning */ -#define GENESYS_FLAG_DARK_CALIBRATION (1 << 8) /**< do dark calibration */ -#define GENESYS_FLAG_STAGGERED_LINE (1 << 9) /**< pixel columns are shifted vertically for hi-res modes */ - -#define GENESYS_FLAG_MUST_WAIT (1 << 10) /**< tells wether the scanner must wait for the head when parking */ - - -#define GENESYS_FLAG_HAS_UTA (1 << 11) /**< scanner has a transparency adapter */ - -#define GENESYS_FLAG_DARK_WHITE_CALIBRATION (1 << 12) /**< yet another calibration method. does white and dark shading in one run, depending on a black and a white strip*/ -#define GENESYS_FLAG_CUSTOM_GAMMA (1 << 13) /**< allow custom gamma tables */ -#define GENESYS_FLAG_NO_CALIBRATION (1 << 14) /**< allow scanners to use skip the calibration, needed for sheetfed scanners */ -#define GENESYS_FLAG_SIS_SENSOR (1 << 16) /**< handling of multi-segments sensors in software */ -#define GENESYS_FLAG_SHADING_NO_MOVE (1 << 17) /**< scanner doesn't move sensor during shading calibration */ -#define GENESYS_FLAG_SHADING_REPARK (1 << 18) /**< repark head between shading scans */ -#define GENESYS_FLAG_FULL_HWDPI_MODE (1 << 19) /**< scanner always use maximum hw dpi to setup the sensor */ -// scanner has infrared transparency scanning capability -#define GENESYS_FLAG_HAS_UTA_INFRARED (1 << 20) - -#define GENESYS_HAS_NO_BUTTONS 0 /**< scanner has no supported button */ -#define GENESYS_HAS_SCAN_SW (1 << 0) /**< scanner has SCAN button */ -#define GENESYS_HAS_FILE_SW (1 << 1) /**< scanner has FILE button */ -#define GENESYS_HAS_COPY_SW (1 << 2) /**< scanner has COPY button */ -#define GENESYS_HAS_EMAIL_SW (1 << 3) /**< scanner has EMAIL button */ -#define GENESYS_HAS_PAGE_LOADED_SW (1 << 4) /**< scanner has paper in detection */ -#define GENESYS_HAS_OCR_SW (1 << 5) /**< scanner has OCR button */ -#define GENESYS_HAS_POWER_SW (1 << 6) /**< scanner has power button */ -#define GENESYS_HAS_CALIBRATE (1 << 7) /**< scanner has 'calibrate' software button to start calibration */ -#define GENESYS_HAS_EXTRA_SW (1 << 8) /**< scanner has extra function button */ - -/* USB control message values */ -#define REQUEST_TYPE_IN (USB_TYPE_VENDOR | USB_DIR_IN) -#define REQUEST_TYPE_OUT (USB_TYPE_VENDOR | USB_DIR_OUT) -#define REQUEST_REGISTER 0x0c -#define REQUEST_BUFFER 0x04 -#define VALUE_BUFFER 0x82 -#define VALUE_SET_REGISTER 0x83 -#define VALUE_READ_REGISTER 0x84 -#define VALUE_WRITE_REGISTER 0x85 -#define VALUE_INIT 0x87 -#define GPIO_OUTPUT_ENABLE 0x89 -#define GPIO_READ 0x8a -#define GPIO_WRITE 0x8b -#define VALUE_BUF_ENDACCESS 0x8c -#define VALUE_GET_REGISTER 0x8e -#define INDEX 0x00 - -/* todo: used? -#define VALUE_READ_STATUS 0x86 -*/ - -/* Read/write bulk data/registers */ -#define BULK_OUT 0x01 -#define BULK_IN 0x00 -#define BULK_RAM 0x00 -#define BULK_REGISTER 0x11 - -#define BULKOUT_MAXSIZE 0xF000 - -/* AFE values */ -#define AFE_INIT 1 -#define AFE_SET 2 -#define AFE_POWER_SAVE 4 - -#define LOWORD(x) ((uint16_t)((x) & 0xffff)) -#define HIWORD(x) ((uint16_t)((x) >> 16)) -#define LOBYTE(x) ((uint8_t)((x) & 0xFF)) -#define HIBYTE(x) ((uint8_t)((x) >> 8)) - -/* Global constants */ -/* TODO: emove this leftover of early backend days */ -#define MOTOR_SPEED_MAX 350 -#define DARK_VALUE 0 - -#define PWRBIT 0x80 -#define BUFEMPTY 0x40 -#define FEEDFSH 0x20 -#define SCANFSH 0x10 -#define HOMESNR 0x08 -#define LAMPSTS 0x04 -#define FEBUSY 0x02 -#define MOTORENB 0x01 - -#define GENESYS_MAX_REGS 256 - -enum class ScanMethod : unsigned { - // normal scan method - FLATBED = 0, - // scan using transparency adaptor - TRANSPARENCY = 1, - // scan using transparency adaptor via infrared channel - TRANSPARENCY_INFRARED = 2 -}; - -inline void serialize(std::istream& str, ScanMethod& x) -{ - unsigned value; - serialize(str, value); - x = static_cast<ScanMethod>(value); -} - -inline void serialize(std::ostream& str, ScanMethod& x) -{ - unsigned value = static_cast<unsigned>(x); - serialize(str, value); -} - -enum class ScanColorMode : unsigned { - LINEART = 0, - HALFTONE, - GRAY, - COLOR_SINGLE_PASS -}; - -inline void serialize(std::istream& str, ScanColorMode& x) -{ - unsigned value; - serialize(str, value); - x = static_cast<ScanColorMode>(value); -} - -inline void serialize(std::ostream& str, ScanColorMode& x) -{ - unsigned value = static_cast<unsigned>(x); - serialize(str, value); -} - -enum class ColorFilter : unsigned { - RED = 0, - GREEN, - BLUE, - NONE -}; - -inline void serialize(std::istream& str, ColorFilter& x) -{ - unsigned value; - serialize(str, value); - x = static_cast<ColorFilter>(value); -} - -inline void serialize(std::ostream& str, ColorFilter& x) -{ - unsigned value = static_cast<unsigned>(x); - serialize(str, value); -} - -struct GenesysRegister { - uint16_t address = 0; - uint8_t value = 0; -}; - -inline bool operator<(const GenesysRegister& lhs, const GenesysRegister& rhs) -{ - return lhs.address < rhs.address; -} - -struct GenesysRegisterSetState { - bool is_lamp_on = false; - bool is_xpa_on = false; -}; - -class Genesys_Register_Set { -public: - using container = std::vector<GenesysRegister>; - using iterator = typename container::iterator; - using const_iterator = typename container::const_iterator; - - // FIXME: this shouldn't live here, but in a separate struct that contains Genesys_Register_Set - GenesysRegisterSetState state; - - enum Options { - SEQUENTIAL = 1 - }; - - Genesys_Register_Set() - { - registers_.reserve(GENESYS_MAX_REGS); - } - - // by default the register set is sorted by address. In certain cases it's importand to send - // the registers in certain order: use the SEQUENTIAL option for that - Genesys_Register_Set(Options opts) : Genesys_Register_Set() - { - if ((opts & SEQUENTIAL) == SEQUENTIAL) { - sorted_ = false; - } - } - - void init_reg(uint16_t address, uint8_t default_value) - { - if (find_reg_index(address) >= 0) { - set8(address, default_value); - return; - } - GenesysRegister reg; - reg.address = address; - reg.value = default_value; - registers_.push_back(reg); - if (sorted_) - std::sort(registers_.begin(), registers_.end()); - } - - void remove_reg(uint16_t address) - { - int i = find_reg_index(address); - if (i < 0) { - throw std::runtime_error("the register does not exist"); - } - registers_.erase(registers_.begin() + i); - } - - GenesysRegister& find_reg(uint16_t address) - { - int i = find_reg_index(address); - if (i < 0) { - throw std::runtime_error("the register does not exist"); - } - return registers_[i]; - } - - const GenesysRegister& find_reg(uint16_t address) const - { - int i = find_reg_index(address); - if (i < 0) { - throw std::runtime_error("the register does not exist"); - } - return registers_[i]; - } - - GenesysRegister* find_reg_address(uint16_t address) - { - return &find_reg(address); - } - - const GenesysRegister* find_reg_address(uint16_t address) const - { - return &find_reg(address); - } - - void set8(uint16_t address, uint8_t value) - { - find_reg(address).value = value; - } - - void set8_mask(uint16_t address, uint8_t value, uint8_t mask) - { - auto& reg = find_reg(address); - reg.value = (reg.value & ~mask) | value; - } - - void set16(uint16_t address, uint16_t value) - { - find_reg(address).value = (value >> 8) & 0xff; - find_reg(address + 1).value = value & 0xff; - } - - void set24(uint16_t address, uint32_t value) - { - find_reg(address).value = (value >> 16) & 0xff; - find_reg(address + 1).value = (value >> 8) & 0xff; - find_reg(address + 2).value = value & 0xff; - } - - uint8_t get8(uint16_t address) const - { - return find_reg(address).value; - } - - uint16_t get16(uint16_t address) const - { - return (find_reg(address).value << 8) | find_reg(address + 1).value; - } - - uint32_t get24(uint16_t address) const - { - return (find_reg(address).value << 16) | - (find_reg(address + 1).value << 8) | - find_reg(address + 2).value; - } - - void clear() { registers_.clear(); } - size_t size() const { return registers_.size(); } - - iterator begin() { return registers_.begin(); } - const_iterator begin() const { return registers_.begin(); } - - iterator end() { return registers_.end(); } - const_iterator end() const { return registers_.end(); } - -private: - int find_reg_index(uint16_t address) const - { - if (!sorted_) { - for (size_t i = 0; i < registers_.size(); i++) { - if (registers_[i].address == address) { - return i; - } - } - return -1; - } - - GenesysRegister search; - search.address = address; - auto it = std::lower_bound(registers_.begin(), registers_.end(), search); - if (it == registers_.end()) - return -1; - if (it->address != address) - return -1; - return std::distance(registers_.begin(), it); - } - - // registers are stored in a sorted vector - bool sorted_ = true; - std::vector<GenesysRegister> registers_; -}; - -template<class T, size_t Size> -struct AssignableArray : public std::array<T, Size> { - AssignableArray() = default; - AssignableArray(const AssignableArray&) = default; - AssignableArray& operator=(const AssignableArray&) = default; - - AssignableArray& operator=(std::initializer_list<T> init) - { - if (init.size() != std::array<T, Size>::size()) - throw std::runtime_error("An array of incorrect size assigned"); - std::copy(init.begin(), init.end(), std::array<T, Size>::begin()); - return *this; - } -}; - -struct GenesysRegisterSetting { - GenesysRegisterSetting() = default; - - GenesysRegisterSetting(uint16_t p_address, uint8_t p_value) : - address(p_address), value(p_value) - {} - - GenesysRegisterSetting(uint16_t p_address, uint8_t p_value, uint8_t p_mask) : - address(p_address), value(p_value), mask(p_mask) - {} - - uint16_t address = 0; - uint8_t value = 0; - uint8_t mask = 0xff; - - bool operator==(const GenesysRegisterSetting& other) const - { - return address == other.address && value == other.value && mask == other.mask; - } -}; - -template<class Stream> -void serialize(Stream& str, GenesysRegisterSetting& reg) -{ - serialize(str, reg.address); - serialize(str, reg.value); - serialize(str, reg.mask); -} - -class GenesysRegisterSettingSet { -public: - using container = std::vector<GenesysRegisterSetting>; - using iterator = typename container::iterator; - using const_iterator = typename container::const_iterator; - - GenesysRegisterSettingSet() = default; - GenesysRegisterSettingSet(std::initializer_list<GenesysRegisterSetting> ilist) : regs_(ilist) {} - - iterator begin() { return regs_.begin(); } - const_iterator begin() const { return regs_.begin(); } - iterator end() { return regs_.end(); } - const_iterator end() const { return regs_.end(); } - - GenesysRegisterSetting& operator[](size_t i) { return regs_[i]; } - const GenesysRegisterSetting& operator[](size_t i) const { return regs_[i]; } - - size_t size() const { return regs_.size(); } - bool empty() const { return regs_.empty(); } - void clear() { regs_.clear(); } - - void push_back(GenesysRegisterSetting reg) { regs_.push_back(reg); } - - void merge(const GenesysRegisterSettingSet& other) - { - for (const auto& reg : other) { - set_value(reg.address, reg.value); - } - } - - uint8_t get_value(uint16_t address) const - { - for (const auto& reg : regs_) { - if (reg.address == address) - return reg.value; - } - throw std::runtime_error("Unknown register"); - } - - void set_value(uint16_t address, uint8_t value) - { - for (auto& reg : regs_) { - if (reg.address == address) { - reg.value = value; - return; - } - } - push_back(GenesysRegisterSetting(address, value)); - } - - friend void serialize(std::istream& str, GenesysRegisterSettingSet& reg); - friend void serialize(std::ostream& str, GenesysRegisterSettingSet& reg); - - bool operator==(const GenesysRegisterSettingSet& other) const - { - return regs_ == other.regs_; - } - -private: - std::vector<GenesysRegisterSetting> regs_; -}; - -inline void serialize(std::istream& str, GenesysRegisterSettingSet& reg) -{ - reg.clear(); - const size_t max_register_address = - 1 << (sizeof(GenesysRegisterSetting::address) * CHAR_BIT); - serialize(str, reg.regs_, max_register_address); -} - -inline void serialize(std::ostream& str, GenesysRegisterSettingSet& reg) -{ - serialize(str, reg.regs_); -} - -struct GenesysFrontendLayout -{ - std::array<uint16_t, 3> offset_addr = {}; - std::array<uint16_t, 3> gain_addr = {}; - - bool operator==(const GenesysFrontendLayout& other) const - { - return offset_addr == other.offset_addr && gain_addr == other.gain_addr; - } -}; - -/** @brief Data structure to set up analog frontend. - The analog frontend converts analog value from image sensor to digital value. It has its own - control registers which are set up with this structure. The values are written using - sanei_genesys_fe_write_data. - */ -struct Genesys_Frontend -{ - Genesys_Frontend() = default; - - // id of the frontend description - uint8_t fe_id = 0; - - // all registers of the frontend - GenesysRegisterSettingSet regs; - - // extra control registers - std::array<uint8_t, 3> reg2 = {}; - - GenesysFrontendLayout layout; - - void set_offset(unsigned which, uint8_t value) - { - regs.set_value(layout.offset_addr[which], value); - } - - void set_gain(unsigned which, uint8_t value) - { - regs.set_value(layout.gain_addr[which], value); - } - - uint8_t get_offset(unsigned which) const - { - return regs.get_value(layout.offset_addr[which]); - } - - uint8_t get_gain(unsigned which) const - { - return regs.get_value(layout.gain_addr[which]); - } - - bool operator==(const Genesys_Frontend& other) const - { - return fe_id == other.fe_id && - regs == other.regs && - reg2 == other.reg2 && - layout == other.layout; - } -}; - -template<class Stream> -void serialize(Stream& str, Genesys_Frontend& x) -{ - serialize(str, x.fe_id); - serialize_newline(str); - serialize(str, x.regs); - serialize_newline(str); - serialize(str, x.reg2); - serialize_newline(str); - serialize(str, x.layout.offset_addr); - serialize(str, x.layout.gain_addr); -} - -struct SensorExposure { - uint16_t red, green, blue; -}; - -struct Genesys_Sensor { - - Genesys_Sensor() = default; - ~Genesys_Sensor() = default; - - // id of the sensor description - uint8_t sensor_id = 0; - int optical_res = 0; - - // the minimum and maximum resolution this sensor is usable at. -1 means that the resolution - // can be any. - int min_resolution = -1; - int max_resolution = -1; - - // the scan method used with the sensor - ScanMethod method = ScanMethod::FLATBED; - - // CCD may present itself as half or quarter-size CCD on certain resolutions - int ccd_size_divisor = 1; - - int black_pixels = 0; - // value of the dummy register - int dummy_pixel = 0; - // last pixel of CCD margin at optical resolution - int CCD_start_xoffset = 0; - // total pixels used by the sensor - int sensor_pixels = 0; - // TA CCD target code (reference gain) - int fau_gain_white_ref = 0; - // CCD target code (reference gain) - int gain_white_ref = 0; - - // red, green and blue initial exposure values - SensorExposure exposure; - - int exposure_lperiod = -1; - - GenesysRegisterSettingSet custom_regs; - GenesysRegisterSettingSet custom_fe_regs; - - // red, green and blue gamma coefficient for default gamma tables - AssignableArray<float, 3> gamma; - - int get_ccd_size_divisor_for_dpi(int xres) const - { - if (ccd_size_divisor >= 4 && xres * 4 <= optical_res) { - return 4; - } - if (ccd_size_divisor >= 2 && xres * 2 <= optical_res) { - return 2; - } - return 1; - } - - bool operator==(const Genesys_Sensor& other) const - { - return sensor_id == other.sensor_id && - optical_res == other.optical_res && - min_resolution == other.min_resolution && - max_resolution == other.max_resolution && - method == other.method && - ccd_size_divisor == other.ccd_size_divisor && - black_pixels == other.black_pixels && - dummy_pixel == other.dummy_pixel && - CCD_start_xoffset == other.CCD_start_xoffset && - sensor_pixels == other.sensor_pixels && - fau_gain_white_ref == other.fau_gain_white_ref && - gain_white_ref == other.gain_white_ref && - exposure.blue == other.exposure.blue && - exposure.green == other.exposure.green && - exposure.red == other.exposure.red && - exposure_lperiod == other.exposure_lperiod && - custom_regs == other.custom_regs && - custom_fe_regs == other.custom_fe_regs && - gamma == other.gamma; - } -}; - -template<class Stream> -void serialize(Stream& str, Genesys_Sensor& x) -{ - serialize(str, x.sensor_id); - serialize(str, x.optical_res); - serialize(str, x.min_resolution); - serialize(str, x.max_resolution); - serialize(str, x.method); - serialize(str, x.ccd_size_divisor); - serialize(str, x.black_pixels); - serialize(str, x.dummy_pixel); - serialize(str, x.CCD_start_xoffset); - serialize(str, x.sensor_pixels); - serialize(str, x.fau_gain_white_ref); - serialize(str, x.gain_white_ref); - serialize_newline(str); - serialize(str, x.exposure.blue); - serialize(str, x.exposure.green); - serialize(str, x.exposure.red); - serialize(str, x.exposure_lperiod); - serialize_newline(str); - serialize(str, x.custom_regs); - serialize_newline(str); - serialize(str, x.custom_fe_regs); - serialize_newline(str); - serialize(str, x.gamma); -} - -struct Genesys_Gpo -{ - Genesys_Gpo() = default; - - Genesys_Gpo(uint8_t id, const std::array<uint8_t, 2>& v, const std::array<uint8_t, 2>& e) - { - gpo_id = id; - value[0] = v[0]; - value[1] = v[1]; - enable[0] = e[0]; - enable[1] = e[1]; - } - - // Genesys_Gpo - uint8_t gpo_id = 0; - - // registers 0x6c and 0x6d on GL841, GL842, GL843, GL846, GL848 and possibly others - uint8_t value[2] = { 0, 0 }; - - // registers 0x6e and 0x6f on GL841, GL842, GL843, GL846, GL848 and possibly others - uint8_t enable[2] = { 0, 0 }; -}; - -struct Genesys_Motor_Slope -{ - Genesys_Motor_Slope() = default; - Genesys_Motor_Slope(int p_maximum_start_speed, int p_maximum_speed, int p_minimum_steps, - float p_g) : - maximum_start_speed(p_maximum_start_speed), - maximum_speed(p_maximum_speed), - minimum_steps(p_minimum_steps), - g(p_g) - {} - - // maximum speed allowed when accelerating from standstill. Unit: pixeltime/step - int maximum_start_speed = 0; - // maximum speed allowed. Unit: pixeltime/step - int maximum_speed = 0; - // number of steps used for default curve - int minimum_steps = 0; - - /* power for non-linear acceleration curves. - vs*(1-i^g)+ve*(i^g) where - vs = start speed, ve = end speed, - i = 0.0 for first entry and i = 1.0 for last entry in default table - */ - float g = 0; -}; - - -struct Genesys_Motor -{ - Genesys_Motor() = default; - Genesys_Motor(uint8_t p_motor_id, int p_base_ydpi, int p_optical_ydpi, int p_max_step_type, - int p_power_mode_count, - const std::vector<std::vector<Genesys_Motor_Slope>>& p_slopes) : - motor_id(p_motor_id), - base_ydpi(p_base_ydpi), - optical_ydpi(p_optical_ydpi), - max_step_type(p_max_step_type), - power_mode_count(p_power_mode_count), - slopes(p_slopes) - {} - - // id of the motor description - uint8_t motor_id = 0; - // motor base steps. Unit: 1/inch - int base_ydpi = 0; - // maximum resolution in y-direction. Unit: 1/inch - int optical_ydpi = 0; - // maximum step type. 0-2 - int max_step_type = 0; - // number of power modes - int power_mode_count = 0; - // slopes to derive individual slopes from - std::vector<std::vector<Genesys_Motor_Slope>> slopes; -}; - -typedef enum Genesys_Color_Order -{ - COLOR_ORDER_RGB, - COLOR_ORDER_BGR -} -Genesys_Color_Order; - - -#define MAX_RESOLUTIONS 13 -#define MAX_DPI 4 - -#define GENESYS_GL646 646 -#define GENESYS_GL841 841 -#define GENESYS_GL843 843 -#define GENESYS_GL845 845 -#define GENESYS_GL846 846 -#define GENESYS_GL847 847 -#define GENESYS_GL848 848 -#define GENESYS_GL123 123 -#define GENESYS_GL124 124 - -enum Genesys_Model_Type -{ - MODEL_UMAX_ASTRA_4500 = 0, - MODEL_CANON_LIDE_50, - MODEL_PANASONIC_KV_SS080, - MODEL_HP_SCANJET_4850C, - MODEL_HP_SCANJET_G4010, - MODEL_HP_SCANJET_G4050, - MODEL_CANON_CANOSCAN_4400F, - MODEL_CANON_CANOSCAN_8400F, - MODEL_CANON_CANOSCAN_8600F, - MODEL_CANON_LIDE_100, - MODEL_CANON_LIDE_110, - MODEL_CANON_LIDE_120, - MODEL_CANON_LIDE_210, - MODEL_CANON_LIDE_220, - MODEL_CANON_CANOSCAN_5600F, - MODEL_CANON_LIDE_700F, - MODEL_CANON_LIDE_200, - MODEL_CANON_LIDE_60, - MODEL_CANON_LIDE_80, - MODEL_HP_SCANJET_2300C, - MODEL_HP_SCANJET_2400C, - MODEL_VISIONEER_STROBE_XP200, - MODEL_HP_SCANJET_3670C, - MODEL_PLUSTEK_OPTICPRO_ST12, - MODEL_PLUSTEK_OPTICPRO_ST24, - MODEL_MEDION_MD5345, - MODEL_VISIONEER_STROBE_XP300, - MODEL_SYSCAN_DOCKETPORT_665, - MODEL_VISIONEER_ROADWARRIOR, - MODEL_SYSCAN_DOCKETPORT_465, - MODEL_VISIONEER_STROBE_XP100_REVISION3, - MODEL_PENTAX_DSMOBILE_600, - MODEL_SYSCAN_DOCKETPORT_467, - MODEL_SYSCAN_DOCKETPORT_685, - MODEL_SYSCAN_DOCKETPORT_485, - MODEL_DCT_DOCKETPORT_487, - MODEL_VISIONEER_7100, - MODEL_XEROX_2400, - MODEL_XEROX_TRAVELSCANNER_100, - MODEL_PLUSTEK_OPTICPRO_3600, - MODEL_HP_SCANJET_N6310, - MODEL_PLUSTEK_OPTICBOOK_3800, - MODEL_CANON_IMAGE_FORMULA_101 -}; - -enum Genesys_Dac_Type -{ - DAC_WOLFSON_UMAX = 0, - DAC_WOLFSON_ST12, - DAC_WOLFSON_ST24, - DAC_WOLFSON_5345, - DAC_WOLFSON_HP2400, - DAC_WOLFSON_HP2300, - DAC_CANONLIDE35, - DAC_AD_XP200, - DAC_WOLFSON_XP300, - DAC_WOLFSON_HP3670, - DAC_WOLFSON_DSM600, - DAC_CANONLIDE200, - DAC_KVSS080, - DAC_G4050, - DAC_CANONLIDE110, - DAC_PLUSTEK_3600, - DAC_CANONLIDE700, - DAC_CS8400F, - DAC_CS8600F, - DAC_IMG101, - DAC_PLUSTEK3800, - DAC_CANONLIDE80, - DAC_CANONLIDE120 -}; - -enum Genesys_Sensor_Type -{ - CCD_UMAX = 0, - CCD_ST12, // SONY ILX548: 5340 Pixel ??? - CCD_ST24, // SONY ILX569: 10680 Pixel ??? - CCD_5345, - CCD_HP2400, - CCD_HP2300, - CCD_CANONLIDE35, - CIS_XP200, // CIS sensor for Strobe XP200, - CCD_HP3670, - CCD_DP665, - CCD_ROADWARRIOR, - CCD_DSMOBILE600, - CCD_XP300, - CCD_DP685, - CIS_CANONLIDE200, - CIS_CANONLIDE100, - CCD_KVSS080, - CCD_G4050, - CIS_CANONLIDE110, - CCD_PLUSTEK_3600, - CCD_HP_N6310, - CIS_CANONLIDE700, - CCD_CS4400F, - CCD_CS8400F, - CCD_CS8600F, - CCD_IMG101, - CCD_PLUSTEK3800, - CIS_CANONLIDE210, - CIS_CANONLIDE80, - CIS_CANONLIDE220, - CIS_CANONLIDE120, -}; - -enum Genesys_Gpo_Type -{ - GPO_UMAX, - GPO_ST12, - GPO_ST24, - GPO_5345, - GPO_HP2400, - GPO_HP2300, - GPO_CANONLIDE35, - GPO_XP200, - GPO_XP300, - GPO_HP3670, - GPO_DP665, - GPO_DP685, - GPO_CANONLIDE200, - GPO_KVSS080, - GPO_G4050, - GPO_CANONLIDE110, - GPO_PLUSTEK_3600, - GPO_CANONLIDE210, - GPO_HP_N6310, - GPO_CANONLIDE700, - GPO_CS4400F, - GPO_CS8400F, - GPO_CS8600F, - GPO_IMG101, - GPO_PLUSTEK3800, - GPO_CANONLIDE80, - GPO_CANONLIDE120 -}; - -enum Genesys_Motor_Type -{ - MOTOR_UMAX = 0, - MOTOR_5345, - MOTOR_ST24, - MOTOR_HP2400, - MOTOR_HP2300, - MOTOR_CANONLIDE35, - MOTOR_XP200, - MOTOR_XP300, - MOTOR_HP3670, - MOTOR_DP665, - MOTOR_ROADWARRIOR, - MOTOR_DSMOBILE_600, - MOTOR_CANONLIDE200, - MOTOR_CANONLIDE100, - MOTOR_KVSS080, - MOTOR_G4050, - MOTOR_CANONLIDE110, - MOTOR_PLUSTEK_3600, - MOTOR_CANONLIDE700, - MOTOR_CS8400F, - MOTOR_CS8600F, - MOTOR_IMG101, - MOTOR_PLUSTEK3800, - MOTOR_CANONLIDE210, - MOTOR_CANONLIDE80, - MOTOR_CANONLIDE120 -}; - -/* Forward typedefs */ -typedef struct Genesys_Device Genesys_Device; -struct Genesys_Scanner; -typedef struct Genesys_Calibration_Cache Genesys_Calibration_Cache; - -/** - * Scanner command set description. - * - * This description contains parts which are common to all scanners with the - * same command set, but may have different optical resolution and other - * parameters. - */ -typedef struct Genesys_Command_Set -{ - /** @name Identification */ - /*@{ */ - - /** Name of this command set */ - SANE_String_Const name; - - /*@} */ - - bool (*needs_home_before_init_regs_for_scan) (Genesys_Device* dev); - - /** For ASIC initialization */ - SANE_Status (*init) (Genesys_Device * dev); - - SANE_Status (*init_regs_for_warmup) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, - int *channels, int *total_size); - SANE_Status (*init_regs_for_coarse_calibration) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - SANE_Status (*init_regs_for_shading) (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - SANE_Status (*init_regs_for_scan) (Genesys_Device * dev, const Genesys_Sensor& sensor); - - SANE_Bool (*get_filter_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_lineart_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_bitset_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_gain4_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_fast_feed_bit) (Genesys_Register_Set * reg); - - SANE_Bool (*test_buffer_empty_bit) (SANE_Byte val); - SANE_Bool (*test_motor_flag_bit) (SANE_Byte val); - - SANE_Status (*set_fe) (Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set); - SANE_Status (*set_powersaving) (Genesys_Device * dev, int delay); - SANE_Status (*save_power) (Genesys_Device * dev, SANE_Bool enable); - - SANE_Status (*begin_scan) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, - SANE_Bool start_motor); - SANE_Status (*end_scan) (Genesys_Device * dev, - Genesys_Register_Set * regs, - SANE_Bool check_stop); - - /** - * Send gamma tables to ASIC - */ - SANE_Status (*send_gamma_table) (Genesys_Device * dev, const Genesys_Sensor& sensor); - - SANE_Status (*search_start_position) (Genesys_Device * dev); - SANE_Status (*offset_calibration) (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - SANE_Status (*coarse_gain_calibration) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi); - SANE_Status (*led_calibration) (Genesys_Device * dev, Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - - void (*wait_for_motor_stop) (Genesys_Device* dev); - SANE_Status (*slow_back_home) (Genesys_Device * dev, SANE_Bool wait_until_home); - SANE_Status (*rewind) (Genesys_Device * dev); - - SANE_Status (*bulk_write_register) (Genesys_Device * dev, - Genesys_Register_Set& regs); - - SANE_Status (*bulk_write_data) (Genesys_Device * dev, uint8_t addr, - uint8_t * data, size_t len); - - SANE_Status (*bulk_read_data) (Genesys_Device * dev, uint8_t addr, - uint8_t * data, size_t len); - - // Updates hardware sensor information in Genesys_Scanner.val[]. - SANE_Status (*update_hardware_sensors) (struct Genesys_Scanner * s); - - /* functions for sheetfed scanners */ - /** - * load document into scanner - */ - SANE_Status (*load_document) (Genesys_Device * dev); - /** - * detects is the scanned document has left scanner. In this - * case it updates the amount of data to read and set up - * flags in the dev struct - */ - SANE_Status (*detect_document_end) (Genesys_Device * dev); - /** - * eject document from scanner - */ - SANE_Status (*eject_document) (Genesys_Device * dev); - /** - * search for an black or white area in forward or reverse - * direction */ - SANE_Status (*search_strip) (Genesys_Device * dev, const Genesys_Sensor& sensor, - SANE_Bool forward, SANE_Bool black); - - bool (*is_compatible_calibration) (Genesys_Device* dev, const Genesys_Sensor& sensor, - Genesys_Calibration_Cache* cache, SANE_Bool for_overwrite); - - /* functions for transparency adapter */ - /** - * move scanning head to transparency adapter - */ - SANE_Status (*move_to_ta) (Genesys_Device * dev); - - /** - * write shading data calibration to ASIC - */ - SANE_Status (*send_shading_data) (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size); - - // calculate current scan setup - void (*calculate_current_setup) (Genesys_Device * dev, const Genesys_Sensor& sensor); - - /** - * cold boot init function - */ - SANE_Status (*asic_boot) (Genesys_Device * dev, SANE_Bool cold); - -} Genesys_Command_Set; - -/** @brief structure to describe a scanner model - * This structure describes a model. It is composed of information on the - * sensor, the motor, scanner geometry and flags to drive operation. - */ -typedef struct Genesys_Model -{ - SANE_String_Const name; - SANE_String_Const vendor; - SANE_String_Const model; - SANE_Int model_id; - - SANE_Int asic_type; /* ASIC type gl646 or gl841 */ - Genesys_Command_Set *cmd_set; /* pointers to low level functions */ - - SANE_Int xdpi_values[MAX_RESOLUTIONS]; /* possible x resolutions */ - SANE_Int ydpi_values[MAX_RESOLUTIONS]; /* possible y resolutions */ - SANE_Int bpp_gray_values[MAX_DPI]; /* possible depths in gray mode */ - SANE_Int bpp_color_values[MAX_DPI]; /* possible depths in color mode */ - - SANE_Fixed x_offset; /* Start of scan area in mm */ - SANE_Fixed y_offset; /* Start of scan area in mm (Amount of - feeding needed to get to the medium) */ - SANE_Fixed x_size; /* Size of scan area in mm */ - SANE_Fixed y_size; /* Size of scan area in mm */ - - SANE_Fixed y_offset_calib; /* Start of white strip in mm */ - SANE_Fixed x_offset_mark; /* Start of black mark in mm */ - - SANE_Fixed x_offset_ta; /* Start of scan area in TA mode in mm */ - SANE_Fixed y_offset_ta; /* Start of scan area in TA mode in mm */ - SANE_Fixed x_size_ta; /* Size of scan area in TA mode in mm */ - SANE_Fixed y_size_ta; /* Size of scan area in TA mode in mm */ - - SANE_Fixed y_offset_calib_ta; /* Start of white strip in TA mode in mm */ - - SANE_Fixed post_scan; /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_Fixed eject_feed; /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - /* Line-distance correction (in pixel at optical_ydpi) for CCD scanners */ - SANE_Int ld_shift_r; /* red */ - SANE_Int ld_shift_g; /* green */ - SANE_Int ld_shift_b; /* blue */ - - Genesys_Color_Order line_mode_color_order; /* Order of the CCD/CIS colors */ - - SANE_Bool is_cis; /* Is this a CIS or CCD scanner? */ - SANE_Bool is_sheetfed; /* Is this sheetfed scanner? */ - - SANE_Int ccd_type; /* which SENSOR type do we have ? */ - SANE_Int dac_type; /* which DAC do we have ? */ - SANE_Int gpo_type; /* General purpose output type */ - SANE_Int motor_type; /* stepper motor type */ - SANE_Word flags; /* Which hacks are needed for this scanner? */ - SANE_Word buttons; /* Button flags, described existing buttons for the model */ - /*@} */ - SANE_Int shading_lines; /* how many lines are used for shading calibration */ - SANE_Int shading_ta_lines; // how many lines are used for shading calibration in TA mode - SANE_Int search_lines; /* how many lines are used to search start position */ -} Genesys_Model; - -struct Genesys_Settings -{ - ScanMethod scan_method = ScanMethod::FLATBED; - ScanColorMode scan_mode = ScanColorMode::LINEART; - - // horizontal dpi - int xres = 0; - // vertical dpi - int yres = 0; - - //x start on scan table in mm - double tl_x = 0; - // y start on scan table in mm - double tl_y = 0; - - // number of lines at scan resolution - unsigned int lines = 0; - // number of pixels at scan resolution - unsigned int pixels = 0; - - // bit depth of the scan - unsigned int depth = 0; - - ColorFilter color_filter = ColorFilter::NONE; - - // true if scan is true gray, false if monochrome scan - int true_gray = 0; - - // lineart threshold - int threshold = 0; - - // lineart threshold curve for dynamic rasterization - int threshold_curve = 0; - - // Disable interpolation for xres<yres - int disable_interpolation = 0; - - // true is lineart is generated from gray data by the dynamic rasterization algoright - int dynamic_lineart = 0; - - // value for contrast enhancement in the [-100..100] range - int contrast = 0; - - // value for brightness enhancement in the [-100..100] range - int brightness = 0; - - // cache entries expiration time - int expiration_time = 0; -}; - -struct SetupParams { - - static constexpr unsigned NOT_SET = std::numeric_limits<unsigned>::max(); - - // resolution in x direction - unsigned xres = NOT_SET; - // resolution in y direction - unsigned yres = NOT_SET; - // start pixel in X direction, from dummy_pixel + 1 - float startx = -1; - // start pixel in Y direction, counted according to base_ydpi - float starty = -1; - // the number of pixels in X direction - unsigned pixels = NOT_SET; - // the number of pixels in Y direction - unsigned lines = NOT_SET; - // the depth of the scan in bits. Allowed are 1, 8, 16 - unsigned depth = NOT_SET; - // the number of channels - unsigned channels = NOT_SET; - - ScanMethod scan_method = static_cast<ScanMethod>(NOT_SET); - - ScanColorMode scan_mode = static_cast<ScanColorMode>(NOT_SET); - - ColorFilter color_filter = static_cast<ColorFilter>(NOT_SET); - - unsigned flags = NOT_SET; - - void assert_valid() const - { - if (xres == NOT_SET || yres == NOT_SET || startx < 0 || starty < 0 || - pixels == NOT_SET || lines == NOT_SET ||depth == NOT_SET || channels == NOT_SET || - scan_method == static_cast<ScanMethod>(NOT_SET) || - scan_mode == static_cast<ScanColorMode>(NOT_SET) || - color_filter == static_cast<ColorFilter>(NOT_SET) || - flags == NOT_SET) - { - throw std::runtime_error("SetupParams are not valid"); - } - } - - bool operator==(const SetupParams& other) const - { - return xres == other.xres && - yres == other.yres && - startx == other.startx && - starty == other.starty && - pixels == other.pixels && - lines == other.lines && - depth == other.depth && - channels == other.channels && - scan_method == other.scan_method && - scan_mode == other.scan_mode && - color_filter == other.color_filter && - flags == other.flags; - } -}; - -template<class Stream> -void serialize(Stream& str, SetupParams& x) -{ - serialize(str, x.xres); - serialize(str, x.yres); - serialize(str, x.startx); - serialize(str, x.starty); - serialize(str, x.pixels); - serialize(str, x.lines); - serialize(str, x.depth); - serialize(str, x.channels); - serialize(str, x.scan_method); - serialize(str, x.scan_mode); - serialize(str, x.color_filter); - serialize(str, x.flags); -} - -struct Genesys_Current_Setup -{ - // params used for this setup - SetupParams params; - - // pixel count expected from scanner - int pixels = 0; - // line count expected from scanner - int lines = 0; - // depth expected from scanner - int depth = 0; - // channel count expected from scanner - int channels = 0; - - // used exposure time - int exposure_time = 0; - // used xres - float xres = 0; - // used yres - float yres = 0; - // half ccd mode - unsigned ccd_size_divisor = 1; - SANE_Int stagger = 0; - // max shift of any ccd component, including staggered pixels - SANE_Int max_shift = 0; - - bool operator==(const Genesys_Current_Setup& other) const - { - return params == other.params && - pixels == other.pixels && - lines == other.lines && - depth == other.depth && - channels == other.channels && - exposure_time == other.exposure_time && - xres == other.xres && - yres == other.yres && - ccd_size_divisor == other.ccd_size_divisor && - stagger == other.stagger && - max_shift == other.max_shift; - } -}; - -template<class Stream> -void serialize(Stream& str, Genesys_Current_Setup& x) -{ - serialize(str, x.params); - serialize_newline(str); - serialize(str, x.pixels); - serialize(str, x.lines); - serialize(str, x.depth); - serialize(str, x.channels); - serialize(str, x.exposure_time); - serialize(str, x.xres); - serialize(str, x.yres); - serialize(str, x.ccd_size_divisor); - serialize(str, x.stagger); - serialize(str, x.max_shift); -} - -struct Genesys_Buffer -{ - Genesys_Buffer() = default; - - size_t size() const { return buffer_.size(); } - size_t avail() const { return avail_; } - size_t pos() const { return pos_; } - - // TODO: refactor code that uses this function to no longer use it - void set_pos(size_t pos) { pos_ = pos; } - - void alloc(size_t size); - void clear(); - - void reset(); - - uint8_t* get_write_pos(size_t size); - uint8_t* get_read_pos(); // TODO: mark as const - - void produce(size_t size); - void consume(size_t size); - -private: - std::vector<uint8_t> buffer_; - // current position in read buffer - size_t pos_ = 0; - // data bytes currently in buffer - size_t avail_ = 0; -}; - -struct Genesys_Calibration_Cache -{ - Genesys_Calibration_Cache() = default; - ~Genesys_Calibration_Cache() = default; - - // used to check if entry is compatible - Genesys_Current_Setup used_setup; - time_t last_calibration = 0; - - Genesys_Frontend frontend; - Genesys_Sensor sensor; - - size_t calib_pixels = 0; - size_t calib_channels = 0; - size_t average_size = 0; - std::vector<uint8_t> white_average_data; - std::vector<uint8_t> dark_average_data; - - bool operator==(const Genesys_Calibration_Cache& other) const - { - return used_setup == other.used_setup && - last_calibration == other.last_calibration && - frontend == other.frontend && - sensor == other.sensor && - calib_pixels == other.calib_pixels && - calib_channels == other.calib_channels && - average_size == other.average_size && - white_average_data == other.white_average_data && - dark_average_data == other.dark_average_data; - } -}; - -template<class Stream> -void serialize(Stream& str, Genesys_Calibration_Cache& x) -{ - serialize(str, x.used_setup); - serialize_newline(str); - serialize(str, x.last_calibration); - serialize_newline(str); - serialize(str, x.frontend); - serialize_newline(str); - serialize(str, x.sensor); - serialize_newline(str); - serialize(str, x.calib_pixels); - serialize(str, x.calib_channels); - serialize(str, x.average_size); - serialize_newline(str); - serialize(str, x.white_average_data); - serialize_newline(str); - serialize(str, x.dark_average_data); -} - -/** - * Describes the current device status for the backend - * session. This should be more accurately called - * Genesys_Session . - */ -struct Genesys_Device -{ - Genesys_Device() = default; - ~Genesys_Device(); - - using Calibration = std::vector<Genesys_Calibration_Cache>; - - // frees commonly used data - void clear(); - - UsbDevice usb_dev; - SANE_Word vendorId = 0; /**< USB vendor identifier */ - SANE_Word productId = 0; /**< USB product identifier */ - - // USB mode: - // 0: not set - // 1: USB 1.1 - // 2: USB 2.0 - SANE_Int usb_mode = 0; - - SANE_String file_name = nullptr; - std::string calib_file; - - // if enabled, no calibration data will be loaded or saved to files - SANE_Int force_calibration = 0; - Genesys_Model *model = nullptr; - - Genesys_Register_Set reg; - Genesys_Register_Set calib_reg; - Genesys_Settings settings; - Genesys_Frontend frontend, frontend_initial; - Genesys_Gpo gpo; - Genesys_Motor motor; - uint8_t control[6] = {}; - time_t init_date = 0; - - size_t average_size = 0; - // number of pixels used during shading calibration - size_t calib_pixels = 0; - // number of lines used during shading calibration - size_t calib_lines = 0; - size_t calib_channels = 0; - size_t calib_resolution = 0; - // bytes to read from USB when calibrating. If 0, this is not set - size_t calib_total_bytes_to_read = 0; - // certain scanners support much higher resolution when scanning transparency, but we can't - // read whole width of the scanner as a single line at that resolution. Thus for stuff like - // calibration we want to read only the possible calibration area. - size_t calib_pixels_offset = 0; - - // gamma overrides. If a respective array is not empty then it means that the gamma for that - // color is overridden. - std::vector<uint16_t> gamma_override_tables[3]; - - std::vector<uint8_t> white_average_data; - std::vector<uint8_t> dark_average_data; - uint16_t dark[3] = {}; - - SANE_Bool already_initialized = 0; - SANE_Int scanhead_position_in_steps = 0; - SANE_Int lamp_off_time = 0; - - SANE_Bool read_active = 0; - // signal wether the park command has been issued - SANE_Bool parking = 0; - - // for sheetfed scanner's, is TRUE when there is a document in the scanner - SANE_Bool document = 0; - - SANE_Bool needs_home_ta = 0; - - Genesys_Buffer read_buffer; - Genesys_Buffer lines_buffer; - Genesys_Buffer shrink_buffer; - Genesys_Buffer out_buffer; - - // buffer for digital lineart from gray data - Genesys_Buffer binarize_buffer = {}; - // local buffer for gray data during dynamix lineart - Genesys_Buffer local_buffer = {}; - - // bytes to read from scanner - size_t read_bytes_left = 0; - - // total bytes read sent to frontend - size_t total_bytes_read = 0; - // total bytes read to be sent to frontend - size_t total_bytes_to_read = 0; - // asic's word per line - size_t wpl = 0; - - // contains the real used values - Genesys_Current_Setup current_setup; - - // look up table used in dynamic rasterization - unsigned char lineart_lut[256] = {}; - - Calibration calibration_cache; - - // used red line-distance shift - SANE_Int ld_shift_r = 0; - // used green line-distance shift - SANE_Int ld_shift_g = 0; - // used blue line-distance shift - SANE_Int ld_shift_b = 0; - // number of segments composing the sensor - int segnb = 0; - // number of lines used in line interpolation - int line_interp = 0; - // number of scan lines used during scan - int line_count = 0; - // bytes per full scan widthline - size_t bpl = 0; - // bytes distance between an odd and an even pixel - size_t dist = 0; - // number of even pixels - size_t len = 0; - // current pixel position within sub window - size_t cur = 0; - // number of bytes to skip at start of line - size_t skip = 0; - - // array describing the order of the sub-segments of the sensor - size_t* order = nullptr; - - // buffer to handle even/odd data - Genesys_Buffer oe_buffer = {}; - - // when true the scanned picture is first buffered to allow software image enhancements - SANE_Bool buffer_image = 0; - - // image buffer where the scanned picture is stored - std::vector<uint8_t> img_buffer; - - // binary logger file - FILE *binary = nullptr; -}; - -typedef struct Genesys_USB_Device_Entry -{ - SANE_Word vendor; /**< USB vendor identifier */ - SANE_Word product; /**< USB product identifier */ - Genesys_Model *model; /**< Scanner model information */ -} Genesys_USB_Device_Entry; - -/** - * structure for motor database - */ -typedef struct { - int motor_type; /**< motor id */ - int exposure; /**< exposure for the slope table */ - int step_type; /**< default step type for given exposure */ - uint32_t *table; // 0-terminated slope table at full step (i.e. step_type == 0) -} Motor_Profile; - -#define FULL_STEP 0 -#define HALF_STEP 1 -#define QUARTER_STEP 2 -#define EIGHTH_STEP 3 - -#define SLOPE_TABLE_SIZE 1024 - -#define SCAN_TABLE 0 /* table 1 at 0x4000 for gl124 */ -#define BACKTRACK_TABLE 1 /* table 2 at 0x4800 for gl124 */ -#define STOP_TABLE 2 /* table 3 at 0x5000 for gl124 */ -#define FAST_TABLE 3 /* table 4 at 0x5800 for gl124 */ -#define HOME_TABLE 4 /* table 5 at 0x6000 for gl124 */ - -#define SCAN_FLAG_SINGLE_LINE 0x001 -#define SCAN_FLAG_DISABLE_SHADING 0x002 -#define SCAN_FLAG_DISABLE_GAMMA 0x004 -#define SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE 0x008 -#define SCAN_FLAG_IGNORE_LINE_DISTANCE 0x010 -#define SCAN_FLAG_USE_OPTICAL_RES 0x020 -#define SCAN_FLAG_DISABLE_LAMP 0x040 -#define SCAN_FLAG_DYNAMIC_LINEART 0x080 -#define SCAN_FLAG_CALIBRATION 0x100 -#define SCAN_FLAG_FEEDING 0x200 -#define SCAN_FLAG_USE_XPA 0x400 -#define SCAN_FLAG_ENABLE_LEDADD 0x800 -#define MOTOR_FLAG_AUTO_GO_HOME 0x01 -#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 0x02 -#define MOTOR_FLAG_FEED 0x04 -#define MOTOR_FLAG_USE_XPA 0x08 - -/** @name "Optical flags" */ -/*@{ optical flags available when setting up sensor for scan */ - -#define OPTICAL_FLAG_DISABLE_GAMMA 0x01 /**< disable gamma correction */ -#define OPTICAL_FLAG_DISABLE_SHADING 0x02 /**< disable shading correction */ -#define OPTICAL_FLAG_DISABLE_LAMP 0x04 /**< turn off lamp */ -#define OPTICAL_FLAG_ENABLE_LEDADD 0x08 /**< enable true CIS gray by enabling LED addition */ -#define OPTICAL_FLAG_DISABLE_DOUBLE 0x10 /**< disable automatic x-direction double data expansion */ -#define OPTICAL_FLAG_STAGGER 0x20 /**< disable stagger correction */ -#define OPTICAL_FLAG_USE_XPA 0x40 /**< use XPA lamp rather than regular one */ - -/*@} */ - -/*--------------------------------------------------------------------------*/ -/* common functions needed by low level specific functions */ -/*--------------------------------------------------------------------------*/ - -inline GenesysRegister* sanei_genesys_get_address(Genesys_Register_Set* regs, uint16_t addr) -{ - auto* ret = regs->find_reg_address(addr); - if (ret == nullptr) { - DBG(DBG_error, "%s: failed to find address for register 0x%02x, crash expected !\n", - __func__, addr); - } - return ret; -} - -inline uint8_t sanei_genesys_read_reg_from_set(Genesys_Register_Set* regs, uint16_t address) -{ - return regs->get8(address); -} - -inline void sanei_genesys_set_reg_from_set(Genesys_Register_Set* regs, uint16_t address, - uint8_t value) -{ - regs->set8(address, value); -} - -extern SANE_Status sanei_genesys_init_cmd_set (Genesys_Device * dev); - -extern SANE_Status -sanei_genesys_read_register (Genesys_Device * dev, uint16_t reg, uint8_t * val); - -extern SANE_Status -sanei_genesys_write_register (Genesys_Device * dev, uint16_t reg, uint8_t val); - -extern SANE_Status -sanei_genesys_read_hregister (Genesys_Device * dev, uint16_t reg, uint8_t * val); - -extern SANE_Status -sanei_genesys_write_hregister (Genesys_Device * dev, uint16_t reg, uint8_t val); - -extern SANE_Status -sanei_genesys_bulk_write_register(Genesys_Device * dev, - Genesys_Register_Set& regs); - -extern SANE_Status sanei_genesys_write_0x8c (Genesys_Device * dev, uint8_t index, uint8_t val); - -extern unsigned sanei_genesys_get_bulk_max_size(Genesys_Device * dev); - -extern SANE_Status sanei_genesys_bulk_read_data(Genesys_Device * dev, uint8_t addr, uint8_t* data, - size_t len); - -extern SANE_Status sanei_genesys_bulk_write_data(Genesys_Device * dev, uint8_t addr, uint8_t* data, - size_t len); - -extern SANE_Status sanei_genesys_get_status (Genesys_Device * dev, uint8_t * status); - -extern void sanei_genesys_print_status (uint8_t val); - -extern SANE_Status -sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t size, uint8_t * data); - -extern void sanei_genesys_init_structs (Genesys_Device * dev); - -const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev); -Genesys_Sensor& sanei_genesys_find_sensor_any_for_write(Genesys_Device* dev); -const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, int dpi, - ScanMethod scan_method = ScanMethod::FLATBED); -Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, int dpi, - ScanMethod scan_method = ScanMethod::FLATBED); - -extern SANE_Status -sanei_genesys_init_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - int pixels_per_line); - -extern SANE_Status sanei_genesys_read_valid_words (Genesys_Device * dev, - unsigned int *steps); - -extern SANE_Status sanei_genesys_read_scancnt (Genesys_Device * dev, - unsigned int *steps); - -extern SANE_Status sanei_genesys_read_feed_steps (Genesys_Device * dev, - unsigned int *steps); - -void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, bool set); - -void sanei_genesys_set_motor_power(Genesys_Register_Set& regs, bool set); - -extern void -sanei_genesys_calculate_zmode2 (SANE_Bool two_table, - uint32_t exposure_time, - uint16_t * slope_table, - int reg21, - int move, int reg22, uint32_t * z1, - uint32_t * z2); - -extern void -sanei_genesys_calculate_zmode (uint32_t exposure_time, - uint32_t steps_sum, - uint16_t last_speed, uint32_t feedl, - uint8_t fastfed, uint8_t scanfed, - uint8_t fwdstep, uint8_t tgtime, - uint32_t * z1, uint32_t * z2); - -extern SANE_Status -sanei_genesys_set_buffer_address (Genesys_Device * dev, uint32_t addr); - -/** @brief Reads data from frontend register. - * Reads data from the given frontend register. May be used to query - * analog frontend status by reading the right register. - */ -extern SANE_Status -sanei_genesys_fe_read_data (Genesys_Device * dev, uint8_t addr, - uint16_t *data); -/** @brief Write data to frontend register. - * Writes data to analog frontend register at the given address. - * The use and address of registers change from model to model. - */ -extern SANE_Status -sanei_genesys_fe_write_data (Genesys_Device * dev, uint8_t addr, - uint16_t data); - -extern SANE_Int -sanei_genesys_exposure_time2 (Genesys_Device * dev, - float ydpi, int step_type, int endpixel, - int led_exposure, int power_mode); - -extern SANE_Int -sanei_genesys_exposure_time (Genesys_Device * dev, Genesys_Register_Set * reg, - int xdpi); -extern SANE_Int -sanei_genesys_generate_slope_table (uint16_t * slope_table, unsigned int max_steps, - unsigned int use_steps, uint16_t stop_at, - uint16_t vstart, uint16_t vend, - unsigned int steps, double g, - unsigned int *used_steps, unsigned int *vfinal); - -extern SANE_Int -sanei_genesys_create_slope_table (Genesys_Device * dev, - uint16_t * slope_table, int steps, - int step_type, int exposure_time, - SANE_Bool same_speed, double yres, - int power_mode); - -SANE_Int -sanei_genesys_create_slope_table3 (Genesys_Device * dev, - uint16_t * slope_table, int max_step, - unsigned int use_steps, - int step_type, int exposure_time, - double yres, - unsigned int *used_steps, - unsigned int *final_exposure, - int power_mode); - -void sanei_genesys_create_default_gamma_table(Genesys_Device* dev, - std::vector<uint16_t>& gamma_table, float gamma); - -std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor, - int color); - -SANE_Status sanei_genesys_send_gamma_table(Genesys_Device * dev, const Genesys_Sensor& sensor); - -extern SANE_Status sanei_genesys_start_motor (Genesys_Device * dev); - -extern SANE_Status sanei_genesys_stop_motor (Genesys_Device * dev); - -extern SANE_Status -sanei_genesys_search_reference_point(Genesys_Device * dev, Genesys_Sensor& sensor, - uint8_t * data, - int start_pixel, int dpi, int width, - int height); - -extern SANE_Status sanei_genesys_write_file(const char *filename, uint8_t* data, size_t length); - -extern SANE_Status -sanei_genesys_write_pnm_file (const char *filename, uint8_t * data, int depth, - int channels, int pixels_per_line, int lines); - -extern SANE_Status -sanei_genesys_test_buffer_empty (Genesys_Device * dev, SANE_Bool * empty); - -extern SANE_Status -sanei_genesys_read_data_from_scanner (Genesys_Device * dev, uint8_t * data, - size_t size); - -inline void sanei_genesys_set_double(Genesys_Register_Set* regs, uint16_t addr, uint16_t value) -{ - regs->set16(addr, value); -} - -inline void sanei_genesys_set_triple(Genesys_Register_Set* regs, uint16_t addr, uint32_t value) -{ - regs->set24(addr, value); -} - -inline void sanei_genesys_get_double(Genesys_Register_Set* regs, uint16_t addr, uint16_t* value) -{ - *value = regs->get16(addr); -} - -inline void sanei_genesys_get_triple(Genesys_Register_Set* regs, uint16_t addr, uint32_t* value) -{ - *value = regs->get24(addr); -} - -inline void sanei_genesys_set_exposure(Genesys_Register_Set& regs, const SensorExposure& exposure) -{ - regs.set8(0x10, (exposure.red >> 8) & 0xff); - regs.set8(0x11, exposure.red & 0xff); - regs.set8(0x12, (exposure.green >> 8) & 0xff); - regs.set8(0x13, exposure.green & 0xff); - regs.set8(0x14, (exposure.blue >> 8) & 0xff); - regs.set8(0x15, exposure.blue & 0xff); -} - -inline uint16_t sanei_genesys_fixup_exposure_value(uint16_t value) -{ - if ((value & 0xff00) == 0) { - value |= 0x100; - } - if ((value & 0x00ff) == 0) { - value |= 0x1; - } - return value; -} - -inline SensorExposure sanei_genesys_fixup_exposure(SensorExposure exposure) -{ - exposure.red = sanei_genesys_fixup_exposure_value(exposure.red); - exposure.green = sanei_genesys_fixup_exposure_value(exposure.green); - exposure.blue = sanei_genesys_fixup_exposure_value(exposure.blue); - return exposure; -} - -extern SANE_Status -sanei_genesys_wait_for_home(Genesys_Device *dev); - -extern SANE_Status -sanei_genesys_asic_init(Genesys_Device *dev, SANE_Bool cold); - -int sanei_genesys_compute_dpihw(Genesys_Device *dev, const Genesys_Sensor& sensor, int xres); - -int sanei_genesys_compute_dpihw_calibration(Genesys_Device *dev, const Genesys_Sensor& sensor, - int xres); - -extern -Motor_Profile *sanei_genesys_get_motor_profile(Motor_Profile *motors, int motor_type, int exposure); - -extern -int sanei_genesys_compute_step_type(Motor_Profile *motors, int motor_type, int exposure); - -extern -int sanei_genesys_slope_table(uint16_t *slope, int *steps, int dpi, int exposure, int base_dpi, int step_type, int factor, int motor_type, Motor_Profile *motors); - -/** @brief find lowest motor resolution for the device. - * Parses the resolution list for motor and - * returns the lowest value. - * @param dev for which to find the lowest motor resolution - * @return the lowest available motor resolution for the device - */ -extern -int sanei_genesys_get_lowest_ydpi(Genesys_Device *dev); - -/** @brief find lowest resolution for the device. - * Parses the resolution list for motor and sensor and - * returns the lowest value. - * @param dev for which to find the lowest resolution - * @return the lowest available resolution for the device - */ -extern -int sanei_genesys_get_lowest_dpi(Genesys_Device *dev); - -extern bool -sanei_genesys_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Calibration_Cache * cache, - int for_overwrite); - -/** @brief compute maximum line distance shift - * compute maximum line distance shift for the motor and sensor - * combination. Line distance shift is the distance between different - * color component of CCD sensors. Since these components aren't at - * the same physical place, they scan diffrent lines. Software must - * take this into account to accurately mix color data. - * @param dev device session to compute max_shift for - * @param channels number of color channels for the scan - * @param yres motor resolution used for the scan - * @param flags scan flags - * @return 0 or line distance shift - */ -extern -int sanei_genesys_compute_max_shift(Genesys_Device *dev, - int channels, - int yres, - int flags); - -extern SANE_Status -sanei_genesys_load_lut (unsigned char * lut, - int in_bits, - int out_bits, - int out_min, - int out_max, - int slope, - int offset); - -extern SANE_Status -sanei_genesys_generate_gamma_buffer(Genesys_Device * dev, - const Genesys_Sensor& sensor, - int bits, - int max, - int size, - uint8_t *gamma); - -/*---------------------------------------------------------------------------*/ -/* ASIC specific functions declarations */ -/*---------------------------------------------------------------------------*/ -extern SANE_Status sanei_gl646_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl841_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl843_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl846_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl847_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl124_init_cmd_set (Genesys_Device * dev); - -// same as usleep, except that it does nothing if testing mode is enabled -extern void sanei_genesys_usleep(unsigned int useconds); - -// same as sanei_genesys_usleep just that the duration is in milliseconds -extern void sanei_genesys_sleep_ms(unsigned int milliseconds); - -void add_function_to_run_at_backend_exit(std::function<void()> function); - -// calls functions added via add_function_to_run_at_backend_exit() in reverse order of being -// added. -void run_functions_at_backend_exit(); - -template<class T> -class StaticInit { -public: - StaticInit() = default; - StaticInit(const StaticInit&) = delete; - StaticInit& operator=(const StaticInit&) = delete; - - template<class... Args> - void init(Args&& ... args) - { - ptr_ = std::unique_ptr<T>(new T(std::forward<Args>(args)...)); - add_function_to_run_at_backend_exit([this](){ deinit(); }); - } - - void deinit() - { - ptr_.release(); - } - - const T* operator->() const { return ptr_.get(); } - T* operator->() { return ptr_.get(); } - const T& operator*() const { return *ptr_.get(); } - T& operator*() { return *ptr_.get(); } - -private: - std::unique_ptr<T> ptr_; -}; - -extern StaticInit<std::vector<Genesys_Sensor>> s_sensors; -void genesys_init_sensor_tables(); -void genesys_init_frontend_tables(); - -void debug_dump(unsigned level, const Genesys_Settings& settings); -void debug_dump(unsigned level, const SetupParams& params); -void debug_dump(unsigned level, const Genesys_Current_Setup& setup); - -#endif /* not GENESYS_LOW_H */ diff --git a/backend/gt68xx.c b/backend/gt68xx.c index fb3bfb4..00190fe 100644 --- a/backend/gt68xx.c +++ b/backend/gt68xx.c @@ -752,7 +752,7 @@ init_options (GT68xx_Scanner * s) /* calibration needed */ s->opt[OPT_NEED_CALIBRATION_SW].name = "need-calibration"; - s->opt[OPT_NEED_CALIBRATION_SW].title = SANE_I18N ("Need calibration"); + s->opt[OPT_NEED_CALIBRATION_SW].title = SANE_I18N ("Needs calibration"); s->opt[OPT_NEED_CALIBRATION_SW].desc = SANE_I18N ("The scanner needs calibration for the current settings"); s->opt[OPT_NEED_CALIBRATION_SW].type = SANE_TYPE_BOOL; s->opt[OPT_NEED_CALIBRATION_SW].unit = SANE_UNIT_NONE; @@ -947,25 +947,30 @@ download_firmware_file (GT68xx_Device * dev) if (strncmp (dev->model->firmware_name, PATH_SEP, 1) != 0) { /* probably filename only */ - snprintf (filename, PATH_MAX, "%s%s%s%s%s%s%s", + snprintf (filename, sizeof(filename), "%s%s%s%s%s%s%s", STRINGIFY (PATH_SANE_DATA_DIR), PATH_SEP, "sane", PATH_SEP, "gt68xx", PATH_SEP, dev->model->firmware_name); - snprintf (dirname, PATH_MAX, "%s%s%s%s%s", + snprintf (dirname, sizeof(dirname), "%s%s%s%s%s", STRINGIFY (PATH_SANE_DATA_DIR), PATH_SEP, "sane", PATH_SEP, "gt68xx"); - strncpy (basename, dev->model->firmware_name, PATH_MAX); + strncpy (basename, dev->model->firmware_name, sizeof(basename) - 1); + basename[sizeof(basename) - 1] = '\0'; } else { /* absolute path */ char *pos; - strncpy (filename, dev->model->firmware_name, PATH_MAX); - strncpy (dirname, dev->model->firmware_name, PATH_MAX); + strncpy (filename, dev->model->firmware_name, sizeof(filename) - 1); + filename[sizeof(filename) - 1] = '\0'; + strncpy (dirname, dev->model->firmware_name, sizeof(dirname) - 1); + dirname[sizeof(dirname) - 1] = '\0'; + pos = strrchr (dirname, PATH_SEP[0]); if (pos) pos[0] = '\0'; - strncpy (basename, pos + 1, PATH_MAX); + strncpy (basename, pos + 1, sizeof(basename) - 1); + basename[sizeof(basename) - 1] = '\0'; } /* first, try to open with exact case */ @@ -994,11 +999,16 @@ download_firmware_file (GT68xx_Device * dev) { direntry = readdir (dir); if (direntry - && (strncasecmp (direntry->d_name, basename, PATH_MAX) == - 0)) + && (strncasecmp (direntry->d_name, basename, PATH_MAX) == 0)) { - snprintf (filename, PATH_MAX, "%s%s%s", - dirname, PATH_SEP, direntry->d_name); + int len = snprintf (filename, sizeof(filename), "%s%s%s", + dirname, PATH_SEP, direntry->d_name); + if ((len < 0) || (len >= (int) sizeof(filename))) + { + DBG (5, "download_firmware: filepath `%s%s%s' too long\n", + dirname, PATH_SEP, direntry->d_name); + status = SANE_STATUS_INVAL; + } break; } } diff --git a/backend/hp-option.h b/backend/hp-option.h index d1795e1..a6da585 100644 --- a/backend/hp-option.h +++ b/backend/hp-option.h @@ -118,7 +118,7 @@ # define SANE_NAME_MATRIX_TYPE "matrix-type" # define SANE_TITLE_MATRIX_TYPE SANE_I18N("Color Matrix") /* FIXME: better description */ -# define SANE_DESC_MATRIX_TYPE SANE_I18N("Set the scanners color matrix.") +# define SANE_DESC_MATRIX_TYPE SANE_I18N("Set the scanner's color matrix.") #endif #ifndef SANE_NAME_MATRIX_RGB diff --git a/backend/hp-scl.c b/backend/hp-scl.c index a7376e6..fae7f97 100644 --- a/backend/hp-scl.c +++ b/backend/hp-scl.c @@ -523,8 +523,8 @@ sanei_hp_nonscsi_new (HpScsi * newp, const char * devname, HpConnect connect) } /* For SCSI-devices we would have the inquire command here */ - strncpy ((char *)new->inq_data, "\003zzzzzzzHP ------ R000", - sizeof (new->inq_data)); + memcpy (new->inq_data, "\003zzzzzzzHP ------ R000", + sizeof (new->inq_data)); new->bufp = new->buf + HP_SCSI_CMD_LEN; new->devname = sanei_hp_alloc ( strlen ( devname ) + 1 ); diff --git a/backend/hp3900_config.c b/backend/hp3900_config.c index 830243b..dba5302 100644 --- a/backend/hp3900_config.c +++ b/backend/hp3900_config.c @@ -1049,7 +1049,7 @@ static SANE_Byte *cfg_motor_resource_get(SANE_Byte *size) if (rst != NULL) { - bzero(rst, sizeof(SANE_Byte) * 32); + memset(rst, 0, sizeof(SANE_Byte) * 32); switch(RTS_Debug->dev_model) { diff --git a/backend/hp3900_debug.c b/backend/hp3900_debug.c index b8cd8f1..7b21c8d 100644 --- a/backend/hp3900_debug.c +++ b/backend/hp3900_debug.c @@ -761,7 +761,7 @@ dbg_buffer (SANE_Int level, char *title, SANE_Byte * buffer, SANE_Int size, snprintf (sline, 80, " BF: "); else snprintf (sline, 80, " "); - bzero (&text, sizeof (text)); + memset (&text, 0, sizeof (text)); } data = _B0 (buffer[cont]); text[col] = (data > 31) ? data : '·'; @@ -776,7 +776,7 @@ dbg_buffer (SANE_Int level, char *title, SANE_Byte * buffer, SANE_Int size, start + offset - 8); sline = strcat (sline, sdata); DBG (level, "%s", sline); - bzero (sline, 81); + memset (sline, 0, 81); } } if (col > 0) @@ -791,7 +791,7 @@ dbg_buffer (SANE_Int level, char *title, SANE_Byte * buffer, SANE_Int size, start + offset - 8); sline = strcat (sline, sdata); DBG (level, "%s", sline); - bzero (sline, 81); + memset (sline, 0, 81); } free (sdata); } diff --git a/backend/hp3900_rts8822.c b/backend/hp3900_rts8822.c index bbd1e38..d76763d 100644 --- a/backend/hp3900_rts8822.c +++ b/backend/hp3900_rts8822.c @@ -63,7 +63,7 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> /* bzero() */ +#include <string.h> /* memset() */ #include <time.h> /* clock() */ #include <math.h> /* truncf() */ #include <ctype.h> /* tolower() */ @@ -630,12 +630,12 @@ RTS_Alloc () { SANE_Int rst = OK; - bzero (dev, sizeof (struct st_device)); + memset (dev, 0, sizeof (struct st_device)); /* initial registers */ dev->init_regs = malloc (sizeof (SANE_Byte) * RT_BUFFER_LEN); if (dev->init_regs != NULL) - bzero (dev->init_regs, sizeof (SANE_Byte) * RT_BUFFER_LEN); + memset (dev->init_regs, 0, sizeof (SANE_Byte) * RT_BUFFER_LEN); else rst = ERROR; @@ -643,7 +643,7 @@ RTS_Alloc () { dev->scanning = malloc (sizeof (struct st_scanning)); if (dev->scanning != NULL) - bzero (dev->scanning, sizeof (struct st_scanning)); + memset (dev->scanning, 0, sizeof (struct st_scanning)); else rst = ERROR; } @@ -652,7 +652,7 @@ RTS_Alloc () { dev->Reading = malloc (sizeof (struct st_readimage)); if (dev->Reading != NULL) - bzero (dev->Reading, sizeof (struct st_readimage)); + memset (dev->Reading, 0, sizeof (struct st_readimage)); else rst = ERROR; } @@ -661,7 +661,7 @@ RTS_Alloc () { dev->Resize = malloc (sizeof (struct st_resize)); if (dev->Resize != NULL) - bzero (dev->Resize, sizeof (struct st_resize)); + memset (dev->Resize, 0, sizeof (struct st_resize)); else rst = ERROR; } @@ -670,7 +670,7 @@ RTS_Alloc () { dev->status = malloc (sizeof (struct st_status)); if (dev->status != NULL) - bzero (dev->status, sizeof (struct st_status)); + memset (dev->status, 0, sizeof (struct st_status)); else rst = ERROR; } @@ -1255,7 +1255,7 @@ Load_Chipset (struct st_device *dev) { SANE_Int model; - bzero (dev->chipset, sizeof (struct st_chip)); + memset (dev->chipset, 0, sizeof (struct st_chip)); /* get chipset model of selected scanner */ model = cfg_chipset_model_get (RTS_Debug->dev_model); @@ -1611,7 +1611,7 @@ RTS_Scanner_SetParams (struct st_device *dev, struct params *param) compression = FALSE; /* resetting low level config */ - bzero (&hwdcfg, sizeof (struct st_hwdconfig)); + memset (&hwdcfg, 0, sizeof (struct st_hwdconfig)); /* setting low level config */ hwdcfg.scantype = scan.scantype; @@ -1650,7 +1650,7 @@ SetScanParams (struct st_device *dev, SANE_Byte * Regs, dbg_ScanParams (scancfg); dbg_hwdcfg (hwdcfg); - bzero (&mycoords, sizeof (struct st_coords)); + memset (&mycoords, 0, sizeof (struct st_coords)); /* Copy scancfg to scan2 */ memcpy (&scan2, scancfg, sizeof (struct st_scanparams)); @@ -3675,7 +3675,7 @@ Init_Registers (struct st_device *dev) DBG (DBG_FNC, "+ Init_Registers:\n"); /* Lee dev->init_regs */ - bzero (dev->init_regs, RT_BUFFER_LEN); + memset (dev->init_regs, 0, RT_BUFFER_LEN); RTS_ReadRegs (dev->usb_handle, dev->init_regs); Read_FE3E (dev, &v1619); @@ -4116,7 +4116,7 @@ Lamp_Status_Get (struct st_device *dev, SANE_Byte * flb_lamp, case RTS8822BL_03A: *flb_lamp = ((data2 & 0x40) != 0) ? 1 : 0; *tma_lamp = (((data2 & 0x20) != 0) - && ((data1 & 0x10) == 1)) ? 1 : 0; + && ((data1 & 0x10) != 0)) ? 1 : 0; break; default: if ((_B1 (data1) & 0x10) == 0) @@ -4825,8 +4825,8 @@ Refs_Analyze_Pattern (struct st_scanparams *scancfg, if ((scancfg->coord.width - dist) > 1) { /* clear buffers */ - bzero (color_sum, sizeof (double) * buffersize); - bzero (color_dif, sizeof (double) * buffersize); + memset (color_sum, 0, sizeof (double) * buffersize); + memset (color_dif, 0, sizeof (double) * buffersize); for (xpos = 0; xpos < scancfg->coord.width; xpos++) { @@ -4875,8 +4875,8 @@ Refs_Analyze_Pattern (struct st_scanparams *scancfg, if ((scancfg->coord.height - dist) > 1) { /* clear buffers */ - bzero (color_sum, sizeof (double) * buffersize); - bzero (color_dif, sizeof (double) * buffersize); + memset (color_sum, 0, sizeof (double) * buffersize); + memset (color_dif, 0, sizeof (double) * buffersize); for (ypos = 0; ypos < scancfg->coord.height; ypos++) { @@ -4924,8 +4924,8 @@ Refs_Analyze_Pattern (struct st_scanparams *scancfg, if ((scancfg->coord.width - dist) > 1) { /* clear buffers */ - bzero (color_sum, sizeof (double) * buffersize); - bzero (color_dif, sizeof (double) * buffersize); + memset (color_sum, 0, sizeof (double) * buffersize); + memset (color_dif, 0, sizeof (double) * buffersize); for (xpos = 0; xpos < scancfg->coord.width; xpos++) { @@ -6188,7 +6188,7 @@ Reading_DestroyBuffers (struct st_device *dev) dev->scanning->imagebuffer = NULL; } - bzero (dev->Reading, sizeof (struct st_readimage)); + memset (dev->Reading, 0, sizeof (struct st_readimage)); return OK; } @@ -6462,7 +6462,7 @@ RTS_ScanCounter_Inc (struct st_device *dev) break; default: /* value is 4 bytes size starting from address 0x21 in lsb format */ - bzero (&somebuffer, sizeof (somebuffer)); + memset (&somebuffer, 0, sizeof (somebuffer)); somebuffer[4] = 0x0c; RTS_EEPROM_ReadInteger (dev->usb_handle, 0x21, &idata); @@ -7786,7 +7786,7 @@ Scan_Read_BufferA (struct st_device *dev, SANE_Int buffer_size, SANE_Int arg2, opStatus = Reading_Wait (dev, rd->Channels_per_dot, rd->Channel_size, iAmount, - &rd->Bytes_Available, 10, sc); + &rd->Bytes_Available, 60, sc); /* If something fails, perhaps we can read some bytes... */ if (opStatus != OK) @@ -8072,7 +8072,7 @@ Scan_Start (struct st_device *dev) dbg_ScanParams (&scancfg); /* reserva buffer 6 dwords en fa84-fa9f */ - bzero (&hwdcfg, sizeof (struct st_hwdconfig)); + memset (&hwdcfg, 0, sizeof (struct st_hwdconfig)); /* wait till lamp is at home (should use timeout windows driver doesn't use it) @@ -10009,7 +10009,7 @@ Shading_apply (struct st_device *dev, SANE_Byte * Regs, } /*3d4c */ - bzero (&calbuffers, sizeof (struct st_cal2)); + memset (&calbuffers, 0, sizeof (struct st_cal2)); /* If black shading correction is enabled ... */ if ((Regs[0x1cf] & 8) != 0) @@ -10340,7 +10340,7 @@ RTS_GetImage (struct st_device *dev, SANE_Byte * Regs, (struct st_hwdconfig *) malloc (sizeof (struct st_hwdconfig)); if (hwdcfg != NULL) { - bzero (hwdcfg, sizeof (struct st_hwdconfig)); + memset (hwdcfg, 0, sizeof (struct st_hwdconfig)); if (((options & 2) != 0) || ((_B1 (options) & 1) != 0)) { @@ -10404,7 +10404,7 @@ RTS_GetImage (struct st_device *dev, SANE_Byte * Regs, sizeof (SANE_Byte)); if (myRegs != NULL) { - bzero (myRegs, + memset (myRegs, 0, RT_BUFFER_LEN * sizeof (SANE_Byte)); RTS_Setup (dev, myRegs, &scan, hwdcfg, gain_offset); @@ -10547,7 +10547,7 @@ Refs_Detect (struct st_device *dev, SANE_Byte * Regs, SANE_Int resolution_x, *x = *y = 0; /* default */ /* set configuration to scan a little area at the top-left corner */ - bzero (&scancfg, sizeof (struct st_scanparams)); + memset (&scancfg, 0, sizeof (struct st_scanparams)); scancfg.depth = 8; scancfg.colormode = CM_GRAY; scancfg.channel = CL_RED; @@ -10588,7 +10588,7 @@ Refs_Detect (struct st_device *dev, SANE_Byte * Regs, SANE_Int resolution_x, pwmlamplevel = 0; Lamp_PWM_use (dev, 1); - bzero (&gain_offset, sizeof (struct st_gain_offset)); + memset (&gain_offset, 0, sizeof (struct st_gain_offset)); for (C = CL_RED; C <= CL_BLUE; C++) { gain_offset.pag[C] = 3; @@ -11290,7 +11290,7 @@ Head_Relocate (struct st_device *dev, SANE_Int speed, SANE_Int direction, struct st_motormove mymotor; struct st_motorpos mtrpos; - bzero (&mymotor, sizeof (struct st_motormove)); + memset (&mymotor, 0, sizeof (struct st_motormove)); memcpy (Regs, dev->init_regs, RT_BUFFER_LEN * sizeof (SANE_Byte)); if (speed < dev->motormove_count) @@ -11338,7 +11338,7 @@ Calib_CreateFixedBuffers () (USHORT *) malloc (0x7f8 * sizeof (USHORT)); if (fixed_black_shading[channel] != NULL) - bzero (fixed_black_shading[channel], 0x7f8 * sizeof (USHORT)); + memset (fixed_black_shading[channel], 0, 0x7f8 * sizeof (USHORT)); else ret = ERROR; @@ -11348,7 +11348,7 @@ Calib_CreateFixedBuffers () (USHORT *) malloc (0x7f8 * sizeof (USHORT)); if (fixed_white_shading[channel] != NULL) - bzero (fixed_white_shading[channel], 0x7f8 * sizeof (USHORT)); + memset (fixed_white_shading[channel], 0, 0x7f8 * sizeof (USHORT)); else ret = ERROR; @@ -12779,7 +12779,7 @@ Calib_WhiteShading_3 (struct st_device *dev, /*a743 */ if (lf130 > 0) - bzero (buffer1, lf130 * sizeof (double)); + memset (buffer1, 0, lf130 * sizeof (double)); /*a761 */ if (lf12c > 0) @@ -12959,7 +12959,7 @@ Calib_WhiteShading_3 (struct st_device *dev, /*a743 */ if (lf130 > 0) - bzero (buffer1, lf130 * sizeof (double)); + memset (buffer1, 0, lf130 * sizeof (double)); /*a761 */ if (lf12c > 0) @@ -13325,14 +13325,14 @@ Calib_BlackShading (struct st_device *dev, if (scancfg.depth > 8) { /*8bb2 */ - bzero (&dbvalue, 6 * sizeof (double)); + memset (&dbvalue, 0, 6 * sizeof (double)); position = 0; if (bytes_per_line > 0) { do { - bzero (&buff3, 0x8000 * sizeof (SANE_Int)); + memset (&buff3, 0, 0x8000 * sizeof (SANE_Int)); sumatorio = 0; ptr = buffer + position; current_line = 0; @@ -13435,14 +13435,14 @@ Calib_BlackShading (struct st_device *dev, else { /*8eb6 */ - bzero (&dbvalue, 6 * sizeof (double)); + memset (&dbvalue, 0, 6 * sizeof (double)); position = 0; if (bytes_per_line > 0) { do { - bzero (&buff2, 256 * sizeof (SANE_Byte)); + memset (&buff2, 0, 256 * sizeof (SANE_Byte)); sumatorio = 0; /* ptr points to the next position of the first line */ ptr = buffer + position; @@ -13634,7 +13634,7 @@ Calibration (struct st_device *dev, SANE_Byte * Regs, Calib_LoadConfig (dev, &calibcfg, scan.scantype, scancfg->resolution_x, scancfg->depth); - bzero (&calibdata->gain_offset, sizeof (struct st_gain_offset)); /*[42b3654] */ + memset (&calibdata->gain_offset, 0, sizeof (struct st_gain_offset)); /*[42b3654] */ for (a = CL_RED; a <= CL_BLUE; a++) { myCalib->WRef[a] = calibcfg.WRef[a]; @@ -14110,7 +14110,7 @@ Init_Vars (void) hp_gamma = malloc (sizeof (struct st_gammatables)); if (hp_gamma != NULL) - bzero (hp_gamma, sizeof (struct st_gammatables)); + memset (hp_gamma, 0, sizeof (struct st_gammatables)); else rst = ERROR; @@ -14118,7 +14118,7 @@ Init_Vars (void) { RTS_Debug = malloc (sizeof (struct st_debug_opts)); if (RTS_Debug != NULL) - bzero (RTS_Debug, sizeof (struct st_debug_opts)); + memset (RTS_Debug, 0, sizeof (struct st_debug_opts)); else rst = ERROR; } @@ -14127,7 +14127,7 @@ Init_Vars (void) { default_gain_offset = malloc (sizeof (struct st_gain_offset)); if (default_gain_offset != NULL) - bzero (default_gain_offset, sizeof (struct st_gain_offset)); + memset (default_gain_offset, 0, sizeof (struct st_gain_offset)); else rst = ERROR; } @@ -14136,7 +14136,7 @@ Init_Vars (void) { calibdata = malloc (sizeof (struct st_calibration_data)); if (calibdata != NULL) - bzero (calibdata, sizeof (struct st_calibration_data)); + memset (calibdata, 0, sizeof (struct st_calibration_data)); else rst = ERROR; } @@ -14145,7 +14145,7 @@ Init_Vars (void) { wshading = malloc (sizeof (struct st_shading)); if (wshading != NULL) - bzero (wshading, sizeof (struct st_shading)); + memset (wshading, 0, sizeof (struct st_shading)); else rst = ERROR; } @@ -14467,7 +14467,7 @@ WShading_Calibrate (struct st_device *dev, SANE_Byte * Regs, DBG (DBG_FNC, "> WShading_Calibrate(*myCalib)\n"); - bzero (&myCalibTable, sizeof (struct st_gain_offset)); + memset (&myCalibTable, 0, sizeof (struct st_gain_offset)); for (C = CL_RED; C <= CL_BLUE; C++) { myCalibTable.pag[C] = 3; @@ -14687,7 +14687,7 @@ motor_pos (struct st_device *dev, SANE_Byte * Regs, DBG (DBG_FNC, "> Calib_test(*myCalib)\n"); - bzero (&myCalibTable, sizeof (struct st_gain_offset)); + memset (&myCalibTable, 0, sizeof (struct st_gain_offset)); calibcfg = (struct st_calibration_config *) @@ -14821,7 +14821,7 @@ Calib_BlackShading_jkd (struct st_device *dev, SANE_Byte * Regs, DBG (DBG_FNC, "> Calib_BlackShading_jkd(*myCalib)\n"); - bzero (&myCalibTable, sizeof (struct st_gain_offset)); + memset (&myCalibTable, 0, sizeof (struct st_gain_offset)); for (C = CL_RED; C <= CL_BLUE; C++) { myCalibTable.pag[C] = 3; @@ -14955,7 +14955,7 @@ Calib_test (struct st_device *dev, SANE_Byte * Regs, DBG (DBG_FNC, "> Calib_test(*myCalib)\n"); - bzero (&myCalibTable, sizeof (struct st_gain_offset)); + memset (&myCalibTable, 0, sizeof (struct st_gain_offset)); calibcfg = (struct st_calibration_config *) diff --git a/backend/hp3900_sane.c b/backend/hp3900_sane.c index 410e35e..f8ed139 100644 --- a/backend/hp3900_sane.c +++ b/backend/hp3900_sane.c @@ -1405,7 +1405,7 @@ options_init (TScanner * scanner) pDesc->title = SANE_I18N ("Scanner model"); pDesc->desc = SANE_I18N - ("Allows one to test device behaviour with other supported models"); + ("Allows one to test device behavior with other supported models"); pDesc->type = SANE_TYPE_STRING; pDesc->size = max_string_size (scanner->list_models); pDesc->constraint_type = SANE_CONSTRAINT_STRING_LIST; @@ -1419,7 +1419,7 @@ options_init (TScanner * scanner) case opt_negative: pDesc->name = "opt_negative"; pDesc->title = SANE_I18N ("Negative"); - pDesc->desc = SANE_I18N ("Image colours will be inverted"); + pDesc->desc = SANE_I18N ("Image colors will be inverted"); pDesc->type = SANE_TYPE_BOOL; pDesc->unit = SANE_UNIT_NONE; pDesc->size = sizeof (SANE_Word); @@ -1991,6 +1991,7 @@ option_get (TScanner * scanner, SANE_Int optid, void *result) /* scanner buttons */ case opt_button_0: get_button_status (scanner); + // fall through case opt_button_1: case opt_button_2: case opt_button_3: diff --git a/backend/hp3900_usb.c b/backend/hp3900_usb.c index 440c963..99623b4 100644 --- a/backend/hp3900_usb.c +++ b/backend/hp3900_usb.c @@ -459,7 +459,7 @@ show_buffer (SANE_Int level, SANE_Byte * buffer, SANE_Int size) sdata = (char *) malloc (256); if (sdata != NULL) { - bzero (sline, 256); + memset (sline, 0, 256); for (cont = 0; cont < size; cont++) { if (col == 0) @@ -480,7 +480,7 @@ show_buffer (SANE_Int level, SANE_Byte * buffer, SANE_Int size) snprintf (sdata, 255, " : %i\n", offset - 8); sline = strcat (sline, sdata); DBG (level, "%s", sline); - bzero (sline, 256); + memset (sline, 0, 256); } } if (col > 0) @@ -494,7 +494,7 @@ show_buffer (SANE_Int level, SANE_Byte * buffer, SANE_Int size) snprintf (sdata, 255, " : %i\n", offset - 8); sline = strcat (sline, sdata); DBG (level, "%s", sline); - bzero (sline, 256); + memset (sline, 0, 256); } free (sdata); } diff --git a/backend/hpsj5s.c b/backend/hpsj5s.c index 786a8d6..77fcc46 100644 --- a/backend/hpsj5s.c +++ b/backend/hpsj5s.c @@ -961,8 +961,7 @@ GetCalibration () { /*WARNING!!! Deadlock possible! */ bTest = CallFunctionWithRetVal (0xB5); } - while ((((bTest & 0x80) == 1) && ((bTest & 0x3F) <= 2)) || - (((bTest & 0x80) == 0) && ((bTest & 0x3F) >= 5))); + while ((bTest & 0x80) ? (bTest & 0x3F) <= 2 : (bTest & 0x3F) >= 5); CallFunctionWithParameter (0xCD, 0); /*Skip this line for ECP: */ @@ -1150,8 +1149,7 @@ CalibrateScanElements () usleep (1); } while ((timeout < 1000) && - ((((bTest & 0x80) == 1) && ((bTest & 0x3F) <= 2)) || - (((bTest & 0x80) == 0) && ((bTest & 0x3F) >= 5)))); + ((bTest & 0x80) ? (bTest & 0x3F) <= 2 : (bTest & 0x3F) >= 5)); /*Let's read it... */ if(timeout < 1000) @@ -1218,8 +1216,7 @@ CalibrateScanElements () usleep (1); } while ((timeout < 1000) && - ((((bTest & 0x80) == 1) && ((bTest & 0x3F) <= 2)) || - (((bTest & 0x80) == 0) && ((bTest & 0x3F) >= 5)))); + ((bTest & 0x80) ? (bTest & 0x3F) <= 2 : (bTest & 0x3F) >= 5)); /*Let's read it... */ if(timeout < 1000) diff --git a/backend/ibm.c b/backend/ibm.c index e527a04..1f26226 100644 --- a/backend/ibm.c +++ b/backend/ibm.c @@ -248,12 +248,14 @@ attach (const char *devnam, Ibm_Device ** devp) dev->sane.name = strdup (devnam); dev->sane.vendor = "IBM"; - str = malloc (sizeof(ibuf.product) + sizeof(ibuf.revision) + 1); + + size_t prod_rev_size = sizeof(ibuf.product) + sizeof(ibuf.revision) + 1; + str = malloc (prod_rev_size); if (str) { - str[0] = '\0'; - strncat (str, (char *)ibuf.product, sizeof(ibuf.product)); - strncat (str, (char *)ibuf.revision, sizeof(ibuf.revision)); + snprintf (str, prod_rev_size, "%.*s%.*s", + (int) sizeof(ibuf.product), (const char *) ibuf.product, + (int) sizeof(ibuf.revision), (const char *) ibuf.revision); } dev->sane.model = str; dev->sane.type = "flatbed scanner"; diff --git a/backend/kodakaio.c b/backend/kodakaio.c index c8cc9a7..d5c2857 100644 --- a/backend/kodakaio.c +++ b/backend/kodakaio.c @@ -3276,12 +3276,11 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) case OPT_BR_X: case OPT_BR_Y: - sval->w = *((SANE_Word *) value); - if (SANE_UNFIX(sval->w) == 0) { + if (SANE_UNFIX(*((SANE_Word *) value)) == 0) { DBG(17, "invalid br-x or br-y\n"); return SANE_STATUS_INVAL; } - /* passthru */ + // fall through case OPT_TL_X: case OPT_TL_Y: sval->w = *((SANE_Word *) value); diff --git a/backend/kvs1025_opt.c b/backend/kvs1025_opt.c index 71fbf89..628f056 100644 --- a/backend/kvs1025_opt.c +++ b/backend/kvs1025_opt.c @@ -226,7 +226,7 @@ static const int go_image_emphasis_val[] = { static SANE_String_Const go_gamma_list[] = { SANE_I18N ("normal"), SANE_I18N ("crt"), - SANE_I18N ("linier"), + SANE_I18N ("linear"), NULL }; static const int go_gamma_val[] = { diff --git a/backend/kvs20xx_opt.c b/backend/kvs20xx_opt.c index fc527f3..e4b841b 100644 --- a/backend/kvs20xx_opt.c +++ b/backend/kvs20xx_opt.c @@ -230,7 +230,7 @@ kvs20xx_init_options (struct scanner *s) o->title = SANE_I18N ("Length control mode"); o->desc = SANE_I18N - ("Length Control Mode is a mode that the scanner reads up to the shorter length of actual" + ("Length Control Mode causes the scanner to read the shorter of either the length of the actual" " paper or logical document length."); o->type = SANE_TYPE_BOOL; o->unit = SANE_UNIT_NONE; diff --git a/backend/kvs40xx.c b/backend/kvs40xx.c index 6c19e55..6416d64 100644 --- a/backend/kvs40xx.c +++ b/backend/kvs40xx.c @@ -524,9 +524,10 @@ static SANE_Status read_image_simplex(SANE_Handle handle) return st; } -static SANE_Status read_data(struct scanner *s) +static void * read_data (void *arg) { - SANE_Status st; + struct scanner *s = (struct scanner *) arg; + SANE_Status st; int duplex = s->val[DUPLEX].w; s->read = 0; s->side = SIDE_FRONT; @@ -549,7 +550,7 @@ static SANE_Status read_data(struct scanner *s) return SANE_STATUS_GOOD; err: s->scanning = 0; - return st; + return (void *) st; } /* Start scanning */ @@ -640,7 +641,7 @@ sane_start (SANE_Handle handle) goto err; } - if (pthread_create (&s->thread, NULL, (void *(*)(void *)) read_data, s)) + if (pthread_create (&s->thread, NULL, read_data, s)) { st = SANE_STATUS_IO_ERROR; goto err; diff --git a/backend/kvs40xx_opt.c b/backend/kvs40xx_opt.c index 2bf9a5c..c812f2c 100644 --- a/backend/kvs40xx_opt.c +++ b/backend/kvs40xx_opt.c @@ -228,8 +228,8 @@ static SANE_String_Const lamp_list[] = { }; static SANE_String_Const dfeed_sence_list[] = { SANE_I18N ("Normal"), - SANE_I18N ("High sensivity"), - SANE_I18N ("Low sensivity"), + SANE_I18N ("High sensitivity"), + SANE_I18N ("Low sensitivity"), NULL }; @@ -393,8 +393,8 @@ kvs40xx_init_options (struct scanner *s) o->title = SANE_I18N ("Length control mode"); o->desc = SANE_I18N - ("Length Control Mode is a mode that the scanner reads up to the shorter length of actual" - " paper or logical document length."); + ("Length Control Mode causes the scanner to read the shorter of either the length of the actual" + " paper or logical document length"); o->type = SANE_TYPE_BOOL; o->unit = SANE_UNIT_NONE; s->val[LENGTHCTL].w = SANE_FALSE; @@ -715,7 +715,7 @@ kvs40xx_init_options (struct scanner *s) o->title = SANE_I18N ("JPEG compression"); o->desc = SANE_I18N - ("JPEG compression (yours application must be able to uncompress)"); + ("JPEG compression (your application must be able to uncompress)"); o->type = SANE_TYPE_BOOL; o->unit = SANE_UNIT_NONE; @@ -805,8 +805,8 @@ kvs40xx_init_options (struct scanner *s) o = &s->opt[STOP_SKEW]; o->name = "stop-skew"; - o->title = SANE_I18N ("Stop scanner when a paper have been skewed"); - o->desc = SANE_I18N ("Scanner will be stop when a paper have been skewed"); + o->title = SANE_I18N ("Stop scanner if a sheet is skewed"); + o->desc = SANE_I18N ("Scanner will stop if a sheet is skewed"); o->type = SANE_TYPE_BOOL; o->unit = SANE_UNIT_NONE; s->val[STOP_SKEW].w = SANE_FALSE; @@ -814,7 +814,7 @@ kvs40xx_init_options (struct scanner *s) o = &s->opt[CROP]; o->name = "crop"; o->title = SANE_I18N ("Crop actual image area"); - o->desc = SANE_I18N ("Scanner automatically detect image area and crop it"); + o->desc = SANE_I18N ("Scanner will automatically detect image area and crop to it"); o->type = SANE_TYPE_BOOL; o->unit = SANE_UNIT_NONE; s->val[CROP].w = SANE_FALSE; @@ -824,7 +824,7 @@ kvs40xx_init_options (struct scanner *s) o = &s->opt[MIRROR]; o->name = "mirror"; o->title = SANE_I18N ("Mirror image"); - o->desc = SANE_I18N ("It is right and left reversing"); + o->desc = SANE_I18N ("Left/right mirror image"); o->type = SANE_TYPE_BOOL; o->unit = SANE_UNIT_NONE; s->val[MIRROR].w = SANE_FALSE; diff --git a/backend/magicolor.c b/backend/magicolor.c index 3b27a85..af9fb1a 100644 --- a/backend/magicolor.c +++ b/backend/magicolor.c @@ -2789,12 +2789,11 @@ setvalue(SANE_Handle handle, SANE_Int option, void *value, SANE_Int *info) case OPT_BR_X: case OPT_BR_Y: - sval->w = *((SANE_Word *) value); - if (SANE_UNFIX(sval->w) == 0) { + if (SANE_UNFIX(*((SANE_Word *) value)) == 0) { DBG(17, "invalid br-x or br-y\n"); return SANE_STATUS_INVAL; } - /* passthru */ + // fall through case OPT_TL_X: case OPT_TL_Y: sval->w = *((SANE_Word *) value); diff --git a/backend/microtek.c b/backend/microtek.c index 05f8003..c3b87ec 100644 --- a/backend/microtek.c +++ b/backend/microtek.c @@ -3444,6 +3444,7 @@ sane_control_option (SANE_Handle handle, case OPT_RESOLUTION: if (info) *info |= SANE_INFO_RELOAD_PARAMS; + // fall through case OPT_SPEED: case OPT_PREVIEW: case OPT_BACKTRACK: diff --git a/backend/mustek_pp.c b/backend/mustek_pp.c index 912c3bd..bb97f86 100644 --- a/backend/mustek_pp.c +++ b/backend/mustek_pp.c @@ -160,8 +160,6 @@ free_cfg_options(int *numoptions, Mustek_pp_config_option** options) /* do_eof: * closes the pipeline * - * ChangeLog: - * * Description: * closes the pipe (read-only end) */ @@ -180,8 +178,6 @@ do_eof (Mustek_pp_Handle *hndl) /* do_stop: * ends the reader_process and stops the scanner * - * ChangeLog: - * * Description: * kills the reader process with a SIGTERM and cancels the scanner */ @@ -218,8 +214,6 @@ do_stop(Mustek_pp_Handle *hndl) /* sigterm_handler: * cancel scanner when receiving a SIGTERM * - * ChangeLog: - * * Description: * just exit... reader_process takes care that nothing bad will happen * @@ -247,8 +241,6 @@ sigterm_handler (int signal __UNUSED__) /* reader_process: * receives data from the scanner and stuff it into the pipeline * - * ChangeLog: - * * Description: * The signal handle for SIGTERM is initialized. * @@ -318,8 +310,6 @@ reader_process (Mustek_pp_Handle * hndl, int pipe) /* sane_attach: * adds a new entry to the Mustek_pp_Device *devlist list * - * ChangeLog: - * * Description: * After memory for a new device entry is allocated, the * parameters for the device are determined by a call to @@ -382,8 +372,6 @@ sane_attach (SANE_String_Const port, SANE_String_Const name, SANE_Int driver, SA /* init_options: * Sets up the option descriptors for a device * - * ChangeLog: - * * Description: */ static void @@ -626,8 +614,6 @@ init_options(Mustek_pp_Handle *hndl) * Attempts to attach a device to the list after parsing of a section * of the configuration file. * - * ChangeLog: - * * Description: * After parsing a scanner section of the config file, this function * is called to look for a driver with a matching name. When found, @@ -691,8 +677,6 @@ attach_device(SANE_String *driver, SANE_String *name, /* sane_init: * Reads configuration file and registers hardware driver * - * ChangeLog: - * * Description: * in *version_code the SANE version this backend was compiled with and the * version of the backend is returned. The value of authorize is stored in @@ -1001,8 +985,6 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) /* sane_exit: * Unloads all drivers and frees allocated memory * - * ChangeLog: - * * Description: * All open devices are closed first. Then all registered devices * are removed. @@ -1051,8 +1033,6 @@ sane_exit (void) /* sane_get_devices: * Returns a list of registered devices * - * ChangeLog: - * * Description: * A possible present old device_list is removed first. A new * devarray is allocated and filled with pointers to the @@ -1093,8 +1073,6 @@ sane_get_devices (const SANE_Device *** device_list, /* sane_open: * opens a device and prepares it for operation * - * ChangeLog: - * * Description: * The device identified by ``devicename'' is looked * up in the list, or if devicename is zero, the @@ -1201,8 +1179,6 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle) /* sane_close: * closes a given device and frees all resources * - * ChangeLog: - * * Description: * The handle is searched in the list of active handles. * If it's found, the handle is removed. @@ -1261,8 +1237,6 @@ sane_close (SANE_Handle handle) /* sane_get_option_descriptor: * does what it says * - * ChangeLog: - * * Description: * */ @@ -1285,8 +1259,6 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /* sane_control_option: * Reads or writes an option * - * ChangeLog: - * * Desription: * If a pointer to info is given, the value is initialized to zero * while scanning options cannot be read or written. next a basic @@ -1523,8 +1495,6 @@ sane_control_option (SANE_Handle handle, SANE_Int option, /* sane_get_parameters: * returns the set of parameters, that is used for the next scan * - * ChangeLog: - * * Description: * * First of all it is impossible to change the parameter set @@ -1716,8 +1686,6 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) /* sane_start: * starts the scan. data aquisition will start immedially * - * ChangeLog: - * * Description: * */ @@ -1775,8 +1743,6 @@ sane_start (SANE_Handle handle) /* sane_read: * receives data from pipeline and passes it to the caller * - * ChangeLog: - * * Description: * ditto */ @@ -1877,8 +1843,6 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, /* sane_cancel: * stops a scan and ends the reader process * - * ChangeLog: - * * Description: * */ @@ -1900,8 +1864,6 @@ sane_cancel (SANE_Handle handle) /* sane_set_io_mode: * toggles between blocking and non-blocking reading * - * ChangeLog: - * * Description: * */ @@ -1930,8 +1892,6 @@ sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking) /* sane_get_select_fd: * returns the pipeline fd for direct reading * - * ChangeLog: - * * Description: * to allow the frontend to receive the data directly it * can read from the pipeline itself diff --git a/backend/mustek_usb2_transparent.c b/backend/mustek_usb2_transparent.c index 33adcc0..74f7b52 100644 --- a/backend/mustek_usb2_transparent.c +++ b/backend/mustek_usb2_transparent.c @@ -1382,7 +1382,7 @@ Transparent_LineCalibration16Bits (unsigned short wTAShadingMinus) memset (lpBuf, 0, 50); stream = fopen ("/root/darkshading(Tra).pnm", "wb+\n"); - sprintf (lpBuf, "P6\n%d %d\n65535\n", wCalWidth * wCalHeight); + sprintf (lpBuf, "P6\n%d %d\n65535\n", wCalWidth, wCalHeight); fwrite (lpBuf, sizeof (SANE_Byte), strlen (lpBuf), stream); fwrite (lpDarkData, sizeof (SANE_Byte), wCalWidth * wCalHeight * 3 * 2, stream); fclose (stream); diff --git a/backend/nec.c b/backend/nec.c index f12e997..d123be0 100644 --- a/backend/nec.c +++ b/backend/nec.c @@ -349,6 +349,9 @@ sense_handler(int fd, u_char *sense_buffer, void *ss) DBG(5, "Scanner not ready: undocumented reason\n"); return SANE_STATUS_IO_ERROR; } + default: + DBG(5, "Scanner not ready: unknown sense code\n"); + return SANE_STATUS_IO_ERROR; } case 0x03: /* medium error */ DBG(5, "medium error: undocumented reason\n"); @@ -2306,6 +2309,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, case OPT_BR_Y: if (info && s->val[option].w != *(SANE_Word *) val) *info |= SANE_INFO_RELOAD_PARAMS; + // fall through case OPT_NUM_OPTS: case OPT_THRESHOLD: /* xxx theoretically, we could use OPT_THRESHOLD in diff --git a/backend/niash.c b/backend/niash.c index bbc90d3..b62bdba 100644 --- a/backend/niash.c +++ b/backend/niash.c @@ -768,6 +768,7 @@ _InitOptions (TScanner * s) SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_INACTIVE | SANE_CAP_EMULATED; pVal->w = 50; + break; default: DBG (DBG_ERR, "Uninitialised option %d\n", i); diff --git a/backend/pieusb_buffer.h b/backend/pieusb_buffer.h index 3724a40..282595a 100644 --- a/backend/pieusb_buffer.h +++ b/backend/pieusb_buffer.h @@ -48,6 +48,10 @@ #include "pieusb.h" #include "../include/sane/sanei_ir.h" +#ifndef L_tmpnam +#define L_tmpnam 20 +#endif + struct Pieusb_Read_Buffer { SANE_Uint* data; /* image data - always store as 16 bit values; mmap'ed */ diff --git a/backend/pieusb_specific.c b/backend/pieusb_specific.c index ce107cf..1b5f0f4 100644 --- a/backend/pieusb_specific.c +++ b/backend/pieusb_specific.c @@ -322,7 +322,7 @@ pieusb_initialize_device_definition (Pieusb_Device_Definition* dev, Pieusb_Scann buf = malloc(9); if (buf == NULL) return SANE_STATUS_NO_MEM; - strncpy(buf, inq->vendor, 8); + memcpy(buf, inq->vendor, 8); pp = buf + 8; *pp-- = '\0'; while (*pp == ' ') *pp-- = '\0'; @@ -332,7 +332,7 @@ pieusb_initialize_device_definition (Pieusb_Device_Definition* dev, Pieusb_Scann buf = malloc(17); if (buf == NULL) return SANE_STATUS_NO_MEM; - strncpy(buf, inq->product, 16); + memcpy(buf, inq->product, 16); pp = buf + 16; *pp-- = '\0'; while (*pp == ' ') *pp-- = '\0'; @@ -346,7 +346,7 @@ pieusb_initialize_device_definition (Pieusb_Device_Definition* dev, Pieusb_Scann buf = malloc(5); if (buf == NULL) return SANE_STATUS_NO_MEM; - strncpy(buf, inq->productRevision, 4); + memcpy(buf, inq->productRevision, 4); pp = buf + 4; *pp-- = '\0'; while (*pp == ' ') *pp-- = '\0'; diff --git a/backend/pixma.conf.in b/backend/pixma.conf.in index 3f5c61a..d6184b4 100644 --- a/backend/pixma.conf.in +++ b/backend/pixma.conf.in @@ -1,5 +1,10 @@ # pixma.conf configuration for the sane pixma backend # +# disable network scanner detection. +# This must be the first not commented line +# Uncomment the following line: +# networking=no +# # bjnp-timeout=5000 # Specify the timeout (in ms) to be used for all the folllowing # scanners. @@ -16,10 +21,12 @@ # port number can normally be left out, port 8612 is used as default # The timeout parameter sets a timeout value for the scanner on # the same line -# Example: +# Examples using bjnp: # bjnp://myscanner.my.domain:8612 // uses the default 1000ms timeout # bjnp-timeout=5000 # bjnp://printer-1.pheasant.org // will use the 5000 ms timeout # bjnp://scanner.bad-network.org/timeout=1500 // timeout set to 1500 ms # bjnp-timeout=3000 // will be used for auto-detected scanners # +# Example using for a scanner using mfnp including the optional timeout: +# mfnp://scanner.bad-network.org/timeout=1500 diff --git a/backend/pixma.c b/backend/pixma/pixma.c index d33a74e..f763496 100644 --- a/backend/pixma.c +++ b/backend/pixma/pixma.c @@ -242,12 +242,12 @@ cleanup_device_list (void) } static void -find_scanners (void) +find_scanners (SANE_Bool local_only) { unsigned i, nscanners; cleanup_device_list (); - nscanners = pixma_find_scanners (conf_devices); + nscanners = pixma_find_scanners (conf_devices, local_only); PDBG (pixma_dbg (3, "pixma_find_scanners() found %u devices\n", nscanners)); dev_list = (const SANE_Device **) calloc (nscanners + 1, sizeof (*dev_list)); @@ -1602,11 +1602,9 @@ sane_exit (void) SANE_Status sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) { - UNUSED (local_only); - if (!device_list) return SANE_STATUS_INVAL; - find_scanners (); + find_scanners (local_only); *device_list = dev_list; return (dev_list) ? SANE_STATUS_GOOD : SANE_STATUS_NO_MEM; } @@ -1623,7 +1621,7 @@ sane_open (SANE_String_Const name, SANE_Handle * h) return SANE_STATUS_INVAL; *h = NULL; - nscanners = pixma_find_scanners (conf_devices); + nscanners = pixma_find_scanners (conf_devices, SANE_FALSE); if (nscanners == 0) return SANE_STATUS_INVAL; if (name[0] == '\0') diff --git a/backend/pixma.h b/backend/pixma/pixma.h index 370203a..c2df3cc 100644 --- a/backend/pixma.h +++ b/backend/pixma/pixma.h @@ -45,6 +45,9 @@ #ifndef PIXMA_H #define PIXMA_H +#include "../include/sane/sane.h" + + /*! * \mainpage Scanner driver for Canon PIXMA MP series * \section example Sample code for application @@ -116,7 +119,7 @@ typedef uint32_t uint32_t; /** \name Version of the driver */ /**@{*/ #define PIXMA_VERSION_MAJOR 0 -#define PIXMA_VERSION_MINOR 23 +#define PIXMA_VERSION_MINOR 27 #define PIXMA_VERSION_BUILD 0 /**@}*/ @@ -313,7 +316,7 @@ struct pixma_scan_param_t /** Flag indicating whether the offset correction for TPU scans * was already performed (to avoid repeated corrections). - * Currently only used in pixma_mp810.c sub-driver */ + * Currently only used in pixma_mp800.c sub-driver */ unsigned tpu_offset_added; /* Flag indicating if data from scanner will be in JPEG format */ @@ -362,6 +365,7 @@ struct pixma_config_t uint16_t pid; /**< USB Product ID */ unsigned iface; /**< USB Interface number */ const pixma_scan_ops_t *ops; /**< Subdriver ops */ + unsigned min_xdpi; /**< Minimum horizontal resolution[DPI] */ unsigned xdpi; /**< Maximum horizontal resolution[DPI] */ unsigned ydpi; /**< Maximum vertical resolution[DPI] */ unsigned adftpu_min_dpi; /**< Maximum horizontal resolution[DPI] for adf/tpu @@ -403,7 +407,7 @@ void pixma_set_debug_level (int level); * * \return The number of scanners found currently. The return value is * guaranteed to be valid until the next call to pixma_find_scanners(). */ -int pixma_find_scanners (const char **conf_devices); +int pixma_find_scanners (const char **conf_devices, SANE_Bool local_only); /** Return the model name of the device \a devnr. */ const char *pixma_get_device_model (unsigned devnr); diff --git a/backend/pixma_bjnp.c b/backend/pixma/pixma_bjnp.c index 5a9932e..34ba918 100644 --- a/backend/pixma_bjnp.c +++ b/backend/pixma/pixma_bjnp.c @@ -39,6 +39,7 @@ whether to permit this exception to apply to your modifications. If you do not wish that, delete this exception notice. */ + #undef BACKEND_NAME #define BACKEND_NAME bjnp @@ -68,6 +69,9 @@ #ifdef HAVE_LIMITS_H #include <limits.h> #endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif /* * networking stuff @@ -114,6 +118,40 @@ static int bjnp_no_devices = 0; * Private functions */ +static const struct pixma_config_t *lookup_scanner(const char *makemodel, + const struct pixma_config_t *const pixma_devices[]) +{ + int i; + const struct pixma_config_t *cfg; + char *match; + + for (i = 0; pixma_devices[i]; i++) + { + /* loop through the device classes (mp150, mp730 etc) */ + for (cfg = pixma_devices[i]; cfg->name; cfg++) + { + /* loop through devices in class */ + PDBG( bjnp_dbg( LOG_DEBUG3, "lookup_scanner: Checking for %s in %s\n", makemodel, cfg->model)); + if ((match = strcasestr (makemodel, cfg->model)) != NULL) + { + /* possible match found, make sure it is not a partial match */ + /* MP600 and MP600R are different models! */ + /* some models contain ranges, so check for a '-' too */ + + if ((match[strlen(cfg->model)] == ' ') || + (match[strlen(cfg->model)] == '\0') || + (match[strlen(cfg->model)] == '-')) + { + PDBG( bjnp_dbg (LOG_DEBUG, "lookup_scanner: Scanner model found: Name %s(%s) matches %s\n", cfg->model, cfg->name, makemodel)); + return cfg; + } + } + } + } + PDBG( bjnp_dbg (LOG_DEBUG, "lookup_scanner: Scanner model %s not found, giving up!\n", makemodel)); + return NULL; +} + static void u8tohex (char *string, const uint8_t *value, int len ) { @@ -289,6 +327,7 @@ parse_IEEE1284_to_model (char *scanner_id, char *model) char s[BJNP_IEEE1284_MAX]; char *tok; + char * model_str; strncpy (s, scanner_id, BJNP_IEEE1284_MAX); s[BJNP_IEEE1284_MAX - 1] = '\0'; @@ -299,10 +338,11 @@ parse_IEEE1284_to_model (char *scanner_id, char *model) { /* MDL contains make and model */ - if (strncmp (tok, "MDL:", 4) == 0) + if (strncmp (tok, "MDL:", strlen("MDL:")) == 0) { - strncpy (model, tok + 4, BJNP_IEEE1284_MAX); - model[BJNP_IEEE1284_MAX -1] = '\0'; + model_str = tok + strlen("MDL:"); + strncpy (model, model_str, BJNP_MODEL_MAX); + model[BJNP_MODEL_MAX -1] = '\0'; return 1; } tok = strtok (NULL, ";"); @@ -421,6 +461,7 @@ bjnp_open_tcp (int devno) bjnp_sockaddr_t *addr = device[devno].addr; char host[BJNP_HOST_MAX]; int port; + int connect_timeout = BJNP_TIMEOUT_TCP_CONNECT; get_address_info( addr, host, &port); PDBG (bjnp_dbg (LOG_DEBUG, "bjnp_open_tcp: Setting up a TCP socket, dest: %s port %d\n", @@ -457,16 +498,22 @@ bjnp_open_tcp (int devno) fcntl (sock, F_SETFD, FD_CLOEXEC); - if (connect - (sock, &(addr->addr), sa_size(device[devno].addr) )!= 0) + while (connect_timeout > 0) { - PDBG (bjnp_dbg - (LOG_CRIT, "bjnp_open_tcp: ERROR - Can not connect to scanner: %s\n", - strerror (errno))); - return -1; + if (connect + (sock, &(addr->addr), sa_size(device[devno].addr)) == 0) + { + device[devno].tcp_socket = sock; + return 0; + } + PDBG (bjnp_dbg( LOG_INFO, "bjnp_open_tcp: INFO - Can not yet connect over TCP to scanner: %s, retrying\n", + strerror(errno))); + usleep(BJNP_TCP_CONNECT_INTERVAL * BJNP_USLEEP_MS); + connect_timeout = connect_timeout - BJNP_TCP_CONNECT_INTERVAL; } - device[devno].tcp_socket = sock; - return 0; + PDBG (bjnp_dbg + (LOG_CRIT, "bjnp_open_tcp: ERROR - Can not connect to scanner, giving up!")); + return -1; } static int @@ -598,7 +645,7 @@ set_cmd_from_string (char* protocol_string, struct BJNP_command *cmd, char cmd_c * Returns: sequence number of command */ - strncpy (cmd->BJNP_id, protocol_string, sizeof (cmd->BJNP_id)); + memcpy (cmd->BJNP_id, protocol_string, sizeof (cmd->BJNP_id)); cmd->dev_type = BJNP_CMD_SCAN; cmd->cmd_code = cmd_code; cmd->unknown1 = htons (0); @@ -617,7 +664,7 @@ set_cmd_for_dev (int devno, struct BJNP_command *cmd, char cmd_code, int payload * Returns: sequence number of command */ - strncpy (cmd->BJNP_id, device[devno].protocol_string, sizeof (cmd->BJNP_id)); + memcpy(cmd->BJNP_id, device[devno].protocol_string, sizeof (cmd->BJNP_id)); cmd->dev_type = BJNP_CMD_SCAN; cmd->cmd_code = cmd_code; cmd->unknown1 = htons (0); @@ -707,8 +754,8 @@ udp_command (const int dev_no, char *command, int cmd_len, char *response, FD_ZERO (&fdset); FD_SET (sockfd, &fdset); - timeout.tv_sec = device[dev_no].bjnp_timeout /1000; - timeout.tv_usec = device[dev_no].bjnp_timeout %1000; + timeout.tv_sec = device[dev_no].bjnp_ip_timeout /1000; + timeout.tv_usec = device[dev_no].bjnp_ip_timeout %1000; } while (((result = select (sockfd + 1, &fdset, NULL, NULL, &timeout)) <= 0) @@ -738,7 +785,7 @@ udp_command (const int dev_no, char *command, int cmd_len, char *response, close(sockfd); PDBG (bjnp_dbg - (LOG_CRIT, "udp_command: ERROR - no data received (timeout = %d)\n", device[dev_no].bjnp_timeout ) ); + (LOG_CRIT, "udp_command: ERROR - no data received (timeout = %d)\n", device[dev_no].bjnp_ip_timeout ) ); return -1; } @@ -1424,8 +1471,8 @@ bjnp_recv_header (int devno, size_t *payload_size ) FD_ZERO (&input); FD_SET (fd, &input); - timeout.tv_sec = device[devno].bjnp_timeout /1000; - timeout.tv_usec = device[devno].bjnp_timeout %1000; + timeout.tv_sec = device[devno].bjnp_ip_timeout /1000; + timeout.tv_usec = device[devno].bjnp_ip_timeout %1000; } while ( ( (result = select (fd + 1, &input, NULL, NULL, &timeout)) <= 0) && (errno == EINTR) && (attempt++ < BJNP_MAX_SELECT_ATTEMPTS)); @@ -1444,7 +1491,7 @@ bjnp_recv_header (int devno, size_t *payload_size ) terrno = errno; PDBG (bjnp_dbg (LOG_CRIT, "bjnp_recv_header: ERROR - could not read response header (select timed out after %d ms)!\n", - device[devno].bjnp_timeout ) ); + device[devno].bjnp_ip_timeout ) ); errno = terrno; return SANE_STATUS_IO_ERROR; } @@ -1504,7 +1551,7 @@ bjnp_recv_header (int devno, size_t *payload_size ) } static int -bjnp_init_device_structure(int dn, bjnp_sockaddr_t *sa, bjnp_protocol_defs_t *protocol_defs, int min_timeout) +bjnp_init_device_structure(int dn, bjnp_sockaddr_t *sa, bjnp_protocol_defs_t *protocol_defs, int ip_timeout) { /* initialize device structure */ @@ -1526,8 +1573,8 @@ bjnp_init_device_structure(int dn, bjnp_sockaddr_t *sa, bjnp_protocol_defs_t *pr device[dn].address_level = get_scanner_name(sa, name); device[dn].session_id = 0; device[dn].serial = -1; - device[dn].bjnp_timeout = min_timeout; - device[dn].bjnp_min_timeout = min_timeout; + device[dn].bjnp_ip_timeout = ip_timeout; + device[dn].bjnp_scanner_timeout = 1000; device[dn].scanner_data_left = 0; device[dn].last_cmd = 0; device[dn].blocksize = BJNP_BLOCKSIZE_START; @@ -1538,8 +1585,10 @@ bjnp_init_device_structure(int dn, bjnp_sockaddr_t *sa, bjnp_protocol_defs_t *pr { PDBG (bjnp_dbg (LOG_CRIT, "bjnp_init_device_structure: Cannot read mac address, skipping this scanner\n" ) ); + device[dn].open = 0; return -1; } + device[dn].open = 1; return 0; } @@ -1600,8 +1649,8 @@ bjnp_recv_data (int devno, SANE_Byte * buffer, size_t start_pos, size_t * len) /* wait for data to be received, retry on a signal being received */ FD_ZERO (&input); FD_SET (fd, &input); - timeout.tv_sec = device[devno].bjnp_timeout /1000; - timeout.tv_usec = device[devno].bjnp_timeout %1000; + timeout.tv_sec = device[devno].bjnp_ip_timeout /1000; + timeout.tv_usec = device[devno].bjnp_ip_timeout %1000; } while (((result = select (fd + 1, &input, NULL, NULL, &timeout)) <= 0) && (errno == EINTR) && (attempt++ < BJNP_MAX_SELECT_ATTEMPTS)); @@ -1621,7 +1670,7 @@ bjnp_recv_data (int devno, SANE_Byte * buffer, size_t start_pos, size_t * len) terrno = errno; PDBG (bjnp_dbg (LOG_CRIT, "bjnp_recv_data: ERROR - could not read response payload (select timed out after %d ms)!\n", - device[devno].bjnp_timeout) ); + device[devno].bjnp_ip_timeout) ); errno = terrno; *len = 0; return SANE_STATUS_IO_ERROR; @@ -1658,7 +1707,7 @@ bjnp_allocate_device (SANE_String_Const devname, struct addrinfo hints; int result; int i; - int min_timeout = BJNP_TIMEOUT_DEFAULT; + int ip_timeout = BJNP_TIMEOUT_DEFAULT; PDBG (bjnp_dbg (LOG_DEBUG, "bjnp_allocate_device(%s) %d\n", devname, bjnp_no_devices)); @@ -1669,13 +1718,11 @@ bjnp_allocate_device (SANE_String_Const devname, if (strlen (args) > 0) { - /* get device specific timeout if any */ + /* get device specific ip timeout if any */ if (strncmp(args, "timeout=", strlen("timeout=")) == 0) { - min_timeout = atoi(args + strlen("timeout=")); - if (min_timeout < BJNP_TIMEOUT_DEFAULT) - min_timeout = BJNP_TIMEOUT_DEFAULT; + ip_timeout = atoi(args + strlen("timeout=")); } else { PDBG (bjnp_dbg (LOG_CRIT, @@ -1735,10 +1782,11 @@ bjnp_allocate_device (SANE_String_Const devname, return BJNP_STATUS_INVAL; } if (bjnp_init_device_structure( bjnp_no_devices, (bjnp_sockaddr_t *)cur -> ai_addr, - protocol_defs, min_timeout) != 0) + protocol_defs, ip_timeout) != 0) { /* giving up on this address, try next one if any */ - break; + cur = cur->ai_next; + continue; } for (i = 0; i < bjnp_no_devices; i++) { @@ -1759,15 +1807,8 @@ bjnp_allocate_device (SANE_String_Const devname, device[i].address_level = device[bjnp_no_devices].address_level; } - /* check if new timeout value was defined (e.g. from sanei_bjnp_device_open) - * if so, use new timout value */ + /* Leave timeout values unchanged, as they were probably specified by the user */ - if (device[i].bjnp_min_timeout < device[bjnp_no_devices].bjnp_min_timeout) - { - /* use the longer timeout as requested */ - device[i].bjnp_timeout = device[bjnp_no_devices].bjnp_min_timeout; - device[i].bjnp_min_timeout = device[bjnp_no_devices].bjnp_min_timeout; - } freeaddrinfo(res); *dn = i; bjnp_free_device_structure( bjnp_no_devices); @@ -1778,6 +1819,12 @@ bjnp_allocate_device (SANE_String_Const devname, } freeaddrinfo(res); + if (device[bjnp_no_devices].open == 0) + { + PDBG (bjnp_dbg(LOG_NOTICE, "bjnp_allocate_device: Cannot access scanner, skipping!")); + return BJNP_STATUS_INVAL; + } + PDBG (bjnp_dbg (LOG_INFO, "bjnp_allocate_device: Scanner not yet in our list, added it: %s:%s\n", host, port)); /* Commit new device structure */ @@ -1799,16 +1846,15 @@ static void add_scanner(SANE_Int *dev_no, const char *uri, SANE_Status (*attach_bjnp) (SANE_String_Const devname, - SANE_String_Const makemodel, SANE_String_Const serial, - const struct pixma_config_t * - const pixma_devices[]), - const struct pixma_config_t *const pixma_devices[]) + const struct pixma_config_t *cfg), + const struct pixma_config_t *const pixma_devices[]) { char scanner_host[BJNP_HOST_MAX]; char serial[BJNP_SERIAL_MAX]; - char makemodel[BJNP_IEEE1284_MAX]; + char makemodel[BJNP_MODEL_MAX]; + const struct pixma_config_t *cfg = NULL; /* Allocate device structure for scanner */ switch (bjnp_allocate_device (uri, dev_no, scanner_host)) @@ -1821,17 +1867,32 @@ static void add_scanner(SANE_Int *dev_no, } else { - /* - * inform caller of found scanner - */ + /* + * fetch scanner configuration + */ + if ((cfg = lookup_scanner(makemodel, pixma_devices)) == (struct pixma_config_t *)NULL) + { + PDBG (bjnp_dbg (LOG_CRIT, "add_scanner: Scanner %s is not supported, model is unknown! Please report upstream\n", makemodel)); + break; + } - determine_scanner_serial (scanner_host, device[*dev_no].mac_address, serial); + /* + * inform caller of found scanner + */ - attach_bjnp (uri, makemodel, - serial, pixma_devices); - PDBG (bjnp_dbg (LOG_NOTICE, "add_scanner: New scanner added: %s, serial %s, mac address: %s.\n", - uri, serial, device[*dev_no].mac_address)); + determine_scanner_serial (scanner_host, device[*dev_no].mac_address, serial); + + switch (attach_bjnp (uri, serial, cfg)) + { + case SANE_STATUS_GOOD: + PDBG (bjnp_dbg (LOG_NOTICE, "add_scanner: New scanner added: %s, serial %s, mac address: %s.\n", + uri, serial, device[*dev_no].mac_address)); + break; + default: + PDBG (bjnp_dbg (LOG_CRIT, "add_scanner: unexpected error (out of memory?), adding %s\n", makemodel)); + } } + break; case BJNP_STATUS_ALREADY_ALLOCATED: PDBG (bjnp_dbg (LOG_NOTICE, "add_scanner: Scanner at %s was added before, good!\n", @@ -1845,13 +1906,14 @@ static void add_scanner(SANE_Int *dev_no, } } -int add_default_timeout(char *uri, int timeout, int max_len) +int add_timeout_to_uri(char *uri, int timeout, int max_len) { char method[BJNP_METHOD_MAX]; char host[BJNP_HOST_MAX]; char port_str[BJNP_PORT_MAX]; char args[BJNP_HOST_MAX]; int port; + bjnp_protocol_defs_t *proto_struct; if (split_uri(uri, method, host, port_str, args ) != 0) { @@ -1859,24 +1921,33 @@ int add_default_timeout(char *uri, int timeout, int max_len) } port = atoi(port_str); + if (port == 0) { - port = 8612; + proto_struct = get_protocol_by_method(method); + if (proto_struct == NULL) + { + PDBG (bjnp_dbg (LOG_NOTICE, "uri: %s: Method %s cannot be recognized\n", uri, method)); + } + else + { + port = proto_struct-> default_port; + } } + /* add timeout value only if missing in URI */ + if (strstr(args, "timeout=") == NULL) { sprintf(args, "timeout=%d", timeout); } snprintf(uri, max_len -1, "%s://%s:%d/%s", method,host, port, args); + uri[max_len - 1] = '\0'; return 0; } - -/* - * Public functions - */ +/** Public functions **/ /** Initialize sanei_bjnp. * @@ -1901,11 +1972,9 @@ sanei_bjnp_init (void) extern SANE_Status sanei_bjnp_find_devices (const char **conf_devices, SANE_Status (*attach_bjnp) - (SANE_String_Const devname, - SANE_String_Const makemodel, - SANE_String_Const serial, - const struct pixma_config_t * - const pixma_devices[]), + (SANE_String_Const devname, + SANE_String_Const serial, + const struct pixma_config_t *cfg), const struct pixma_config_t *const pixma_devices[]) { int numbytes = 0; @@ -1921,10 +1990,11 @@ sanei_bjnp_find_devices (const char **conf_devices, fd_set fdset; fd_set active_fdset; struct timeval timeout; - char scanner_host[256]; - char uri[256]; + char scanner_host[HOST_NAME_MAX]; + char uri[HOST_NAME_MAX + 32]; int dev_no; int port; + int auto_detect = 1; int timeout_default = BJNP_TIMEOUT_DEFAULT; bjnp_sockaddr_t broadcast_addr[BJNP_SOCK_MAX]; bjnp_sockaddr_t scanner_sa; @@ -1942,38 +2012,57 @@ sanei_bjnp_find_devices (const char **conf_devices, socket_fd[i] = -1; } - /* Add devices from config file */ - - if (conf_devices[0] == NULL) - PDBG (bjnp_dbg( LOG_DEBUG, "sanei_bjnp_find_devices: No devices specified in configuration file.\n" ) ); + /* parse config file */ - for (i = 0; conf_devices[i] != NULL; i++) + if (conf_devices[0] != NULL) { - if (strncmp(conf_devices[i], "bjnp-timeout=", strlen("bjnp-timeout="))== 0) + if (strcmp(conf_devices[0], "networking=no") == 0) { - timeout_default = atoi(conf_devices[i] + strlen("bjnp-timeout=") ); - if (timeout_default < BJNP_TIMEOUT_DEFAULT) - { - timeout_default = BJNP_TIMEOUT_DEFAULT; + /* networking=no may only occur on the first non-commented line */ + + PDBG (bjnp_dbg( LOG_DEBUG, "sanei_bjnp_find_devices: Networked scanner detection is disabled in configuration file.\n" ) ); + return SANE_STATUS_GOOD; + } + /* parse configuration file */ + + for (i = 0; conf_devices[i] != NULL; i++) + { + if (strncmp(conf_devices[i], "bjnp-timeout=", strlen("bjnp-timeout="))== 0) + { + timeout_default = atoi(conf_devices[i] + strlen("bjnp-timeout=") ); + PDBG ( bjnp_dbg (LOG_DEBUG, "Set new default timeout value: %d ms.", timeout_default)); + continue; } - PDBG ( bjnp_dbg - (LOG_DEBUG, "Set new default timeout value: %d ms.", timeout_default)); - continue; - } - PDBG (bjnp_dbg - (LOG_DEBUG, "sanei_bjnp_find_devices: Adding scanner from pixma.conf: %s\n", conf_devices[i])); - strncpy(uri, conf_devices[i], sizeof(uri)); - add_default_timeout(uri, timeout_default, sizeof(uri)); - add_scanner(&dev_no, uri, attach_bjnp, pixma_devices); + else if (strncmp(conf_devices[i], "auto_detection=no", strlen("auto_detection=no"))== 0) + { + auto_detect = 0; + PDBG ( bjnp_dbg (LOG_DEBUG, "sanei_bjnp_find_devices: auto detection of scanners disabled")); + continue; + } + else + { + PDBG (bjnp_dbg (LOG_DEBUG, "sanei_bjnp_find_devices: Adding scanner from pixma.conf: %s\n", conf_devices[i])); + memcpy(uri, conf_devices[i], sizeof(uri)); + add_timeout_to_uri(uri, timeout_default, sizeof(uri)); + add_scanner(&dev_no, uri, attach_bjnp, pixma_devices); + } + } + PDBG (bjnp_dbg (LOG_DEBUG, "sanei_bjnp_find_devices: Added all specified scanners.\n")); + } + else + { + PDBG (bjnp_dbg( LOG_DEBUG, "sanei_bjnp_find_devices: Configuration file is empty, No devices specified.\n" ) ); } - PDBG (bjnp_dbg - (LOG_DEBUG, - "sanei_bjnp_find_devices: Added all configured scanners, now do auto detection...\n")); + if (auto_detect == 0) + { + return SANE_STATUS_GOOD; + } /* * Send UDP DISCOVER to discover scanners and return the list of scanners found */ + PDBG (bjnp_dbg( LOG_DEBUG, "sanei_bjnp_find_devices: Start auto-detection.\n" ) ); FD_ZERO (&fdset); no_sockets = 0; @@ -2252,17 +2341,10 @@ sanei_bjnp_deactivate (SANE_Int dn) extern void sanei_bjnp_set_timeout (SANE_Int devno, SANE_Int timeout) { - if (timeout < device[devno].bjnp_min_timeout) - { - PDBG (bjnp_dbg (LOG_INFO, "bjnp_set_timeout to %d, but using minimum value %d\n", - timeout, device[devno].bjnp_min_timeout)); - timeout = device[devno].bjnp_min_timeout; - } else { - PDBG (bjnp_dbg (LOG_INFO, "bjnp_set_timeout to %d\n", - timeout)); - } + PDBG (bjnp_dbg (LOG_INFO, "bjnp_set_timeout to %d\n", + timeout)); - device[devno].bjnp_timeout = timeout; + device[devno].bjnp_scanner_timeout = timeout; } /** Initiate a bulk transfer read. @@ -2490,7 +2572,7 @@ sanei_bjnp_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) char hostname[256]; int resp_len; int timeout; - int seconds; + int interval; PDBG (bjnp_dbg (LOG_INFO, "bjnp_read_int(%d, bufferptr, 0x%lx = %ld):\n", dn, @@ -2518,17 +2600,21 @@ sanei_bjnp_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) } device[dn].polling_status = BJNP_POLL_STARTED; - /* fall through to BJNP_POLL_STARTED */ - + /* fall through */ case BJNP_POLL_STARTED: - /* we use only seonds accuracy between poll attempts */ - timeout = device[dn].bjnp_timeout /1000; + /* we use only seonds (rounded up) accuracy between poll attempts */ + timeout = device[dn].bjnp_scanner_timeout /1000 + 1; + if (device[dn].bjnp_scanner_timeout %1000 > 0) + { + timeout++; + } + interval = 1; do { if ( (resp_len = bjnp_poll_scanner (dn, 2, hostname, getusername (), buffer, *size ) ) < 0 ) { - PDBG (bjnp_dbg (LOG_NOTICE, "bjnp_read_int: Restarting polling dialog!\n")); + PDBG (bjnp_dbg (LOG_NOTICE, "bjnp_read_int: Poll failed, Restarting polling dialog!\n")); device[dn].polling_status = BJNP_POLL_STOPPED; *size = 0; return SANE_STATUS_EOF; @@ -2539,9 +2625,10 @@ sanei_bjnp_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) device[dn].polling_status = BJNP_POLL_STATUS_RECEIVED; return SANE_STATUS_GOOD; } - seconds = timeout > 2 ? 2 : timeout; - sleep(seconds); - timeout = timeout - seconds; + timeout = timeout - interval; + if (timeout <= 0) + return SANE_STATUS_EOF; + sleep(interval); } while ( timeout > 0 ) ; break; case BJNP_POLL_STATUS_RECEIVED: diff --git a/backend/pixma_bjnp.h b/backend/pixma/pixma_bjnp.h index a27082c..79e084e 100644 --- a/backend/pixma_bjnp.h +++ b/backend/pixma/pixma_bjnp.h @@ -81,12 +81,10 @@ extern void sanei_bjnp_init (void); extern SANE_Status sanei_bjnp_find_devices (const char **conf_devices, SANE_Status (*attach_bjnp) - (SANE_String_Const devname, - SANE_String_Const makemodel, - SANE_String_Const serial, - const struct pixma_config_t * - const pixma_devices[]), - const struct pixma_config_t *const pixma_devices[]); + (SANE_String_Const devname, + SANE_String_Const serial, + const struct pixma_config_t *cfg), + const struct pixma_config_t *const pixma_devices[]); /** Open a BJNP device. * diff --git a/backend/pixma_bjnp_private.h b/backend/pixma/pixma_bjnp_private.h index 84f5c3f..edfb330 100644 --- a/backend/pixma_bjnp_private.h +++ b/backend/pixma/pixma_bjnp_private.h @@ -81,7 +81,9 @@ #define BJNP_BROADCAST_INTERVAL 10 /* ms between broadcasts */ #define BJNP_BC_RESPONSE_TIMEOUT 500 /* waiting time for broadc. responses */ #define BJNP_TIMEOUT_DEFAULT 10000 /* minimum tiemout value for network operations */ +#define BJNP_TIMEOUT_TCP_CONNECT 2000 /* timeout for tcp connect attempts in ms */ #define BJNP_USLEEP_MS 1000 /* sleep for 1 msec */ +#define BJNP_TCP_CONNECT_INTERVAL 100 /* TCP retry interval in ms */ /* retries */ #define BJNP_MAX_SELECT_ATTEMPTS 3 /* max nr of retries on select (EINTR) */ @@ -369,8 +371,8 @@ typedef struct device_s /* mac-address, used as device serial no */ bjnp_sockaddr_t * addr; /* ip-address of the scanner */ int address_level; /* link local, public or has a FQDN */ - int bjnp_timeout; /* timeout (msec) for next poll command */ - int bjnp_min_timeout; /* device specific min timeout */ + int bjnp_scanner_timeout; /* timeout (msec) for next poll command */ + int bjnp_ip_timeout; /* device specific min timeout for the IP-protocol */ #ifdef PIXMA_BJNP_USE_STATUS /* polling state information */ diff --git a/backend/pixma_common.c b/backend/pixma/pixma_common.c index 82c4fde..7b7ecec 100644 --- a/backend/pixma_common.c +++ b/backend/pixma/pixma_common.c @@ -58,7 +58,7 @@ #include "pixma_io.h" #include "../include/sane/sanei_usb.h" - +#include "../include/sane/sane.h" #ifdef __GNUC__ # define UNUSED(v) (void) v @@ -69,14 +69,14 @@ extern const pixma_config_t pixma_mp150_devices[]; extern const pixma_config_t pixma_mp750_devices[]; extern const pixma_config_t pixma_mp730_devices[]; -extern const pixma_config_t pixma_mp810_devices[]; +extern const pixma_config_t pixma_mp800_devices[]; extern const pixma_config_t pixma_iclass_devices[]; static const pixma_config_t *const pixma_devices[] = { pixma_mp150_devices, pixma_mp750_devices, pixma_mp730_devices, - pixma_mp810_devices, + pixma_mp800_devices, pixma_iclass_devices, NULL }; @@ -1164,9 +1164,9 @@ pixma_fill_gamma_table (double gamma, uint8_t * table, unsigned n) } int -pixma_find_scanners (const char **conf_devices) +pixma_find_scanners (const char **conf_devices, SANE_Bool local_only) { - return pixma_collect_devices (conf_devices, pixma_devices); + return pixma_collect_devices (conf_devices, pixma_devices, local_only); } const char * diff --git a/backend/pixma_common.h b/backend/pixma/pixma_common.h index c0ed4ba..c0ed4ba 100644 --- a/backend/pixma_common.h +++ b/backend/pixma/pixma_common.h diff --git a/backend/pixma_imageclass.c b/backend/pixma/pixma_imageclass.c index 9301bc6..ce0c37d 100644 --- a/backend/pixma_imageclass.c +++ b/backend/pixma/pixma_imageclass.c @@ -119,7 +119,9 @@ #define MF420_PID 0x27f1 #define MF260_PID 0x27f4 #define MF740_PID 0x27fb +#define MF743_PID 0x27fc #define MF640_PID 0x27fe +#define MF645_PID 0x27fd enum iclass_state_t @@ -913,6 +915,7 @@ static const pixma_scan_ops_t pixma_iclass_ops = { 0x04a9, pid, /* vid pid */ \ 1, /* iface */ \ &pixma_iclass_ops, /* ops */ \ + 0, /* min_xdpi not used in this subdriver */ \ dpi, dpi, /* xdpi, ydpi */ \ 0, /* adftpu_min_dpi not used in this subdriver */ \ adftpu_max_dpi, /* adftpu_max_dpi */ \ @@ -966,14 +969,17 @@ const pixma_config_t pixma_iclass_devices[] = { DEV ("Canon i-SENSYS MF630 Series", "MF630", MF630_PID, 600, 0, 637, 1050, PIXMA_CAP_ADFDUP), DEV ("Canon i-SENSYS MF730 Series", "MF730", MF730_PID, 600, 0, 637, 1050, PIXMA_CAP_ADFDUP), DEV ("Canon i-SENSYS MF731C", "MF731", MF731_PID, 600, 0, 637, 1050, PIXMA_CAP_ADFDUP), + DEV ("Canon i-SENSYS MF633C/MF635C", "MF633C/635C", MF630_PID, 600, 0, 637, 877, PIXMA_CAP_ADFDUP), /* max. w = 216mm */ DEV ("Canon imageCLASS MF634C", "MF632C/634C", MF634_PID, 600, 0, 637, 1050, PIXMA_CAP_ADFDUP), DEV ("Canon imageCLASS MF733C", "MF731C/733C", MF731_PID, 600, 0, 637, 1050, PIXMA_CAP_ADFDUP), /* however, we need this for ethernet/wifi */ DEV ("Canon imageCLASS D570", "D570", D570_PID, 600, 0, 640, 877, 0), DEV ("Canon i-SENSYS MF110 Series", "MF110", MF110_PID, 600, 0, 640, 1050, 0), DEV ("Canon i-SENSYS MF520 Series", "MF520", MF520_PID, 600, 0, 640, 1050, PIXMA_CAP_ADFDUP), DEV ("Canon i-SENSYS MF420 Series", "MF420", MF420_PID, 600, 0, 640, 1050, PIXMA_CAP_ADFDUP), - DEV ("Canon i-SENSYS MF260 Series", "MF260", MF260_PID, 600, 0, 640, 1050, 0), + DEV ("Canon i-SENSYS MF260 Series", "MF260", MF260_PID, 600, 0, 640, 1050, PIXMA_CAP_ADFDUP), DEV ("Canon i-SENSYS MF740 Series", "MF740", MF740_PID, 600, 0, 640, 1050, PIXMA_CAP_ADFDUP), - DEV ("Canon i-SENSYS MF640 Series", "MF640", MF640_PID, 600, 0, 640, 1050, PIXMA_CAP_ADFDUP), + DEV ("Canon i-SENSYS MF741C/743C", "MF741C/743C", MF743_PID, 600, 300, 640, 1050, PIXMA_CAP_ADFDUP), /* ADFDUP restricted to 300dpi */ + DEV ("Canon i-SENSYS MF640 Series", "MF642C/643C/644C", MF640_PID, 600, 0, 640, 1050, PIXMA_CAP_ADFDUP), + DEV ("Canon i-SENSYS MF645C", "MF645C", MF645_PID, 600, 0, 637, 877, PIXMA_CAP_ADFDUP), /* max. w = 216mm */ DEV (NULL, NULL, 0, 0, 0, 0, 0, 0) }; diff --git a/backend/pixma_io.h b/backend/pixma/pixma_io.h index 29bb38d..715bab5 100644 --- a/backend/pixma_io.h +++ b/backend/pixma/pixma_io.h @@ -93,7 +93,7 @@ void pixma_io_cleanup (void); * \return Number of devices found */ unsigned pixma_collect_devices (const char ** conf_devices, const struct pixma_config_t *const - pixma_devices[]); + pixma_devices[], SANE_Bool local_only); /** Get device configuration. */ const struct pixma_config_t *pixma_get_device_config (unsigned devnr); diff --git a/backend/pixma_io_sanei.c b/backend/pixma/pixma_io_sanei.c index 4710cf4..c30b404 100644 --- a/backend/pixma_io_sanei.c +++ b/backend/pixma/pixma_io_sanei.c @@ -55,6 +55,7 @@ #include "pixma_bjnp.h" #include "../include/sane/sanei_usb.h" +#include "../include/sane/sane.h" #ifdef __GNUC__ @@ -106,39 +107,6 @@ get_scanner_info (unsigned devnr) return si; } -static const struct pixma_config_t *lookup_scanner(const char *makemodel, - const struct pixma_config_t *const pixma_devices[]) -{ - int i; - const struct pixma_config_t *cfg; - char *match; - - for (i = 0; pixma_devices[i]; i++) - { - /* loop through the device classes (mp150, mp730 etc) */ - for (cfg = pixma_devices[i]; cfg->name; cfg++) - { - /* loop through devices in class */ - if ((match = strcasestr (makemodel, cfg->model)) != NULL) - { - /* possible match found, make sure it is not a partial match */ - /* MP600 and MP600R are different models! */ - /* some models contain ranges, so check for a '-' too */ - - if ((match[strlen(cfg->model)] == ' ') || - (match[strlen(cfg->model)] == '\0') || - (match[strlen(cfg->model)] == '-')) - { - pixma_dbg (3, "Scanner model found: Name %s(%s) matches %s\n", cfg->model, cfg->name, makemodel); - return cfg; - } - } - pixma_dbg (20, "Scanner model %s(%s) not found, giving up! %s\n", cfg->model, cfg->name, makemodel); - } - } - return NULL; -} - static SANE_Status attach (SANE_String_Const devname) { @@ -159,13 +127,11 @@ attach (SANE_String_Const devname) static SANE_Status -attach_bjnp (SANE_String_Const devname, SANE_String_Const makemodel, +attach_bjnp (SANE_String_Const devname, SANE_String_Const serial, - const struct pixma_config_t *const pixma_devices[]) + const struct pixma_config_t *cfg) { scanner_info_t *si; - const pixma_config_t *cfg; - SANE_Status error; si = (scanner_info_t *) calloc (1, sizeof (*si)); if (!si) @@ -173,19 +139,14 @@ attach_bjnp (SANE_String_Const devname, SANE_String_Const makemodel, si->devname = strdup (devname); if (!si->devname) return SANE_STATUS_NO_MEM; - if ((cfg = lookup_scanner(makemodel, pixma_devices)) == (struct pixma_config_t *)NULL) - error = SANE_STATUS_INVAL; - else - { - si->cfg = cfg; - sprintf(si->serial, "%s_%s", cfg->model, serial); - si -> interface = INT_BJNP; - si->next = first_scanner; - first_scanner = si; - nscanners++; - error = SANE_STATUS_GOOD; - } - return error; + + si->cfg = cfg; + sprintf(si->serial, "%s_%s", cfg->model, serial); + si -> interface = INT_BJNP; + si->next = first_scanner; + first_scanner = si; + nscanners++; + return SANE_STATUS_GOOD; } static void @@ -349,7 +310,7 @@ pixma_io_cleanup (void) unsigned pixma_collect_devices (const char **conf_devices, - const struct pixma_config_t *const pixma_devices[]) + const struct pixma_config_t *const pixma_devices[], SANE_Bool local_only) { unsigned i, j; struct scanner_info_t *si; @@ -374,7 +335,9 @@ pixma_collect_devices (const char **conf_devices, } } } - sanei_bjnp_find_devices(conf_devices, attach_bjnp, pixma_devices); + if (! local_only) + sanei_bjnp_find_devices(conf_devices, attach_bjnp, pixma_devices); + si = first_scanner; while (j < nscanners) { diff --git a/backend/pixma_mp150.c b/backend/pixma/pixma_mp150.c index 5f0a4ac..3973702 100644 --- a/backend/pixma_mp150.c +++ b/backend/pixma/pixma_mp150.c @@ -49,10 +49,6 @@ 4. cancel using ctrl-c (must send abort command) */ -#define TPU_48 /* uncomment to activate TPU scan at 48 bits */ -/*#define DEBUG_TPU_48*/ /* uncomment to debug 48 bits TPU on a non TPU device */ -/*#define DEBUG_TPU_24*/ /* uncomment to debug 24 bits TPU on a non TPU device */ - #include "../include/sane/config.h" #include <stdio.h> @@ -101,9 +97,6 @@ #define MP450_PID 0x170b #define MP500_PID 0x170c #define MP530_PID 0x1712 -#define MP800_PID 0x170d -#define MP800R_PID 0x170e -#define MP830_PID 0x1713 /* Generation 2 */ #define MP160_PID 0x1714 @@ -266,6 +259,7 @@ /* 2019 new devices (untested) */ #define TS8100_PID 0x1821 +#define G2010_PID 0x183a #define G3010_PID 0x183b #define G4010_PID 0x183d #define TS9180_PID 0x183e @@ -288,7 +282,21 @@ #define TS8230_PID 0x185b #define TS9580_PID 0x185d #define TR9530_PID 0x185e +#define G6000_PID 0x1865 +#define G6080_PID 0x1866 #define XK80_PID 0x1873 +#define TS5300_PID 0x188b +#define TS5380_PID 0x188c +#define TS6300_PID 0x188d +#define TS6380_PID 0x188e +#define TS7330_PID 0x188f +#define TS8300_PID 0x1890 +#define TS8380_PID 0x1891 +#define TS8330_PID 0x1892 +#define XK60_PID 0x1893 +#define TS6330_PID 0x1894 +#define TS3300_PID 0x18a2 +#define E3300_PID 0x18a3 /* Generation 4 XML messages that encapsulates the Pixma protocol messages */ #define XML_START_1 \ @@ -336,15 +344,9 @@ enum mp150_cmd_t cmd_read_image = 0xd420, cmd_error_info = 0xff20, - 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, - cmd_get_tpu_info_3 = 0xf520, - cmd_set_tpu_info_3 = 0xea20, - - cmd_e920 = 0xe920 /* seen in MP800 */ }; typedef struct mp150_t @@ -355,16 +357,17 @@ typedef struct mp150_t uint8_t current_status[16]; unsigned last_block; uint8_t generation; - /* for Generation 3 and CCD shift */ + /* for Generation 3 shift */ uint8_t *linebuf; uint8_t *data_left_ofs; unsigned data_left_len; - int shift[3]; - unsigned color_shift; - unsigned stripe_shift; - uint8_t tpu_datalen; - uint8_t tpu_data[0x40]; uint8_t adf_state; /* handle adf scanning */ + unsigned scale; /* Scale factor for lower resolutions, the + * scanner doesn't support. We scale down the + * image after scanning minimum possible + * resolution. + */ + } mp150_t; /* @@ -442,12 +445,6 @@ is_scanning_jpeg (pixma_t *s) } static int -is_scanning_from_tpu (pixma_t * s) -{ - return (s->param->source == PIXMA_SOURCE_TPU); -} - -static int send_xml_dialog (pixma_t * s, const char * xml_message) { mp150_t *mp = (mp150_t *) s->subdriver; @@ -466,19 +463,13 @@ send_xml_dialog (pixma_t * s, const char * xml_message) return (strcasestr ((const char *) mp->cb.buf, XML_OK) != NULL); } -static void -new_cmd_tpu_msg (pixma_t *s, pixma_cmdbuf_t * cb, uint16_t cmd) -{ - pixma_newcmd (cb, cmd, 0, 0); - cb->buf[3] = (is_scanning_from_tpu (s)) ? 0x01 : 0x00; -} - static int start_session (pixma_t * s) { mp150_t *mp = (mp150_t *) s->subdriver; - new_cmd_tpu_msg (s, &mp->cb, cmd_start_session); + pixma_newcmd (&mp->cb, cmd_start_session, 0, 0); + mp->cb.buf[3] = 0x00; return pixma_exec (s, &mp->cb); } @@ -487,17 +478,8 @@ start_scan_3 (pixma_t * s) { mp150_t *mp = (mp150_t *) s->subdriver; - new_cmd_tpu_msg (s, &mp->cb, cmd_scan_start_3); - return pixma_exec (s, &mp->cb); -} - -static int -send_cmd_start_calibrate_ccd_3 (pixma_t * s) -{ - mp150_t *mp = (mp150_t *) s->subdriver; - - pixma_newcmd (&mp->cb, cmd_start_calibrate_ccd_3, 0, 0); - mp->cb.buf[3] = 0x01; + pixma_newcmd (&mp->cb, cmd_scan_start_3, 0, 0); + mp->cb.buf[3] = 0x00; return pixma_exec (s, &mp->cb); } @@ -546,13 +528,6 @@ abort_session (pixma_t * s) } static int -send_cmd_e920 (pixma_t * s) -{ - mp150_t *mp = (mp150_t *) s->subdriver; - return pixma_exec_short_cmd (s, &mp->cb, cmd_e920); -} - -static int select_source (pixma_t * s) { mp150_t *mp = (mp150_t *) s->subdriver; @@ -579,41 +554,13 @@ select_source (pixma_t * s) data[6] = 3; break; - case PIXMA_SOURCE_TPU: - data[0] = 4; - data[1] = 2; - break; + default: + return PIXMA_EPROTO; } return pixma_exec (s, &mp->cb); } static int -send_get_tpu_info_3 (pixma_t * s) -{ - mp150_t *mp = (mp150_t *) s->subdriver; - uint8_t *data; - int error; - - data = pixma_newcmd (&mp->cb, cmd_get_tpu_info_3, 0, 0x34); - RET_IF_ERR (pixma_exec (s, &mp->cb)); - memcpy (mp->tpu_data, data, 0x34); - return error; -} - -static int -send_set_tpu_info (pixma_t * s) -{ - mp150_t *mp = (mp150_t *) s->subdriver; - uint8_t *data; - - if (mp->tpu_datalen == 0) - return 0; - data = pixma_newcmd (&mp->cb, cmd_set_tpu_info_3, 0x34, 0); - memcpy (data, mp->tpu_data, 0x34); - return pixma_exec (s, &mp->cb); -} - -static int send_gamma_table (pixma_t * s) { mp150_t *mp = (mp150_t *) s->subdriver; @@ -670,7 +617,7 @@ calc_raw_width (const mp150_t * mp, const pixma_scan_param_t * param) other models, too? */ if (mp->generation >= 2) { - raw_width = ALIGN_SUP (param->w + param->xs, 32); + raw_width = ALIGN_SUP ((param->w * mp->scale) + param->xs, 32); /* PDBG (pixma_dbg (4, "*calc_raw_width***** width %i extended by %i and rounded to %i *****\n", param->w, param->xs, raw_width)); */ } else if (param->channels == 1) @@ -684,82 +631,16 @@ calc_raw_width (const mp150_t * mp, const pixma_scan_param_t * param) return raw_width; } -static int -has_ccd_sensor (pixma_t * s) -{ - return ((s->cfg->cap & PIXMA_CAP_CCD) != 0); -} - -static int -is_ccd_grayscale (pixma_t * s) -{ - return (has_ccd_sensor (s) && (s->param->channels == 1) && !s->param->software_lineart); -} - -static int -is_ccd_lineart (pixma_t * s) -{ - return (has_ccd_sensor (s) && s->param->software_lineart); -} - -/* CCD sensors don't have neither a Grayscale mode nor a Lineart mode, - * but use color mode instead */ static unsigned -get_cis_ccd_line_size (pixma_t * s) -{ - return ((s->param->wx ? s->param->line_size / s->param->w * s->param->wx - : s->param->line_size) * ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : 1)); -} - -static unsigned -calc_shifting (pixma_t * s) +get_cis_line_size (pixma_t * s) { mp150_t *mp = (mp150_t *) s->subdriver; - /* If stripes shift needed (CCD devices), how many pixels shift */ - mp->stripe_shift = 0; - /* If color plane shift (CCD devices), how many pixels shift */ - mp->color_shift = mp->shift[0] = mp->shift[1] = mp->shift[2] = 0; - - switch (s->cfg->pid) - { - case MP800_PID: - case MP800R_PID: - case MP830_PID: - if (s->param->xdpi == 2400) - { - if (is_scanning_from_tpu(s)) - mp->stripe_shift = 6; - else - mp->stripe_shift = 3; - } - if (s->param->ydpi > 75) - { - mp->color_shift = s->param->ydpi / ((s->param->ydpi < 1200) ? 150 : 75); - - if (is_scanning_from_tpu (s)) - mp->color_shift = s->param->ydpi / 75; - - /* If you're trying to decipher this color-shifting code, - the following line is where the magic is revealed. */ - mp->shift[1] = mp->color_shift * get_cis_ccd_line_size (s); - if (is_scanning_from_adf (s)) - { /* ADF */ - mp->shift[0] = 0; - mp->shift[2] = 2 * mp->shift[1]; - } - else - { /* Flatbed or TPU */ - mp->shift[0] = 2 * mp->shift[1]; - mp->shift[2] = 0; - } - } - break; + /*PDBG (pixma_dbg (4, "%s: line_size=%ld, w=%d, wx=%d, scale=%d\n", + __func__, s->param->line_size, s->param->w, s->param->wx, mp->scale));*/ - default: /* Default, and all CIS devices */ - break; - } - return (2 * mp->color_shift + mp->stripe_shift); + return (s->param->wx ? s->param->line_size / s->param->w * s->param->wx + : s->param->line_size) * mp->scale; } static int @@ -767,33 +648,31 @@ send_scan_param (pixma_t * s) { mp150_t *mp = (mp150_t *) s->subdriver; uint8_t *data; - unsigned raw_width = calc_raw_width (mp, s->param); - unsigned h = MIN (s->param->h + calc_shifting (s), - s->cfg->height * s->param->ydpi / 75); - - /* TPU scan does not support lineart */ - if (is_scanning_from_tpu (s) && is_ccd_lineart (s)) - { - return PIXMA_ENOTSUP; - } + unsigned xdpi = s->param->xdpi * mp->scale; + unsigned ydpi = s->param->xdpi * mp->scale; + unsigned x = s->param->x * mp->scale; + unsigned xs = s->param->xs; + unsigned y = s->param->y * mp->scale; + unsigned wx = calc_raw_width (mp, s->param); + unsigned h = MIN (s->param->h, s->cfg->height * s->param->ydpi / 75) * mp->scale; if (mp->generation <= 2) { - /*PDBG (pixma_dbg (4, "*send_scan_param gen. 1-2 ***** Setting: xdpi=%hi ydpi=%hi x=%i y=%i w=%i ***** \n", - s->param->xdpi,s->param->ydpi,(s->param->x)-(s->param->xs),s->param->y,raw_width));*/ + PDBG (pixma_dbg (4, "*send_scan_param gen. 1-2 ***** Setting: xdpi=%hi ydpi=%hi x=%i y=%i wx=%i ***** \n", + xdpi, ydpi, x-xs, y, wx)); data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x30, 0); - pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x04); - pixma_set_be16 (s->param->ydpi | 0x8000, data + 0x06); - pixma_set_be32 (s->param->x, data + 0x08); + pixma_set_be16 (xdpi | 0x8000, data + 0x04); + pixma_set_be16 (ydpi | 0x8000, data + 0x06); + pixma_set_be32 (x, data + 0x08); if (mp->generation == 2) - pixma_set_be32 (s->param->x - s->param->xs, data + 0x08); - pixma_set_be32 (s->param->y, data + 0x0c); - pixma_set_be32 (raw_width, data + 0x10); + pixma_set_be32 (x - s->param->xs, data + 0x08); + pixma_set_be32 (y, data + 0x0c); + pixma_set_be32 (wx, data + 0x10); pixma_set_be32 (h, data + 0x14); - data[0x18] = ((s->param->channels != 1) || is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 0x08 : 0x04; + data[0x18] = (s->param->channels != 1) ? 0x08 : 0x04; data[0x19] = ((s->param->software_lineart) ? 8 : s->param->depth) - * ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels); /* bits per pixel */ - data[0x1a] = (is_scanning_from_tpu (s) ? 1 : 0); + * s->param->channels; /* bits per pixel */ + data[0x1a] = 0; data[0x20] = 0xff; data[0x23] = 0x81; data[0x26] = 0x02; @@ -801,15 +680,11 @@ send_scan_param (pixma_t * s) } else { + PDBG (pixma_dbg (4, "*send_scan_param gen. 3+ ***** Setting: xdpi=%hi ydpi=%hi x=%i xs=%i y=%i wx=%i h=%i ***** \n", + xdpi, ydpi, x, xs, y, wx, h)); data = pixma_newcmd (&mp->cb, cmd_scan_param_3, 0x38, 0); data[0x00] = (is_scanning_from_adf (s)) ? 0x02 : 0x01; data[0x01] = 0x01; - if (is_scanning_from_tpu (s)) - { - data[0x00] = 0x04; - data[0x01] = 0x02; - data[0x1e] = 0x02; - } data[0x02] = 0x01; if (is_scanning_from_adfdup (s)) { @@ -824,23 +699,16 @@ send_scan_param (pixma_t * s) { data[0x05] = 0x01; /* This one also seen at 0. Don't know yet what's used for */ } - pixma_set_be16 (s->param->xdpi | 0x8000, data + 0x08); - pixma_set_be16 (s->param->ydpi | 0x8000, data + 0x0a); - /*PDBG (pixma_dbg (4, "*send_scan_param gen. 3+ ***** Setting: xdpi=%hi ydpi=%hi x=%i y=%i w=%i ***** \n", - s->param->xdpi,s->param->ydpi,(s->param->x)-(s->param->xs),s->param->y,raw_width));*/ - pixma_set_be32 (s->param->x - s->param->xs, data + 0x0c); - pixma_set_be32 (s->param->y, data + 0x10); - pixma_set_be32 (raw_width, data + 0x14); + pixma_set_be16 (xdpi | 0x8000, data + 0x08); + pixma_set_be16 (ydpi | 0x8000, data + 0x0a); + pixma_set_be32 (x - xs, data + 0x0c); + pixma_set_be32 (y, data + 0x10); + pixma_set_be32 (wx, data + 0x14); pixma_set_be32 (h, data + 0x18); - data[0x1c] = ((s->param->channels != 1) || is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 0x08 : 0x04; + data[0x1c] = (s->param->channels != 1) ? 0x08 : 0x04; -#ifdef DEBUG_TPU_48 - data[0x1d] = 24; -#else - data[0x1d] = (is_scanning_from_tpu (s)) ? 48 - : (((s->param->software_lineart) ? 8 : s->param->depth) - * ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels)); /* bits per pixel */ -#endif + data[0x1d] = ((s->param->software_lineart) ? 8 : s->param->depth) + * s->param->channels; /* bits per pixel */ data[0x1f] = 0x01; /* This one also seen at 0. Don't know yet what's used for */ data[0x20] = 0xff; @@ -917,10 +785,7 @@ send_time (pixma_t * s) data = pixma_newcmd (&mp->cb, cmd_time, 20, 0); pixma_get_time (&now, NULL); t = localtime (&now); - snprintf ((char *) data, 16, - "%02d/%02d/%02d %02d:%02d", - t->tm_year % 100, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min); + strftime ((char *) data, 16, "%y/%m/%d %H:%M", t); PDBG (pixma_dbg (3, "Sending time: '%s'\n", (char *) data)); return pixma_exec (s, &mp->cb); } @@ -1036,7 +901,8 @@ handle_interrupt (pixma_t * s, int timeout) || s->cfg->pid == MX720_PID || s->cfg->pid == MX920_PID || s->cfg->pid == MB2300_PID - || s->cfg->pid == MB5000_PID) + || s->cfg->pid == MB5000_PID + || s->cfg->pid == MB5400_PID) /* button no. in buf[7] * size in buf[10] 01=A4; 02=Letter; 08=10x15; 09=13x18; 0b=auto * format in buf[11] 01=JPEG; 02=TIFF; 03=PDF; 04=Kompakt-PDF @@ -1079,32 +945,6 @@ handle_interrupt (pixma_t * s, int timeout) } static int -init_ccd_lamp_3 (pixma_t * s) -{ - mp150_t *mp = (mp150_t *) s->subdriver; - uint8_t *data; - int error, status_len, tmo; - - status_len = 8; - RET_IF_ERR (query_status (s)); - RET_IF_ERR (query_status (s)); - RET_IF_ERR (send_cmd_start_calibrate_ccd_3 (s)); - RET_IF_ERR (query_status (s)); - tmo = 20; /* like Windows driver, CCD lamp adjustment */ - while (--tmo >= 0) - { - data = pixma_newcmd (&mp->cb, cmd_end_calibrate_ccd_3, 0, status_len); - RET_IF_ERR (pixma_exec (s, &mp->cb)); - memcpy (mp->current_status, data, status_len); - PDBG (pixma_dbg (3, "Lamp status: %u , timeout in: %u\n", data[0], tmo)); - if (mp->current_status[0] == 3 || !is_scanning_from_tpu (s)) - break; - WAIT_INTERRUPT (1000); - } - return error; -} - -static int wait_until_ready (pixma_t * s) { mp150_t *mp = (mp150_t *) s->subdriver; @@ -1118,8 +958,7 @@ wait_until_ready (pixma_t * s) if (mp->generation >= 3) RET_IF_ERR (query_status_3 (s)); else if (s->cfg->pid == MP600_PID || - s->cfg->pid == MP600R_PID || - s->cfg->pid == MP800R_PID) + s->cfg->pid == MP600R_PID) RET_IF_ERR (query_status (s)); if (--tmo == 0) { @@ -1131,30 +970,6 @@ wait_until_ready (pixma_t * s) return 0; } -static uint8_t * -shift_colors (uint8_t * dptr, uint8_t * sptr, - unsigned w, unsigned dpi, unsigned pid, unsigned c, - int * colshft, unsigned strshft) -{ - unsigned i, sr, sg, sb, st; - UNUSED(dpi); - UNUSED(pid); - sr = colshft[0]; sg = colshft[1]; sb = colshft[2]; - for (i = 0; i < w; i++) - { - /* stripes shift for MP800, MP800R at 2400 dpi */ - st = (i % 2 == 0) ? strshft : 0; - - *sptr++ = *(dptr++ + sr + st); - if (c == 6) *sptr++ = *(dptr++ + sr + st); - *sptr++ = *(dptr++ + sg + st); - if (c == 6) *sptr++ = *(dptr++ + sg + st); - *sptr++ = *(dptr++ + sb + st); - if (c == 6) *sptr++ = *(dptr++ + sb + st); - } - return dptr; -} - static void reorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n, unsigned m, unsigned w, unsigned line_size) @@ -1168,32 +983,69 @@ reorder_pixels (uint8_t * linebuf, uint8_t * sptr, unsigned c, unsigned n, memcpy (sptr, linebuf, line_size); } -#ifndef TPU_48 -static unsigned -pack_48_24_bpc (uint8_t * sptr, unsigned n) +/* the scanned image must be shrinked by factor "scale" + * the image can be formatted as rgb (c=3) or gray (c=1) + * we need to crop the left side (xs) + * we ignore more pixels inside scanned line (wx), behind needed line (w) + * + * example (scale=2): + * line | pixel[0] | pixel[1] | ... | pixel[w-1] + * --------- + * 0 | rgbrgb | rgbrgb | ... | rgbrgb + * wx*c | rgbrgb | rgbrgb | ... | rgbrgb + */ +uint8_t * +shrink_image (uint8_t * dptr, uint8_t * sptr, unsigned xs, unsigned w, + unsigned wx, unsigned scale, unsigned c) { - unsigned i; - uint8_t *cptr, lsb; - static uint8_t offset = 0; + unsigned i, ic; + uint16_t pixel; + uint8_t *dst = dptr; /* don't change dptr */ + uint8_t *src = sptr; /* don't change sptr */ + + /*PDBG (pixma_dbg (4, "%s: w=%d, wx=%d, c=%d, scale=%d\n", + __func__, w, wx, c, scale)); + PDBG (pixma_dbg (4, "\tdptr=%ld, sptr=%ld\n", + dptr, sptr));*/ + + /* crop left side */ + src += c * xs; - cptr = sptr; - if (n % 2 != 0) - PDBG (pixma_dbg (3, "WARNING: misaligned image.\n")); - for (i = 0; i < n; i += 2) + /* process line */ + for (i = 0; i < w; i++) + { + /* process rgb or gray pixel */ + for (ic = 0; ic < c; ic++) { - /* offset = 1 + (offset % 3); */ - lsb = *sptr++; - *cptr++ = ((*sptr++) << offset) | lsb >> (8 - offset); +#if 0 + dst[ic] = src[ic]; +#else + pixel = 0; + + /* sum shrink pixels */ + for (unsigned m = 0; m < scale; m++) /* get pixels from shrinked lines */ + { + for (unsigned n = 0; n < scale; n++) /* get pixels from same line */ + { + pixel += src[ic + c * n + wx * c * m]; + } + } + dst[ic] = pixel / (scale * scale); +#endif } - return (n / 2); + + /* jump over shrinked data */ + src += c * scale; + /* next pixel */ + dst += c; + } + + return dst; } -#endif -/* This function deals both with PIXMA CCD sensors producing shifted color - * planes images, Grayscale CCD scan and Generation >= 3 high dpi images. - * Each complete line in mp->imgbuf is processed for shifting CCD sensor - * color planes, reordering pixels above 600 dpi for Generation >= 3, and - * converting to Grayscale for CCD sensors. */ +/* This function deals with Generation >= 3 high dpi images. + * Each complete line in mp->imgbuf is processed for reordering pixels above + * 600 dpi for Generation >= 3. */ static unsigned post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib) { @@ -1209,46 +1061,48 @@ post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib) return 0; /* # of non processed bytes */ } + /* process image sizes */ + c = s->param->channels + * ((s->param->software_lineart) ? 8 : s->param->depth) / 8; /* color channels count */ + cw = c * s->param->w; /* image width */ + cx = c * s->param->xs; /* x-offset */ - c = ((is_ccd_grayscale (s) || is_ccd_lineart (s)) ? 3 : s->param->channels) - * ((s->param->software_lineart) ? 8 : s->param->depth) / 8; - cw = c * s->param->w; - cx = c * s->param->xs; - + /* special image format parameters + * n: no. of sub-images + * m: sub-image width + */ if (mp->generation >= 3) n = s->param->xdpi / 600; - else /* FIXME: maybe need different values for CIS and CCD sensors */ + else n = s->param->xdpi / 2400; - if (s->cfg->pid == MP600_PID || s->cfg->pid == MP600R_PID) n = s->param->xdpi / 1200; - m = (n > 0) ? s->param->wx / n : 1; + + /* Initialize pointers */ sptr = dptr = gptr = cptr = mp->imgbuf; - line_size = get_cis_ccd_line_size (s); - /*PDBG (pixma_dbg (4, "*post_process_image_data***** ----- Set n=%u, m=%u, line_size=%u ----- ***** \n", n, m, line_size));*/ + /* walk through complete received lines */ + line_size = get_cis_line_size (s); lines = (mp->data_left_ofs - mp->imgbuf) / line_size; - /*PDBG (pixma_dbg (4, "*post_process_image_data***** lines = %i > 2 * mp->color_shift + mp->stripe_shift = %i ***** \n", - lines, 2 * mp->color_shift + mp->stripe_shift));*/ - if (lines > 2 * mp->color_shift + mp->stripe_shift) + if (lines > 0) { unsigned i; - lines -= 2 * mp->color_shift + mp->stripe_shift; + /*PDBG (pixma_dbg (4, "*post_process_image_data***** Processing with c=%u, n=%u, m=%u, wx=%i, line_size=%u, cx=%u, cw=%u ***** \n", + c, n, m, s->param->wx, line_size, cx, cw));*/ + /*PDBG (pixma_dbg (4, "*post_process_image_data***** lines = %i ***** \n", lines));*/ + for (i = 0; i < lines; i++, sptr += line_size) { - /* Color plane and stripes shift needed by e.g. CCD */ /*PDBG (pixma_dbg (4, "*post_process_image_data***** Processing with c=%u, n=%u, m=%u, w=%i, line_size=%u ***** \n", - c, n, m, s->param->wx, line_size));*/ - if (s->cfg->pid != MG5300_PID && s->cfg->pid != MG6300_PID && c >= 3) - dptr = shift_colors (dptr, sptr, - s->param->wx, s->param->xdpi, s->cfg->pid, c, - mp->shift, mp->stripe_shift); + c, n, m, s->param->wx, line_size));*/ + /*PDBG (pixma_dbg (4, "*post_process_image_data***** Pointers: sptr=%lx, dptr=%lx, linebuf=%lx ***** \n", + sptr, dptr, mp->linebuf));*/ /* special image format for *most* devices at high dpi. * MP220, MX360 and generation 5 scanners are exceptions */ - if (n > 0 + if (n > 1 && s->cfg->pid != MP220_PID && s->cfg->pid != MP490_PID && s->cfg->pid != MX360_PID @@ -1266,15 +1120,22 @@ post_process_image_data (pixma_t * s, pixma_imagebuf_t * ib) || s->cfg->pid == MX520_PID)) reorder_pixels (mp->linebuf, sptr, c, n, m, s->param->wx, line_size); - /* Crop line to selected borders */ - memmove(cptr, sptr + cx, cw); + + /* scale image */ + if (mp->scale > 1) + { + /* Crop line inside shrink_image() */ + shrink_image(cptr, sptr, s->param->xs, s->param->w, s->param->wx, mp->scale, c); + } + else + { + /* Crop line to selected borders */ + memmove(cptr, sptr + cx, cw); + } /* Color / Gray to Lineart convert */ if (s->param->software_lineart) cptr = gptr = pixma_binarize_line (s->param, gptr, cptr, s->param->w, c); - /* Color to Grayscale convert for CCD sensor */ - else if (is_ccd_grayscale (s)) - cptr = gptr = pixma_rgb_to_gray (gptr, cptr, s->param->w, c); else cptr += cw; } @@ -1330,9 +1191,6 @@ mp150_open (pixma_t * s) PDBG (pixma_dbg (3, "*mp150_open***** This is a generation %d scanner. *****\n", mp->generation)); - /* TPU info data setup */ - mp->tpu_datalen = 0; - /* adf scanning */ mp->adf_state = state_idle; @@ -1340,8 +1198,6 @@ mp150_open (pixma_t * s) { query_status (s); handle_interrupt (s, 200); - if (mp->generation == 3 && has_ccd_sensor (s)) - send_cmd_start_calibrate_ccd_3 (s); } return 0; } @@ -1370,12 +1226,6 @@ mp150_check_param (pixma_t * s, pixma_scan_param_t * sp) { sp->software_lineart = 0; sp->depth = 8; -#ifdef TPU_48 -#ifndef DEBUG_TPU_48 - if (sp->source == PIXMA_SOURCE_TPU) -#endif - sp->depth = 16; /* TPU in 16 bits mode */ -#endif } else { @@ -1403,14 +1253,14 @@ mp150_check_param (pixma_t * s, pixma_scan_param_t * sp) { /* mod 32 and expansion of the X scan limits */ /*PDBG (pixma_dbg (4, "*mp150_check_param***** ----- Initially: x=%i, y=%i, w=%i, h=%i *****\n", sp->x, sp->y, sp->w, sp->h));*/ - sp->xs = (sp->x) % 32; + sp->xs = (sp->x * mp->scale) % 32; } else sp->xs = 0; /*PDBG (pixma_dbg (4, "*mp150_check_param***** Selected origin, origin shift: %i, %i *****\n", sp->x, sp->xs));*/ sp->wx = calc_raw_width (mp, sp); sp->line_size = sp->w * sp->channels * (((sp->software_lineart) ? 8 : sp->depth) / 8); /* bytes per line per color after cropping */ - /*PDBG (pixma_dbg (4, "*mp150_check_param***** Final scan width and line-size: %i, %i *****\n", sp->wx, sp->line_size));*/ + /*PDBG (pixma_dbg (4, "*mp150_check_param***** Final scan width and line-size: %i, %li *****\n", sp->wx, sp->line_size));*/ /* Some exceptions here for particular devices */ /* Those devices can scan up to legal 14" with ADF, but A4 11.7" in flatbed */ @@ -1418,27 +1268,6 @@ mp150_check_param (pixma_t * s, pixma_scan_param_t * sp) if ((s->cfg->cap & PIXMA_CAP_ADF) && sp->source == PIXMA_SOURCE_FLATBED) sp->h = MIN (sp->h, 877 * sp->xdpi / 75); - if (sp->source == PIXMA_SOURCE_TPU - || s->cfg->pid == LIDE300_PID - || s->cfg->pid == LIDE400_PID) - { - uint8_t k; - - /* TPU mode: lowest res is 150 or 300 dpi */ - if (mp->generation >= 3) - k = MAX (sp->xdpi, 300) / sp->xdpi; - else - k = MAX (sp->xdpi, 150) / sp->xdpi; - sp->x *= k; - sp->xs *= k; - sp->y *= k; - sp->w *= k; - sp->wx *= k; - sp->h *= k; - sp->xdpi *= k; - sp->ydpi = sp->xdpi; - } - if (sp->source == PIXMA_SOURCE_ADF || sp->source == PIXMA_SOURCE_ADFDUP) { uint8_t k = 1; @@ -1460,6 +1289,14 @@ mp150_check_param (pixma_t * s, pixma_scan_param_t * sp) (sp->source == PIXMA_SOURCE_ADF || sp->source == PIXMA_SOURCE_ADFDUP); + mp->scale = 1; + if (s->cfg->min_xdpi && sp->xdpi < s->cfg->min_xdpi) + { + mp->scale = s->cfg->min_xdpi / sp->xdpi; + } + /*PDBG (pixma_dbg (4, "*mp150_check_param***** xdpi=%u, min_xdpi=%u, scale=%u *****\n", + sp->xdpi, s->cfg->min_xdpi, mp->scale));*/ + /*PDBG (pixma_dbg (4, "*mp150_check_param***** Finally: channels=%u, depth=%u, x=%u, y=%u, w=%u, h=%u, xs=%u, wx=%u *****\n", sp->channels, sp->depth, sp->x, sp->y, sp->w, sp->h, sp->xs, sp->wx));*/ return 0; @@ -1534,33 +1371,6 @@ mp150_scan (pixma_t * s) } } - if (has_ccd_sensor (s) && (mp->generation <= 2)) - { - error = send_cmd_e920 (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) - { - WAIT_INTERRUPT (1000); - PDBG (pixma_dbg (2, "CCD Calibration ends in %d sec.\n", tmo)); - } - /* pixma_sleep(2000000); */ - } - tmo = 10; /* adf: first page or idle */ if (mp->generation <= 2 || mp->adf_state == state_idle) @@ -1593,17 +1403,13 @@ mp150_scan (pixma_t * s) mp->state = state_warmup; if ((error >= 0) && (mp->generation <= 2)) error = select_source (s); - if ((error >= 0) && (mp->generation >= 3) && has_ccd_sensor (s)) - error = init_ccd_lamp_3 (s); - if ((error >= 0) && !is_scanning_from_tpu (s) && !is_scanning_jpeg (s)) + if ((error >= 0) && !is_scanning_jpeg (s)) { int i; for (i = (mp->generation >= 3) ? 3 : 1 ; i > 0 && error >= 0; i--) error = send_gamma_table (s); } - else if (error >= 0) /* in TPU mode, for gen 1, 2, and 3 */ - error = send_set_tpu_info (s); } else /* ADF pageid != 0 and gen3 or above */ { /* next sheet from ADF */ @@ -1645,8 +1451,8 @@ mp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) mp->state = state_scanning; mp->last_block = 0; - line_size = get_cis_ccd_line_size (s); - proc_buf_size = (2 * calc_shifting (s) + 2) * line_size; + line_size = get_cis_line_size (s); + proc_buf_size = 2 * line_size; mp->cb.buf = realloc (mp->cb.buf, CMDBUF_SIZE + IMAGE_BLOCK_SIZE + proc_buf_size); if (!mp->cb.buf) @@ -1699,15 +1505,6 @@ mp150_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib) { /* no image data at this moment. */ pixma_sleep (10000); } - /* For TPU at 48 bits/pixel to output at 24 bits/pixel */ -#ifndef DEBUG_TPU_48 -#ifndef TPU_48 -#ifndef DEBUG_TPU_24 - if (is_scanning_from_tpu (s)) -#endif - bytes_received = pack_48_24_bpc (mp->imgbuf + mp->data_left_len, bytes_received); -#endif -#endif /* Post-process the image data */ mp->data_left_ofs = mp->imgbuf + mp->data_left_len + bytes_received; mp->data_left_len = post_process_image_data (s, ib); @@ -1732,9 +1529,6 @@ mp150_finish_scan (pixma_t * s) case state_scanning: case state_warmup: case state_finished: - /* Send the get TPU info message */ - if (is_scanning_from_tpu (s) && mp->tpu_datalen == 0) - send_get_tpu_info_3 (s); /* FIXME: to process several pages ADF scan, must not send * abort_session and start_session between pages (last_block=0x28) */ if (mp->generation <= 2 || !is_scanning_from_adf (s) || mp->last_block == 0x38) @@ -1795,219 +1589,229 @@ static const pixma_scan_ops_t pixma_mp150_ops = { mp150_get_status }; -#define DEVICE(name, model, pid, dpi, adftpu_min_dpi, adftpu_max_dpi, w, h, cap) { \ +#define DEVICE(name, model, pid, min_dpi, dpi, adftpu_min_dpi, adftpu_max_dpi, w, h, cap) { \ name, /* name */ \ model, /* model */ \ CANON_VID, pid, /* vid pid */ \ 0, /* iface */ \ &pixma_mp150_ops, /* ops */ \ + min_dpi, /* min_xdpi */ \ dpi, 2*(dpi), /* xdpi, ydpi */ \ adftpu_min_dpi, adftpu_max_dpi, /* adftpu_min_dpi, adftpu_max_dpi */ \ 0, 0, /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */ \ w, h, /* width, height */ \ PIXMA_CAP_EASY_RGB| \ - PIXMA_CAP_GRAY| /* CIS with native grayscale and CCD with software grayscale */ \ + PIXMA_CAP_GRAY| /* CIS with native grayscale */ \ PIXMA_CAP_LINEART| /* all scanners with software lineart */ \ PIXMA_CAP_GAMMA_TABLE|PIXMA_CAP_EVENTS|cap \ } -#define END_OF_DEVICE_LIST DEVICE(NULL, NULL, 0, 0, 0, 0, 0, 0, 0) +#define END_OF_DEVICE_LIST DEVICE(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0) const pixma_config_t pixma_mp150_devices[] = { /* Generation 1: CIS */ - DEVICE ("Canon PIXMA MP150", "MP150", MP150_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP170", "MP170", MP170_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP450", "MP450", MP450_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP500", "MP500", MP500_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP530", "MP530", MP530_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - - /* Generation 1: CCD */ - DEVICE ("Canon PIXMA MP800", "MP800", MP800_PID, 2400, 150, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), - DEVICE ("Canon PIXMA MP800R", "MP800R", MP800R_PID, 2400, 150, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), - DEVICE ("Canon PIXMA MP830", "MP830", MP830_PID, 2400, 150, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MP150", "MP150", MP150_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP170", "MP170", MP170_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP450", "MP450", MP450_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP500", "MP500", MP500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP530", "MP530", MP530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), /* Generation 2: CIS */ - DEVICE ("Canon PIXMA MP140", "MP140", MP140_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP160", "MP160", MP160_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP180", "MP180", MP180_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP460", "MP460", MP460_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP510", "MP510", MP510_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP600", "MP600", MP600_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP600R", "MP600R", MP600R_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP140", "MP140", MP140_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP160", "MP160", MP160_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP180", "MP180", MP180_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP460", "MP460", MP460_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP510", "MP510", MP510_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP600", "MP600", MP600_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP600R", "MP600R", MP600R_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Generation 3: CIS */ - DEVICE ("Canon PIXMA MP210", "MP210", MP210_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP220", "MP220", MP220_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP470", "MP470", MP470_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP520", "MP520", MP520_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP610", "MP610", MP610_PID, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), - - DEVICE ("Canon PIXMA MX300", "MX300", MX300_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MX310", "MX310", MX310_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX700", "MX700", MX700_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX850", "MX850", MX850_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon PIXMA MX7600", "MX7600", MX7600_PID, 4800, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - - DEVICE ("Canon PIXMA MP630", "MP630", MP630_PID, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP620", "MP620", MP620_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP540", "MP540", MP540_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP480", "MP480", MP480_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP240", "MP240", MP240_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP260", "MP260", MP260_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP190", "MP190", MP190_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP210", "MP210", MP210_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP220", "MP220", MP220_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP470", "MP470", MP470_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP520", "MP520", MP520_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP610", "MP610", MP610_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), + + DEVICE ("Canon PIXMA MX300", "MX300", MX300_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MX310", "MX310", MX310_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX700", "MX700", MX700_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX850", "MX850", MX850_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MX7600", "MX7600", MX7600_PID, 0, 4800, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + + DEVICE ("Canon PIXMA MP630", "MP630", MP630_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP620", "MP620", MP620_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP540", "MP540", MP540_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP480", "MP480", MP480_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP240", "MP240", MP240_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP260", "MP260", MP260_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP190", "MP190", MP190_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* PIXMA 2009 vintage */ - DEVICE ("Canon PIXMA MX320", "MX320", MX320_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX330", "MX330", MX330_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX860", "MX860", MX860_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MX320", "MX320", MX320_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX330", "MX330", MX330_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX860", "MX860", MX860_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), /* width and height adjusted to flatbed size 21.8 x 30.2 cm^2 respective * Not sure if anything's going wrong here, leaving as is - DEVICE ("Canon PIXMA MX860", "MX860", MX860_PID, 2400, 0, 0, 638, 880, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),*/ + DEVICE ("Canon PIXMA MX860", "MX860", MX860_PID, 0, 2400, 0, 0, 638, 880, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP),*/ /* PIXMA 2010 vintage */ - DEVICE ("Canon PIXMA MX340", "MX340", MX340_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX350", "MX350", MX350_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX870", "MX870", MX870_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MX340", "MX340", MX340_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX350", "MX350", MX350_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX870", "MX870", MX870_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), /* PIXMA 2011 vintage */ - DEVICE ("Canon PIXMA MX360", "MX360", MX360_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX410", "MX410", MX410_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX420", "MX420", MX420_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX880 Series", "MX880", MX880_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MX360", "MX360", MX360_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX410", "MX410", MX410_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX420", "MX420", MX420_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX880 Series", "MX880", MX880_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), /* Generation 4: CIS */ - DEVICE ("Canon PIXMA MP640", "MP640", MP640_PID, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP560", "MP560", MP560_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP550", "MP550", MP550_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP490", "MP490", MP490_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP250", "MP250", MP250_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP270", "MP270", MP270_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - - /* Latest devices (2010) Generation 4 CIS/CCD */ - DEVICE ("Canon PIXMA MP280", "MP280", MP280_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* TODO: 1200dpi doesn't work yet */ - DEVICE ("Canon PIXMA MP495", "MP495", MP495_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG5100", "MG5100", MG5100_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG5200", "MG5200", MG5200_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6100", "MG6100", MG6100_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - - /* Latest devices (2011) Generation 5 CIS/CCD */ - DEVICE ("Canon PIXMA MG2100", "MG2100", MG2100_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG3100", "MG3100", MG3100_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG4100", "MG4100", MG4100_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG5300", "MG5300", MG5300_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6200", "MG6200", MG6200_PID, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MP493", "MP493", MP493_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA E500", "E500", E500_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP640", "MP640", MP640_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP560", "MP560", MP560_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP550", "MP550", MP550_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP490", "MP490", MP490_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP250", "MP250", MP250_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP270", "MP270", MP270_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + + /* Latest devices (2010) Generation 4 CIS */ + DEVICE ("Canon PIXMA MP280", "MP280", MP280_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* TODO: 1200dpi doesn't work yet */ + DEVICE ("Canon PIXMA MP495", "MP495", MP495_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG5100", "MG5100", MG5100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG5200", "MG5200", MG5200_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6100", "MG6100", MG6100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + + /* Latest devices (2011) Generation 5 CIS */ + DEVICE ("Canon PIXMA MG2100", "MG2100", MG2100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG3100", "MG3100", MG3100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG4100", "MG4100", MG4100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG5300", "MG5300", MG5300_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6200", "MG6200", MG6200_PID, 0, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MP493", "MP493", MP493_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E500", "E500", E500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2012) Generation 5 CIS */ - DEVICE ("Canon PIXMA MX370 Series", "MX370", MX370_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX430 Series", "MX430", MX430_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX510 Series", "MX510", MX510_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX710 Series", "MX710", MX710_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon PIXMA MX890 Series", "MX890", MX890_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon PIXMA E600 Series", "E600", E600_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MG4200", "MG4200", MG4200_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MX370 Series", "MX370", MX370_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX430 Series", "MX430", MX430_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX510 Series", "MX510", MX510_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX710 Series", "MX710", MX710_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MX890 Series", "MX890", MX890_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA E600 Series", "E600", E600_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MG4200", "MG4200", MG4200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2013) Generation 5 CIS */ - DEVICE ("Canon PIXMA E510", "E510", E510_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA E610", "E610", E610_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MP230", "MP230", MP230_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG2200 Series", "MG2200", MG2200_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG3200 Series", "MG3200", MG3200_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG5400 Series", "MG5400", MG5400_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6300 Series", "MG6300", MG6300_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MX390 Series", "MX390", MX390_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX450 Series", "MX450", MX450_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX520 Series", "MX520", MX520_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX720 Series", "MX720", MX720_PID, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon PIXMA MX920 Series", "MX920", MX920_PID, 2400, 0, 600, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon PIXMA MG2400 Series", "MG2400", MG2400_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG2500 Series", "MG2500", MG2500_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG3500 Series", "MG3500", MG3500_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG5500 Series", "MG5500", MG5500_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6400 Series", "MG6400", MG6400_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6500 Series", "MG6500", MG6500_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG7100 Series", "MG7100", MG7100_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E510", "E510", E510_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E610", "E610", E610_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MP230", "MP230", MP230_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG2200 Series", "MG2200", MG2200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG3200 Series", "MG3200", MG3200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG5400 Series", "MG5400", MG5400_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6300 Series", "MG6300", MG6300_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MX390 Series", "MX390", MX390_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX450 Series", "MX450", MX450_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX520 Series", "MX520", MX520_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX720 Series", "MX720", MX720_PID, 0, 2400, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MX920 Series", "MX920", MX920_PID, 0, 2400, 0, 600, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA MG2400 Series", "MG2400", MG2400_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG2500 Series", "MG2500", MG2500_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG3500 Series", "MG3500", MG3500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG5500 Series", "MG5500", MG5500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6400 Series", "MG6400", MG6400_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6500 Series", "MG6500", MG6500_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG7100 Series", "MG7100", MG7100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2014) Generation 5 CIS */ - DEVICE ("Canon PIXMA MX470 Series", "MX470", MX470_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MX530 Series", "MX530", MX530_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon MAXIFY MB5000 Series", "MB5000", MB5000_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon MAXIFY MB5300 Series", "MB5300", MB5300_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon MAXIFY MB2000 Series", "MB2000", MB2000_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon MAXIFY MB2100 Series", "MB2100", MB2100_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG), - DEVICE ("Canon MAXIFY MB2300 Series", "MB2300", MB2300_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon MAXIFY MB2700 Series", "MB2700", MB2700_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG), - DEVICE ("Canon PIXMA E400", "E400", E400_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA E560", "E560", E560_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG7500 Series", "MG7500", MG7500_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6600 Series", "MG6600", MG6600_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG5600 Series", "MG5600", MG5600_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG2900 Series", "MG2900", MG2900_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA E460 Series", "E460", E460_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MX470 Series", "MX470", MX470_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MX530 Series", "MX530", MX530_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon MAXIFY MB5000 Series", "MB5000", MB5000_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG), + DEVICE ("Canon MAXIFY MB5300 Series", "MB5300", MB5300_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon MAXIFY MB2000 Series", "MB2000", MB2000_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP | PIXMA_CAP_ADF_JPEG), + DEVICE ("Canon MAXIFY MB2100 Series", "MB2100", MB2100_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG), + DEVICE ("Canon MAXIFY MB2300 Series", "MB2300", MB2300_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG), + DEVICE ("Canon MAXIFY MB2700 Series", "MB2700", MB2700_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF | PIXMA_CAP_ADF_JPEG), + DEVICE ("Canon PIXMA E400", "E400", E400_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E560", "E560", E560_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG7500 Series", "MG7500", MG7500_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6600 Series", "MG6600", MG6600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG5600 Series", "MG5600", MG5600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG2900 Series", "MG2900", MG2900_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E460 Series", "E460", E460_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2015) Generation 5 CIS */ - DEVICE ("Canon PIXMA MX490 Series", "MX490", MX490_PID, 600, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA E480 Series", "E480", E480_PID, 600, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MG3600 Series", "MG3600", MG3600_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG7700 Series", "MG7700", MG7700_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6900 Series", "MG6900", MG6900_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG6800 Series", "MG6800", MG6800_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG5700 Series", "MG5700", MG5700_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MX490 Series", "MX490", MX490_PID, 0, 600, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA E480 Series", "E480", E480_PID, 0, 600, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MG3600 Series", "MG3600", MG3600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG7700 Series", "MG7700", MG7700_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6900 Series", "MG6900", MG6900_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG6800 Series", "MG6800", MG6800_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG5700 Series", "MG5700", MG5700_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2016) Generation 5 CIS */ - DEVICE ("Canon PIXMA G3000", "G3000", G3000_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA G2000", "G2000", G2000_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS9000 Series", "TS9000", TS9000_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS8000 Series", "TS8000", TS8000_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS6000 Series", "TS6000", TS6000_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS5000 Series", "TS5000", TS5000_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA MG3000 Series", "MG3000", MG3000_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA E470 Series", "E470", E470_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA E410 Series", "E410", E410_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA G3000", "G3000", G3000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA G2000", "G2000", G2000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS9000 Series", "TS9000", TS9000_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8000 Series", "TS8000", TS8000_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6000 Series", "TS6000", TS6000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS5000 Series", "TS5000", TS5000_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA MG3000 Series", "MG3000", MG3000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E470 Series", "E470", E470_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E410 Series", "E410", E410_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2017) Generation 5 CIS */ - DEVICE ("Canon PIXMA G4000", "G4000", G4000_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS6100 Series", "TS6100", TS6100_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS5100 Series", "TS5100", TS5100_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS3100 Series", "TS3100", TS3100_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA E3100 Series", "E3100", E3100_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA G4000", "G4000", G4000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6100 Series", "TS6100", TS6100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS5100 Series", "TS5100", TS5100_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS3100 Series", "TS3100", TS3100_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E3100 Series", "E3100", E3100_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2018) Generation 5 CIS */ - DEVICE ("Canon MAXIFY MB5400 Series", "MB5400", MB5400_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon MAXIFY MB5100 Series", "MB5100", MB5100_PID, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), - DEVICE ("Canon PIXMA TS9100 Series", "TS9100", TS9100_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TR8500 Series", "TR8500", TR8500_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA TR7500 Series", "TR7500", TR7500_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA TS9500 Series", "TS9500", TS9500_PID, 1200, 0, 600, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("CanoScan LiDE 400", "LIDE400", LIDE400_PID, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("CanoScan LiDE 300", "LIDE300", LIDE300_PID, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon MAXIFY MB5400 Series", "MB5400", MB5400_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP | PIXMA_CAP_ADF_JPEG), + DEVICE ("Canon MAXIFY MB5100 Series", "MB5100", MB5100_PID, 0, 1200, 0, 0, 638, 1050, PIXMA_CAP_CIS | PIXMA_CAP_ADFDUP), + DEVICE ("Canon PIXMA TS9100 Series", "TS9100", TS9100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TR8500 Series", "TR8500", TR8500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA TR7500 Series", "TR7500", TR7500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA TS9500 Series", "TS9500", TS9500_PID, 0, 1200, 0, 600, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("CanoScan LiDE 400", "LIDE400", LIDE400_PID, 300, 4800, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("CanoScan LiDE 300", "LIDE300", LIDE300_PID, 300, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), /* Latest devices (2019) Generation 5 CIS */ - DEVICE ("Canon PIXMA TS8100 Series", "TS8100", TS8100_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA G3010 Series", "G3010", G3010_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA G4010 Series", "G4010", G4010_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA TS9180 Series", "TS9180", TS9180_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS8180 Series", "TS8180", TS8180_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS6180 Series", "TS6180", TS6180_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TR8580 Series", "TR8580", TR8580_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA TS8130 Series", "TS8130", TS8130_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS6130 Series", "TS6130", TS6130_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TR8530 Series", "TR8530", TR8530_PID, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA TR7530 Series", "TR7530", TR7530_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXUS XK50 Series", "XK50", XK50_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXUS XK70 Series", "XK70", XK70_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TR4500 Series", "TR4500", TR4500_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA E4200 Series", "E4200", E4200_PID, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA TS6200 Series", "TS6200", TS6200_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS6280 Series", "TS6280", TS6280_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS6230 Series", "TS6230", TS6230_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS8200 Series", "TS8200", TS8200_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS8280 Series", "TS8280", TS8280_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS8230 Series", "TS8230", TS8230_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), - DEVICE ("Canon PIXMA TS9580 Series", "TS9580", TS9580_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA TR9530 Series", "TR9530", TR9530_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), - DEVICE ("Canon PIXUS XK80 Series", "XK80", XK80_PID, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8100 Series", "TS8100", TS8100_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA G2010 Series", "G2010", G2010_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA G3010 Series", "G3010", G3010_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA G4010 Series", "G4010", G4010_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA TS9180 Series", "TS9180", TS9180_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8180 Series", "TS8180", TS8180_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6180 Series", "TS6180", TS6180_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TR8580 Series", "TR8580", TR8580_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA TS8130 Series", "TS8130", TS8130_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6130 Series", "TS6130", TS6130_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TR8530 Series", "TR8530", TR8530_PID, 0, 2400, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA TR7530 Series", "TR7530", TR7530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXUS XK50 Series", "XK50", XK50_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXUS XK70 Series", "XK70", XK70_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TR4500 Series", "TR4500", TR4500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA E4200 Series", "E4200", E4200_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA TS6200 Series", "TS6200", TS6200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6280 Series", "TS6280", TS6280_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6230 Series", "TS6230", TS6230_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8200 Series", "TS8200", TS8200_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8280 Series", "TS8280", TS8280_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8230 Series", "TS8230", TS8230_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS9580 Series", "TS9580", TS9580_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA TR9530 Series", "TR9530", TR9530_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA G6000 Series", "G6000", G6000_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA G6080 Series", "G6080", G6080_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXUS XK80 Series", "XK80", XK80_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS5300 Series", "TS5300", TS5300_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS5380 Series", "TS5380", TS5380_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6300 Series", "TS6300", TS6300_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6380 Series", "TS6380", TS6380_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS7330 Series", "TS7330", TS7330_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8380 Series", "TS8380", TS8380_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS8330 Series", "TS8330", TS8330_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA XK60 Series", "XK60", XK60_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS6330 Series", "TS6330", TS6330_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA TS3300 Series", "TS3300", TS3300_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS), + DEVICE ("Canon PIXMA E3300 Series", "E3300", E3300_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS), END_OF_DEVICE_LIST }; diff --git a/backend/pixma_mp730.c b/backend/pixma/pixma_mp730.c index c801daa..93d518b 100644 --- a/backend/pixma_mp730.c +++ b/backend/pixma/pixma_mp730.c @@ -298,10 +298,7 @@ send_time (pixma_t * s) data = pixma_newcmd (&mp->cb, cmd_time, 20, 0); pixma_get_time (&now, NULL); t = localtime (&now); - snprintf ((char *) data, 16, - "%02d/%02d/%02d %02d:%02d", - t->tm_year % 100, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min); + strftime ((char *) data, 16, "%y/%m/%d %H:%M", t); PDBG (pixma_dbg (3, "Sending time: '%s'\n", (char *) data)); return pixma_exec (s, &mp->cb); } @@ -818,6 +815,7 @@ static const pixma_scan_ops_t pixma_mp730_ops = { 0x04a9, pid, /* vid pid */ \ 1, /* iface */ \ &pixma_mp730_ops, /* ops */ \ + 0, /* min_xdpi not used in this subdriver */ \ dpi, dpi, /* xdpi, ydpi */ \ 0, 0, /* adftpu_min_dpi & adftpu_max_dpi not used in this subdriver */ \ 0, 0, /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */ \ diff --git a/backend/pixma_mp750.c b/backend/pixma/pixma_mp750.c index 5bd6ef0..7f00023 100644 --- a/backend/pixma_mp750.c +++ b/backend/pixma/pixma_mp750.c @@ -955,16 +955,18 @@ static const pixma_scan_ops_t pixma_mp750_ops = { 0x04a9, pid, /* vid pid */ \ 0, /* iface */ \ &pixma_mp750_ops, /* ops */ \ + 0, /* min_xdpi not used in this subdriver */ \ dpi, 2*(dpi), /* xdpi, ydpi */ \ 0, 0, /* adftpu_min_dpi & adftpu_max_dpi not used in this subdriver */ \ 0, 0, /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */ \ 637, 877, /* width, height */ \ - PIXMA_CAP_GRAY|PIXMA_CAP_EVENTS|cap \ + PIXMA_CAP_CCD| /* all scanners with CCD */ \ + PIXMA_CAP_GRAY|PIXMA_CAP_EVENTS|cap \ } const pixma_config_t pixma_mp750_devices[] = { - DEVICE ("Canon PIXMA MP750", "MP750", MP750_PID, 2400, PIXMA_CAP_CCD | PIXMA_CAP_ADF), - DEVICE ("Canon PIXMA MP760/770", "MP760/770", MP760_PID, 2400, PIXMA_CAP_CCD | PIXMA_CAP_TPU), - DEVICE ("Canon PIXMA MP780/790", "MP780/790", MP780_PID, 2400, PIXMA_CAP_CCD | PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MP750", "MP750", MP750_PID, 2400, PIXMA_CAP_ADF), + DEVICE ("Canon PIXMA MP760/770", "MP760/770", MP760_PID, 2400, PIXMA_CAP_TPU), + DEVICE ("Canon PIXMA MP780/790", "MP780/790", MP780_PID, 2400, PIXMA_CAP_ADF), DEVICE (NULL, NULL, 0, 0, 0) }; diff --git a/backend/pixma_mp810.c b/backend/pixma/pixma_mp800.c index 5d81e3f..feef611 100644 --- a/backend/pixma_mp810.c +++ b/backend/pixma/pixma_mp800.c @@ -96,6 +96,11 @@ #define CANON_VID 0x04a9 +/* Generation 1 */ +#define MP800_PID 0x170d +#define MP800R_PID 0x170e +#define MP830_PID 0x1713 + /* Generation 2 */ #define MP810_PID 0x171a #define MP960_PID 0x171b @@ -575,6 +580,39 @@ static unsigned calc_shifting (pixma_t * s) switch (s->cfg->pid) { + case MP800_PID: + case MP800R_PID: + case MP830_PID: + if (s->param->xdpi == 2400) + { + if (is_scanning_from_tpu(s)) + mp->stripe_shift = 6; + else + mp->stripe_shift = 3; + } + if (s->param->ydpi > 75) + { + mp->color_shift = s->param->ydpi / ((s->param->ydpi < 1200) ? 150 : 75); + + if (is_scanning_from_tpu (s)) + mp->color_shift = s->param->ydpi / 75; + + /* If you're trying to decipher this color-shifting code, + the following line is where the magic is revealed. */ + mp->shift[1] = mp->color_shift * get_cis_ccd_line_size (s); + if (is_scanning_from_adf (s)) + { /* ADF */ + mp->shift[0] = 0; + mp->shift[2] = 2 * mp->shift[1]; + } + else + { /* Flatbed or TPU */ + mp->shift[0] = 2 * mp->shift[1]; + mp->shift[2] = 0; + } + } + break; + case MP970_PID: /* MP970 at 4800 dpi */ case CS8800F_PID: /* CanoScan 8800F at 4800 dpi */ if (s->param->xdpi == 4800) @@ -1021,8 +1059,7 @@ static int send_time (pixma_t * s) data = pixma_newcmd (&mp->cb, cmd_time, 20, 0); pixma_get_time (&now, NULL); t = localtime (&now); - snprintf ((char *) data, 16, "%02d/%02d/%02d %02d:%02d", t->tm_year % 100, - t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min); + strftime ((char *) data, 16, "%y/%m/%d %H:%M", t); PDBG(pixma_dbg (3, "Sending time: '%s'\n", (char *) data)); return pixma_exec (s, &mp->cb); } @@ -1210,6 +1247,8 @@ static int wait_until_ready (pixma_t * s) WAIT_INTERRUPT(1000); if (mp->generation >= 3) RET_IF_ERR(query_status_3 (s)); + else if (s->cfg->pid == MP800R_PID) + RET_IF_ERR (query_status (s)); if (--tmo == 0) { PDBG(pixma_dbg (1, "WARNING: Timed out in wait_until_ready()\n")); @@ -1783,7 +1822,7 @@ static int mp810_open (pixma_t * s) mp->imgbuf = buf + CMDBUF_SIZE; /* General rules for setting Pixma protocol generation # */ - mp->generation = (s->cfg->pid >= MP810_PID) ? 2 : 1; /* no generation 1 devices anyway, but keep similar to pixma_mp150.c file */ + mp->generation = (s->cfg->pid >= MP810_PID) ? 2 : 1; if (s->cfg->pid >= MP970_PID) mp->generation = 3; @@ -2324,7 +2363,7 @@ static int mp810_get_status (pixma_t * s, pixma_device_status_t * status) return 0; } -static const pixma_scan_ops_t pixma_mp810_ops = +static const pixma_scan_ops_t pixma_mp800_ops = { mp810_open, mp810_close, @@ -2341,11 +2380,13 @@ static const pixma_scan_ops_t pixma_mp810_ops = model, /* model */ \ CANON_VID, pid, /* vid pid */ \ 0, /* iface */ \ - &pixma_mp810_ops, /* ops */ \ + &pixma_mp800_ops, /* ops */ \ + 0, /* min_xdpi not used in this subdriver */ \ dpi, 2*(dpi), /* xdpi, ydpi */ \ adftpu_min_dpi, adftpu_max_dpi, /* adftpu_min_dpi, adftpu_max_dpi */ \ tpuir_min_dpi, tpuir_max_dpi, /* tpuir_min_dpi, tpuir_max_dpi */ \ w, h, /* width, height */ \ + PIXMA_CAP_CCD| /* all scanners with CCD*/ \ PIXMA_CAP_EASY_RGB| \ PIXMA_CAP_GRAY| /* all scanners with software grayscale */ \ PIXMA_CAP_LINEART| /* all scanners with software lineart */ \ @@ -2354,35 +2395,40 @@ static const pixma_scan_ops_t pixma_mp810_ops = #define END_OF_DEVICE_LIST DEVICE(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0) -const pixma_config_t pixma_mp810_devices[] = +const pixma_config_t pixma_mp800_devices[] = { + /* Generation 1: CCD */ + DEVICE ("Canon PIXMA MP800", "MP800", MP800_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), + DEVICE ("Canon PIXMA MP800R", "MP800R", MP800R_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), + DEVICE ("Canon PIXMA MP830", "MP830", MP830_PID, 2400, 150, 0, 0, 0, 638, 877, PIXMA_CAP_ADFDUP), + /* Generation 2: CCD */ - DEVICE ("Canon PIXMA MP810", "MP810", MP810_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), - DEVICE ("Canon PIXMA MP960", "MP960", MP960_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), + DEVICE ("Canon PIXMA MP810", "MP810", MP810_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), + DEVICE ("Canon PIXMA MP960", "MP960", MP960_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), /* Generation 3 CCD not managed as Generation 2 */ - DEVICE ("Canon Pixma MP970", "MP970", MP970_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), + DEVICE ("Canon Pixma MP970", "MP970", MP970_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), /* Flatbed scanner CCD (2007) */ - DEVICE ("Canoscan 8800F", "8800F", CS8800F_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU /*| PIXMA_CAP_NEGATIVE*/ | PIXMA_CAP_48BIT), + DEVICE ("Canoscan 8800F", "8800F", CS8800F_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU /*| PIXMA_CAP_NEGATIVE*/ | PIXMA_CAP_48BIT), /* PIXMA 2008 vintage CCD */ - DEVICE ("Canon MP980 series", "MP980", MP980_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), + DEVICE ("Canon MP980 series", "MP980", MP980_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), /* Generation 4 CCD */ - DEVICE ("Canon MP990 series", "MP990", MP990_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), + DEVICE ("Canon MP990 series", "MP990", MP990_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), /* Flatbed scanner (2010) */ - DEVICE ("Canoscan 9000F", "9000F", CS9000F_PID, 4800, 300, 9600, 600, 2400, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPUIR /*| PIXMA_CAP_NEGATIVE*/ | PIXMA_CAP_48BIT), + DEVICE ("Canoscan 9000F", "9000F", CS9000F_PID, 4800, 300, 9600, 600, 2400, 638, 877, PIXMA_CAP_TPUIR /*| PIXMA_CAP_NEGATIVE*/ | PIXMA_CAP_48BIT), /* Latest devices (2010) Generation 4 CCD untested */ - DEVICE ("Canon PIXMA MG8100", "MG8100", MG8100_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), + DEVICE ("Canon PIXMA MG8100", "MG8100", MG8100_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), /* Latest devices (2011) Generation 4 CCD untested */ - DEVICE ("Canon PIXMA MG8200", "MG8200", MG8200_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPU), + DEVICE ("Canon PIXMA MG8200", "MG8200", MG8200_PID, 4800, 300, 0, 0, 0, 638, 877, PIXMA_CAP_TPU), /* Flatbed scanner (2013) */ - DEVICE ("Canoscan 9000F Mark II", "9000FMarkII", CS9000F_MII_PID, 4800, 300, 9600, 600, 2400, 638, 877, PIXMA_CAP_CCD | PIXMA_CAP_TPUIR | PIXMA_CAP_48BIT), + DEVICE ("Canoscan 9000F Mark II", "9000FMarkII", CS9000F_MII_PID, 4800, 300, 9600, 600, 2400, 638, 877, PIXMA_CAP_TPUIR | PIXMA_CAP_48BIT), END_OF_DEVICE_LIST }; diff --git a/backend/pixma_rename.h b/backend/pixma/pixma_rename.h index ce68ed3..ad3d960 100644 --- a/backend/pixma_rename.h +++ b/backend/pixma/pixma_rename.h @@ -81,7 +81,7 @@ #define pixma_mp150_devices sanei_pixma_mp150_devices #define pixma_mp730_devices sanei_pixma_mp730_devices #define pixma_mp750_devices sanei_pixma_mp750_devices -#define pixma_mp810_devices sanei_pixma_mp810_devices +#define pixma_mp800_devices sanei_pixma_mp800_devices #define pixma_iclass_devices sanei_pixma_iclass_devices #define pixma_newcmd sanei_pixma_newcmd #define pixma_open sanei_pixma_open diff --git a/backend/pixma_sane_options.c b/backend/pixma/pixma_sane_options.c index 6e6abfc..2b8f609 100644 --- a/backend/pixma_sane_options.c +++ b/backend/pixma/pixma_sane_options.c @@ -346,7 +346,7 @@ int build_option_descriptors(struct pixma_sane_t *ss) sod = &opt->sod; sod->type = SANE_TYPE_INT; sod->title = SANE_I18N("ADF Waiting Time"); - sod->desc = SANE_I18N("When set, the scanner searches the waiting time in seconds for a new document inserted into the automatic document feeder."); + sod->desc = SANE_I18N("When set, the scanner waits upto the specified time in seconds for a new document inserted into the automatic document feeder."); sod->name = "adf-wait"; sod->unit = SANE_UNIT_NONE; sod->size = 1 * sizeof(SANE_Word); diff --git a/backend/pixma_sane_options.h b/backend/pixma/pixma_sane_options.h index 1472f1f..1472f1f 100644 --- a/backend/pixma_sane_options.h +++ b/backend/pixma/pixma_sane_options.h diff --git a/backend/scripts/pixma_gen_options.py b/backend/pixma/scripts/pixma_gen_options.py index c4c75e0..c4c75e0 100755 --- a/backend/scripts/pixma_gen_options.py +++ b/backend/pixma/scripts/pixma_gen_options.py diff --git a/backend/plustek-pp_motor.c b/backend/plustek-pp_motor.c index 7f4b1ac..c48710e 100644 --- a/backend/plustek-pp_motor.c +++ b/backend/plustek-pp_motor.c @@ -1912,6 +1912,7 @@ static void motorP96SetupRunTable( pScanData ps ) case 3: if (*(p.pb + 2)) bColor = 1; + // fall through case 2: if (*(p.pb + 1)) bColor++; diff --git a/backend/plustek-usb.c b/backend/plustek-usb.c index 5c6fbeb..107bf9e 100644 --- a/backend/plustek-usb.c +++ b/backend/plustek-usb.c @@ -193,6 +193,7 @@ usb_initDev( Plustek_Device *dev, int idx, int handle, int vendor ) int i; ScanParam sParam; u_short tmp = 0; + int ret = 0; DBG( _DBG_INFO, "usb_initDev(%d,0x%04x,%i)\n", idx, vendor, dev->initialized ); @@ -305,11 +306,16 @@ usb_initDev( Plustek_Device *dev, int idx, int handle, int vendor ) } ptr = getenv ("HOME"); - if( NULL == ptr ) { - sprintf( tmp_str2, "/tmp/%s", tmp_str1 ); - } else { - sprintf( tmp_str2, "%s/.sane/%s", ptr, tmp_str1 ); + ret = ( NULL == ptr )? + snprintf( tmp_str2, sizeof(tmp_str2), "/tmp/%s", tmp_str1 ): + snprintf( tmp_str2, sizeof(tmp_str2), "%s/.sane/%s", ptr, tmp_str1 ); + + if ((ret < 0) || (ret > (int)sizeof(tmp_str2))) { + DBG( _DBG_WARNING, + "Failed to generate calibration file path. Default substituted.\n" ); + snprintf(tmp_str2, sizeof(tmp_str2), "/tmp/plustek-default"); } + dev->calFile = strdup( tmp_str2 ); DBG( _DBG_INFO, "Calibration file-names set to:\n" ); DBG( _DBG_INFO, ">%s-coarse.cal<\n", dev->calFile ); diff --git a/backend/plustek-usbcal.c b/backend/plustek-usbcal.c index 3b9d93a..84a4105 100644 --- a/backend/plustek-usbcal.c +++ b/backend/plustek-usbcal.c @@ -306,7 +306,7 @@ cano_AdjustLightsource( Plustek_Device *dev ) min_rgb.Blue = hw->blue_lamp_on; if((dev->adj.rlampoff != -1) && - (dev->adj.glampoff != -1) && (dev->adj.rlampoff != -1)) { + (dev->adj.glampoff != -1) && (dev->adj.blampoff != -1)) { DBG( _DBG_INFO, "- function skipped, using frontend values!\n" ); return SANE_TRUE; } diff --git a/backend/plustek.c b/backend/plustek.c index e1d9e09..eaddbd3 100644 --- a/backend/plustek.c +++ b/backend/plustek.c @@ -1085,14 +1085,14 @@ init_options( Plustek_Scanner *s ) /* scanner buttons */ for( i = OPT_BUTTON_0; i <= OPT_BUTTON_LAST; i++ ) { - char name [12]; - char title [128]; + char buf [128]; - sprintf (name, "button %d", i - OPT_BUTTON_0); - sprintf (title, "Scanner button %d", i - OPT_BUTTON_0); + snprintf (buf, sizeof(buf), "button %d", i - OPT_BUTTON_0); + s->opt[i].name = strdup(buf); + + snprintf (buf, sizeof(buf), "Scanner button %d", i - OPT_BUTTON_0); + s->opt[i].title = strdup(buf); - s->opt[i].name = strdup(name); - s->opt[i].title = strdup(title); s->opt[i].desc = SANE_I18N("This option reflects the status " "of the scanner buttons."); s->opt[i].type = SANE_TYPE_BOOL; @@ -1916,6 +1916,7 @@ sane_control_option( SANE_Handle handle, SANE_Int option, case OPT_BUTTON_0: if(!s->calibrating) usb_UpdateButtonStatus(s); + // fall through case OPT_BUTTON_1: case OPT_BUTTON_2: case OPT_BUTTON_3: diff --git a/backend/plustek_pp.c b/backend/plustek_pp.c index 551cf27..fdcc6b6 100644 --- a/backend/plustek_pp.c +++ b/backend/plustek_pp.c @@ -1625,7 +1625,7 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option, *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS; } - /* fall through to OPT_HALFTONE */ + // fall through case OPT_HALFTONE: s->val[option].w = optval - s->opt[option].constraint.string_list; break; diff --git a/backend/ricoh.c b/backend/ricoh.c index 58b3a53..fbe5c58 100644 --- a/backend/ricoh.c +++ b/backend/ricoh.c @@ -222,12 +222,14 @@ attach (const char *devnam, Ricoh_Device ** devp) dev->sane.name = strdup (devnam); dev->sane.vendor = "RICOH"; - str = malloc (sizeof(ibuf.product) + sizeof(ibuf.revision) + 1); + + size_t prod_rev_size = sizeof(ibuf.product) + sizeof(ibuf.revision) + 1; + str = malloc (prod_rev_size); if (str) { - str[0] = '\0'; - strncat (str, (char *)ibuf.product, sizeof(ibuf.product)); - strncat (str, (char *)ibuf.revision, sizeof(ibuf.revision)); + snprintf (str, prod_rev_size, "%.*s%.*s", + (int) sizeof(ibuf.product), (const char *) ibuf.product, + (int) sizeof(ibuf.revision), (const char *) ibuf.revision); } dev->sane.model = str; dev->sane.type = "flatbed scanner"; diff --git a/backend/ricoh2.c b/backend/ricoh2.c index 8aa938e..f719268 100644 --- a/backend/ricoh2.c +++ b/backend/ricoh2.c @@ -1,6 +1,6 @@ /* sane - Scanner Access Now Easy. - Copyright (C) 2018 Stanislav Yuzvinsky + Copyright (C) 2018, 2019 Stanislav Yuzvinsky Based on the work done by viruxx This file is part of the SANE package. @@ -113,9 +113,10 @@ typedef struct Ricoh2_device_info { Ricoh2_device_info; static Ricoh2_device_info supported_devices[] = { - { 0x042c, "Aficio SP100SU" }, - { 0x0438, "Aficio SG3100SNw" }, - { 0x0448, "Aficio SP111SU" } + { 0x042c, "Aficio SP-100SU" }, + { 0x0438, "Aficio SG-3100SNw" }, + { 0x0439, "Aficio SG-3110SFNw" }, + { 0x0448, "Aficio SP-111SU/SP-112SU" } }; static SANE_String_Const mode_list[] = { diff --git a/backend/ricoh2_buffer.c b/backend/ricoh2_buffer.c index b8d7d90..e79a7f3 100644 --- a/backend/ricoh2_buffer.c +++ b/backend/ricoh2_buffer.c @@ -46,7 +46,12 @@ #include <memory.h> #include <assert.h> + +#if defined(__APPLE__) && defined(__MACH__) +#include <malloc/malloc.h> +#else #include <malloc.h> +#endif #include "../include/sane/sanei_debug.h" diff --git a/backend/s9036.c b/backend/s9036.c index aa18df7..4124b7b 100644 --- a/backend/s9036.c +++ b/backend/s9036.c @@ -1022,6 +1022,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, case OPT_BR_Y: if (info) *info |= SANE_INFO_RELOAD_PARAMS; + // fall through case OPT_BRIGHT_ADJUST: case OPT_CONTR_ADJUST: s->val[option] = *(SANE_Word *) val; diff --git a/backend/sane_strstatus.c b/backend/sane_strstatus.c index 1fc2220..c76d305 100644 --- a/backend/sane_strstatus.c +++ b/backend/sane_strstatus.c @@ -62,7 +62,7 @@ sane_strstatus (SANE_Status status) return SANE_I18N("Operation not supported"); case SANE_STATUS_CANCELLED: - return SANE_I18N("Operation was cancelled"); + return SANE_I18N("Operation was canceled"); case SANE_STATUS_DEVICE_BUSY: return SANE_I18N("Device busy"); diff --git a/backend/sharp.c b/backend/sharp.c index b2807d7..701b179 100644 --- a/backend/sharp.c +++ b/backend/sharp.c @@ -2825,6 +2825,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, case OPT_BR_Y: if (info && s->val[option].w != *(SANE_Word *) val) *info |= SANE_INFO_RELOAD_PARAMS; + // fall through case OPT_NUM_OPTS: case OPT_THRESHOLD: /* xxx theoretically, we could use OPT_THRESHOLD in diff --git a/backend/sm3600.c b/backend/sm3600.c index 6e411c3..8f8adfc 100644 --- a/backend/sm3600.c +++ b/backend/sm3600.c @@ -609,14 +609,14 @@ sane_control_option (SANE_Handle handle, SANE_Int iOpt, { case optResolution: case optTLX: case optTLY: case optBRX: case optBRY: - if (pnInfo) (*pnInfo) |= SANE_INFO_RELOAD_PARAMS; - /* fall through side effect free */ + if (pnInfo) (*pnInfo) |= SANE_INFO_RELOAD_PARAMS; + // fall through + case optPreview: + case optGrayPreview: #ifdef SM3600_SUPPORT_EXPOSURE case optBrightness: case optContrast: #endif - case optPreview: - case optGrayPreview: this->aoptVal[iOpt].w = *(SANE_Word*)pVal; break; case optMode: diff --git a/backend/snapscan-options.c b/backend/snapscan-options.c index 3ef85ae..999b312 100644 --- a/backend/snapscan-options.c +++ b/backend/snapscan-options.c @@ -927,7 +927,7 @@ static void init_options (SnapScan_Scanner * ps) po[OPT_ADVANCED_GROUP].constraint_type = SANE_CONSTRAINT_NONE; po[OPT_RGB_LPR].name = "rgb-lpr"; - po[OPT_RGB_LPR].title = SANE_I18N("Colour lines per read"); + po[OPT_RGB_LPR].title = SANE_I18N("Color lines per read"); po[OPT_RGB_LPR].desc = lpr_desc; po[OPT_RGB_LPR].type = SANE_TYPE_INT; po[OPT_RGB_LPR].unit = SANE_UNIT_NONE; @@ -939,7 +939,7 @@ static void init_options (SnapScan_Scanner * ps) ps->rgb_lpr = def_rgb_lpr; po[OPT_GS_LPR].name = "gs-lpr"; - po[OPT_GS_LPR].title = SANE_I18N("Greyscale lines per read"); + po[OPT_GS_LPR].title = SANE_I18N("Grayscale lines per read"); po[OPT_GS_LPR].desc = lpr_desc; po[OPT_GS_LPR].type = SANE_TYPE_INT; po[OPT_GS_LPR].unit = SANE_UNIT_NONE; diff --git a/backend/stv680.c b/backend/stv680.c index 8d2fda3..473def0 100644 --- a/backend/stv680.c +++ b/backend/stv680.c @@ -1189,8 +1189,8 @@ stv680_fill_image (Stv680_Vidcam * dev) } #define MSG_MAXLEN 45 -#define CHAR_HEIGHT 11 -#define CHAR_WIDTH 6 +#define TEXT_CHAR_HEIGHT 11 +#define TEXT_CHAR_WIDTH 6 #define CHAR_START 4 static SANE_Status @@ -1216,14 +1216,14 @@ stv680_add_text (SANE_Byte * image, int width, int height, char *txt) len = strftime (line, MSG_MAXLEN, fmttxt, tm); - for (y = 0; y < CHAR_HEIGHT; y++) + for (y = 0; y < TEXT_CHAR_HEIGHT; y++) { - ptr = image + 3 * width * (height - CHAR_HEIGHT - 2 + y) + 12; + ptr = image + 3 * width * (height - TEXT_CHAR_HEIGHT - 2 + y) + 12; for (x = 0; x < len; x++) { - f = fontdata[line[x] * CHAR_HEIGHT + y]; - for (i = CHAR_WIDTH - 1; i >= 0; i--) + f = fontdata[line[x] * TEXT_CHAR_HEIGHT + y]; + for (i = TEXT_CHAR_WIDTH - 1; i >= 0; i--) { if (f & (CHAR_START << i)) { diff --git a/backend/umax_pp.c b/backend/umax_pp.c index b1121ef..16adbe3 100644 --- a/backend/umax_pp.c +++ b/backend/umax_pp.c @@ -103,10 +103,6 @@ * 129 if you want to know which parameters are unused */ -/* history: - * see Changelog - */ - #define UMAX_PP_BUILD 2301 #define UMAX_PP_STATE "release" @@ -206,34 +202,28 @@ umax_pp_attach (SANEI_Config * config, const char *devname) SANE_Status status = SANE_STATUS_GOOD; int ret, prt = 0, mdl; char model[32]; - char name[64]; - char *val; - - memset (name, 0, 64); + const char *name = NULL; + const char *val; - if ((strlen (devname) < 3)) + if (!devname || (strlen (devname) < 3)) return SANE_STATUS_INVAL; sanei_umax_pp_setastra (atoi((SANE_Char *) config->values[CFG_ASTRA])); /* if the name begins with a slash, it's a device, else it's an addr */ - if (devname != NULL) + if ((devname[0] == '/')) { - if ((devname[0] == '/')) - { - strncpy (name, devname, 64); - } + name = devname; + } + else + { + if ((devname[0] == '0') + && ((devname[1] == 'x') || (devname[1] == 'X'))) + prt = strtol (devname + 2, NULL, 16); else - { - if ((devname[0] == '0') - && ((devname[1] == 'x') || (devname[1] == 'X'))) - prt = strtol (devname + 2, NULL, 16); - else - prt = atoi (devname); - } + prt = atoi (devname); } - for (i = 0; i < num_devices; i++) { if (devname[0] == '/') @@ -295,7 +285,7 @@ umax_pp_attach (SANEI_Config * config, const char *devname) devname); return SANE_STATUS_IO_ERROR; } - sprintf (model, "Astra %dP", mdl); + snprintf (model, sizeof(model), "Astra %dP", mdl); dev = malloc (sizeof (Umax_PP_Descriptor) * (num_devices + 1)); @@ -319,12 +309,12 @@ umax_pp_attach (SANEI_Config * config, const char *devname) num_devices++; /* if there are user provided values, use them */ - val=(SANE_Char *) config->values[CFG_NAME]; + val=(const SANE_Char *) config->values[CFG_NAME]; if(strlen(val)==0) dev->sane.name = strdup (devname); else dev->sane.name = strdup (val); - val=(SANE_Char *) config->values[CFG_VENDOR]; + val=(const SANE_Char *) config->values[CFG_VENDOR]; if(strlen(val)==0) dev->sane.vendor = strdup ("UMAX"); else @@ -351,11 +341,11 @@ umax_pp_attach (SANEI_Config * config, const char *devname) dev->max_h_size = 2550; dev->max_v_size = 3500; } - val=(SANE_Char *) config->values[CFG_MODEL]; + val=(const SANE_Char *) config->values[CFG_MODEL]; if(strlen(val)==0) - dev->sane.model = strdup (model); + dev->sane.model = strdup (model); else - dev->sane.model = strdup (val); + dev->sane.model = strdup (val); DBG (3, "umax_pp_attach: device %s attached\n", devname); @@ -1462,6 +1452,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, if (info) *info |= SANE_INFO_RELOAD_PARAMS; + // fall through case OPT_GRAY_GAIN: case OPT_GREEN_GAIN: case OPT_RED_GAIN: diff --git a/backend/umax_pp_low.c b/backend/umax_pp_low.c index c5d9a93..ddcf3da 100644 --- a/backend/umax_pp_low.c +++ b/backend/umax_pp_low.c @@ -924,7 +924,7 @@ sanei_parport_find_device (void) int -sanei_umax_pp_initPort (int port, char *name) +sanei_umax_pp_initPort (int port, const char *name) { #ifndef IO_SUPPORT_MISSING # ifdef HAVE_LINUX_PPDEV_H @@ -1027,26 +1027,20 @@ sanei_umax_pp_initPort (int port, char *name) } else { - sprintf (strmodes, "\n"); - if (modes & PARPORT_MODE_PCSPP) - sprintf (strmodes, "%s\t\tPARPORT_MODE_PCSPP\n", - strmodes); - if (modes & PARPORT_MODE_TRISTATE) - sprintf (strmodes, "%s\t\tPARPORT_MODE_TRISTATE\n", - strmodes); - if (modes & PARPORT_MODE_EPP) - sprintf (strmodes, "%s\t\tPARPORT_MODE_EPP\n", strmodes); + snprintf(strmodes, sizeof(strmodes), + "\n%s%s%s%s%s%s", + (modes & PARPORT_MODE_PCSPP)? "\t\tPARPORT_MODE_PCSPP\n": "", + (modes & PARPORT_MODE_TRISTATE)? "\t\tPARPORT_MODE_TRISTATE\n": "", + (modes & PARPORT_MODE_EPP)? "\t\tPARPORT_MODE_EPP\n": "", + (modes & PARPORT_MODE_ECP)? "\t\tPARPORT_MODE_ECP\n": "", + (modes & PARPORT_MODE_COMPAT)? "\t\tPARPORT_MODE_COMPAT\n": "", + (modes & PARPORT_MODE_DMA)? "\t\tPARPORT_MODE_DMA\n": ""); + if (modes & PARPORT_MODE_ECP) { - sprintf (strmodes, "%s\t\tPARPORT_MODE_ECP\n", - strmodes); gECP = 1; } - if (modes & PARPORT_MODE_COMPAT) - sprintf (strmodes, "%s\t\tPARPORT_MODE_COMPAT\n", - strmodes); - if (modes & PARPORT_MODE_DMA) - sprintf (strmodes, "%s\t\tPARPORT_MODE_DMA\n", strmodes); + DBG (32, "parport modes: %X\n", modes); DBG (32, "parport modes: %s\n", strmodes); if (!(modes & PARPORT_MODE_EPP) @@ -10239,7 +10233,7 @@ moveToOrigin (void) end[0] = 0x19; end[1] = 0xD5; end[4] = 0x1B; - + // fall through case 1220: case 2000: w = 300; @@ -11226,6 +11220,7 @@ sanei_umax_pp_startScan (int x, int y, int width, int height, int dpi, } else y += 80; + // fall through default: y += 8; break; diff --git a/backend/umax_pp_low.h b/backend/umax_pp_low.h index 5e986c0..253ef6a 100644 --- a/backend/umax_pp_low.h +++ b/backend/umax_pp_low.h @@ -46,7 +46,7 @@ /*****************************************************************************/ /* set port to 'idle state' and get iopl */ /*****************************************************************************/ -extern int sanei_umax_pp_initPort (int port, char *name); +extern int sanei_umax_pp_initPort (int port, const char *name); extern int sanei_umax_pp_initScanner (int recover); extern int sanei_umax_pp_initTransport (int recover); extern int sanei_umax_pp_endSession (void); diff --git a/backend/umax_pp_mid.c b/backend/umax_pp_mid.c index 5f9fd5e..4b16745 100644 --- a/backend/umax_pp_mid.c +++ b/backend/umax_pp_mid.c @@ -199,7 +199,7 @@ sanei_umax_pp_model (int port, int *model) } int -sanei_umax_pp_attach (int port, char *name) +sanei_umax_pp_attach (int port, const char *name) { int recover = 0; diff --git a/backend/umax_pp_mid.h b/backend/umax_pp_mid.h index 5903a45..97d1366 100644 --- a/backend/umax_pp_mid.h +++ b/backend/umax_pp_mid.h @@ -74,7 +74,7 @@ */ -extern int sanei_umax_pp_attach (int port, char *name); +extern int sanei_umax_pp_attach (int port, const char *name); /* recognizes 1220P from 2000P diff --git a/backend/xerox_mfp.c b/backend/xerox_mfp.c index b7fcbee..f5fd70e 100644 --- a/backend/xerox_mfp.c +++ b/backend/xerox_mfp.c @@ -95,6 +95,9 @@ static char *str_cmd(int cmd) #define MAX_DUMP 70 const char *encTmpFileName = "/tmp/stmp_enc.tmp"; +/* + * Decode jpeg from `infilename` into dev->decData of dev->decDataSize size. + */ static int decompress(struct device __sane_unused__ *dev, const char __sane_unused__ *infilename) { @@ -131,6 +134,7 @@ static int decompress(struct device __sane_unused__ *dev, height = cinfo.output_height; pixel_size = cinfo.output_components; bmp_size = width * height * pixel_size; + assert(bmp_size <= POST_DATASIZE); dev->decDataSize = bmp_size; row_stride = width * pixel_size; @@ -152,32 +156,30 @@ static int decompress(struct device __sane_unused__ *dev, #endif } +/* copy from decoded jpeg image (dev->decData) into user's buffer (pDest) */ +/* returns 0 if there is no data to copy */ static int copy_decompress_data(struct device *dev, unsigned char *pDest, int maxlen, int *destLen) { int data_size = 0; - size_t result = 0, retVal = 0; - - if (0 == dev->decDataSize) { - *destLen = 0; - return retVal; - } + if (destLen) + *destLen = 0; + if (!dev->decDataSize) + return 0; data_size = dev->decDataSize - dev->currentDecDataIndex; - if (data_size > maxlen) { + if (data_size > maxlen) data_size = maxlen; + if (data_size && pDest) { + memcpy(pDest, dev->decData + dev->currentDecDataIndex, data_size); + if (destLen) + *destLen = data_size; + dev->currentDecDataIndex += data_size; } - memcpy(pDest, dev->decData+dev->currentDecDataIndex, data_size); - result = data_size; - *destLen = result; - dev->currentDecDataIndex += result; - retVal = result; - if (dev->decDataSize == dev->currentDecDataIndex) { dev->currentDecDataIndex = 0; dev->decDataSize = 0; } - - return retVal; + return 1; } static int decompress_tempfile(struct device *dev) @@ -209,6 +211,8 @@ static int isSupportedDevice(struct device __sane_unused__ *dev) if (dev->compressionTypes & (1 << 6)) { /* blacklist malfunctioning device(s) */ if (!strncmp(dev->sane.model, "SCX-4500W", 9) || + !strncmp(dev->sane.model, "C460", 4) || + !!strstr(dev->sane.model, "CLX-3170") || !strncmp(dev->sane.model, "M288x", 5)) return 0; return 1; @@ -1293,9 +1297,10 @@ sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp) dev->decDataSize > 0) { int diff = dev->total_img_size - dev->total_out_size; int bufLen = (diff < maxlen) ? diff : maxlen; - if (0 < diff && - 0 < copy_decompress_data(dev, buf, bufLen, lenp)) { - dev->total_out_size += *lenp; + if (diff && + copy_decompress_data(dev, buf, bufLen, lenp)) { + if (lenp) + dev->total_out_size += *lenp; return SANE_STATUS_GOOD; } } @@ -1459,6 +1464,7 @@ sane_start(SANE_Handle h) if (!dev->data && !(dev->data = malloc(DATASIZE))) return ret_cancel(dev, SANE_STATUS_NO_MEM); + /* this is for jpeg mode only */ if (!dev->decData && !(dev->decData = malloc(POST_DATASIZE))) return ret_cancel(dev, SANE_STATUS_NO_MEM); diff --git a/backend/xerox_mfp.h b/backend/xerox_mfp.h index 3d93f06..d85fe14 100644 --- a/backend/xerox_mfp.h +++ b/backend/xerox_mfp.h @@ -74,8 +74,8 @@ struct device { #define DATATAIL(dev) ((dev->dataoff + dev->datalen) & DATAMASK) #define DATAROOM(dev) dataroom(dev) -#define POST_DATASIZE 0xFFFFFF - SANE_Byte *decData; +#define POST_DATASIZE 0xFFFFFF /* 16777215 bytes */ + SANE_Byte *decData; /* static buffer of POST_DATASIZE bytes */ int decDataSize; int currentDecDataIndex; /* data from CMD_INQUIRY: */ diff --git a/configure.ac b/configure.ac index 376f290..bed7e1a 100644 --- a/configure.ac +++ b/configure.ac @@ -140,6 +140,7 @@ if test "$enable_avahi" = "yes"; then PKG_CHECK_MODULES(AVAHI, [ avahi-client >= 0.6.24 ], [AC_DEFINE(WITH_AVAHI, 1, [define if Avahi support is enabled for saned and the net backend])], enable_avahi=no) fi +AM_CONDITIONAL([have_libavahi], [test x != "x$AVAHI_LIBS"]) dnl check sane to make sure we don't have two installations AC_CHECK_LIB(sane, sane_init, LIBSANE_EXISTS="yes") @@ -430,6 +431,48 @@ AS_IF([test xyes = "x$with_usb" && test xyes != "x$have_usb"], ]) AM_CONDITIONAL([have_usblib], [test x != "x$USB_LIBS"]) +dnl ****************************************************************** +dnl Check for libcurl availability +dnl ****************************************************************** +AC_ARG_WITH(libcurl, + AS_HELP_STRING([--with-libcurl], + [enable functionality that needs libcurl @<:@default=check@:>@]), + [], + [with_libcurl=check]) +AC_DEFINE(HAVE_LIBCURL, + [0], [Define to 1 if libcurl is available]) +AS_IF([test xno != "x$with_libcurl"], + [PKG_CHECK_MODULES(libcurl, [libcurl], + [AC_DEFINE([HAVE_LIBCURL], [1]) + with_libcurl=yes + ], + [AS_IF([test xcheck != "x$with_libcurl"], + [AC_MSG_ERROR([libcurl requested but not found])]) + with_libcurl=no + ]) + ]) +AM_CONDITIONAL([have_libcurl], [test x != "x$libcurl_LIBS"]) + +dnl ****************************************************************** +dnl Check for USB record/replay support +dnl ****************************************************************** +AC_ARG_WITH(usb_record_replay, + AS_HELP_STRING([--with-usb-record-replay], + [enable USB record and replay to XML files @<:@default=yes@:>@])) + +if test "x$with_usb_record_replay" != "xno"; then + PKG_CHECK_MODULES([XML], [libxml-2.0], have_libxml=yes, have_libxml=no) + if test "x$have_libxml" = xyes; then + AC_DEFINE(HAVE_LIBXML2, 1, [Define to 1 if libxml2 is available]) + AC_DEFINE(WITH_USB_RECORD_REPLAY, 1, [define if USB record replay is enabled]) + else + if test "x$with_usb_record_replay" = xyes; then + AC_MSG_ERROR([USB record and replay support was requested but libxml-2.0 was not found]) + fi + fi +fi +AM_CONDITIONAL([have_libxml2], [test x != "x$XML_LIBS"]) + dnl ************ dnl SCSI Support dnl ************ @@ -593,8 +636,8 @@ AC_ARG_ENABLE(local-backends, ALL_BACKENDS="abaton agfafocus apple artec artec_eplus48u as6e \ avision bh canon canon630u canon_dr canon_pp cardscan \ coolscan coolscan2 coolscan3 dc25 dc210 dc240 \ - dell1600n_net dmc epjitsu epson epson2 epsonds fujitsu genesys \ - gphoto2 gt68xx hp hp3500 hp3900 hp4200 hp5400 \ + dell1600n_net dmc epjitsu epson epson2 epsonds escl fujitsu \ + genesys gphoto2 gt68xx hp hp3500 hp3900 hp4200 hp5400 \ hp5590 hpsj5s hpljm1005 hs2p ibm kodak kodakaio kvs1025 kvs20xx \ kvs40xx leo lexmark ma1509 magicolor \ matsushita microtek microtek2 mustek mustek_pp \ @@ -823,6 +866,7 @@ else fi echo "IPv6 support: `eval eval echo ${ipv6}`" echo "Avahi support: `eval eval echo ${enable_avahi}`" +echo "cURL support: `eval eval echo ${with_libcurl}`" echo "SNMP support: `eval eval echo ${with_snmp}`" echo "-> The following backends will be built:" for backend in ${BACKENDS} ; do diff --git a/doc/Makefile.am b/doc/Makefile.am index 1651ed9..56d3517 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -19,12 +19,12 @@ EXTRA_DIST = scanimage.man sane-config.man sane-find-scanner.man \ BACKEND_5MANS = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 \ sane-dll.5 sane-dc25.5 sane-dmc.5 sane-epson.5 sane-epson2.5 sane-epsonds.5 \ - sane-hp.5 sane-gphoto2.5 sane-leo.5 sane-lexmark.5 \ + sane-escl.5 sane-hp.5 sane-gphoto2.5 sane-leo.5 sane-lexmark.5 \ sane-matsushita.5 sane-microtek.5 sane-microtek2.5 sane-mustek.5 \ sane-nec.5 sane-net.5 sane-pie.5 sane-pieusb.5 sane-pint.5 sane-pnm.5 \ sane-umax.5 sane-qcam.5 sane-scsi.5 sane-artec.5 sane-kodak.5 sane-kodakaio.5 \ sane-fujitsu.5 sane-sharp.5 sane-s9036.5 sane-tamarack.5 \ - sane-ricoh.5 sane-ricoh.5 sane-avision.5 sane-plustek.5 sane-st400.5 \ + sane-ricoh.5 sane-ricoh2.5 sane-avision.5 sane-plustek.5 sane-st400.5 \ sane-mustek_pp.5 sane-dc210.5 sane-v4l.5 sane-snapscan.5 \ sane-canon.5 sane-coolscan.5 sane-bh.5 sane-dc240.5 \ sane-umax_pp.5 sane-umax1220u.5 sane-sm3600.5 sane-usb.5 \ @@ -41,8 +41,8 @@ BACKEND_5MANS = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 \ EXTRA_DIST += sane-abaton.man sane-agfafocus.man sane-apple.man sane-as6e.man \ sane-dll.man sane-dc25.man sane-dmc.man sane-epson.man \ - sane-epson2.man sane-epsonds.man sane-hp.man sane-gphoto2.man sane-leo.man \ - sane-lexmark.man sane-matsushita.man sane-microtek.man \ + sane-epson2.man sane-epsonds.man sane-escl.man sane-hp.man sane-gphoto2.man \ + sane-leo.man sane-lexmark.man sane-matsushita.man sane-microtek.man \ sane-microtek2.man sane-mustek.man sane-nec.man sane-net.man \ sane-pie.man sane-pieusb.man sane-pint.man sane-pnm.man sane-umax.man \ sane-qcam.man sane-scsi.man sane-artec.man sane-fujitsu.man \ @@ -157,7 +157,7 @@ DESC_FILES = descriptions/abaton.desc descriptions/agfafocus.desc \ descriptions/dc210.desc descriptions/dc240.desc descriptions/dc25.desc \ descriptions/dell1600n_net.desc descriptions/dll.desc descriptions/dmc.desc \ descriptions/epjitsu.desc descriptions/epson2.desc descriptions/epson.desc \ - descriptions/epsonds.desc \ + descriptions/epsonds.desc descriptions/escl.desc \ descriptions/fujitsu.desc descriptions/genesys.desc \ descriptions/gphoto2.desc descriptions/gt68xx.desc descriptions/hp3500.desc \ descriptions/hp3900.desc descriptions/hp4200.desc descriptions/hp5400.desc \ @@ -203,6 +203,7 @@ DESC_EXT_FILES = descriptions-external/brother2.desc \ descriptions-external/primascan.desc \ descriptions-external/primax.desc \ descriptions-external/samsung.desc \ + descriptions-external/scangearmp2.desc \ descriptions-external/scanwit.desc \ descriptions-external/utsushi.desc \ descriptions-external/v4l2.desc \ diff --git a/doc/backend-writing.txt b/doc/backend-writing.txt index 576e8e4..736fcec 100644 --- a/doc/backend-writing.txt +++ b/doc/backend-writing.txt @@ -1,4 +1,4 @@ -2006-01-01 +2019-08-26 Here are a few rules and tips that should help writing a SANE-conforming backend and including it into the SANE package: @@ -79,16 +79,10 @@ sane-backends/ configure.ac depcomp install-sh ltmain.sh Makefile.am Makefile.in missing mkinstalldirs: Part of the build system as explained above. * ChangeLog: - The ChangeLog contains all the changes made since the last stable release. - If anything is changed in git, write a decent commit message documenting - your work. This commit message will be included as is in the ChangeLog - file for the next stable release. Users of development code should refer - to the `git log` output or the on-line log. - For more details on the format, see the SANE git page on the website. - * ChangeLog-1.0.0, ChangeLog-1.0.1 (...): - These files contain the ChangeLogs of older releases. Once a new release has - been made, the current ChangeLog renamed to ChangeLog-1.something.something - and a new empty ChangeLog is created. + The ChangeLog contains all the changes made since sane-backends-1.0.28 + or a stub explaining how to create an up-to-date list of changes. + ChangeLogs for all releases up to and including 1.0.28 can be found in + the ChangeLogs/ directory. Please note that we skipped 1.0.26. * AUTHORS COPYING INSTALL LICENSE: General documentation + license. * NEWS: diff --git a/doc/descriptions-external/brother-mfc4600.desc b/doc/descriptions-external/brother-mfc4600.desc index 18bd3cb..1f03591 100644 --- a/doc/descriptions-external/brother-mfc4600.desc +++ b/doc/descriptions-external/brother-mfc4600.desc @@ -12,8 +12,6 @@ :backend "brother-mfc4600" ; name of backend ;:version "0.42" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://sourceforge.net/projects/brother-mfc" ;:comment "" diff --git a/doc/descriptions-external/brother.desc b/doc/descriptions-external/brother.desc index 39c54da..e935a53 100644 --- a/doc/descriptions-external/brother.desc +++ b/doc/descriptions-external/brother.desc @@ -12,8 +12,6 @@ :backend "brother" ; name of backend ;:version "1.0.0" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://solutions.brother.com/linux/sol/printer/linux/sane_drivers.html" ; backend's web page :comment "External backend made by brother. As this software contains non-free parts, it can't be included into SANE. If you can't find your model here, please have a look at the brother website which contains the latest list." diff --git a/doc/descriptions-external/brother2.desc b/doc/descriptions-external/brother2.desc index afdb1a6..6be12ec 100644 --- a/doc/descriptions-external/brother2.desc +++ b/doc/descriptions-external/brother2.desc @@ -12,8 +12,6 @@ :backend "brother2" ; name of backend ;:version "1.0.0" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://solutions.brother.com/linux/sol/printer/linux/sane_drivers.html" ; backend's web page :comment "External backend made by brother. As this software contains non-free parts, it can't be included into SANE. If you can't find your model here, please have a look at the brother website which contains the latest list." diff --git a/doc/descriptions-external/cs3200f.desc b/doc/descriptions-external/cs3200f.desc index 15c8c33..4d22d95 100644 --- a/doc/descriptions-external/cs3200f.desc +++ b/doc/descriptions-external/cs3200f.desc @@ -12,8 +12,6 @@ :backend "cs3200f" ; name of backend ;:version "0" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-cs3200f" ; name of manpage (if it exists) ;:url "http://www.luser.com/temp/" ; backend's web page :comment "Backend is in experimental CVS" diff --git a/doc/descriptions-external/hp3770.desc b/doc/descriptions-external/hp3770.desc index c6e8b9f..03ce486 100644 --- a/doc/descriptions-external/hp3770.desc +++ b/doc/descriptions-external/hp3770.desc @@ -12,8 +12,6 @@ :backend "hp3770" ; name of backend ;:version "0.0" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://www.cyberbaladeur.fr/telechargement.html" ; backend's web page :comment "This backend can't be added to the SANE distribution because it consists of binary-only code." diff --git a/doc/descriptions-external/hp8200.desc b/doc/descriptions-external/hp8200.desc index 0a259be..7593d67 100644 --- a/doc/descriptions-external/hp8200.desc +++ b/doc/descriptions-external/hp8200.desc @@ -12,8 +12,6 @@ :backend "hp8200" ; name of backend ;:version "0.0" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://www.cyberbaladeur.fr/telechargement.html" ; backend's web page :comment "This backend can't be added to the SANE distribution because it consists of binary-only code." diff --git a/doc/descriptions-external/hpaio.desc b/doc/descriptions-external/hpaio.desc index dab5a8c..611d877 100644 --- a/doc/descriptions-external/hpaio.desc +++ b/doc/descriptions-external/hpaio.desc @@ -10,148 +10,568 @@ :devicetype :scanner ; start of a list of devices.... :mfg "Hewlett-Packard" ; name a manufacturer :url "http://www.hp.com/united-states/consumer/gateway/printing_multifunction.html" -:model "HP Officejet v30 All-in-one Printer" +:model "HP 915 Inkjet All-in-one Printer" :status :good -:model "HP Officejet v40xi All-in-one Printer" +:model "HP cm8050 Color Multifunction Printer With Edgeline Technology" :status :good -:model "HP Officejet v40s All-in-one Printer" +:model "HP cm8060 Color Multifunction Printer With Edgeline Technology" :status :good -:model "HP Officejet r40 All-in-one Printer" +:model "HP Color LaserJet 2800 All-in-one Printer" :status :good -:model "HP Officejet v40 All-in-one Printer" +:model "HP Color LaserJet 2820 All-in-one Printer" :status :good -:model "HP Officejet r40xi All-in-one Printer" +:model "HP Color LaserJet 2830 All-in-one Printer" :status :good -:model "HP Officejet t45xi All-in-one Printer" +:model "HP Color LaserJet 2840 All-in-one Printer" :status :good -:model "HP Officejet r45 All-in-one Printer" +:model "HP Color LaserJet 4730 Multifunction Printer" :status :good -:model "HP Officejet v45 All-in-one Printer" +:model "HP Color LaserJet 4730x Multifunction Printer" :status :good -:model "HP Officejet t45 All-in-one Printer" +:model "HP Color LaserJet 4730xm Multifunction Printer" :status :good -:model "HP Officejet g55 All-in-one Printer" +:model "HP Color LaserJet 4730xs Multifunction Printer" :status :good -:model "HP Officejet g55xi All-in-one Printer" +:model "HP Color LaserJet cm1015 Multifunction Printer" :status :good -:model "HP Officejet k60 All-in-one Printer" +:model "HP Color LaserJet cm1017 Multifunction Printer" :status :good -:model "HP Officejet r60 All-in-one Printer" +:model "HP Color LaserJet cm1312 Multifunction Printer" :status :good -:model "HP Officejet k60xi All-in-one Printer" +:model "HP Color LaserJet cm1312nfi Multifunction Printer" :status :good -:model "HP Officejet t65xi All-in-one Printer" +:model "HP Color LaserJet cm2320 Multifunction Printer" :status :good -:model "HP Officejet t65 All-in-one Printer" +:model "HP Color LaserJet cm2320fxi Multifunction Printer" :status :good -:model "HP Officejet r65 All-in-one Printer" +:model "HP Color LaserJet cm2320n Multifunction Printer" :status :good -:model "HP Officejet k80 All-in-one Printer" +:model "HP Color LaserJet cm2320nf Multifunction Printer" :status :good -:model "HP Officejet k80xi All-in-one Printer" +:model "HP Color LaserJet cm4730 Multifunction Printer" :status :good -:model "HP Officejet r80xi All-in-one Printer" +:model "HP Color LaserJet cm4730f Multifunction Printer" :status :good -:model "HP Officejet r80 All-in-one Printer" +:model "HP Color LaserJet cm4730fm Multifunction Printer" :status :good -:model "HP Officejet g85 All-in-one Printer" +:model "HP Color LaserJet cm4730fsk Multifunction Printer" :status :good -:model "HP Officejet g85xi All-in-one Printer" +:model "HP Color LaserJet Enterprise Flow MFP m776z" :status :good -:model "HP Officejet g95 All-in-one Printer" +:model "HP Color LaserJet Enterprise Flow MFP m776zs" :status :good -:model "HP Photosmart All-in-one Printer - b109d" +:model "HP Color LaserJet Enterprise MFP m776dn" :status :good -:model "HP Photosmart All-in-one Printer - b109e" +:model "HP Color LaserJet Managed Flow MFP e67560z" :status :good -:model "HP Photosmart All-in-one Printer - b109c" +:model "HP Color LaserJet Managed Flow MFP e67660z" :status :good -:model "HP Photosmart All-in-one Printer - b109a" +:model "HP Color LaserJet Managed Flow MFP e77822z" :status :good -:model "HP Photosmart Wireless All-in-one Printer - b109q" +:model "HP Color LaserJet Managed Flow MFP e77825z" :status :good -:model "HP Photosmart Wireless All-in-one Printer - b109n" +:model "HP Color LaserJet Managed Flow MFP e77830z" :status :good -:model "HP Photosmart Wireless All-in-one Printer - b109q=r" +:model "HP Color LaserJet Managed Flow MFP e87640z" :status :good -:model "HP Officejet d125xi All-in-one Printer" +:model "HP Color LaserJet Managed Flow MFP e87650z" :status :good -:model "HP Officejet d135 All-in-one Printer" +:model "HP Color LaserJet Managed Flow MFP e87660z" :status :good -:model "HP Officejet d135xi All-in-one Printer" +:model "HP Color LaserJet Managed MFP e67650dh" :status :good -:model "HP Officejet d145xi All-in-one Printer" +:model "HP Color LaserJet Managed MFP e77422a" :status :good -:model "HP Officejet d145 All-in-one Printer" +:model "HP Color LaserJet Managed MFP e77422dn" :status :good -:model "HP Officejet d155xi All-in-one Printer" +:model "HP Color LaserJet Managed MFP e77422dv" :status :good -:model "HP Deskjet Ink Advantage k209a All-in-one Printer" +:model "HP Color LaserJet Managed MFP e77428dn" :status :good -:model "HP Photosmart Plus All-in-one Printer - b209a" +:model "HP Color LaserJet Managed MFP e77822dn" :status :good -:model "HP Photosmart Plus All-in-one Printer - b209b" +:model "HP Color LaserJet Managed MFP e77825dn" :status :good -:model "HP Photosmart Plus All-in-one Printer - b209c" +:model "HP Color LaserJet Managed MFP e77830dn" :status :good -:model "HP Printer Scanner Copier 300" +:model "HP Color LaserJet Managed MFP e87640 Dn" :status :good -:model "HP Photosmart Premium All-in-one Printer Series - c309h" +:model "HP Color LaserJet Managed MFP e87640 Du" :status :good -:model "HP Photosmart Premium All-in-one Printer Series - c309g" +:model "HP Color LaserJet Managed MFP e87650dn" :status :good -:model "HP Photosmart Premium Fax All-in-one Printer - c309a" +:model "HP Color LaserJet Managed MFP e87650du" :status :good -:model "HP Photosmart Premium Fax All-in-one Printer Series -c309c" +:model "HP Color LaserJet Managed MFP e87660dn" :status :good -:model "HP Photosmart Premium Fax All-in-one Printer Series -c309a" +:model "HP Color LaserJet Managed MFP e87660du" +:status :good + +:model "HP Color LaserJet MFP m277c6" +:status :good + +:model "HP Color LaserJet MFP m277dw" +:status :good + +:model "HP Color LaserJet MFP m277n" +:status :good + +:model "HP Color LaserJet MFP m377 Fnw" +:status :good + +:model "HP Color LaserJet Pro MFP m178cn" +:status :good + +:model "HP Color LaserJet Pro MFP m178n" +:status :good + +:model "HP Color LaserJet Pro MFP m179cfw" +:status :good + +:model "HP Color LaserJet Pro MFP m179fw" +:status :good + +:model "HP Color LaserJet Pro MFP m180cn" +:status :good + +:model "HP Color LaserJet Pro MFP m180n" +:status :good + +:model "HP Color LaserJet Pro MFP m180nw" +:status :good + +:model "HP Color LaserJet Pro MFP m181cfw" +:status :good + +:model "HP Color LaserJet Pro MFP m181fnw" +:status :good + +:model "HP Color LaserJet Pro MFP m181fw" +:status :good + +:model "HP Color LaserJet Pro MFP m274n" +:status :good + +:model "HP Color LaserJet Pro MFP m278cw" +:status :good + +:model "HP Color LaserJet Pro MFP m278dn" +:status :good + +:model "HP Color LaserJet Pro MFP m278nw" +:status :good + +:model "HP Color LaserJet Pro MFP m279fdw" +:status :good + +:model "HP Color LaserJet Pro MFP m280c2" +:status :good + +:model "HP Color LaserJet Pro MFP m280cnw" +:status :good + +:model "HP Color LaserJet Pro MFP m280nw" +:status :good + +:model "HP Color LaserJet Pro MFP m281cdw" +:status :good + +:model "HP Color LaserJet Pro MFP m281dne" +:status :good + +:model "HP Color LaserJet Pro MFP m281fdn" +:status :good + +:model "HP Color LaserJet Pro MFP m281fdw" +:status :good + +:model "HP Color LaserJet Pro MFP m476dn" +:status :good + +:model "HP Color LaserJet Pro MFP m476dw" +:status :good + +:model "HP Color LaserJet Pro MFP m476nw" +:status :good + +:model "HP Color LaserJet Pro MFP m477 Fdn" +:status :good + +:model "HP Color LaserJet Pro MFP m477 Fdw" +:status :good + +:model "HP Color LaserJet Pro MFP m477 Fnw" +:status :good + +:model "HP Color LaserJet Pro MFP m478fcdn" +:status :good + +:model "HP Color LaserJet Pro MFP m478fcdw" +:status :good + +:model "HP Color LaserJet Pro MFP m479dw" +:status :good + +:model "HP Color LaserJet Pro MFP m479fcdn" +:status :good + +:model "HP Color LaserJet Pro MFP m479fcdw" +:status :good + +:model "HP Color LaserJet Pro MFP m479fdn" +:status :good + +:model "HP Color LaserJet Pro MFP m479fdw" +:status :good + +:model "HP Color LaserJet Pro MFP m479fnw" +:status :good + +:model "HP Color LaserJet Pro Mpf m176n" +:status :good + +:model "HP Color LaserJet Pro Mpf m177fw" +:status :good + +:model "HP Designjet 4500mfp" +:status :good + +:model "HP Designjet 4520mfp" +:status :good + +:model "HP Designjet t790ps 24in" +:status :good + +:model "HP Deskjet 1050 j410 All-in-one Printer" +:status :good + +:model "HP Deskjet 1051 All-in-one Printer" +:status :good + +:model "HP Deskjet 1055 All-in-one Printer -j410e" +:status :good + +:model "HP Deskjet 1056 All-in-one Printer -j410a" +:status :good + +:model "HP Deskjet 1510 All-in-one Printer" +:status :good + +:model "HP Deskjet 1511 All-in-one Printer" +:status :good + +:model "HP Deskjet 1512 All-in-one Printer" +:status :good + +:model "HP Deskjet 1513 All-in-one Printer" +:status :good + +:model "HP Deskjet 1514 All-in-one Printer" +:status :good + +:model "HP Deskjet 2050 j510 All-in-one Printer" +:status :good + +:model "HP Deskjet 2130 All-in-one Printer Series" +:status :good + +:model "HP Deskjet 2131 All-in-one Printer" +:status :good + +:model "HP Deskjet 2132 All-in-one Printer" +:status :good + +:model "HP Deskjet 2134 All-in-one Printer" +:status :good + +:model "HP Deskjet 2200 All-in-one" +:status :good + +:model "HP Deskjet 2510 All-in-one Printer" +:status :good + +:model "HP Deskjet 2511 All-in-one Printer" +:status :good + +:model "HP Deskjet 2512 All-in-one Printer" +:status :good + +:model "HP Deskjet 2514 All-in-one Printer" +:status :good + +:model "HP Deskjet 2540 All-in-one Printer" +:status :good + +:model "HP Deskjet 2541 All-in-one Printer" +:status :good + +:model "HP Deskjet 2542 All-in-one Printer" +:status :good + +:model "HP Deskjet 2543 All-in-one Printer" +:status :good + +:model "HP Deskjet 2544 All-in-one Printer" +:status :good + +:model "HP Deskjet 2545 All-in-one Printer" +:status :good + +:model "HP Deskjet 2546b All-in-one Printer" +:status :good + +:model "HP Deskjet 2546p All-in-one Printer" +:status :good + +:model "HP Deskjet 2546r All-in-one Printer" +:status :good + +:model "HP Deskjet 2549 All-in-one Printer" +:status :good + +:model "HP Deskjet 2620 All-in-one" +:status :good + +:model "HP Deskjet 2621 All-in-one" +:status :good + +:model "HP Deskjet 2622 All-in-one" +:status :good + +:model "HP Deskjet 2623 All-in-one" +:status :good + +:model "HP Deskjet 3050 j610 Series" +:status :good + +:model "HP Deskjet 3050a j611 Series" +:status :good + +:model "HP Deskjet 3051a E-all-in-one Printer j611h" +:status :good + +:model "HP Deskjet 3052a E-all-in-one Printer j611e" +:status :good + +:model "HP Deskjet 3052a E-all-in-one Printer j611f" +:status :good + +:model "HP Deskjet 3052a E-all-in-one Printer j611g" +:status :good + +:model "HP Deskjet 3054a E-all-in-one Printer j611c" +:status :good + +:model "HP Deskjet 3054a E-all-in-one Printer j611d" +:status :good + +:model "HP Deskjet 3054a E-all-in-one Printer j611j" +:status :good + +:model "HP Deskjet 3055a E-all-in-one Printer j611n" +:status :good + +:model "HP Deskjet 3056a E-all-in-one Printer" +:status :good + +:model "HP Deskjet 3057a E-all-in-one Printer j611n" +:status :good + +:model "HP Deskjet 3059a E-all-in-one Printer j611n" +:status :good + +:model "HP Deskjet 3070 b611 Series" +:status :good + +:model "HP Deskjet 3510 E-all-in-one" +:status :good + +:model "HP Deskjet 3511 E-all-in-one" +:status :good + +:model "HP Deskjet 3512 E-all-in-one" +:status :good + +:model "HP Deskjet 3520 E-all-in-one Series" +:status :good + +:model "HP Deskjet 3521 E-all-in-one Printer" +:status :good + +:model "HP Deskjet 3522 E-all-in-one Printer" +:status :good + +:model "HP Deskjet 3524 E-all-in-one Printer" +:status :good + +:model "HP Deskjet 3526 E-all-in-one Printer" +:status :good + +:model "HP Deskjet 3630 All-in-one Printer" +:status :good + +:model "HP Deskjet 3632 All-in-one Printer" +:status :good + +:model "HP Deskjet 3633 All-in-one Printer" +:status :good + +:model "HP Deskjet 3634 All-in-one Printer" +:status :good + +:model "HP Deskjet 3700 All-in-one" +:status :good + +:model "HP Deskjet 3722 All-in-one" +:status :good + +:model "HP Deskjet f2110 All-in-one Printer" +:status :good + +:model "HP Deskjet f2120 All-in-one Printer" +:status :good + +:model "HP Deskjet f2128 All-in-one Printer" +:status :good + +:model "HP Deskjet f2140 All-in-one Printer" +:status :good + +:model "HP Deskjet f2179 All-in-one Printer" +:status :good + +:model "HP Deskjet f2180 All-in-one Printer" +:status :good + +:model "HP Deskjet f2185 All-in-one Printer" +:status :good + +:model "HP Deskjet f2187 All-in-one Printer" +:status :good + +:model "HP Deskjet f2188 All-in-one Printer" +:status :good + +:model "HP Deskjet f2210 All-in-one Printer" +:status :good + +:model "HP Deskjet f2212 All-in-one Printer" +:status :good + +:model "HP Deskjet f2214 All-in-one Printer" +:status :good + +:model "HP Deskjet f2224 All-in-one Printer" +:status :good + +:model "HP Deskjet f2235 All-in-one Printer" +:status :good + +:model "HP Deskjet f2238 All-in-one Printer" +:status :good + +:model "HP Deskjet f2240 All-in-one Printer" +:status :good + +:model "HP Deskjet f2250 All-in-one Printer" +:status :good + +:model "HP Deskjet f2275 All-in-one Printer" +:status :good + +:model "HP Deskjet f2276 All-in-one Printer" +:status :good + +:model "HP Deskjet f2280 All-in-one Printer" +:status :good + +:model "HP Deskjet f2288 All-in-one Printer" +:status :good + +:model "HP Deskjet f2290 All-in-one Printer" +:status :good + +:model "HP Deskjet f2410 All-in-one Printer" +:status :good + +:model "HP Deskjet f2418 All-in-one Printer" +:status :good + +:model "HP Deskjet f2420 All-in-one Printer" +:status :good + +:model "HP Deskjet f2423 All-in-one Printer" +:status :good + +:model "HP Deskjet f2430 All-in-one Printer" +:status :good + +:model "HP Deskjet f2440 All-in-one Printer" +:status :good + +:model "HP Deskjet f2476 All-in-one Printer" +:status :good + +:model "HP Deskjet f2480 All-in-one Printer" +:status :good + +:model "HP Deskjet f2483 All-in-one Printer" +:status :good + +:model "HP Deskjet f2488 All-in-one Printer" +:status :good + +:model "HP Deskjet f2492 All-in-one Printer" +:status :good + +:model "HP Deskjet f2493 All-in-one Printer" :status :good :model "HP Deskjet f310 All-in-one Printer" @@ -196,670 +616,844 @@ :model "HP Deskjet f394 All-in-one Printer" :status :good -:model "HP PSC 500xi All-in-one Printer" +:model "HP Deskjet f4135 All-in-one Printer" :status :good -:model "HP PSC 500 All-in-one Printer" +:model "HP Deskjet f4140 All-in-one Printer" :status :good -:model "HP Officejet 500 All-in-one Printer" +:model "HP Deskjet f4150 All-in-one Printer" :status :good -:model "HP Officejet 520 All-in-one Printer" +:model "HP Deskjet f4172 All-in-one Printer" :status :good -:model "HP Officejet 570 All-in-one Printer" +:model "HP Deskjet f4175 All-in-one Printer" :status :good -:model "HP Officejet 580 All-in-one Printer" +:model "HP Deskjet f4180 All-in-one Printer" :status :good -:model "HP Officejet 590 All-in-one Printer" +:model "HP Deskjet f4185 All-in-one Printer" :status :good -:model "HP Officejet 600 All-in-one Printer" +:model "HP Deskjet f4188 All-in-one Printer" :status :good -:model "HP Officejet 610 All-in-one Printer" +:model "HP Deskjet f4190 All-in-one Printer" :status :good -:model "HP Officejet 630 All-in-one Printer" +:model "HP Deskjet f4194 All-in-one Printer" :status :good -:model "HP Officejet 635 All-in-one Printer" +:model "HP Deskjet f4210 All-in-one Printer" :status :good -:model "HP Officejet 700 All-in-one Printer" +:model "HP Deskjet f4213 All-in-one Printer" :status :good -:model "HP Officejet 710 All-in-one Printer" +:model "HP Deskjet f4224 All-in-one Printer" :status :good -:model "HP PSC 720 All-in-one Printer" +:model "HP Deskjet f4230 All-in-one Printer" :status :good -:model "HP Officejet 720 All-in-one Printer" +:model "HP Deskjet f4235 All-in-one Printer" :status :good -:model "HP Officejet 725 All-in-one Printer" +:model "HP Deskjet f4238 All-in-one Printer" +:status :good + +:model "HP Deskjet f4240 All-in-one Printer" +:status :good + +:model "HP Deskjet f4250 All-in-one Printer" +:status :good + +:model "HP Deskjet f4272 All-in-one Printer" +:status :good + +:model "HP Deskjet f4273 All-in-one Printer" +:status :good + +:model "HP Deskjet f4274 All-in-one Printer" +:status :good + +:model "HP Deskjet f4275 All-in-one Printer" +:status :good + +:model "HP Deskjet f4280 All-in-one Printer" +:status :good + +:model "HP Deskjet f4283 All-in-one Printer" +:status :good + +:model "HP Deskjet f4288 All-in-one Printer" +:status :good + +:model "HP Deskjet f4292 All-in-one Printer" +:status :good + +:model "HP Deskjet f4293 All-in-one Printer" +:status :good + +:model "HP Deskjet f4294 All-in-one Printer" +:status :good + +:model "HP Deskjet f4435 All-in-one Printer" +:status :good + +:model "HP Deskjet f4440 All-in-one Printer" +:status :good + +:model "HP Deskjet f4450 All-in-one Printer" +:status :good + +:model "HP Deskjet f4470 All-in-one Printer" +:status :good + +:model "HP Deskjet f4472 All-in-one Printer" +:status :good + +:model "HP Deskjet f4473 All-in-one Printer" +:status :good + +:model "HP Deskjet f4480 All-in-one Printer" +:status :good + +:model "HP Deskjet f4483 All-in-one Printer" +:status :good + +:model "HP Deskjet f4488 All-in-one Printer" +:status :good + +:model "HP Deskjet f4492 All-in-one Printer" +:status :good + +:model "HP Deskjet f4500 All-in-one Printer Series" :status :good :model "HP Deskjet f735 All-in-one Printer" :status :good -:model "HP PSC 750 All-in-one Printer" +:model "HP Deskjet Gt 5810 All-in-one Printer" :status :good -:model "HP PSC 750xi All-in-one Printer" +:model "HP Deskjet Gt 5820 All-in-one Printer" :status :good -:model "HP PSC 760 All-in-one Printer" +:model "HP Deskjet Ink Adv 2060 k110" :status :good -:model "HP PSC 780 All-in-one Printer" +:model "HP Deskjet Ink Advantage 1510 All-in-one Printer Series" :status :good -:model "HP PSC 780xi All-in-one Printer" +:model "HP Deskjet Ink Advantage 1515 All-in-one Printer" :status :good -:model "HP PSC 900 All-in-one Printer" +:model "HP Deskjet Ink Advantage 1516 All-in-one Printer" :status :good -:model "HP 915 Inkjet All-in-one Printer" +:model "HP Deskjet Ink Advantage 1518 All-in-one Printer" :status :good -:model "HP PSC 920 All-in-one Printer" +:model "HP Deskjet Ink Advantage 2130 All-in One Printer" :status :good -:model "HP PSC 950 All-in-one Printer" +:model "HP Deskjet Ink Advantage 2135 All-in One Printer" :status :good -:model "HP PSC 950vr All-in-one Printer" +:model "HP Deskjet Ink Advantage 2136 All-in One Printer" :status :good -:model "HP PSC 950xi All-in-one Printer" +:model "HP Deskjet Ink Advantage 2138 All-in One Printer" :status :good -:model "HP LaserJet m1005 Multifunction Printer" +:model "HP Deskjet Ink Advantage 2200 All-in-one" :status :good -:model "HP Color LaserJet cm1015 Multifunction Printer" +:model "HP Deskjet Ink Advantage 2510 All-in-one" :status :good -:model "HP Color LaserJet cm1017 Multifunction Printer" +:model "HP Deskjet Ink Advantage 2515 All-in-one Printer" :status :good -:model "HP LaserJet 1100a Xi All-in-one Printer" +:model "HP Deskjet Ink Advantage 2516 All-in-one Printer" :status :good -:model "HP LaserJet 1100xi Printer" +:model "HP Deskjet Ink Advantage 2520hc All-in-one" :status :good -:model "HP LaserJet 1100a All-in-one Printer" +:model "HP Deskjet Ink Advantage 2540 All-in-one Printer Series" :status :good -:model "HP LaserJet 1100 Printer" +:model "HP Deskjet Ink Advantage 2545 All-in-one Printer" :status :good -:model "HP LaserJet 1100a Se All-in-one Printer" +:model "HP Deskjet Ink Advantage 2546 All-in-one Printer" :status :good -:model "HP LaserJet 1100se Printer" +:model "HP Deskjet Ink Advantage 2548 All-in-one Printer" :status :good -:model "HP PSC 1110v All-in-one Printer" +:model "HP Deskjet Ink Advantage 2635 All-in-one" :status :good -:model "HP PSC 1110 All-in-one Printer" +:model "HP Deskjet Ink Advantage 2636 All-in-one" :status :good -:model "HP PSC 1118 All-in-one Printer" +:model "HP Deskjet Ink Advantage 2645 All-in-one Printer" :status :good -:model "HP LaserJet m1120 Multifunction Printer" +:model "HP Deskjet Ink Advantage 2646 All-in-one Printer" :status :good -:model "HP LaserJet m1120n Multifunction Printer" +:model "HP Deskjet Ink Advantage 2675 All-in-one" :status :good -:model "HP Officejet Pro 1150c All-in-one Printer" +:model "HP Deskjet Ink Advantage 2676 All-in-one" :status :good -:model "HP Officejet Pro 1150cse All-in-one Printer" +:model "HP Deskjet Ink Advantage 2677 All-in-one" :status :good -:model "HP Officejet Pro 1170cse All-in-one Printer" +:model "HP Deskjet Ink Advantage 2678 All-in-one" :status :good -:model "HP Officejet Pro 1170c All-in-one Printer" +:model "HP Deskjet Ink Advantage 3515 E-all-in-one" :status :good -:model "HP Officejet Pro 1170cxi All-in-one Printer" +:model "HP Deskjet Ink Advantage 3516 E-all-in-one" :status :good -:model "HP Officejet Pro 1175cxi All-in-one Printer" +:model "HP Deskjet Ink Advantage 3525 E-all-in-one" :status :good -:model "HP Officejet Pro 1175cse All-in-one Printer" +:model "HP Deskjet Ink Advantage 3540 E-all-in-one Printer Series" :status :good -:model "HP Officejet Pro 1175c All-in-one Printer" +:model "HP Deskjet Ink Advantage 3545 E-all-in-one Printer" :status :good -:model "HP PSC 1200 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3546 E-all-in-one Printer" :status :good -:model "HP PSC 1205 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3630 All-in-one Printer" :status :good -:model "HP PSC 1209 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3635 All-in-one Printer" :status :good -:model "HP PSC 1210xi All-in-one Printer" +:model "HP Deskjet Ink Advantage 3636 All-in-one Printer" :status :good -:model "HP PSC 1210v All-in-one Printer" +:model "HP Deskjet Ink Advantage 3638 All-in-one Printer" :status :good -:model "HP PSC 1210 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3735 All-in-one" :status :good -:model "HP PSC 1213 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3789 All-in-one" :status :good -:model "HP PSC 1215 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3790 All-in-one" :status :good -:model "HP PSC 1216 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3830 All-in-one Printer" :status :good -:model "HP PSC 1217 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3835 All-in-one Printer" :status :good -:model "HP PSC 1218 All-in-one Printer" +:model "HP Deskjet Ink Advantage 3836 All-in-one Printer" :status :good -:model "HP PSC 1219 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4515 E-all-in-one Printer" :status :good -:model "HP LaserJet 1220 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4518 E-all-in-one Printer" :status :good -:model "HP LaserJet 1220se All-in-one Printer" +:model "HP Deskjet Ink Advantage 4530 All-in-one" :status :good -:model "HP PSC 1300 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4535 All-in-one" :status :good -:model "HP PSC 1310 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4536 All-in-one" :status :good -:model "HP PSC 1311 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4610 All-in-one Printer Series" :status :good -:model "HP Color LaserJet cm1312 Multifunction Printer" +:model "HP Deskjet Ink Advantage 4615 All-in-one Printer" :status :good -:model "HP Color LaserJet cm1312nfi Multifunction Printer" +:model "HP Deskjet Ink Advantage 4620 E-all-in-one Printer" :status :good -:model "HP PSC 1312 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4625 E-all-in-one Printer" :status :good -:model "HP PSC 1315v All-in-one Printer" +:model "HP Deskjet Ink Advantage 4640 E-all-in-one Printer Series" :status :good -:model "HP PSC 1315s All-in-one Printer" +:model "HP Deskjet Ink Advantage 4645 E-all-in-one Printer" :status :good -:model "HP PSC 1315xi All-in-one Printer" +:model "HP Deskjet Ink Advantage 4646 E-all-in-one Printer" :status :good -:model "HP PSC 1315 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4648 E-all-in-one Printer" :status :good -:model "HP PSC 1317 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4670 All-in-one" :status :good -:model "HP PSC 1318 All-in-one Printer" +:model "HP Deskjet Ink Advantage 4675 All-in-one" :status :good -:model "HP LaserJet m1319f Multifunction Printer" +:model "HP Deskjet Ink Advantage 4676 All-in-one" :status :good -:model "HP PSC 1340 All-in-one Printer" +:model "HP Deskjet Ink Advantage 5075 All-in-one" :status :good -:model "HP PSC 1345 All-in-one Printer" +:model "HP Deskjet Ink Advantage 5275 All-in-one" :status :good -:model "HP PSC 1350xi All-in-one Printer" +:model "HP Deskjet Ink Advantage 5525 E-all-in-one" :status :good -:model "HP PSC 1350v All-in-one Printer" +:model "HP Deskjet Ink Advantage 5570 All-in-one" :status :good -:model "HP PSC 1350 All-in-one Printer" +:model "HP Deskjet Ink Advantage 5575 All-in-one" :status :good -:model "HP PSC 1355 All-in-one Printer" +:model "HP Deskjet Ink Advantage 5640 All-in-one Printer Series" :status :good -:model "HP PSC 1401 All-in-one Printer" +:model "HP Deskjet Ink Advantage 5645 All-in-one Printer" :status :good -:model "HP PSC 1402 All-in-one Printer" +:model "HP Deskjet Ink Advantage 6525 E-all-in-one" :status :good -:model "HP PSC 1403 All-in-one Printer" +:model "HP Deskjet Ink Advantage k209a All-in-one Printer" :status :good -:model "HP PSC 1406 All-in-one Printer" +:model "HP Deskjet Ink Advantage Ultra 2529 All-in-one Printer" :status :good -:model "HP PSC 1408 All-in-one Printer" +:model "HP Deskjet Ink Advantage Ultra 4720 All-in-one Printer Series" :status :good -:model "HP PSC 1410 All-in-one Printer" +:model "HP Deskjet Ink Advantage Ultra 4729 All-in-one Printer" :status :good -:model "HP PSC 1410v All-in-one Printer" +:model "HP Deskjet Ink Advantage Ultra 5738 All-in-one Printer" :status :good -:model "HP PSC 1410xi All-in-one Printer" +:model "HP Deskjet Ink Advantage Ultra 5739 All-in-one Printer" :status :good -:model "HP PSC 1415 All-in-one Printer" +:model "HP Digital Sender Flow 8500 fn2 Document Capture Workstation" :status :good -:model "HP PSC 1417 All-in-one Printer" +:model "HP Envy 100 d410 Series" :status :good -:model "HP PSC 1503 All-in-one Printer" +:model "HP Envy 110 E-all-in-one" :status :good -:model "HP PSC 1504 All-in-one Printer" +:model "HP Envy 111 E-all-in-one" :status :good -:model "HP PSC 1507 All-in-one Printer" +:model "HP Envy 114 E-all-in-one" :status :good -:model "HP PSC 1508 All-in-one Printer" +:model "HP Envy 120 E-all-in-one" :status :good -:model "HP PSC 1510s All-in-one Printer" +:model "HP Envy 121 E-all-in-one" :status :good -:model "HP PSC 1510xi All-in-one Printer" +:model "HP Envy 4500 E-all-in-one" :status :good -:model "HP PSC 1510 All-in-one Printer" +:model "HP Envy 4501 E-all-in-one" :status :good -:model "HP PSC 1510v All-in-one Printer" +:model "HP Envy 4502 E-all-in-one" :status :good -:model "HP PSC 1513s All-in-one Printer" +:model "HP Envy 4503 E-all-in-one" :status :good -:model "HP PSC 1513 All-in-one Printer" +:model "HP Envy 4504 E-all-in-one" :status :good -:model "HP PSC 1514 All-in-one Printer" +:model "HP Envy 4505 E-all-in-one" :status :good -:model "HP LaserJet m1522n Multifunction Printer" +:model "HP Envy 4507 E-all-in-one" :status :good -:model "HP LaserJet m1522nf Multifunction Printer" +:model "HP Envy 4508 E-all-in-one" :status :good -:model "HP LaserJet m1522 Multifunction Printer" +:model "HP Envy 4510 All-in-one" :status :good -:model "HP PSC 1600 All-in-one Printer" +:model "HP Envy 4512 All-in-one" :status :good -:model "HP PSC 1603 All-in-one Printer" +:model "HP Envy 4516 All-in-one" :status :good -:model "HP PSC 1605 All-in-one Printer" +:model "HP Envy 4520 All-in-one Printer" :status :good -:model "HP PSC 1608 All-in-one Printer" +:model "HP Envy 4520 All-in-one Printer Series" :status :good -:model "HP PSC 1610 All-in-one Printer" +:model "HP Envy 4522 All-in-one Printer" :status :good -:model "HP PSC 1610xi All-in-one Printer" +:model "HP Envy 4523 All-in-one Printer" :status :good -:model "HP PSC 1610v All-in-one Printer" +:model "HP Envy 4524 All-in-one Printer" :status :good -:model "HP PSC 1613 All-in-one Printer" +:model "HP Envy 5000 All-in-one" :status :good -:model "HP PSC 1615 All-in-one Printer" +:model "HP Envy 5020 All-in-one" :status :good -:model "HP PSC 2105 All-in-one Printer" +:model "HP Envy 5030 All-in-one" :status :good -:model "HP PSC 2108 All-in-one Printer" +:model "HP Envy 5032 All-in-one" :status :good -:model "HP Deskjet f2110 All-in-one Printer" +:model "HP Envy 5530 E-all-in-one Printer" :status :good -:model "HP PSC 2110 All-in-one Printer" +:model "HP Envy 5531 E-all-in-one Printer" :status :good -:model "HP PSC 2110v All-in-one Printer" +:model "HP Envy 5532 E-all-in-one Printer" :status :good -:model "HP PSC 2110xi All-in-one Printer" +:model "HP Envy 5534 E-all-in-one Printer" :status :good -:model "HP PSC 2115 All-in-one Printer" +:model "HP Envy 5535 E-all-in-one Printer" :status :good -:model "HP Deskjet f2120 All-in-one Printer" +:model "HP Envy 5536 E-all-in-one Printer" :status :good -:model "HP Deskjet f2128 All-in-one Printer" +:model "HP Envy 5539 E-all-in-one Printer" :status :good -:model "HP Deskjet f2140 All-in-one Printer" +:model "HP Envy 5540 All-in-one Printer" :status :good -:model "HP PSC 2150 All-in-one Printer" +:model "HP Envy 5540 All-in-one Printer Series" :status :good -:model "HP PSC 2170 All-in-one Printer" +:model "HP Envy 5542 E-all-in-one Printer" :status :good -:model "HP PSC 2171 All-in-one Printer" +:model "HP Envy 5543 All-in-one Printer" :status :good -:model "HP PSC 2175 All-in-one Printer" +:model "HP Envy 5544 All-in-one Printer" :status :good -:model "HP PSC 2175v All-in-one Printer" +:model "HP Envy 5545 E-all-in-one Printer" :status :good -:model "HP PSC 2175xi All-in-one Printer" +:model "HP Envy 5546 All-in-one Printer" :status :good -:model "HP Deskjet f2179 All-in-one Printer" +:model "HP Envy 5640 E-all-in-one" :status :good -:model "HP PSC 2179 All-in-one Printer" +:model "HP Envy 5642 E-all-in-one" :status :good -:model "HP Deskjet f2180 All-in-one Printer" +:model "HP Envy 5643 E-all-in-one" :status :good -:model "HP Deskjet f2185 All-in-one Printer" +:model "HP Envy 5644 E-all-in-one" :status :good -:model "HP Deskjet f2187 All-in-one Printer" +:model "HP Envy 5660 E-all-in-one" :status :good -:model "HP Deskjet f2188 All-in-one Printer" +:model "HP Envy 5665 E-all-in-one" :status :good -:model "HP PSC 2200 All-in-one Printer" +:model "HP Envy 7640 E-all-in-one" :status :good -:model "HP PSC 2210 All-in-one Printer" +:model "HP Envy 7645 E-all-in-one" :status :good -:model "HP PSC 2210v All-in-one Printer" +:model "HP Envy 8000 E-all-in-one" :status :good -:model "HP PSC 2210xi All-in-one Printer" +:model "HP Envy Photo 6200 All-in-one" :status :good -:model "HP Deskjet f2210 All-in-one Printer" +:model "HP Envy Photo 6220 All-in-one" :status :good -:model "HP Deskjet f2212 All-in-one Printer" +:model "HP Envy Photo 6230 All-in-one" :status :good -:model "HP Deskjet f2214 All-in-one Printer" +:model "HP Envy Photo 6232 All-in-one" :status :good -:model "HP Deskjet f2224 All-in-one Printer" +:model "HP Envy Photo 6234 All-in-one" :status :good -:model "HP Deskjet f2235 All-in-one Printer" +:model "HP Envy Photo 7100 All-in-one" :status :good -:model "HP Deskjet f2238 All-in-one Printer" +:model "HP Envy Photo 7120 All-in-one" :status :good -:model "HP Deskjet f2240 All-in-one Printer" +:model "HP Envy Photo 7130 All-in-one" :status :good -:model "HP Deskjet f2250 All-in-one Printer" +:model "HP Envy Photo 7134 All-in-one" :status :good -:model "HP Deskjet f2275 All-in-one Printer" +:model "HP Envy Photo 7155 All-in-one" :status :good -:model "HP Deskjet f2276 All-in-one Printer" +:model "HP Envy Photo 7164 All-in-one" :status :good -:model "HP Deskjet f2280 All-in-one Printer" +:model "HP Envy Photo 7800 All-in-one" :status :good -:model "HP Deskjet f2288 All-in-one Printer" +:model "HP Envy Photo 7820 All-in-one" :status :good -:model "HP Deskjet f2290 All-in-one Printer" +:model "HP Envy Photo 7830 All-in-one" :status :good -:model "HP PSC 2300 Series All-in-one Printer" +:model "HP Envy Photo 7855 All-in-one" :status :good -:model "HP PSC 2310 All-in-one Printer" +:model "HP Hotspot LaserJet Pro m1218nfs MFP" :status :good -:model "HP Color LaserJet cm2320n Multifunction Printer" +:model "HP Ink Tank 310" :status :good -:model "HP Color LaserJet cm2320nf Multifunction Printer" +:model "HP Ink Tank Wireless 410" :status :good -:model "HP Color LaserJet cm2320fxi Multifunction Printer" +:model "HP Laser Ns MFP 1005" :status :good -:model "HP Color LaserJet cm2320 Multifuntion Printer" +:model "HP Laser Ns MFP 1005w" :status :good -:model "HP PSC 2350 All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175" :status :good -:model "HP PSC 2352 All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175a" :status :good -:model "HP PSC 2353p All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175b" :status :good -:model "HP PSC 2353 All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175c" :status :good -:model "HP PSC 2355 All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175e" :status :good -:model "HP PSC 2355p All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175nw" :status :good -:model "HP PSC 2355xi All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175p" :status :good -:model "HP PSC 2355v All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175q" :status :good -:model "HP PSC 2357 All-in-one Printer" +:model "HP LaserJet 100 Color MFP m175r" :status :good -:model "HP PSC 2358 All-in-one Printer" +:model "HP LaserJet 1100 Printer" :status :good -:model "HP PSC 2405 Photosmart All-in-one Printer" +:model "HP LaserJet 1100a All-in-one Printer" :status :good -:model "HP PSC 2410v Photosmart All-in-one Printer" +:model "HP LaserJet 1100a Se All-in-one Printer" :status :good -:model "HP PSC 2410xi Photosmart All-in-one Printer" +:model "HP LaserJet 1100a Xi All-in-one Printer" :status :good -:model "HP Deskjet f2410 All-in-one Printer" +:model "HP LaserJet 1100se Printer" :status :good -:model "HP PSC 2410 Photosmart All-in-one Printer" +:model "HP LaserJet 1220 All-in-one Printer" :status :good -:model "HP Deskjet f2418 All-in-one Printer" +:model "HP LaserJet 1220se All-in-one Printer" :status :good -:model "HP Deskjet f2420 All-in-one Printer" +:model "HP LaserJet 200 Color MFP m275nw" :status :good -:model "HP PSC 2420 Photosmart All-in-one Printer" +:model "HP LaserJet 200 Color MFP m275s" :status :good -:model "HP Deskjet f2423 All-in-one Printer" +:model "HP LaserJet 200 Color MFP m275t" :status :good -:model "HP Deskjet f2430 All-in-one Printer" +:model "HP LaserJet 200 Color MFP m275u" :status :good -:model "HP Deskjet f2440 All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276b" :status :good -:model "HP PSC 2450 Photosmart All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276e" :status :good -:model "HP Deskjet f2476 All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276g" :status :good -:model "HP Deskjet f2480 All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276j" :status :good -:model "HP Deskjet f2483 All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276k" :status :good -:model "HP Deskjet f2488 All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276p" :status :good -:model "HP Deskjet f2492 All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276q" :status :good -:model "HP Deskjet f2493 All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276r" :status :good -:model "HP PSC 2500 Photosmart All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276u" :status :good -:model "HP PSC 2510 Photosmart All-in-one Printer" +:model "HP LaserJet 200 Colormfp m276v" :status :good -:model "HP PSC 2510xi Photosmart All-in-one Printer" +:model "HP LaserJet 300 Color MFP m375nw" :status :good -:model "HP PSC 2550 Photosmart All-in-one Printer" +:model "HP LaserJet 3015 All-in-one Printer" :status :good -:model "HP Photosmart 2570 All-in-one Printer" +:model "HP LaserJet 3020 All-in-one Printer" :status :good -:model "HP Photosmart 2571 All-in-one Printer" +:model "HP LaserJet 3030 All-in-one Printer" :status :good -:model "HP Photosmart 2573 All-in-one Printer" +:model "HP LaserJet 3050 All-in-one Printer" :status :good -:model "HP Photosmart 2574 All-in-one Printer" +:model "HP LaserJet 3050z All-in-one Printer" :status :good -:model "HP Photosmart 2575a All-in-one Printer" +:model "HP LaserJet 3052 All-in-one Printer" :status :good -:model "HP Photosmart 2575v All-in-one Printer" +:model "HP LaserJet 3055 All-in-one Printer" :status :good -:model "HP Photosmart 2575xi All-in-one Printer" +:model "HP LaserJet 3100 All-in-one Printer" :status :good -:model "HP Photosmart 2575 All-in-one Printer" +:model "HP LaserJet 3100se All-in-one Printer" :status :good -:model "HP Photosmart 2578 All-in-one Printer" +:model "HP LaserJet 3100xi All-in-one Printer" :status :good -:model "HP Photosmart 2605 All-in-one Printer" +:model "HP LaserJet 3150 All-in-one Printer" :status :good -:model "HP Photosmart 2608 All-in-one Printer" +:model "HP LaserJet 3150se All-in-one Printer" :status :good -:model "HP Photosmart 2610 All-in-one Printer" +:model "HP LaserJet 3150xi All-in-one Printer" :status :good -:model "HP Photosmart 2610v All-in-one Printer" +:model "HP LaserJet 3200 All-in-one Printer" :status :good -:model "HP Photosmart 2610xi All-in-one Printer" +:model "HP LaserJet 3200se All-in-one Printer" :status :good -:model "HP Photosmart 2613 All-in-one Printer" +:model "HP LaserJet 3300 Multifunction Printer" :status :good -:model "HP Photosmart 2615 All-in-one Printer" +:model "HP LaserJet 3310 Digital Printer Copier" :status :good -:model "HP Photosmart 2710 All-in-one Printer" +:model "HP LaserJet 3320 Multifunction Printer" :status :good -:model "HP Photosmart 2710xi All-in-one Printer" +:model "HP LaserJet 3320n Multifunction Printer" :status :good -:model "HP Photosmart 2713 All-in-one Printer" +:model "HP LaserJet 3330 Multifunction Printer" :status :good -:model "HP LaserJet m2727nf Multifunction Printer" +:model "HP LaserJet 3380 All-in-one Printer" :status :good -:model "HP LaserJet m2727 Multifunction Printer" +:model "HP LaserJet 3390 All-in-one Printer" :status :good -:model "HP LaserJet m2727nfs Multifunction Printer" +:model "HP LaserJet 3392 All-in-one Printer" :status :good -:model "HP Color LaserJet 2800 All-in-one Printer" +:model "HP LaserJet 400 Color MFP m475dn" :status :good -:model "HP Color LaserJet 2820 All-in-one Printer" +:model "HP LaserJet 400 Color MFP m475dw" :status :good -:model "HP Color LaserJet 2830 All-in-one Printer" +:model "HP LaserJet 400 MFP m425dn" :status :good -:model "HP Color LaserJet 2840 All-in-one Printer" +:model "HP LaserJet 400 MFP m425dw" :status :good -:model "HP LaserJet 3015 All-in-one Printer" +:model "HP LaserJet 4100 Multifunction Printer" :status :good -:model "HP LaserJet 3020 All-in-one Printer" +:model "HP LaserJet 4101 Multifunction Printer" :status :good -:model "HP LaserJet 3030 All-in-one Printer" +:model "HP LaserJet 4345 Multifunction Printer" +:status :good + +:model "HP LaserJet 4345x Multifunction Printer" +:status :good + +:model "HP LaserJet 4345xm Multifunction Printer" +:status :good + +:model "HP LaserJet 4345xs Multifunction Printer" +:status :good + +:model "HP LaserJet 8100 Multifunction Printer" +:status :good + +:model "HP LaserJet 8150 Multifunction Printer" +:status :good + +:model "HP LaserJet 9000 Multifunction Printer" +:status :good + +:model "HP LaserJet 9000l Multifunction Printer" +:status :good + +:model "HP LaserJet 9040 Multifunction Printer" +:status :good + +:model "HP LaserJet 9050 Multifunction Printer" +:status :good + +:model "HP LaserJet 9055 Multifunction Printer" +:status :good + +:model "HP LaserJet 9065 Multifunction Printer" +:status :good + +:model "HP LaserJet Enterprise Flow MFP m528c" +:status :good + +:model "HP LaserJet Enterprise Flow MFP m528z" +:status :good + +:model "HP LaserJet Enterprise Flow MFP m630h" +:status :good + +:model "HP LaserJet Enterprise Flow MFP m630z" +:status :good + +:model "HP LaserJet Enterprise MFP m528dn" +:status :good + +:model "HP LaserJet Enterprise MFP m528f" +:status :good + +:model "HP LaserJet Enterprise MFP m630dn" +:status :good + +:model "HP LaserJet Enterprise MFP m630f" +:status :good + +:model "HP LaserJet Enterprise MFP m630h" +:status :good + +:model "HP LaserJet m1005 Multifunction Printer" +:status :good + +:model "HP LaserJet m1120 Multifunction Printer" +:status :good + +:model "HP LaserJet m1120n Multifunction Printer" +:status :good + +:model "HP LaserJet m1210 MFP Series" +:status :good + +:model "HP LaserJet m1319f Multifunction Printer" +:status :good + +:model "HP LaserJet m1522 Multifunction Printer" +:status :good + +:model "HP LaserJet m1522n Multifunction Printer" +:status :good + +:model "HP LaserJet m1522nf Multifunction Printer" +:status :good + +:model "HP LaserJet m1536dnf MFP" +:status :good + +:model "HP LaserJet m1537dnf MFP" +:status :good + +:model "HP LaserJet m1538dnf MFP" +:status :good + +:model "HP LaserJet m1539dnf MFP" +:status :good + +:model "HP LaserJet m2727 Multifunction Printer" +:status :good + +:model "HP LaserJet m2727nf Multifunction Printer" +:status :good + +:model "HP LaserJet m2727nfs Multifunction Printer" :status :good :model "HP LaserJet m3035 Multifunction Printer" @@ -868,397 +1462,511 @@ :model "HP LaserJet m3035xs Multifunction Printer" :status :good -:model "HP LaserJet 3050z All-in-one Printer" +:model "HP LaserJet m4345 Multifunction Printer" :status :good -:model "HP LaserJet 3050 All-in-one Printer" +:model "HP LaserJet m4345x Multifunction Printer" :status :good -:model "HP LaserJet 3052 All-in-one Printer" +:model "HP LaserJet m4345xm Multifunction Printer" :status :good -:model "HP LaserJet 3055 All-in-one Printer" +:model "HP LaserJet m4345xs Multifunction Printer" :status :good -:model "HP LaserJet 3100xi All-in-one Printer" +:model "HP LaserJet m4349 MFP" :status :good -:model "HP LaserJet 3100se All-in-one Printer" +:model "HP LaserJet m4555 MFP" :status :good -:model "HP LaserJet 3100 All-in-one Printer" +:model "HP LaserJet m5035 Multifunction Printer" :status :good -:model "HP Photosmart 3108 All-in-one Printer" +:model "HP LaserJet m5035x Multifunction Printer" :status :good -:model "HP Photosmart 3110v All-in-one Printer" +:model "HP LaserJet m5035xs Multifunction Printer" :status :good -:model "HP Photosmart 3110 All-in-one Printer" +:model "HP LaserJet m5039 Multifunction Printer" :status :good -:model "HP Photosmart c3110 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e52645c" :status :good -:model "HP Photosmart c3125 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e62665h" :status :good -:model "HP Photosmart c3135 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e62665z" :status :good -:model "HP Photosmart c3140 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e62675z" :status :good -:model "HP LaserJet 3150se All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e72525z" :status :good -:model "HP Photosmart c3150 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e72530z" :status :good -:model "HP LaserJet 3150 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e72535z" :status :good -:model "HP LaserJet 3150xi All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e82540z" :status :good -:model "HP Photosmart c3170 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e82550z" :status :good -:model "HP Photosmart c3173 All-in-one Printer" +:model "HP LaserJet Managed Flow MFP e82560z" :status :good -:model "HP Photosmart c3175 All-in-one Printer" +:model "HP LaserJet Managed MFP e52645dn" :status :good -:model "HP Photosmart c3180 All-in-one Printer" +:model "HP LaserJet Managed MFP e62655dn" :status :good -:model "HP Photosmart c3183 All-in-one Printer" +:model "HP LaserJet Managed MFP e62665hs" :status :good -:model "HP Photosmart c3188 All-in-one Printer" +:model "HP LaserJet Managed MFP e72525dn" :status :good -:model "HP Photosmart c3190 All-in-one Printer" +:model "HP LaserJet Managed MFP e72530dn" :status :good -:model "HP Photosmart c3193 All-in-one Printer" +:model "HP LaserJet Managed MFP e72535dn" :status :good -:model "HP Photosmart c3194 All-in-one Printer" +:model "HP LaserJet Managed MFP e82540dn" :status :good -:model "HP LaserJet 3200 All-in-one Printer" +:model "HP LaserJet Managed MFP e82540du" :status :good -:model "HP LaserJet 3200m All-in-one Printer" +:model "HP LaserJet Managed MFP e82550dn" :status :good -:model "HP Photosmart 3207 All-in-one Printer" +:model "HP LaserJet Managed MFP e82550du" :status :good -:model "HP Photosmart 3210a All-in-one Printer" +:model "HP LaserJet Managed MFP e82560dn" :status :good -:model "HP Photosmart 3210v All-in-one Printer" +:model "HP LaserJet Managed MFP e82560du" :status :good -:model "HP Photosmart 3210xi All-in-one Printer" +:model "HP LaserJet MFP e72425a" :status :good -:model "HP Photosmart 3210 All-in-one Printer" +:model "HP LaserJet MFP e72425dn" :status :good -:model "HP Photosmart 3213 All-in-one Printer" +:model "HP LaserJet MFP e72425dv" :status :good -:model "HP Photosmart 3214 All-in-one Printer" +:model "HP LaserJet MFP e72430dn" :status :good -:model "HP LaserJet 3300 Multifunction Printer" +:model "HP LaserJet Pro 200 Color MFP m276n" :status :good -:model "HP Photosmart 3308 All-in-one Printer" +:model "HP LaserJet Pro 200 Color MFP m276nw" :status :good -:model "HP Photosmart 3310 All-in-one Printer" +:model "HP LaserJet Pro 500 Color MFP m570dn" :status :good -:model "HP Photosmart 3310xi All-in-one Printer" +:model "HP LaserJet Pro 500 Color MFP m570dw" :status :good -:model "HP LaserJet 3310 Digital Printer Copier" +:model "HP LaserJet Pro m521dn Multifunction Printer" :status :good -:model "HP Photosmart 3313 All-in-one Printer" +:model "HP LaserJet Pro m521dw Multifunction Printer" :status :good -:model "HP Photosmart 3314 All-in-one Printer" +:model "HP LaserJet Pro MFP m125a" :status :good -:model "HP LaserJet 3320n Multifunction Printer" +:model "HP LaserJet Pro MFP m125nr" :status :good -:model "HP LaserJet 3320 Multifunction Printer" +:model "HP LaserJet Pro MFP m125nw" :status :good -:model "HP LaserJet 3330 Multifunction Printer" +:model "HP LaserJet Pro MFP m125r" :status :good -:model "HP LaserJet 3380 All-in-one Printer" +:model "HP LaserJet Pro MFP m125rnw" :status :good -:model "HP LaserJet 3390 All-in-one Printer" +:model "HP LaserJet Pro MFP m125s" :status :good -:model "HP LaserJet 3392 All-in-one Printer" +:model "HP LaserJet Pro MFP m126a" :status :good -:model "HP Officejet j3608 All-in-one Printer" +:model "HP LaserJet Pro MFP m126nw" :status :good -:model "HP Officejet j3625 All-in-one Printer" +:model "HP LaserJet Pro MFP m127fn" :status :good -:model "HP Officejet j3635 All-in-one Printer" +:model "HP LaserJet Pro MFP m127fp" :status :good -:model "HP Officejet j3640 All-in-one Printer" +:model "HP LaserJet Pro MFP m127fs" :status :good -:model "HP Officejet j3650 All-in-one Printer" +:model "HP LaserJet Pro MFP m127fw" :status :good -:model "HP Officejet j3680 All-in-one Printer" +:model "HP LaserJet Pro MFP m128fn" :status :good -:model "HP Officejet 4100 Series All-in-one Printer" +:model "HP LaserJet Pro MFP m128fp" :status :good -:model "HP LaserJet 4100 Multifunction Printer" +:model "HP LaserJet Pro MFP m128fw" :status :good -:model "HP LaserJet 4101 Multifunction Printer" +:model "HP LaserJet Pro MFP m130a" :status :good -:model "HP Officejet 4105 All-in-one Printer" +:model "HP LaserJet Pro MFP m130fn" :status :good -:model "HP Officejet 4110xi All-in-one Printer" +:model "HP LaserJet Pro MFP m130fw" :status :good -:model "HP Photosmart c4110 All-in-one Printer" +:model "HP LaserJet Pro MFP m130nw" :status :good -:model "HP Officejet 4110v All-in-one Printer" +:model "HP LaserJet Pro MFP m132a" :status :good -:model "HP Officejet 4110 All-in-one Printer" +:model "HP LaserJet Pro MFP m132fn" :status :good -:model "HP Officejet 4115 All-in-one Printer" +:model "HP LaserJet Pro MFP m132fp" :status :good -:model "HP Deskjet f4135 All-in-one Printer" +:model "HP LaserJet Pro MFP m132fw" :status :good -:model "HP Photosmart c4140 All-in-one Printer" +:model "HP LaserJet Pro MFP m132nw" :status :good -:model "HP Deskjet f4140 All-in-one Printer" +:model "HP LaserJet Pro MFP m132snw" :status :good -:model "HP Deskjet f4150 All-in-one Printer" +:model "HP LaserJet Pro MFP m134a" :status :good -:model "HP Photosmart c4150 All-in-one Printer" +:model "HP LaserJet Pro MFP m134fn" :status :good -:model "HP Photosmart c4170 All-in-one Printer" +:model "HP LaserJet Pro MFP m148dw" :status :good -:model "HP Deskjet f4172 All-in-one Printer" +:model "HP LaserJet Pro MFP m148fdw" :status :good -:model "HP Photosmart c4173 All-in-one Printer" +:model "HP LaserJet Pro MFP m149dw" :status :good -:model "HP Deskjet f4175 All-in-one Printer" +:model "HP LaserJet Pro MFP m149fdw" :status :good -:model "HP Photosmart c4175 All-in-one Printer" +:model "HP LaserJet Pro MFP m225dn" :status :good -:model "HP Deskjet f4180 All-in-one Printer" +:model "HP LaserJet Pro MFP m225dw" :status :good -:model "HP Photosmart c4180 All-in-one Printer" +:model "HP LaserJet Pro MFP m225rdn" :status :good -:model "HP Photosmart c4183 All-in-one Printer" +:model "HP LaserJet Pro MFP m226dn" :status :good -:model "HP Deskjet f4185 All-in-one Printer" +:model "HP LaserJet Pro MFP m226dw" :status :good -:model "HP Photosmart c4188 All-in-one Printer" +:model "HP LaserJet Pro MFP m227d" :status :good -:model "HP Deskjet f4188 All-in-one Printer" +:model "HP LaserJet Pro MFP m227fdn" :status :good -:model "HP Deskjet f4190 All-in-one Printer" +:model "HP LaserJet Pro MFP m227fdw" :status :good -:model "HP Photosmart c4190 All-in-one Printer" +:model "HP LaserJet Pro MFP m227sdn" :status :good -:model "HP Photosmart c4193 All-in-one Printer" +:model "HP LaserJet Pro MFP m25a" :status :good -:model "HP Deskjet f4194 All-in-one Printer" +:model "HP LaserJet Pro MFP m25nw" :status :good -:model "HP Photosmart c4194 All-in-one Printer" +:model "HP LaserJet Pro MFP m26a" :status :good -:model "HP Officejet 4200 All-in-one Printer" +:model "HP LaserJet Pro MFP m26nw" :status :good -:model "HP Photosmart c4205 All-in-one Printer" +:model "HP LaserJet Pro MFP m27c" :status :good -:model "HP Photosmart c4210 All-in-one Printer" +:model "HP LaserJet Pro MFP m27cnw" :status :good -:model "HP Deskjet f4210 All-in-one Printer" +:model "HP LaserJet Pro MFP m28a" :status :good -:model "HP Officejet 4211 All-in-one Printer" +:model "HP LaserJet Pro MFP m29a" :status :good -:model "HP Officejet 4212 All-in-one Printer" +:model "HP LaserJet Pro MFP m30a" :status :good -:model "HP Deskjet f4213 All-in-one Printer" +:model "HP LaserJet Pro MFP m30c" :status :good -:model "HP Officejet 4215 All-in-one Printer" +:model "HP LaserJet Pro MFP m31a" :status :good -:model "HP Officejet 4215v All-in-one Printer" +:model "HP LaserJet Pro MFP m31c" :status :good -:model "HP Officejet 4215xi All-in-one Printer" +:model "HP LaserJet Pro MFP m329dn" :status :good -:model "HP Officejet 4219 All-in-one Printer" +:model "HP LaserJet Pro MFP m329dw" :status :good -:model "HP Deskjet f4224 All-in-one Printer" +:model "HP LaserJet Pro MFP m426dw" :status :good -:model "HP Deskjet f4230 All-in-one Printer" +:model "HP LaserJet Pro MFP m426fdn" :status :good -:model "HP Deskjet f4235 All-in-one Printer" +:model "HP LaserJet Pro MFP m426fdw" :status :good -:model "HP Photosmart c4235 All-in-one Printer" +:model "HP LaserJet Pro MFP m427dn" :status :good -:model "HP Deskjet f4238 All-in-one Printer" +:model "HP LaserJet Pro MFP m427dw" :status :good -:model "HP Deskjet f4240 All-in-one Printer" +:model "HP LaserJet Pro MFP m427fdw" :status :good -:model "HP Photosmart c4240 All-in-one Printer" +:model "HP LaserJet Pro MFP m428c1" :status :good -:model "HP Photosmart c4250 All-in-one Printer" +:model "HP LaserJet Pro MFP m428c2" :status :good -:model "HP Deskjet f4250 All-in-one Printer" +:model "HP LaserJet Pro MFP m428c3" :status :good -:model "HP Officejet 4251 All-in-one Printer" +:model "HP LaserJet Pro MFP m428c4" :status :good -:model "HP Officejet 4252 All-in-one Printer" +:model "HP LaserJet Pro MFP m428dw" :status :good -:model "HP Officejet 4255 All-in-one Printer" +:model "HP LaserJet Pro MFP m428fdn" :status :good -:model "HP Officejet 4256 All-in-one Printer" +:model "HP LaserJet Pro MFP m428fdw" :status :good -:model "HP Officejet 4259 All-in-one Printer" +:model "HP LaserJet Pro MFP m428m" :status :good -:model "HP Photosmart c4270 All-in-one Printer" +:model "HP LaserJet Pro MFP m429dw" :status :good -:model "HP Deskjet f4272 All-in-one Printer" +:model "HP LaserJet Pro MFP m429fdn" :status :good -:model "HP Photosmart c4272 All-in-one Printer" +:model "HP LaserJet Pro MFP m429fdw" :status :good -:model "HP Deskjet f4273 All-in-one Printer" +:model "HP LaserJet Pro MFP m435nw" :status :good -:model "HP Photosmart c4273 All-in-one Printer" +:model "HP LaserJet Professional cm1411fn" :status :good -:model "HP Deskjet f4274 All-in-one Printer" +:model "HP LaserJet Professional cm1412fn" :status :good -:model "HP Photosmart c4275 All-in-one Printer" +:model "HP LaserJet Professional cm1413fn" :status :good -:model "HP Deskjet f4275 All-in-one Printer" +:model "HP LaserJet Professional cm1415fn" :status :good -:model "HP Deskjet f4280 All-in-one" +:model "HP LaserJet Professional cm1415fnw" :status :good -:model "HP Photosmart c4280 All-in-one Printer" +:model "HP LaserJet Professional cm1416fnw" :status :good -:model "HP Deskjet f4280 All-in-one Printer" +:model "HP LaserJet Professional cm1417fnw" :status :good -:model "HP Photosmart c4283 All-in-one Printer" +:model "HP LaserJet Professional cm1418fnw" :status :good -:model "HP Deskjet f4283 All-in-one Printer" +:model "HP LaserJet Professional m1132 Multifunction Printer" :status :good -:model "HP Photosmart c4285 All-in-one Printer" +:model "HP LaserJet Professional m1132s Multifunction Printer" :status :good -:model "HP Photosmart c4288 All-in-one Printer" +:model "HP LaserJet Professional m1136 Multifunction Printer" :status :good -:model "HP Deskjet f4288 All-in-one Printer" +:model "HP LaserJet Professional m1137 Multifunction Printer" :status :good -:model "HP Deskjet f4292 All-in-one Printer" +:model "HP LaserJet Professional m1138 Multifunction Printer" :status :good -:model "HP Deskjet f4293 All-in-one Printer" +:model "HP LaserJet Professional m1139 Multifunction Printer" :status :good -:model "HP Photosmart c4293 All-in-one Printer" +:model "HP LaserJet Professional m1212nf Multifunction Printer" :status :good -:model "HP Deskjet f4294 All-in-one Printer" +:model "HP LaserJet Professional m1213nf Multifunction Printer" :status :good -:model "HP Photosmart c4294 All-in-one Printer" +:model "HP LaserJet Professional m1214nfh Multifunction Printer" +:status :good + +:model "HP LaserJet Professional m1216nfh MFP" +:status :good + +:model "HP LaserJet Professional m1217nfw Multifunction Printer" +:status :good + +:model "HP LaserJet Professional m1219nf MFP" +:status :good + +:model "HP LaserJet Professional m1219nfg MFP" +:status :good + +:model "HP LaserJet Professional m1219nfs MFP" +:status :good + +:model "HP LaserJet Ultra MFP m230sdn" +:status :good + +:model "HP Neverstop Laser MFP 1200a" +:status :good + +:model "HP Neverstop Laser MFP 1200w" +:status :good + +:model "HP Officejet 150 Mobile All-in-one" +:status :good + +:model "HP Officejet 250 Mobile All-in-one" +:status :good + +:model "HP Officejet 250c Mobile All-in-one" +:status :good + +:model "HP Officejet 252 Mobile All-in-one" +:status :good + +:model "HP Officejet 252c Mobile All-in-one" +:status :good + +:model "HP Officejet 258 Mobile All-in-one" +:status :good + +:model "HP Officejet 2620 All-in-one" +:status :good + +:model "HP Officejet 2621 All-in-one" +:status :good + +:model "HP Officejet 2622 All-in-one" +:status :good + +:model "HP Officejet 3830 All-in-one Printer" +:status :good + +:model "HP Officejet 3832 All-in-one Printer" +:status :good + +:model "HP Officejet 3834 All-in-one Printer" +:status :good + +:model "HP Officejet 4100 Series All-in-one Printer" +:status :good + +:model "HP Officejet 4105 All-in-one Printer" +:status :good + +:model "HP Officejet 4110 All-in-one Printer" +:status :good + +:model "HP Officejet 4110v All-in-one Printer" +:status :good + +:model "HP Officejet 4110xi All-in-one Printer" +:status :good + +:model "HP Officejet 4115 All-in-one Printer" +:status :good + +:model "HP Officejet 4200 All-in-one Printer" +:status :good + +:model "HP Officejet 4211 All-in-one Printer" +:status :good + +:model "HP Officejet 4212 All-in-one Printer" +:status :good + +:model "HP Officejet 4215 All-in-one Printer" +:status :good + +:model "HP Officejet 4215v All-in-one Printer" +:status :good + +:model "HP Officejet 4215xi All-in-one Printer" +:status :good + +:model "HP Officejet 4219 All-in-one Printer" +:status :good + +:model "HP Officejet 4251 All-in-one Printer" +:status :good + +:model "HP Officejet 4252 All-in-one Printer" +:status :good + +:model "HP Officejet 4255 All-in-one Printer" +:status :good + +:model "HP Officejet 4256 All-in-one Printer" +:status :good + +:model "HP Officejet 4259 All-in-one Printer" :status :good :model "HP Officejet 4308 All-in-one Printer" @@ -1276,10 +1984,10 @@ :model "HP Officejet 4315 All-in-one Printer" :status :good -:model "HP Officejet 4315xi All-in-one Printer" +:model "HP Officejet 4315v All-in-one Printer" :status :good -:model "HP Officejet 4315v All-in-one Printer" +:model "HP Officejet 4315xi All-in-one Printer" :status :good :model "HP Officejet 4317 All-in-one Printer" @@ -1291,163 +1999,484 @@ :model "HP Officejet 4338 All-in-one Printer" :status :good -:model "HP Photosmart c4340 All-in-one Printer" +:model "HP Officejet 4352 All-in-one Printer" :status :good -:model "HP Photosmart c4342 All-in-one Printer" +:model "HP Officejet 4353 All-in-one Printer" :status :good -:model "HP Photosmart c4343 All-in-one Printer" +:model "HP Officejet 4355 All-in-one Printer" :status :good -:model "HP Photosmart c4344 All-in-one Printer" +:model "HP Officejet 4357 All-in-one Printer" :status :good -:model "HP LaserJet m4345 Multifunction Printer" +:model "HP Officejet 4359 All-in-one Printer" :status :good -:model "HP LaserJet 4345xm Multifunction Printer" +:model "HP Officejet 4400 k410 All-in-one Printer" :status :good -:model "HP LaserJet 4345 Multifunction Printer" +:model "HP Officejet 4500 All-in-one Desktop Printer - g510b" :status :good -:model "HP LaserJet m4345x Multifunction Printer" +:model "HP Officejet 4500 All-in-one Printer - g510g" :status :good -:model "HP LaserJet m4345xs Multifunction Printer" +:model "HP Officejet 4500 All-in-one Printer - g510h" :status :good -:model "HP LaserJet 4345xs Multifunction Printer" +:model "HP Officejet 4500 All-in-one Printer - k710" :status :good -:model "HP LaserJet 4345x Multifunction Printer" +:model "HP Officejet 4500 Desktop All-in-one Printer - g510a" :status :good -:model "HP Photosmart c4345 All-in-one Printer" +:model "HP Officejet 4500 g510n-z All-in-one Printer" :status :good -:model "HP LaserJet m4345xm Multifunction Printer" +:model "HP Officejet 4610 All-in-one Printer Series" :status :good -:model "HP Photosmart c4348 All-in-one Printer" +:model "HP Officejet 4620 E-all-in-one Printer" :status :good -:model "HP LaserJet m4349 MFP" +:model "HP Officejet 4622 E-all-in-one Printer" :status :good -:model "HP Officejet 4352 All-in-one Printer" +:model "HP Officejet 4630 E-all-in-one Printer" :status :good -:model "HP Officejet 4353 All-in-one Printer" +:model "HP Officejet 4631 E-all-in-one Printer" :status :good -:model "HP Officejet 4355 All-in-one Printer" +:model "HP Officejet 4632 E-all-in-one Printer" :status :good -:model "HP Officejet 4357 All-in-one Printer" +:model "HP Officejet 4634 E-all-in-one Printer" :status :good -:model "HP Officejet 4359 All-in-one Printer" +:model "HP Officejet 4635 E-all-in-one Printer" :status :good -:model "HP Photosmart c4380 All-in-one Printer" +:model "HP Officejet 4636 E-all-in-one Printer" :status :good -:model "HP Photosmart c4383 All-in-one Printer" +:model "HP Officejet 4650 All-in-one Printer" :status :good -:model "HP Photosmart c4384 All-in-one Printer" +:model "HP Officejet 4650 All-in-one Printer Series" :status :good -:model "HP Photosmart c4385 All-in-one Printer" +:model "HP Officejet 4652 All-in-one Printer" :status :good -:model "HP Photosmart c4388 All-in-one Printer" +:model "HP Officejet 4654 All-in-one Printer" :status :good -:model "HP Photosmart c4410 All-in-one Printer" +:model "HP Officejet 4655 All-in-one Printer" :status :good -:model "HP Photosmart c4424 All-in-one Printer" +:model "HP Officejet 5100 All-in-one Printer" :status :good -:model "HP Deskjet f4435 All-in-one Printer" +:model "HP Officejet 5105 All-in-one Printer" :status :good -:model "HP Photosmart c4435 All-in-one Printer" +:model "HP Officejet 5110 All-in-one Printer" :status :good -:model "HP Photosmart c4440 All-in-one Printer" +:model "HP Officejet 5110v All-in-one Printer" :status :good -:model "HP Deskjet f4440 All-in-one Printer" +:model "HP Officejet 5110xi All-in-one Printer" :status :good -:model "HP Photosmart c4450 All-in-one Printer" +:model "HP Officejet 520 All-in-one Printer" :status :good -:model "HP Deskjet f4450 All-in-one Printer" +:model "HP Officejet 5200 All-in-one" :status :good -:model "HP Deskjet f4470 All-in-one Printer" +:model "HP Officejet 5220 All-in-one" :status :good -:model "HP Photosmart c4470 All-in-one Printer" +:model "HP Officejet 5230 All-in-one" :status :good -:model "HP Photosmart c4472 All-in-one Printer" +:model "HP Officejet 5232 All-in-one" :status :good -:model "HP Deskjet f4472 All-in-one Printer" +:model "HP Officejet 5505 All-in-one Printer" :status :good -:model "HP Photosmart c4473 All-in-one Printer" +:model "HP Officejet 5508 All-in-one Printer" :status :good -:model "HP Deskjet f4473 All-in-one Printer" +:model "HP Officejet 5510 All-in-one Printer" :status :good -:model "HP Deskjet f4480 All-in-one Printer" +:model "HP Officejet 5510v All-in-one Printer" :status :good -:model "HP Photosmart c4480 All-in-one Printer" +:model "HP Officejet 5510xi All-in-one Printer" :status :good -:model "HP Photosmart c4483 All-in-one Printer" +:model "HP Officejet 5515 All-in-one Printer" :status :good -:model "HP Deskjet f4483 All-in-one Printer" +:model "HP Officejet 5600 Series All-in-one Printer" :status :good -:model "HP Photosmart c4485 All-in-one Printer" +:model "HP Officejet 5605 All-in-one Printer" :status :good -:model "HP Photosmart c4486 All-in-one Printer" +:model "HP Officejet 5607 All-in-one Printer" :status :good -:model "HP Photosmart c4488 All-in-one Printer" +:model "HP Officejet 5608 All-in-one Printer" :status :good -:model "HP Deskjet f4488 All-in-one Printer" +:model "HP Officejet 5609 All-in-one Printer" :status :good -:model "HP Photosmart c4490 All-in-one Printer" +:model "HP Officejet 5610 All-in-one Printer" :status :good -:model "HP Deskjet f4492 All-in-one Printer" +:model "HP Officejet 5610v All-in-one Printer" :status :good -:model "HP Photosmart c4493 All-in-one Printer" +:model "HP Officejet 5610xi All-in-one Printer" :status :good -:model "HP Photosmart c4494 All-in-one Printer" +:model "HP Officejet 5615 All-in-one Printer" :status :good -:model "HP Deskjet f4500 All-in-one Printer Series" +:model "HP Officejet 5679 All-in-one Printer" :status :good -:model "HP Designjet 4520mfp" +:model "HP Officejet 5680 All-in-one Printer" +:status :good + +:model "HP Officejet 570 All-in-one Printer" +:status :good + +:model "HP Officejet 5740 E-all-in-one" +:status :good + +:model "HP Officejet 5742 E-all-in-one" +:status :good + +:model "HP Officejet 5744 E-all-in-one" +:status :good + +:model "HP Officejet 5745 E-all-in-one" +:status :good + +:model "HP Officejet 580 All-in-one Printer" +:status :good + +:model "HP Officejet 590 All-in-one Printer" +:status :good + +:model "HP Officejet 600 All-in-one Printer" +:status :good + +:model "HP Officejet 610 All-in-one Printer" +:status :good + +:model "HP Officejet 6105 All-in-one Printer" +:status :good + +:model "HP Officejet 6110 All-in-one Printer" +:status :good + +:model "HP Officejet 6110v All-in-one Printer" +:status :good + +:model "HP Officejet 6110xi All-in-one Printer" +:status :good + +:model "HP Officejet 6150 All-in-one Printer" +:status :good + +:model "HP Officejet 6200 All-in-one Printer" +:status :good + +:model "HP Officejet 6203 All-in-one Printer" +:status :good + +:model "HP Officejet 6205 All-in-one Printer" +:status :good + +:model "HP Officejet 6208 All-in-one Printer" +:status :good + +:model "HP Officejet 6210 All-in-one Printer" +:status :good + +:model "HP Officejet 6210v All-in-one Printer" +:status :good + +:model "HP Officejet 6210xi All-in-one Printer" +:status :good + +:model "HP Officejet 6213 All-in-one Printer" +:status :good + +:model "HP Officejet 6215 All-in-one Printer" +:status :good + +:model "HP Officejet 630 All-in-one Printer" +:status :good + +:model "HP Officejet 6301 All-in-one Printer" +:status :good + +:model "HP Officejet 6304 All-in-one Printer" +:status :good + +:model "HP Officejet 6305 All-in-one Printer" +:status :good + +:model "HP Officejet 6307 All-in-one Printer" +:status :good + +:model "HP Officejet 6308 All-in-one Printer" +:status :good + +:model "HP Officejet 6310 All-in-one Printer" +:status :good + +:model "HP Officejet 6310v All-in-one Printer" +:status :good + +:model "HP Officejet 6310xi All-in-one Printer" +:status :good + +:model "HP Officejet 6313 All-in-one Printer" +:status :good + +:model "HP Officejet 6315 All-in-one Printer" +:status :good + +:model "HP Officejet 6318 All-in-one Printer" +:status :good + +:model "HP Officejet 635 All-in-one Printer" +:status :good + +:model "HP Officejet 6500 All-in-one Printer - e709a" +:status :good + +:model "HP Officejet 6500 All-in-one Printer - e709c" +:status :good + +:model "HP Officejet 6500 e710" +:status :good + +:model "HP Officejet 6500 e710n-z" +:status :good + +:model "HP Officejet 6500 Wireless All-in-one Printer - e709n" +:status :good + +:model "HP Officejet 6500 Wireless All-in-one Printer - e709q" +:status :good + +:model "HP Officejet 6600 E-all-in-one Printer - h711a" +:status :good + +:model "HP Officejet 6700 Premium E-all-in-one printer-h711n" +:status :good + +:model "HP Officejet 6800 E-all-in-one" +:status :good + +:model "HP Officejet 6810 E-all-in-one Printer Series" +:status :good + +:model "HP Officejet 6812 E-all-in-one Printer" +:status :good + +:model "HP Officejet 6815 E-all-in-one Printer" +:status :good + +:model "HP Officejet 6820 E-all-in-one Printer" +:status :good + +:model "HP Officejet 6950 All-in-one" +:status :good + +:model "HP Officejet 6960 All-in-one" +:status :good + +:model "HP Officejet 700 All-in-one Printer" +:status :good + +:model "HP Officejet 710 All-in-one Printer" +:status :good + +:model "HP Officejet 7100 All-in-one Printer" +:status :good + +:model "HP Officejet 7110 All-in-one Printer" +:status :good + +:model "HP Officejet 7110xi All-in-one Printer" +:status :good + +:model "HP Officejet 7115 All-in-one Printer" +:status :good + +:model "HP Officejet 7130 All-in-one Printer" +:status :good + +:model "HP Officejet 7130xi All-in-one Printer" +:status :good + +:model "HP Officejet 7135xi All-in-one Printer" +:status :good + +:model "HP Officejet 7140xi All-in-one Printer" +:status :good + +:model "HP Officejet 720 All-in-one Printer" +:status :good + +:model "HP Officejet 7205 All-in-one Printer" +:status :good + +:model "HP Officejet 7208 All-in-one Printer" +:status :good + +:model "HP Officejet 7210 All-in-one Printer" +:status :good + +:model "HP Officejet 7210v All-in-one Printer" +:status :good + +:model "HP Officejet 7210xi All-in-one Printer" +:status :good + +:model "HP Officejet 7213 All-in-one Printer" +:status :good + +:model "HP Officejet 7215 All-in-one Printer" +:status :good + +:model "HP Officejet 725 All-in-one Printer" +:status :good + +:model "HP Officejet 7310 All-in-one Printer" +:status :good + +:model "HP Officejet 7310xi All-in-one Printer" +:status :good + +:model "HP Officejet 7313 All-in-one Printer" +:status :good + +:model "HP Officejet 7408 All-in-one Printer" +:status :good + +:model "HP Officejet 7410 All-in-one Printer" +:status :good + +:model "HP Officejet 7410xi All-in-one Printer" +:status :good + +:model "HP Officejet 7413 All-in-one Printer" +:status :good + +:model "HP Officejet 7500 e910" +:status :good + +:model "HP Officejet 7510 Wide Format E-all-in-one Printer" +:status :good + +:model "HP Officejet 7610 Wide Format E-all-in-one Printer" +:status :good + +:model "HP Officejet 7612 Wide Format E-all-in-one Printer" +:status :good + +:model "HP Officejet 8010 All-in-one Printer Series" +:status :good + +:model "HP Officejet 8020 All-in-one Printer Series" +:status :good + +:model "HP Officejet 8040 E-all-in-one" +:status :good + +:model "HP Officejet 8702 All-in-one" +:status :good + +:model "HP Officejet 9110 All-in-one Printer" +:status :good + +:model "HP Officejet 9120 All-in-one Printer" +:status :good + +:model "HP Officejet 9130 All-in-one Printer" +:status :good + +:model "HP Officejet All-in-one 9010" +:status :good + +:model "HP Officejet d125xi All-in-one Printer" +:status :good + +:model "HP Officejet d135 All-in-one Printer" +:status :good + +:model "HP Officejet d135xi All-in-one Printer" +:status :good + +:model "HP Officejet d145 All-in-one Printer" +:status :good + +:model "HP Officejet d145xi All-in-one Printer" +:status :good + +:model "HP Officejet d155xi All-in-one Printer" +:status :good + +:model "HP Officejet g55 All-in-one Printer" +:status :good + +:model "HP Officejet g55xi All-in-one Printer" +:status :good + +:model "HP Officejet g85 All-in-one Printer" +:status :good + +:model "HP Officejet g85xi All-in-one Printer" +:status :good + +:model "HP Officejet g95 All-in-one Printer" +:status :good + +:model "HP Officejet j3508 All-in-one Printer" +:status :good + +:model "HP Officejet j3608 All-in-one Printer" +:status :good + +:model "HP Officejet j3625 All-in-one Printer" +:status :good + +:model "HP Officejet j3635 All-in-one Printer" +:status :good + +:model "HP Officejet j3640 All-in-one Printer" +:status :good + +:model "HP Officejet j3650 All-in-one Printer" +:status :good + +:model "HP Officejet j3680 All-in-one Printer" :status :good :model "HP Officejet j4524 All-in-one Printer" @@ -1459,172 +2488,850 @@ :model "HP Officejet j4535 All-in-one Printer" :status :good -:model "HP Photosmart c4540 All-in-one Printer" +:model "HP Officejet j4540 All-in-one Printer" :status :good -:model "HP Officejet j4540 All-in-one Printer" +:model "HP Officejet j4550 All-in-one Printer" :status :good -:model "HP Photosmart c4550 All-in-one Printer" +:model "HP Officejet j4560 All-in-one Printer" :status :good -:model "HP Officejet j4550 All-in-one Printer" +:model "HP Officejet j4580 All-in-one Printer" :status :good -:model "HP Officejet j4560 All-in-one Printer" +:model "HP Officejet j4580c All-in-one Printer" :status :good -:model "HP Photosmart c4570 All-in-one Printer" +:model "HP Officejet j4585 All-in-one Printer" :status :good -:model "HP Photosmart c4572 All-in-one Printer" +:model "HP Officejet j4660 All-in-one Printer" :status :good -:model "HP Photosmart c4573 All-in-one Printer" +:model "HP Officejet j4680 All-in-one Printer" :status :good -:model "HP Photosmart c4575 All-in-one Printer" +:model "HP Officejet j4680c All-in-one Printer" :status :good -:model "HP Officejet j4580c All-in-one Printer" +:model "HP Officejet j5505 All-in-one Printer" :status :good -:model "HP Photosmart c4580 All-in-one Printer" +:model "HP Officejet j5508 All-in-one Printer" :status :good -:model "HP Officejet j4580 All-in-one Printer" +:model "HP Officejet j5510 All-in-one Printer" :status :good -:model "HP Photosmart c4583 All-in-one Printer" +:model "HP Officejet j5510v All-in-one Printer" :status :good -:model "HP Photosmart c4585 All-in-one Printer" +:model "HP Officejet j5510xi All-in-one Printer" :status :good -:model "HP Officejet j4585 All-in-one Printer" +:model "HP Officejet j5515 All-in-one Printer" :status :good -:model "HP Photosmart c4588 All-in-one Printer" +:model "HP Officejet j5520 All-in-one Printer" :status :good -:model "HP Photosmart c4593 All-in-one Printer" +:model "HP Officejet j5725 All-in-one Printer" :status :good -:model "HP Photosmart c4599 All-in-one Printer" +:model "HP Officejet j5730 All-in-one Printer" :status :good -:model "HP Photosmart c4610 All-in-one Printer" +:model "HP Officejet j5735 All-in-one Printer" :status :good -:model "HP Photosmart c4635 All-in-one Printer" +:model "HP Officejet j5738 All-in-one Printer" :status :good -:model "HP Photosmart c4640 All-in-one Printer" +:model "HP Officejet j5740 All-in-one Printer" :status :good -:model "HP Photosmart c4650 All-in-one Printer" +:model "HP Officejet j5750 All-in-one Printer" :status :good -:model "HP Officejet j4660 All-in-one Printer" +:model "HP Officejet j5780 All-in-one Printer" :status :good -:model "HP Photosmart c4670 All-in-one Printer" +:model "HP Officejet j5783 All-in-one Printer" :status :good -:model "HP Photosmart c4673 All-in-one Printer" +:model "HP Officejet j5785 All-in-one Printer" :status :good -:model "HP Officejet j4680 All-in-one Printer" +:model "HP Officejet j5788 All-in-one Printer" :status :good -:model "HP Photosmart c4680 All-in-one Printer" +:model "HP Officejet j5790 All-in-one Printer" :status :good -:model "HP Officejet j4680c All-in-one Printer" +:model "HP Officejet j6405 All-in-one Printer" :status :good -:model "HP Photosmart c4683 All-in-one Printer" +:model "HP Officejet j6410 All-in-one Printer" :status :good -:model "HP Photosmart c4688 All-in-one Printer" +:model "HP Officejet j6413 All-in-one Printer" :status :good -:model "HP Color LaserJet 4730x Multifunction Printer" +:model "HP Officejet j6415 All-in-one Printer" :status :good -:model "HP Color LaserJet 4730xs Multifunction Printer" +:model "HP Officejet j6424 All-in-one Printer" :status :good -:model "HP Color LaserJet cm4730 Multifunction Printer" +:model "HP Officejet j6450 All-in-one Printer" :status :good -:model "HP Color LaserJet 4730 Multifunction Printer" +:model "HP Officejet j6480 All-in-one Printer" :status :good -:model "HP Color LaserJet cm4730fsk Multifunction Printer" +:model "HP Officejet j6488 All-in-one Printer" :status :good -:model "HP Color LaserJet cm4730fm Multifunction Printer" +:model "HP Officejet k60 All-in-one Printer" :status :good -:model "HP Color LaserJet cm4730f Multifunction Printer" +:model "HP Officejet k60xi All-in-one Printer" :status :good -:model "HP Color LaserJet 4730xm Multifunction Printer" +:model "HP Officejet k80 All-in-one Printer" :status :good -:model "HP Photosmart c4740 All-in-one Printer" +:model "HP Officejet k80xi All-in-one Printer" :status :good -:model "HP Photosmart c4750 All-in-one Printer" +:model "HP Officejet Pro 1150c All-in-one Printer" :status :good -:model "HP Photosmart c4780 All-in-one Printer" +:model "HP Officejet Pro 1150cse All-in-one Printer" :status :good -:model "HP Photosmart c4783 All-in-one Printer" +:model "HP Officejet Pro 1170c All-in-one Printer" :status :good -:model "HP Photosmart c4785 All-in-one Printer" +:model "HP Officejet Pro 1170cse All-in-one Printer" :status :good -:model "HP Photosmart c4788 All-in-one Printer" +:model "HP Officejet Pro 1170cxi All-in-one Printer" :status :good -:model "HP Photosmart c4793 All-in-one Printer" +:model "HP Officejet Pro 1175c All-in-one Printer" :status :good -:model "HP Photosmart c4795 All-in-one Printer" +:model "HP Officejet Pro 1175cse All-in-one Printer" :status :good -:model "HP Photosmart c4798 All-in-one Printer" +:model "HP Officejet Pro 1175cxi All-in-one Printer" :status :good -:model "HP Photosmart c4799 All-in-one Printer" +:model "HP Officejet Pro 276dw Multifunction Printer" :status :good -:model "HP LaserJet m5035 Multifunction Printer" +:model "HP Officejet Pro 3610 Black And White E-all-in-one" :status :good -:model "HP LaserJet m5035xs Multifunction Printer" +:model "HP Officejet Pro 3620 Black And White E-all-in-one" :status :good -:model "HP LaserJet m5035x Multifunction Printer" +:model "HP Officejet Pro 6830 E-all-in-one" :status :good -:model "HP Officejet 5100 All-in-one Printer" +:model "HP Officejet Pro 6835 E-all-in-one" :status :good -:model "HP Officejet 5105 All-in-one Printer" +:model "HP Officejet Pro 6960 All-in-one" :status :good -:model "HP Officejet 5110 All-in-one Printer" +:model "HP Officejet Pro 6968 All-in-one" :status :good -:model "HP Officejet 5110v All-in-one Printer" +:model "HP Officejet Pro 6970 All-in-one" :status :good -:model "HP Officejet 5110xi All-in-one Printer" +:model "HP Officejet Pro 6975 All-in-one" +:status :good + +:model "HP Officejet Pro 6978 All-in-one" +:status :good + +:model "HP Officejet Pro 7720 Wide Format All-in-one" +:status :good + +:model "HP Officejet Pro 7730 Wide Format All-in-one" +:status :good + +:model "HP Officejet Pro 7740 Wide Format All-in-one" +:status :good + +:model "HP Officejet Pro 8020 All-in-one Printer Series" +:status :good + +:model "HP Officejet Pro 8030 All-in-one Printer Series" +:status :good + +:model "HP Officejet Pro 8500 All-in-one Printer - a909a" +:status :good + +:model "HP Officejet Pro 8500 Premier All-in-one Printer - a909n" +:status :good + +:model "HP Officejet Pro 8500 Wireless All-in-one Printer - a909g" +:status :good + +:model "HP Officejet Pro 8500a E-aio Printer - a910a" +:status :good + +:model "HP Officejet Pro 8500a Plus E-aio Printer - a910g" +:status :good + +:model "HP Officejet Pro 8500a Premium E-aio Printer - a910n" +:status :good + +:model "HP Officejet Pro 8600 E-aio n911a" +:status :good + +:model "HP Officejet Pro 8600 Plus E-aio n911g" +:status :good + +:model "HP Officejet Pro 8600 Premium E-aio n911n" +:status :good + +:model "HP Officejet Pro 8610 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8615 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8616 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8620 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8625 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8630 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8640 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8660 E-all-in-one Printer" +:status :good + +:model "HP Officejet Pro 8710 All-in-one Printer" +:status :good + +:model "HP Officejet Pro 8715 All-in-one Printer" +:status :good + +:model "HP Officejet Pro 8720 All-in-one Printer" +:status :good + +:model "HP Officejet Pro 8725 All-in-one Printer" +:status :good + +:model "HP Officejet Pro 8730" +:status :good + +:model "HP Officejet Pro 8732 All-in-one Printer" +:status :good + +:model "HP Officejet Pro 8740 All-in-one Printer" +:status :good + +:model "HP Officejet Pro All-in-one 9010" +:status :good + +:model "HP Officejet Pro All-in-one 9020" +:status :good + +:model "HP Officejet Pro l7300 Series All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7380 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7480 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7500 Series All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7550 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7555 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7580 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7590 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7600 Series All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7650 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7680 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7681 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7700 Series All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7710 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7750 All-in-one Printer" +:status :good + +:model "HP Officejet Pro l7780 All-in-one Printer" +:status :good + +:model "HP Officejet Pro x476 Multifunction Printer Series" +:status :good + +:model "HP Officejet Pro x476dn Multifunction Printer" +:status :good + +:model "HP Officejet Pro x476dw Multifunction Printer" +:status :good + +:model "HP Officejet Pro x576 Multifunction Printer Series" +:status :good + +:model "HP Officejet Pro x576dw Multifunction Printer" +:status :good + +:model "HP Officejet r40 All-in-one Printer" +:status :good + +:model "HP Officejet r40xi All-in-one Printer" +:status :good + +:model "HP Officejet r45 All-in-one Printer" +:status :good + +:model "HP Officejet r60 All-in-one Printer" +:status :good + +:model "HP Officejet r65 All-in-one Printer" +:status :good + +:model "HP Officejet r80 All-in-one Printer" +:status :good + +:model "HP Officejet r80xi All-in-one Printer" +:status :good + +:model "HP Officejet t45 All-in-one Printer" +:status :good + +:model "HP Officejet t45xi All-in-one Printer" +:status :good + +:model "HP Officejet t65 All-in-one Printer" +:status :good + +:model "HP Officejet t65xi All-in-one Printer" +:status :good + +:model "HP Officejet v30 All-in-one Printer" +:status :good + +:model "HP Officejet v40 All-in-one Printer" +:status :good + +:model "HP Officejet v40s All-in-one Printer" +:status :good + +:model "HP Officejet v40xi All-in-one Printer" +:status :good + +:model "HP Officejet v45 All-in-one Printer" +:status :good + +:model "HP Pagewide Managed MFP p57750dw" +:status :good + +:model "HP Pagewide Managed MFP p77740zs" +:status :good + +:model "HP Pagewide Managed MFP p77750z" +:status :good + +:model "HP Pagewide Managed MFP p77750zs" +:status :good + +:model "HP Pagewide MFP 377dw" +:status :good + +:model "HP Pagewide Pro 477dn Multifunction Printer" +:status :good + +:model "HP Pagewide Pro 477dw Multifunction Printer" +:status :good + +:model "HP Pagewide Pro 577dw Multifunction Printer" +:status :good + +:model "HP Pagewide Pro 577z Multifunction Printer" +:status :good + +:model "HP Pagewide Pro MFP 772dw" +:status :good + +:model "HP Photosmart 2570 All-in-one Printer" +:status :good + +:model "HP Photosmart 2571 All-in-one Printer" +:status :good + +:model "HP Photosmart 2573 All-in-one Printer" +:status :good + +:model "HP Photosmart 2574 All-in-one Printer" +:status :good + +:model "HP Photosmart 2575 All-in-one Printer" +:status :good + +:model "HP Photosmart 2575a All-in-one Printer" +:status :good + +:model "HP Photosmart 2575v All-in-one Printer" +:status :good + +:model "HP Photosmart 2575xi All-in-one Printer" +:status :good + +:model "HP Photosmart 2578 All-in-one Printer" +:status :good + +:model "HP Photosmart 2605 All-in-one Printer" +:status :good + +:model "HP Photosmart 2608 All-in-one Printer" +:status :good + +:model "HP Photosmart 2610 All-in-one Printer" +:status :good + +:model "HP Photosmart 2610v All-in-one Printer" +:status :good + +:model "HP Photosmart 2610xi All-in-one Printer" +:status :good + +:model "HP Photosmart 2613 All-in-one Printer" +:status :good + +:model "HP Photosmart 2615 All-in-one Printer" +:status :good + +:model "HP Photosmart 2710 All-in-one Printer" +:status :good + +:model "HP Photosmart 2710xi All-in-one Printer" +:status :good + +:model "HP Photosmart 2713 All-in-one Printer" +:status :good + +:model "HP Photosmart 3108 All-in-one Printer" +:status :good + +:model "HP Photosmart 3110 All-in-one Printer" +:status :good + +:model "HP Photosmart 3110v All-in-one Printer" +:status :good + +:model "HP Photosmart 3207 All-in-one Printer" +:status :good + +:model "HP Photosmart 3210 All-in-one Printer" +:status :good + +:model "HP Photosmart 3210a All-in-one Printer" +:status :good + +:model "HP Photosmart 3210v All-in-one Printer" +:status :good + +:model "HP Photosmart 3210xi All-in-one Printer" +:status :good + +:model "HP Photosmart 3213 All-in-one Printer" +:status :good + +:model "HP Photosmart 3214 All-in-one Printer" +:status :good + +:model "HP Photosmart 3308 All-in-one Printer" +:status :good + +:model "HP Photosmart 3310 All-in-one Printer" +:status :good + +:model "HP Photosmart 3310xi All-in-one Printer" +:status :good + +:model "HP Photosmart 3313 All-in-one Printer" +:status :good + +:model "HP Photosmart 3314 All-in-one Printer" +:status :good + +:model "HP Photosmart 5510 E-all-in-one" +:status :good + +:model "HP Photosmart 5510d E-all-in-one" +:status :good + +:model "HP Photosmart 5520 E-all-in-one" +:status :good + +:model "HP Photosmart 5521 E-all-in-one Printer" +:status :good + +:model "HP Photosmart 5522 E-all-in-one Printer" +:status :good + +:model "HP Photosmart 5524 E-all-in-one Printer" +:status :good + +:model "HP Photosmart 5525 E-all-in-one Printer" +:status :good + +:model "HP Photosmart 6510 E-all-in-one" +:status :good + +:model "HP Photosmart 6525 E All-in-one" +:status :good + +:model "HP Photosmart 7510 E-all-in-one" +:status :good + +:model "HP Photosmart 7520 E-all-in-one" +:status :good + +:model "HP Photosmart 7525 E-all-in-one" +:status :good + +:model "HP Photosmart All-in-one Printer - b010" +:status :good + +:model "HP Photosmart b109a Series" +:status :good + +:model "HP Photosmart c3110 All-in-one Printer" +:status :good + +:model "HP Photosmart c3125 All-in-one Printer" +:status :good + +:model "HP Photosmart c3135 All-in-one Printer" +:status :good + +:model "HP Photosmart c3140 All-in-one Printer" +:status :good + +:model "HP Photosmart c3150 All-in-one Printer" +:status :good + +:model "HP Photosmart c3170 All-in-one Printer" +:status :good + +:model "HP Photosmart c3173 All-in-one Printer" +:status :good + +:model "HP Photosmart c3175 All-in-one Printer" +:status :good + +:model "HP Photosmart c3180 All-in-one Printer" +:status :good + +:model "HP Photosmart c3183 All-in-one Printer" +:status :good + +:model "HP Photosmart c3188 All-in-one Printer" +:status :good + +:model "HP Photosmart c3190 All-in-one Printer" +:status :good + +:model "HP Photosmart c3193 All-in-one Printer" +:status :good + +:model "HP Photosmart c3194 All-in-one Printer" +:status :good + +:model "HP Photosmart c4110 All-in-one Printer" +:status :good + +:model "HP Photosmart c4140 All-in-one Printer" +:status :good + +:model "HP Photosmart c4150 All-in-one Printer" +:status :good + +:model "HP Photosmart c4170 All-in-one Printer" +:status :good + +:model "HP Photosmart c4173 All-in-one Printer" +:status :good + +:model "HP Photosmart c4175 All-in-one Printer" +:status :good + +:model "HP Photosmart c4180 All-in-one Printer" +:status :good + +:model "HP Photosmart c4183 All-in-one Printer" +:status :good + +:model "HP Photosmart c4188 All-in-one Printer" +:status :good + +:model "HP Photosmart c4190 All-in-one Printer" +:status :good + +:model "HP Photosmart c4193 All-in-one Printer" +:status :good + +:model "HP Photosmart c4194 All-in-one Printer" +:status :good + +:model "HP Photosmart c4205 All-in-one Printer" +:status :good + +:model "HP Photosmart c4210 All-in-one Printer" +:status :good + +:model "HP Photosmart c4235 All-in-one Printer" +:status :good + +:model "HP Photosmart c4240 All-in-one Printer" +:status :good + +:model "HP Photosmart c4250 All-in-one Printer" +:status :good + +:model "HP Photosmart c4270 All-in-one Printer" +:status :good + +:model "HP Photosmart c4272 All-in-one Printer" +:status :good + +:model "HP Photosmart c4273 All-in-one Printer" +:status :good + +:model "HP Photosmart c4275 All-in-one Printer" +:status :good + +:model "HP Photosmart c4280 All-in-one Printer" +:status :good + +:model "HP Photosmart c4283 All-in-one Printer" +:status :good + +:model "HP Photosmart c4285 All-in-one Printer" +:status :good + +:model "HP Photosmart c4288 All-in-one Printer" +:status :good + +:model "HP Photosmart c4293 All-in-one Printer" +:status :good + +:model "HP Photosmart c4294 All-in-one Printer" +:status :good + +:model "HP Photosmart c4340 All-in-one Printer" +:status :good + +:model "HP Photosmart c4342 All-in-one Printer" +:status :good + +:model "HP Photosmart c4343 All-in-one Printer" +:status :good + +:model "HP Photosmart c4344 All-in-one Printer" +:status :good + +:model "HP Photosmart c4345 All-in-one Printer" +:status :good + +:model "HP Photosmart c4348 All-in-one Printer" +:status :good + +:model "HP Photosmart c4380 All-in-one Printer" +:status :good + +:model "HP Photosmart c4383 All-in-one Printer" +:status :good + +:model "HP Photosmart c4384 All-in-one Printer" +:status :good + +:model "HP Photosmart c4385 All-in-one Printer" +:status :good + +:model "HP Photosmart c4388 All-in-one Printer" +:status :good + +:model "HP Photosmart c4410 All-in-one Printer" +:status :good + +:model "HP Photosmart c4424 All-in-one Printer" +:status :good + +:model "HP Photosmart c4435 All-in-one Printer" +:status :good + +:model "HP Photosmart c4440 All-in-one Printer" +:status :good + +:model "HP Photosmart c4450 All-in-one Printer" +:status :good + +:model "HP Photosmart c4470 All-in-one Printer" +:status :good + +:model "HP Photosmart c4472 All-in-one Printer" +:status :good + +:model "HP Photosmart c4473 All-in-one Printer" +:status :good + +:model "HP Photosmart c4480 All-in-one Printer" +:status :good + +:model "HP Photosmart c4483 All-in-one Printer" +:status :good + +:model "HP Photosmart c4485 All-in-one Printer" +:status :good + +:model "HP Photosmart c4486 All-in-one Printer" +:status :good + +:model "HP Photosmart c4488 All-in-one Printer" +:status :good + +:model "HP Photosmart c4490 All-in-one Printer" +:status :good + +:model "HP Photosmart c4493 All-in-one Printer" +:status :good + +:model "HP Photosmart c4494 All-in-one Printer" +:status :good + +:model "HP Photosmart c4540 All-in-one Printer" +:status :good + +:model "HP Photosmart c4550 All-in-one Printer" +:status :good + +:model "HP Photosmart c4570 All-in-one Printer" +:status :good + +:model "HP Photosmart c4572 All-in-one Printer" +:status :good + +:model "HP Photosmart c4573 All-in-one Printer" +:status :good + +:model "HP Photosmart c4575 All-in-one Printer" +:status :good + +:model "HP Photosmart c4580 All-in-one Printer" +:status :good + +:model "HP Photosmart c4583 All-in-one Printer" +:status :good + +:model "HP Photosmart c4585 All-in-one Printer" +:status :good + +:model "HP Photosmart c4588 All-in-one Printer" +:status :good + +:model "HP Photosmart c4593 All-in-one Printer" +:status :good + +:model "HP Photosmart c4599 All-in-one Printer" +:status :good + +:model "HP Photosmart c4610 All-in-one Printer" +:status :good + +:model "HP Photosmart c4635 All-in-one Printer" +:status :good + +:model "HP Photosmart c4640 All-in-one Printer" +:status :good + +:model "HP Photosmart c4650 All-in-one Printer" +:status :good + +:model "HP Photosmart c4670 All-in-one Printer" +:status :good + +:model "HP Photosmart c4673 All-in-one Printer" +:status :good + +:model "HP Photosmart c4680 All-in-one Printer" +:status :good + +:model "HP Photosmart c4683 All-in-one Printer" +:status :good + +:model "HP Photosmart c4688 All-in-one Printer" +:status :good + +:model "HP Photosmart c4740 All-in-one Printer" +:status :good + +:model "HP Photosmart c4750 All-in-one Printer" +:status :good + +:model "HP Photosmart c4780 All-in-one Printer" +:status :good + +:model "HP Photosmart c4783 All-in-one Printer" +:status :good + +:model "HP Photosmart c4785 All-in-one Printer" +:status :good + +:model "HP Photosmart c4788 All-in-one Printer" +:status :good + +:model "HP Photosmart c4793 All-in-one Printer" +:status :good + +:model "HP Photosmart c4795 All-in-one Printer" +:status :good + +:model "HP Photosmart c4798 All-in-one Printer" +:status :good + +:model "HP Photosmart c4799 All-in-one Printer" :status :good :model "HP Photosmart c5140 All-in-one Printer" @@ -1708,533 +3415,602 @@ :model "HP Photosmart c5393 All-in-one Printer" :status :good -:model "HP Officejet 5505 All-in-one Printer" +:model "HP Photosmart c5540 All-in-one Printer" :status :good -:model "HP Officejet j5505 All-in-one Printer" +:model "HP Photosmart c5550 All-in-one Printer" :status :good -:model "HP Officejet 5508 All-in-one Printer" +:model "HP Photosmart c5570 All-in-one Printer" :status :good -:model "HP Officejet j5508 All-in-one Printer" +:model "HP Photosmart c5580 All-in-one Printer" :status :good -:model "HP Officejet j5510v All-in-one Printer" +:model "HP Photosmart c6150 All-in-one Printer" :status :good -:model "HP Officejet 5510v All-in-one Printer" +:model "HP Photosmart c6154 All-in-one Printer" :status :good -:model "HP Officejet 5510xi All-in-one Printer" +:model "HP Photosmart c6170 All-in-one Printer" :status :good -:model "HP Officejet 5510 All-in-one Printer" +:model "HP Photosmart c6175 All-in-one Printer" :status :good -:model "HP Officejet j5510xi All-in-one Printer" +:model "HP Photosmart c6180 All-in-one Printer" :status :good -:model "HP Officejet j5510 All-in-one Printer" +:model "HP Photosmart c6183 All-in-one Printer" :status :good -:model "HP Officejet j5515 All-in-one Printer" +:model "HP Photosmart c6185 All-in-one Printer" :status :good -:model "HP Officejet 5515 All-in-one Printer" +:model "HP Photosmart c6188 All-in-one Printer" :status :good -:model "HP Officejet j5520 All-in-one Printer" +:model "HP Photosmart c6190 All-in-one Printer" :status :good -:model "HP Photosmart c5540 All-in-one Printer" +:model "HP Photosmart c6240 All-in-one Printer" :status :good -:model "HP Photosmart c5550 All-in-one Printer" +:model "HP Photosmart c6245 All-in-one Printer" :status :good -:model "HP Photosmart c5570 All-in-one Printer" +:model "HP Photosmart c6250 All-in-one Printer" :status :good -:model "HP Photosmart c5580 All-in-one Printer" +:model "HP Photosmart c6260 All-in-one Printer" :status :good -:model "HP Officejet 5600 Series All-in-one Printer" +:model "HP Photosmart c6263 All-in-one Printer" :status :good -:model "HP Officejet 5605 All-in-one Printer" +:model "HP Photosmart c6268 All-in-one Printer" :status :good -:model "HP Officejet 5607 All-in-one Printer" +:model "HP Photosmart c6270 All-in-one Printer" :status :good -:model "HP Officejet 5608 All-in-one Printer" +:model "HP Photosmart c6275 All-in-one Printer" :status :good -:model "HP Officejet 5609 All-in-one Printer" +:model "HP Photosmart c6280 All-in-one Printer" :status :good -:model "HP Officejet 5610v All-in-one Printer" +:model "HP Photosmart c6283 All-in-one Printer" :status :good -:model "HP Officejet 5610xi All-in-one Printer" +:model "HP Photosmart c6285 All-in-one Printer" :status :good -:model "HP Officejet 5610 All-in-one Printer" +:model "HP Photosmart c6286 All-in-one Printer" :status :good -:model "HP Officejet 5615 All-in-one Printer" +:model "HP Photosmart c6288 All-in-one Printer" :status :good -:model "HP Officejet 5679 All-in-one Printer" +:model "HP Photosmart c6324 All-in-one Printer" :status :good -:model "HP Officejet 5680 All-in-one Printer" +:model "HP Photosmart c6340 All-in-one Printer" :status :good -:model "HP Officejet j5725 All-in-one Printer" +:model "HP Photosmart c6350 All-in-one Printer" :status :good -:model "HP Officejet j5730 All-in-one Printer" +:model "HP Photosmart c6375 All-in-one Printer" :status :good -:model "HP Officejet j5735 All-in-one Printer" +:model "HP Photosmart c6380 All-in-one Printer" :status :good -:model "HP Officejet j5738 All-in-one Printer" +:model "HP Photosmart c6383 All-in-one Printer" :status :good -:model "HP Officejet j5740 All-in-one Printer" +:model "HP Photosmart c6388 All-in-one Printer" :status :good -:model "HP Officejet j5750 All-in-one Printer" +:model "HP Photosmart c7150 All-in-one Printer" :status :good -:model "HP Officejet j5780 All-in-one Printer" +:model "HP Photosmart c7154 All-in-one Printer" :status :good -:model "HP Officejet j5783 All-in-one Printer" +:model "HP Photosmart c7170 All-in-one Printer" :status :good -:model "HP Officejet j5785 All-in-one Printer" +:model "HP Photosmart c7180 All-in-one Printer" :status :good -:model "HP Officejet j5788 All-in-one Printer" +:model "HP Photosmart c7183 All-in-one Printer" :status :good -:model "HP Officejet j5790 All-in-one Printer" +:model "HP Photosmart c7185 All-in-one Printer" :status :good -:model "HP Officejet 6105 All-in-one Printer" +:model "HP Photosmart c7188 All-in-one Printer" :status :good -:model "HP Officejet 6110v All-in-one Printer" +:model "HP Photosmart c7190 All-in-one Printer" :status :good -:model "HP Officejet 6110 All-in-one Printer" +:model "HP Photosmart c7250 All-in-one Printer" :status :good -:model "HP Officejet 6110xi All-in-one Printer" +:model "HP Photosmart c7275 All-in-one Printer" :status :good -:model "HP Officejet 6150 All-in-one Printer" +:model "HP Photosmart c7280 All-in-one Printer" :status :good -:model "HP Photosmart c6150 All-in-one Printer" +:model "HP Photosmart c7283 All-in-one Printer" :status :good -:model "HP Photosmart c6154 All-in-one Printer" +:model "HP Photosmart c7288 All-in-one Printer" :status :good -:model "HP Photosmart c6170 All-in-one Printer" +:model "HP Photosmart c8150 All-in-one Printer" :status :good -:model "HP Photosmart c6175 All-in-one Printer" +:model "HP Photosmart c8180 All-in-one Printer" :status :good -:model "HP Photosmart c6180 All-in-one Printer" +:model "HP Photosmart c8183 All-in-one Printer" :status :good -:model "HP Photosmart c6183 All-in-one Printer" +:model "HP Photosmart c8188 All-in-one Printer" :status :good -:model "HP Photosmart c6185 All-in-one Printer" +:model "HP Photosmart d110 Series Printer" :status :good -:model "HP Photosmart c6188 All-in-one Printer" +:model "HP Photosmart Estn c510 Series" :status :good -:model "HP Photosmart c6190 All-in-one Printer" +:model "HP Photosmart Ink Adv k510" :status :good -:model "HP Officejet 6200 All-in-one Printer" +:model "HP Photosmart Plus All-in-one Printer - b209a" :status :good -:model "HP Officejet 6203 All-in-one Printer" +:model "HP Photosmart Plus All-in-one Printer - b209b" :status :good -:model "HP Officejet 6205 All-in-one Printer" +:model "HP Photosmart Plus All-in-one Printer - b209c" :status :good -:model "HP Officejet 6208 All-in-one Printer" +:model "HP Photosmart Plus b210 Series" :status :good -:model "HP Officejet 6210xi All-in-one Printer" +:model "HP Photosmart Prem c310 Series" :status :good -:model "HP Officejet 6210v All-in-one Printer" +:model "HP Photosmart Prem c410 Series" :status :good -:model "HP Officejet 6210 All-in-one Printer" +:model "HP Photosmart Premium All-in-one Printer Series - c309g" :status :good -:model "HP Officejet 6213 All-in-one Printer" +:model "HP Photosmart Premium All-in-one Printer Series - c309h" :status :good -:model "HP Officejet 6215 All-in-one Printer" +:model "HP Photosmart Premium Fax All-in-one Printer - c309a" :status :good -:model "HP Photosmart c6240 All-in-one Printer" +:model "HP Photosmart Premium Fax All-in-one Printer Series -c309a" :status :good -:model "HP Photosmart c6245 All-in-one Printer" +:model "HP Photosmart Premium Fax All-in-one Printer Series -c309c" :status :good -:model "HP Photosmart c6250 All-in-one Printer" +:model "HP Photosmart Wireless All-in-one Printer - b109n" :status :good -:model "HP Photosmart c6260 All-in-one Printer" +:model "HP Photosmart Wireless All-in-one Printer - b109q" :status :good -:model "HP Photosmart c6263 All-in-one Printer" +:model "HP Photosmart Wireless All-in-one Printer - b109qr" :status :good -:model "HP Photosmart c6268 All-in-one Printer" +:model "HP Photosmart Wireless All-in-one Printer - b110" :status :good -:model "HP Photosmart c6270 All-in-one Printer" +:model "HP Photsmart 6520 E All-in-one" :status :good -:model "HP Photosmart c6275 All-in-one Printer" +:model "HP Printer Scanner Copier 300" :status :good -:model "HP Photosmart c6280 All-in-one Printer" +:model "HP PSC 1000 Series" :status :good -:model "HP Photosmart c6283 All-in-one Printer" +:model "HP PSC 1110 All-in-one Printer" :status :good -:model "HP Photosmart c6285 All-in-one Printer" +:model "HP PSC 1110v All-in-one Printer" :status :good -:model "HP Photosmart c6286 All-in-one Printer" +:model "HP PSC 1118 All-in-one Printer" :status :good -:model "HP Photosmart c6288 All-in-one Printer" +:model "HP PSC 1200 All-in-one Printer" :status :good -:model "HP Officejet 6301 All-in-one Printer" +:model "HP PSC 1205 All-in-one Printer" :status :good -:model "HP Officejet 6304 All-in-one Printer" +:model "HP PSC 1209 All-in-one Printer" :status :good -:model "HP Officejet 6305 All-in-one Printer" +:model "HP PSC 1210 All-in-one Printer" :status :good -:model "HP Officejet 6307 All-in-one Printer" +:model "HP PSC 1210v All-in-one Printer" :status :good -:model "HP Officejet 6308 All-in-one Printer" +:model "HP PSC 1210xi All-in-one Printer" :status :good -:model "HP Officejet 6310 All-in-one Printer" +:model "HP PSC 1213 All-in-one Printer" :status :good -:model "HP Officejet 6310xi All-in-one Printer" +:model "HP PSC 1215 All-in-one Printer" :status :good -:model "HP Officejet 6310v All-in-one Printer" +:model "HP PSC 1216 All-in-one Printer" :status :good -:model "HP Officejet 6313 All-in-one Printer" +:model "HP PSC 1217 All-in-one Printer" :status :good -:model "HP Officejet 6315 All-in-one Printer" +:model "HP PSC 1218 All-in-one Printer" :status :good -:model "HP Officejet 6318 All-in-one Printer" +:model "HP PSC 1219 All-in-one Printer" :status :good -:model "HP Photosmart c6324 All-in-one Printer" +:model "HP PSC 1300 All-in-one Printer" :status :good -:model "HP Photosmart c6340 All-in-one Printer" +:model "HP PSC 1310 All-in-one Printer" :status :good -:model "HP Photosmart c6350 All-in-one Printer" +:model "HP PSC 1311 All-in-one Printer" :status :good -:model "HP Photosmart c6375 All-in-one Printer" +:model "HP PSC 1312 All-in-one Printer" :status :good -:model "HP Photosmart c6380 All-in-one Printer" +:model "HP PSC 1315 All-in-one Printer" :status :good -:model "HP Photosmart c6383 All-in-one Printer" +:model "HP PSC 1315s All-in-one Printer" :status :good -:model "HP Photosmart c6388 All-in-one Printer" +:model "HP PSC 1315v All-in-one Printer" :status :good -:model "HP Officejet j6405 All-in-one Printer" +:model "HP PSC 1315xi All-in-one Printer" :status :good -:model "HP Officejet j6410 All-in-one Printer" +:model "HP PSC 1317 All-in-one Printer" :status :good -:model "HP Officejet j6413 All-in-one Printer" +:model "HP PSC 1318 All-in-one Printer" :status :good -:model "HP Officejet j6415 All-in-one Printer" +:model "HP PSC 1340 All-in-one Printer" :status :good -:model "HP Officejet j6424 All-in-one Printer" +:model "HP PSC 1350 All-in-one Printer" :status :good -:model "HP Officejet j6450 All-in-one Printer" +:model "HP PSC 1350v All-in-one Printer" :status :good -:model "HP Officejet j6480 All-in-one Printer" +:model "HP PSC 1350xi All-in-one Printer" :status :good -:model "HP Officejet j6488 All-in-one Printer" +:model "HP PSC 1355 All-in-one Printer" :status :good -:model "HP Officejet 6500 Wireless All-in-one Printer - e709q" +:model "HP PSC 1358 Series" :status :good -:model "HP Officejet 6500 Wireless All-in-one Printer - e709n" +:model "HP PSC 1401 All-in-one Printer" :status :good -:model "HP Officejet 6500 All-in-one Printer - e709c" +:model "HP PSC 1402 All-in-one Printer" :status :good -:model "HP Officejet 6500 All-in-one Printer - e709a" +:model "HP PSC 1403 All-in-one Printer" :status :good -:model "HP Officejet 7100 All-in-one Printer" +:model "HP PSC 1406 All-in-one Printer" :status :good -:model "HP Officejet 7110xi All-in-one Printer" +:model "HP PSC 1408 All-in-one Printer" :status :good -:model "HP Officejet 7110 All-in-one Printer" +:model "HP PSC 1410 All-in-one Printer" :status :good -:model "HP Officejet 7115 All-in-one Printer" +:model "HP PSC 1410v All-in-one Printer" :status :good -:model "HP Officejet 7130 All-in-one Printer" +:model "HP PSC 1410xi All-in-one Printer" :status :good -:model "HP Officejet 7130xi All-in-one Printer" +:model "HP PSC 1415 All-in-one Printer" :status :good -:model "HP Officejet 7135xi All-in-one Printer" +:model "HP PSC 1417 All-in-one Printer" :status :good -:model "HP Officejet 7140xi All-in-one Printer" +:model "HP PSC 1508 All-in-one Printer" :status :good -:model "HP Photosmart c7150 All-in-one Printer" +:model "HP PSC 1510 All-in-one Printer" :status :good -:model "HP Photosmart c7154 All-in-one Printer" +:model "HP PSC 1510 Series" :status :good -:model "HP Photosmart c7170 All-in-one Printer" +:model "HP PSC 1510s All-in-one Printer" :status :good -:model "HP Photosmart c7180 All-in-one Printer" +:model "HP PSC 1510v All-in-one Printer" :status :good -:model "HP Photosmart c7183 All-in-one Printer" +:model "HP PSC 1510xi All-in-one Printer" :status :good -:model "HP Photosmart c7185 All-in-one Printer" +:model "HP PSC 1513 All-in-one Printer" :status :good -:model "HP Photosmart c7188 All-in-one Printer" +:model "HP PSC 1513s All-in-one Printer" :status :good -:model "HP Photosmart c7190 All-in-one Printer" +:model "HP PSC 1514 All-in-one Printer" :status :good -:model "HP Officejet 7205 All-in-one Printer" +:model "HP PSC 1600 All-in-one Printer" :status :good -:model "HP Officejet 7208 All-in-one Printer" +:model "HP PSC 1603 All-in-one Printer" :status :good -:model "HP Officejet 7210 All-in-one Printer" +:model "HP PSC 1605 All-in-one Printer" :status :good -:model "HP Officejet 7210v All-in-one Printer" +:model "HP PSC 1608 All-in-one Printer" :status :good -:model "HP Officejet 7210xi All-in-one Printer" +:model "HP PSC 1610 All-in-one Printer" :status :good -:model "HP Officejet 7213 All-in-one Printer" +:model "HP PSC 1610v All-in-one Printer" :status :good -:model "HP Officejet 7215 All-in-one Printer" +:model "HP PSC 1610xi All-in-one Printer" :status :good -:model "HP Photosmart c7250 All-in-one Printer" +:model "HP PSC 1613 All-in-one Printer" :status :good -:model "HP Photosmart c7275 All-in-one Printer" +:model "HP PSC 1615 All-in-one Printer" :status :good -:model "HP Photosmart c7280 All-in-one Printer" +:model "HP PSC 2105 All-in-one Printer" :status :good -:model "HP Photosmart c7283 All-in-one Printer" +:model "HP PSC 2108 All-in-one Printer" :status :good -:model "HP Photosmart c7288 All-in-one Printer" +:model "HP PSC 2110 All-in-one Printer" :status :good -:model "HP Officejet Pro l7300 Series All-in-one Printer" +:model "HP PSC 2110v All-in-one Printer" :status :good -:model "HP Officejet 7310xi All-in-one Printer" +:model "HP PSC 2110xi All-in-one Printer" :status :good -:model "HP Officejet 7310 All-in-one Printer" +:model "HP PSC 2115 All-in-one Printer" :status :good -:model "HP Officejet 7313 All-in-one Printer" +:model "HP PSC 2150 All-in-one Printer" :status :good -:model "HP Officejet Pro l7380 All-in-one Printer" +:model "HP PSC 2170 All-in-one Printer" :status :good -:model "HP Officejet 7408 All-in-one Printer" +:model "HP PSC 2171 All-in-one Printer" :status :good -:model "HP Officejet 7410xi All-in-one Printer" +:model "HP PSC 2175 All-in-one Printer" :status :good -:model "HP Officejet 7410 All-in-one Printer" +:model "HP PSC 2175v All-in-one Printer" :status :good -:model "HP Officejet 7413 All-in-one Printer" +:model "HP PSC 2175xi All-in-one Printer" :status :good -:model "HP Officejet Pro l7480 All-in-one Printer" +:model "HP PSC 2179 All-in-one Printer" :status :good -:model "HP Officejet Pro l7500 Series All-in-one Printer" +:model "HP PSC 2200 All-in-one Printer" :status :good -:model "HP Officejet Pro l7550 All-in-one Printer" +:model "HP PSC 2210 All-in-one Printer" :status :good -:model "HP Officejet Pro l7555 All-in-one Printer" +:model "HP PSC 2210v All-in-one Printer" :status :good -:model "HP Officejet Pro l7580 All-in-one Printer" +:model "HP PSC 2210xi All-in-one Printer" :status :good -:model "HP Officejet Pro l7590 All-in-one Printer" +:model "HP PSC 2300 Series All-in-one Printer" :status :good -:model "HP Officejet Pro l7600 Series All-in-one Printer" +:model "HP PSC 2310 All-in-one Printer" :status :good -:model "HP Officejet Pro l7650 All-in-one Printer" +:model "HP PSC 2350 All-in-one Printer" :status :good -:model "HP Officejet Pro l7680 All-in-one Printer" +:model "HP PSC 2352 All-in-one Printer" :status :good -:model "HP Officejet Pro l7681 All-in-one Printer" +:model "HP PSC 2353 All-in-one Printer" :status :good -:model "HP Officejet Pro l7700 Series All-in-one Printer" +:model "HP PSC 2353p All-in-one Printer" :status :good -:model "HP Officejet Pro l7710 All-in-one Printer" +:model "HP PSC 2355 All-in-one Printer" :status :good -:model "HP Officejet Pro l7750 All-in-one Printer" +:model "HP PSC 2355p All-in-one Printer" :status :good -:model "HP Officejet Pro l7780 All-in-one Printer" +:model "HP PSC 2355v All-in-one Printer" :status :good -:model "HP cm8050 Color Multifunction Printer With Edgeline Technology" +:model "HP PSC 2355xi All-in-one Printer" :status :good -:model "HP cm8060 Color Multifunction Printer With Edgeline Technology" +:model "HP PSC 2357 All-in-one Printer" :status :good -:model "HP LaserJet 8100 Multifunction Printer" +:model "HP PSC 2358 All-in-one Printer" :status :good -:model "HP LaserJet 8150 Multifunction Printer" +:model "HP PSC 2405 Photosmart All-in-one Printer" :status :good -:model "HP Photosmart c8150 All-in-one Printer" +:model "HP PSC 2410 Photosmart All-in-one Printer" :status :good -:model "HP Photosmart c8180 All-in-one Printer" +:model "HP PSC 2410v Photosmart All-in-one Printer" :status :good -:model "HP Photosmart c8183 All-in-one Printer" +:model "HP PSC 2410xi Photosmart All-in-one Printer" :status :good -:model "HP Photosmart c8188 All-in-one Printer" +:model "HP PSC 2420 Photosmart All-in-one Printer" :status :good -:model "HP Officejet Pro 8500 Premier All-in-one Printer - a909n" +:model "HP PSC 2450 Photosmart All-in-one Printer" :status :good -:model "HP Officejet Pro 8500 Wireless All-in-one Printer - a909g" +:model "HP PSC 2500 Photosmart All-in-one Printer" :status :good -:model "HP Officejet Pro 8500 All-in-one Printer - a909a" +:model "HP PSC 2510 Photosmart All-in-one Printer" :status :good -:model "HP LaserJet 9000 Multifunction Printer" +:model "HP PSC 2510xi Photosmart All-in-one Printer" :status :good -:model "HP LaserJet 9000l Multifunction Printer" +:model "HP PSC 2550 Photosmart All-in-one Printer" :status :good -:model "HP LaserJet 9040 Multifunction Printer" +:model "HP PSC 500 All-in-one Printer" :status :good -:model "HP LaserJet 9050 Multifunction Printer" +:model "HP PSC 500xi All-in-one Printer" :status :good -:model "HP LaserJet 9055 Multifunction Printer" +:model "HP PSC 720 All-in-one Printer" :status :good -:model "HP LaserJet 9065 Multifunction Printer" +:model "HP PSC 750 All-in-one Printer" :status :good -:model "HP Officejet 9110 All-in-one Printer" +:model "HP PSC 750xi All-in-one Printer" :status :good -:model "HP Officejet 9120 All-in-one Printer" +:model "HP PSC 760 All-in-one Printer" :status :good -:model "HP Officejet 9130 All-in-one Printer" +:model "HP PSC 780 All-in-one Printer" +:status :good + +:model "HP PSC 780xi All-in-one Printer" +:status :good + +:model "HP PSC 900 All-in-one Printer" +:status :good + +:model "HP PSC 920 All-in-one Printer" +:status :good + +:model "HP PSC 950 All-in-one Printer" +:status :good + +:model "HP PSC 950vr All-in-one Printer" +:status :good + +:model "HP PSC 950xi All-in-one Printer" +:status :good + +:model "HP Scanjet Enterprise 7500" +:status :good + +:model "HP Scanjet Enterprise Flow 5000 s4" +:status :good + +:model "HP Scanjet Enterprise Flow 7000 s3" +:status :good + +:model "HP Scanjet Enterprise Flow n9120 fn2 Document Scanner" +:status :good + +:model "HP Scanjet Pro 3000 s3" +:status :good + +:model "HP Scanjet Pro 3500 f1 Flatbed Scanner" +:status :good + +:model "HP Scanjet Pro 4500 fn1" +:status :good + +:model "HP Smart Tank 350" +:status :good + +:model "HP Smart Tank 500 Series" +:status :good + +:model "HP Smart Tank 510" +:status :good + +:model "HP Smart Tank 530 Series" +:status :good + +:model "HP Smart Tank 610" +:status :good + +:model "HP Smart Tank Plus 550" +:status :good + +:model "HP Smart Tank Plus 570 Series" +:status :good + +:model "HP Smart Tank Plus 650" +:status :good + +:model "HP Smart Tank Wireless 450" +:status :good + +:model "HP Tango" :status :good -:model "HP Color LaserJet 9500 Multifunction Printer" +:model "HP Tango X" :status :good diff --git a/doc/descriptions-external/lhii.desc b/doc/descriptions-external/lhii.desc index 1877e0c..19c642d 100644 --- a/doc/descriptions-external/lhii.desc +++ b/doc/descriptions-external/lhii.desc @@ -12,8 +12,6 @@ :backend "lhii" ; name of backend ;:version "0.42" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://www.sane-project.org/backends/lhii/lhii-v0.2.tgz" ; backend's web page :comment "This backend is for old handscanners with proprietary adapter cards. You also need a kernel driver. You may find such drivers at that page: http://www.willamowius.de/scanner.html ." diff --git a/doc/descriptions-external/panamfs.desc b/doc/descriptions-external/panamfs.desc index 5a34cea..066207d 100644 --- a/doc/descriptions-external/panamfs.desc +++ b/doc/descriptions-external/panamfs.desc @@ -12,8 +12,6 @@ :backend "panamfs" ; name of backend ;:version "1.0.0" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://panasonic.net/pcc/support/fax/common/table/linuxdriver.html" ; backend's web page :comment "External backend made by panasonic." diff --git a/doc/descriptions-external/primascan.desc b/doc/descriptions-external/primascan.desc index 6815bcd..8533da3 100644 --- a/doc/descriptions-external/primascan.desc +++ b/doc/descriptions-external/primascan.desc @@ -12,8 +12,6 @@ :backend "primascan" ; name of backend ;:version "0.42" ; version of backend (or "unmaintained") -;:new :yes ; Is the backend new to this SANE release? - ; :yes or :no ;:manpage "sane-template" ; name of manpage (if it exists) :url "http://www.geocities.com/trsh0101/index.html" ; backend's web page :comment "SANE backend and stand-alone program" diff --git a/doc/descriptions-external/scangearmp2.desc b/doc/descriptions-external/scangearmp2.desc new file mode 100644 index 0000000..d3ea973 --- /dev/null +++ b/doc/descriptions-external/scangearmp2.desc @@ -0,0 +1,425 @@ +; +; SANE Backend specification file +; +; It's basically emacs-lisp --- so ";" indicates comment to end of line. +; All syntactic elements are keyword tokens, followed by a string or +; keyword argument, as specified. +; +; ":backend" *must* be specified. +; All other information is optional (but what good is the file without it?). +; + +:backend "canon_pixma" ; name of backend +;:version "(external)" ; version of backend +:url "https://github.com/Ordissimo/scangearmp2/blob/master/README.md" ; backend's web page +:comment "External binary-only backend for Linux i386 and x86_64?. See the website for the latest release." + + + +:devicetype :scanner ; start of a list of devices.... + ; other types: :stillcam, :vidcam, + ; :meta, :api + +:mfg "Canon" ; name a manufacturer +:url "https://www.canon.com/" +:comment "Multi Function Peripheral. External backend made by Canon. Please check the Canon website and/or contact us if you have a Canon device not mentioned here." + +; +; Canon MFP2 conf file +; + +; ---- V390 -------------------------- +:model "G6000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1865" +:status :good + +:model "G6080 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1866" +:status :good + +:model "TS5300 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188b" +:status :good + +:model "TS5380 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188c" +:status :good + +:model "TS6300 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188d" +:status :good + +:model "TS6380 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188e" +:status :good + +:model "TS7330 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188f" +:status :good + +:model "TS8300 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1890" +:status :good + +:model "TS8380 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1891" +:status :good + +:model "TS8330 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1892" +:status :good + +:model "XK60 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1893" +:status :good + +:model "TS6330 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1894" +:status :good + +:model "TS3300 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x18a2" +:status :good + +:model "E3300 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x18a3" +:status :good + +; ---- V370 -------------------------- +:model "TS8200 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1859" +:status :good + +:model "XK80 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1873" +:status :good + +:model "TS8230 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x185b" +:status :good + +:model "TS8280 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x185a" +:status :good + +:model "TS6200 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1856" +:status :good + +:model "TS6230 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1858" +:status :good + +:model "TS6280 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1857" +:status :good + +:model "TS9500 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x185c" +:status :good + +:model "TR9530 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x185e" +:status :good + +:model "TS9580 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x185d" +:status :good + +:model "TR4500 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1854" +:status :good + +:model "E4200 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1855" +:status :good + +:model "LiDE 400" +:interface "USB" +:usbid "0x04a9" "0x1912" +:status :good + +:model "LiDE 300" +:interface "USB" +:usbid "0x04a9" "0x1913" +:status :good + + +; ---- V360 -------------------------- +:model "G3010 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x183b" +:status :good + +:model "G4010 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x183d" +:status :good + + +; ---- V350 -------------------------- +:model "TS9100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1820" +:status :good + +:model "TS8100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1821" +:status :good + +:model "TS6100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1822" +:status :good + +:model "TR8500 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1823" +:status :good + +:model "TR7500 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1824" +:status :good + +:model "TS5100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1825" +:status :good + +:model "TS3100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1827" +:status :good + +:model "E3100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1828" +:status :good + +:model "TS9180 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x183e" +:status :good + +:model "TS8180 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x183f" +:status :good + +:model "TS6180 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1840" +:status :good + +:model "TR8580 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1841" +:status :good + +:model "TS8130 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1842" +:status :good + +:model "TS6130 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1843" +:status :good + +:model "TR8530 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1844" +:status :good + +:model "TR7530 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1845" +:status :good + +:model "XK50 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1846" +:status :good + +:model "XK70 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1847" +:status :good + + +; ---- V340 -------------------------- +:model "TS9000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x179f" +:status :good + +:model "TS8000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1800" +:status :good + +:model "TS6000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1801" +:status :good + +:model "TS5000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1802" +:status :good + +:model "MG3000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x180b" +:status :good + +:model "E470 series" +:interface "USB" +:usbid "0x04a9" "0x180c" +:status :good + +:model "G4000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x181d" +:status :good + +; Network attached versions of the above +:model "MB2100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1793" +:status :good + +:model "MB2700 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1792" +:status :good + +:model "MB5100 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1790" +:status :good + +:model "MB5400 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x178f" +:status :good + +; ---- V330 -------------------------- +:model "G3000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1794" +:status :good + + +; ---- V320 -------------------------- +:model "MG7700 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x178b" +:status :good + +:model "MG6900 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x178c" +:status :good + +:model "MG6800 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x178d" +:status :good + +:model "MG5700 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x178e" +:status :good + +:model "MG3600 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x178a" +:status :good + + +; ---- V310 -------------------------- +:model "MX490 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1787" +:status :good + +:model "E480 series" +:interface "USB" +:usbid "0x04a9" "0x1789" +:status :good + + +; ---- V300 -------------------------- +:model "MG7500 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x177c" +:status :good + +:model "MG6600 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x177e" +:status :good + +:model "MG5600 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x177f" +:status :good + +:model "MG2900 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1780" +:status :good + +:model "MB2000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1778" +:status :good + +:model "MB2300 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1779" +:status :good + +:model "MB5000 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1776" +:status :good + +:model "MB5300 series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1777" +:status :good + +:model "E460 series" +:interface "USB" +:usbid "0x04a9" "0x1788" +:status :good diff --git a/doc/descriptions-external/template.desc. b/doc/descriptions-external/template.desc. index a6b6bab..ce5d077 100644 --- a/doc/descriptions-external/template.desc. +++ b/doc/descriptions-external/template.desc. @@ -12,8 +12,6 @@ :backend "template" ; name of backend :version "0.42" ; version of backend (or "unmaintained") -:new :yes ; Is the backend new to this SANE release? - ; :yes or :no :manpage "sane-template" ; name of manpage (if it exists) :url "http://www.luser.com/temp/" ; backend's web page :url "http://www.luser.com/b/" ; another backend webpage diff --git a/doc/descriptions-external/utsushi.desc b/doc/descriptions-external/utsushi.desc index 08ad17f..105b0c7 100644 --- a/doc/descriptions-external/utsushi.desc +++ b/doc/descriptions-external/utsushi.desc @@ -69,7 +69,7 @@ :interface "USB" :status :good -:model "DS-535" +:model "DS-535H" :interface "USB" :usbid "0x04b8" "0x017a" :status :good @@ -192,6 +192,11 @@ :usbid "0x04b8" "0x1106" :status :good +:model "ET-3750" +:interface "USB" +:usbid "0x04b8" "0x1130" +:status :good + :model "ET-4500" :interface "USB" :usbid "0x04b8" "0x1107" @@ -934,6 +939,18 @@ :status :good :comment "L61x0" +:model "PID 1167" +:interface "USB" +:usbid "0x04b8" "0x1167" +:status :good +:comment "ET-16xxx" + +:model "PID 1168" +:interface "USB" +:usbid "0x04b8" "0x1168" +:status :good +:comment "ET-16xxx" + :model "PID 1169" :interface "USB" :usbid "0x04b8" "0x1169" @@ -951,8 +968,56 @@ :usbid "0x04b8" "0x116b" :status :good +:model "PID 116C" +:interface "USB" +:usbid "0x04b8" "0x116c" +:status :good +:comment "WFC8xxR" + +:model "PID 116D" +:interface "USB" +:usbid "0x04b8" "0x116d" +:status :good +:comment "WFC8xxR" + :model "PID 116E" :interface "USB" :usbid "0x04b8" "0x116e" :status :good :comment "EWM7xxTR" + +:model "PID 116F" +:interface "USB" +:usbid "0x04b8" "0x116f" +:status :good +:comment "ET-16xxx" + +:model "PID 1170" +:interface "USB" +:usbid "0x04b8" "0x1170" +:status :good +:comment "ET-16xxx" + +:model "PID 1174" +:interface "USB" +:usbid "0x04b8" "0x1174" +:status :good +:comment "ET-58xx" + +:model "PID 1175" +:interface "USB" +:usbid "0x04b8" "0x1175" +:status :good +:comment "ET-58xx" + +:model "PID 1176" +:interface "USB" +:usbid "0x04b8" "0x1176" +:status :good +:comment "ET-58xx" + +:model "PID 1177" +:interface "USB" +:usbid "0x04b8" "0x1177" +:status :good +:comment "ET-16xxx" diff --git a/doc/descriptions/escl.desc b/doc/descriptions/escl.desc new file mode 100644 index 0000000..f654f75 --- /dev/null +++ b/doc/descriptions/escl.desc @@ -0,0 +1,7 @@ +:backend "escl" +:new :yes +:manpage "sane-escl" +:url "https://support.apple.com/en-us/HT201311" +:comment "The eSCL backend for sane supports AirScan/eSCL devices that announce themselves on mDNS as _uscan._utcp or _uscans._utcp" + +:devicetype :scanner diff --git a/doc/descriptions/fujitsu.desc b/doc/descriptions/fujitsu.desc index 99e5d7a..b858415 100644 --- a/doc/descriptions/fujitsu.desc +++ b/doc/descriptions/fujitsu.desc @@ -651,3 +651,9 @@ :interface "USB" :status :untested :usbid "0x04c5" "0x1522" + +:model "ScanSnap iX1500" +:interface "USB WiFi" +:status :good +:usbid "0x04c5" "0x159f" +:comment "small, current, WiFi not supported." diff --git a/doc/descriptions/genesys.desc b/doc/descriptions/genesys.desc index 77c1fd8..888f252 100644 --- a/doc/descriptions/genesys.desc +++ b/doc/descriptions/genesys.desc @@ -17,6 +17,21 @@ :status :basic :comment "Has a Primax USB ID" +:model "OpticFilm 7200i" +:interface "USB" +:usbid "0x07b3" "0x0c04" +:status :basic + +:model "OpticFilm 7300" +:interface "USB" +:usbid "0x07b3" "0x0c12" +:status :basic + +:model "OpticFilm 7500i" +:interface "USB" +:usbid "0x07b3" "0x0c13" +:status :basic + ; ----------------------------------------------------------------------------- :mfg "Medion/Lifetec/Tevion/Cytron" @@ -64,7 +79,7 @@ :status :basic :comment "clone of the HP 2400C" -:model "ScanJet 3670C" +:model "ScanJet 3670" :interface "USB" :usbid "0x03f0" "0x1405" :status :complete @@ -74,7 +89,7 @@ :interface "USB" :usbid "0x03f0" "0x1405" :status :complete -:comment "1200x1200 dpi max, same as HP 3670C" +:comment "1200x1200 dpi max, same as HP 3670" :model "ScanJet 4850C" :interface "USB" @@ -169,11 +184,11 @@ :status :complete :comment "GL124+ based, resolution from 75 to 4800 dpi" -:model "CanoScan 4400f" +:model "CanoScan 4400F" :interface "USB" :usbid "0x04a9" "0x2228" -:status :unsupported -:comment "GL843 based, to be added to the genesys backend" +:status :basic +:comment "GL843 based" :model "CanoScan 5600F" :interface "USB" @@ -181,6 +196,13 @@ :status :unsupported :comment "GL847 based, to be added to the genesys backend" +:model "CanoScan 8400F" +:url "unsupported/canon-8400f.html" +:interface "USB" +:usbid "0x04a9" "0x221e" +:status :basic +:comment "GL841 based, to be added to genesys backend" + :model "CanoScan 8600F" :url "unsupported/canon-8600.html" :interface "USB" diff --git a/doc/descriptions/pixma.desc b/doc/descriptions/pixma.desc index be2ec1d..4366891 100644 --- a/doc/descriptions/pixma.desc +++ b/doc/descriptions/pixma.desc @@ -11,7 +11,7 @@ ; See doc/descriptions.txt for details. :backend "pixma" ; name of backend -:version "0.23.0" ; version of backend (or "unmaintained") +:version "0.27.0" ; version of backend (or "unmaintained") :manpage "sane-pixma" ; name of manpage (if it exists) ;:comment "Devices marked as experimantal are disabled by default. See the manual page for how to enable them." @@ -88,6 +88,12 @@ :status :untested :comment "Testers needed!" +:model "PIXMA E3300 Series" +:interface "USB" +:usbid "0x04a9" "0x18a3" +:status :untested +:comment "Testers needed!" + :model "PIXMA E4200 Series" :interface "USB WiFi" :usbid "0x04a9" "0x1855" @@ -100,6 +106,12 @@ :status :complete :comment "All resolutions supported (up to 600DPI)." +:model "PIXMA G2010 Series" +:interface "USB" +:usbid "0x04a9" "0x183a" +:status :complete +:comment "All resolutions supported (up to 600DPI)." + :model "PIXMA G2100" :interface "USB" :usbid "0x04a9" "0x1795" @@ -130,6 +142,18 @@ :status :untested :comment "Testers needed!" +:model "PIXMA G6000" +:interface "USB WiFi" +:usbid "0x04a9" "0x1865" +:status :untested +:comment "Testers needed!" + +:model "PIXMA G6080" +:interface "USB WiFi" +:usbid "0x04a9" "0x1866" +:status :untested +:comment "Testers needed!" + :model "PIXMA MG2100 Series" :interface "USB" :usbid "0x04a9" "0x1751" @@ -163,8 +187,8 @@ :model "PIXMA MG3000 Series" :interface "USB WiFi" :usbid "0x04a9" "0x180b" -:status :untested -:comment "Testers needed!" +:status :good +:comment "All resolutions supported (up to 600DPI). WiFi not working." :model "PIXMA MG3100 Series" :interface "USB WiFi" @@ -875,6 +899,12 @@ :status :good :comment "All resolutions supported (up to 600DPI). WiFi not working." +:model "PIXMA TS3300 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x18a2" +:status :untested +:comment "Testers needed!" + :model "PIXMA TS5000 Series" :interface "USB WiFi" :usbid "0x04a9" "0x1802" @@ -887,6 +917,18 @@ :status :untested :comment "Testers needed!" +:model "PIXMA TS5300 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188b" +:status :untested +:comment "Testers needed!" + +:model "PIXMA TS5380 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188c" +:status :untested +:comment "Testers needed!" + :model "PIXMA TS6000 Series" :interface "USB WiFi" :usbid "0x04a9" "0x1801" @@ -914,8 +956,8 @@ :model "PIXMA TS6200 Series" :interface "USB WiFi" :usbid "0x04a9" "0x1856" -:status :untested -:comment "Testers needed!" +:status :good +:comment "All resolutions supported (up to 1200DPI). WiFi not working." :model "PIXMA TS6230 Series" :interface "USB WiFi" @@ -929,6 +971,30 @@ :status :untested :comment "Testers needed!" +:model "PIXMA TS6300 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188b" +:status :good +:comment "Testers needed!" + +:model "PIXMA TS6330 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1894" +:status :untested +:comment "Testers needed!" + +:model "PIXMA TS6380 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188e" +:status :untested +:comment "Testers needed!" + +:model "PIXMA TS7330 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x188f" +:status :untested +:comment "Testers needed!" + :model "PIXMA TS8000 Series" :interface "USB WiFi" :usbid "0x04a9" "0x1800" @@ -971,6 +1037,24 @@ :status :untested :comment "Testers needed!" +:model "PIXMA TS8300 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1890" +:status :untested +:comment "Testers needed!" + +:model "PIXMA TS8330 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1892" +:status :untested +:comment "Testers needed!" + +:model "PIXMA TS8380 Series" +:interface "USB WiFi" +:usbid "0x04a9" "0x1891" +:status :untested +:comment "Testers needed!" + :model "PIXMA TS9000 Series" :interface "USB WiFi" :usbid "0x04a9" "0x179f" @@ -1019,6 +1103,12 @@ :status :untested :comment "Testers needed!" +:model "CanoScan XK 60" +:interface "USB" +:usbid "0x04a9" "0x1893" +:status :untested +:comment "Testers needed!" + :model "PIXUS XK70 Series" :interface "USB WiFi" :usbid "0x04a9" "0x1847" @@ -1058,8 +1148,8 @@ :model "imageCLASS D570" :interface "USB" :usbid "0x04a9" "0x27e8" -:status :untested -:comment "Testers needed!" +:status :complete +:comment "All resolutions supported (up to 600DPI)" :model "i-SENSYS MF110 Series" :interface "USB Ethernet WiFi" @@ -1130,14 +1220,26 @@ :model "i-SENSYS MF630 Series" :interface "USB Ethernet WiFi" :usbid "0x04a9" "0x27e1" -:status :untested -:comment "Testers needed!" +:status :complete +:comment "Flatbed and ADF scan. All resolutions supported (up to 600DPI)." + +:model "imageCLASS MF634C" +:interface "USB Ethernet WiFi" +:usbid "0x04a9" "0x27e2" +:status :complete +:comment "Flatbed and ADF scan. All resolutions supported (up to 600DPI)." :model "i-SENSYS MF640 Series" :interface "USB Ethernet WiFi" :usbid "0x04a9" "0x27fe" -:status :untested -:comment "Testers needed!" +:status :complete +:comment "Flatbed and ADF scan. All resolutions supported (up to 600DPI)." + +:model "i-SENSYS MF645C" +:interface "USB Ethernet WiFi" +:usbid "0x04a9" "0x27fd" +:status :complete +:comment "Flatbed and ADF scan. All resolutions supported (up to 600DPI)." :model "i-SENSYS MF730 Series" :interface "USB Ethernet WiFi" @@ -1145,14 +1247,6 @@ :status :good :comment "Flatbed and ADF scan. All resolutions supported (up to 600DPI). Ethernet and WiFi not tested yet" - -:model "imageCLASS MF634C" -:interface "USB Ethernet WiFi" -:usbid "0x04a9" "0x27e2" -:status :complete -:comment "Flatbed and ADF scan. All resolutions supported (up to 600DPI)." - - :model "imageCLASS MF733Cdw" :interface "USB Ethernet WiFi" :usbid "0x04a9" "0x27e5" @@ -1171,6 +1265,12 @@ :status :untested :comment "Testers needed!" +:model "i-SENSYS MF741/743" +:interface "USB Ethernet WiFi" +:usbid "0x04a9" "0x27fc" +:status :complete +:comment "Flatbed and ADF scan. All resolutions supported (up to 600DPI)." + :model "i-SENSYS MF810/820" :interface "USB Ethernet" :usbid "0x04a9" "0x27a6" @@ -1462,8 +1562,8 @@ :model "MAXIFY MB5000 Series" :interface "USB" :usbid "0x04a9" "0x1776" -:status :good -:comment "Flatbed works, All resolutions supported (up to 1200DPI), ADF does not work" +:status :complete +:comment "Flatbed and ADF scan. All resolutions supported (up to 1200DPI)." :model "MAXIFY MB5100 Series" :interface "USB Ethernet WiFi" @@ -1480,8 +1580,8 @@ :model "MAXIFY MB5400 Series" :interface "USB Ethernet WiFi" :usbid "0x04a9" "0x178f" -:status :untested -:comment "Testers needed!" +:status :complete +:comment "Flatbed and ADF scan. All resolutions supported (up to 1200DPI)." :model "CanoScan 8800F" :interface "USB" @@ -1505,10 +1605,10 @@ :interface "USB" :usbid "0x04a9" "0x1913" :status :complete -:comment "Support up to 4800DPI (Note: does not have less than 300DPI support)" +:comment "All resolutions supported (up to 2400DPI)" :model "CanoScan LiDE 400" :interface "USB" :usbid "0x04a9" "0x1912" :status :complete -:comment "Support up to 4800DPI (Note: does not have less than 300DPI support)" +:comment "All resolutions supported (up to 4800DPI)" diff --git a/doc/descriptions/ricoh2.desc b/doc/descriptions/ricoh2.desc index 55ee372..12a9b4c 100644 --- a/doc/descriptions/ricoh2.desc +++ b/doc/descriptions/ricoh2.desc @@ -12,8 +12,6 @@ :backend "ricoh2" ; name of backend :version "1.0" ; version of backend (or "unmaintained") -:new :yes ; Is the backend new to this SANE release? - ; :yes or :no :manpage "sane-ricoh2" ; name of manpage (if it exists) :url "http://www.ricoh.com/" ; backend's web page @@ -24,6 +22,11 @@ :mfg "Ricoh" ; name a manufacturer :url "http://www.ricoh.com/" ; manufacturer's URL +:model "SG-3100SFNw" +:status :basic +:interface "USB" +:usbid "0x05ca" "0x0439" + :model "SG-3100SNw" :status :basic :interface "USB" @@ -34,7 +37,7 @@ :interface "USB" :usbid "0x05ca" "0x042c" -:model "SP-111SU" +:model "SP-111SU/SP-112SU" :status :basic :interface "USB" :usbid "0x05ca" "0x0448" diff --git a/doc/descriptions/unsupported.desc b/doc/descriptions/unsupported.desc index 496ebea..e062682 100644 --- a/doc/descriptions/unsupported.desc +++ b/doc/descriptions/unsupported.desc @@ -305,13 +305,6 @@ :status :unsupported :comment "Probably unsupported. See link." -:model "CanoScan 4400F" -:url "unsupported/canon-4400.html" -:interface "USB" -:usbid "0x04a9" "0x2228" -:status :unsupported -:comment "GL843 based, to be added to genesys backend" - :model "CanoScan 5000F" :url "unsupported/canon-5000f.html" :interface "USB" @@ -333,13 +326,6 @@ :status :unsupported :comment "Not supported. See link for more information. With transparency adapter." -:model "CanoScan 8400F" -:url "unsupported/canon-8400f.html" -:interface "USB" -:usbid "0x04a9" "0x221e" -:status :unsupported -:comment "GL841 based, to be added to genesys backend" - :model "CanoScan 9900F" :url "unsupported/canon-9900f.html" :interface "USB" @@ -1766,12 +1752,6 @@ :status :unsupported :comment "GL842 based, maybe to be added to genesys backend" -:model "OpticFilm 7200i" -:interface "USB" -:usbid "0x07b3" "0x0c04" -:status :unsupported -:comment "GL843 based, maybe to be added to genesys backend" - :model "OpticPro A3U" :interface "USB" :status :unsupported diff --git a/doc/releases.txt b/doc/releases.txt index abd007e..0cb7518 100644 --- a/doc/releases.txt +++ b/doc/releases.txt @@ -1,4 +1,4 @@ -2019-07-30 +2019-08-24 This text summarizes some points to pay attention to when a new release of sane-backends is planned. @@ -32,34 +32,31 @@ Before the release: Making the release: * temporarily set a PRIVATE_TOKEN variable in the GitLab CI/CD - variables You have to create one in your own Settings > Access - Tokens. Set it to expire in a few hours to avoid abuse. + variables. You have to create one in your own Settings > Access + Tokens. Set it to expire the next day to avoid abuse. Better yet, + remove it from the CI/CD variables when the job is finished. * git tag -a -s 1.0.28 -m Release * git push --tags origin master * trigger the manual 'release' stage of the build via the web UI when this becomes possible. This requires a valid PRIVATE_TOKEN. -Announcing the release: +Updating the website and announcing the release: -* [TBD] checkout the sane/website.git module and: -* [TBD] copy sane-backends.html to sane-backends-"old-version".html -* [TBD] update sane-supported-devices.html with link to above "old" file -* [TBD] rebuild sane-backends.html and sane-mfgs.html (make -C doc html-pages) +* checkout the sane/website.git module and: +* copy sane-backends.html to sane-backends-"old-version".html +* update sane-supported-devices.html with link to above "old" file +* rebuild sane-backends.html and sane-mfgs.html (make -C doc html-pages) * [TBD] use man2html from http://hydra.nac.uci.edu/indiv/ehood/man2html.html to rebuild html man pages (make -C doc html-man) (no other version works) -* [TBD] add md5 sum to sane-md5sums.txt -* [TBD] check and update platforms page (sane-support.html) -* add announcement to index.html +* update announcement to index.html * git commit -a && git push -* check that website was updated automatically -* [TBD] rebuild descriptions.db (make -C doc descriptions.db) -* announce release on sane-devel and sane-announce mailing lists +* check that website's pipeline succeeded +* announce release on sane-announce mailing list (and Cc: sane-devel). + Ping the sane-announce list's moderator (m. allan noah) to get your + post approved ASAP. After the release: -* [TBD] copy ChangeLog to ChangeLogs/ChangeLog-$version -* [TBD] start a new ChangeLog via git checkout ChangeLog -* [TBD] bump version number in tools/create-changelog.sh * remove the ':new' tag from all doc/descriptions*/*.desc files * git add new and changed files and commit * git push diff --git a/doc/sane-escl.man b/doc/sane-escl.man new file mode 100644 index 0000000..21a4d6c --- /dev/null +++ b/doc/sane-escl.man @@ -0,0 +1,41 @@ +.TH sane\-escl 5 "14 Dec 2019" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" +.IX sane\-escl +.SH NAME +sane\-escl \- SANE backend for eSCL scanners +.SH DESCRIPTION +The +.B sane\-escl +library implements a SANE (Scanner Access Now Easy) backend that +provides access to eSCL protocol scanners. + +.PP +The "escl" backend for SANE supports AirScan/eSCL devices that announce +themselves on mDNS as _uscan._utcp or _uscans._utcp. +If the device is available, the "escl" backend recovers these capacities. +The user configures and starts scanning. +A list of devices that use the eSCL protocol can be found at +.IR https://support.apple.com/en-us/HT201311 . +While these devices are expected to work, your mileage may vary. + +.SH FILES +.TP +.I @CONFIGDIR@/escl.conf +The backend configuration file. +.TP +.I @LIBDIR@/libsane\-escl.a +The static library implementing this backend. +.TP +.I @LIBDIR@/libsane\-escl.so +The shared library implementing this backend (present on systems that +support dynamic loading). +.SH ENVIRONMENT +.TP +.B SANE_DEBUG_ESCL +If the library was compiled with debug support enabled, this +environment variable controls the debug level for this backend. E.g., +a value of 128 requests all debug output to be printed. Smaller +levels reduce verbosity. +.SH "SEE ALSO" +sane(7), scanimage(1), xscanimage(1), xsane(1) +.SH AUTHORS +Touboul Nathane, Thierry HUCHARD diff --git a/doc/sane-pixma.man b/doc/sane-pixma.man index 1ceb6d6..ea85ec5 100644 --- a/doc/sane-pixma.man +++ b/doc/sane-pixma.man @@ -1,4 +1,4 @@ -.TH "sane\-pixma" "5" "29 Jul 2019" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" +.TH "sane\-pixma" "5" "28 Dec 2019" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" .IX sane\-pixma .SH NAME sane\-pixma \- SANE backend for Canon Multi-Function Printers and CanoScan Scanners @@ -17,15 +17,15 @@ Currently, the following models work with this backend: .RS PIXMA E510 .br -PIXMA G2000, G2100 +PIXMA G2000, G2010, G2100 .br -PIXMA MG2100, MG2200, MG2400, MG2500, MG2900, MG3100, MG3200 +PIXMA MG2100, MG2200, MG2400, MG2500, MG2900, MG3000, MG3100 .br -PIXMA MG3500, MG3600, MG4200, MG5100, MG5200, MG5300, MG5400 +PIXMA MG3200, MG3500, MG3600, MG4200, MG5100, MG5200, MG5300 .br -PIXMA MG5500, MG5600, MG5700, MG6100, MG6200, MG6300, MG6400 +PIXMA MG5400, MG5500, MG5600, MG5700, MG6100, MG6200, MG6300 .br -PIXMA MG7100, MG7500, MG7700, MG8200 +PIXMA MG6400, MG7100, MG7500, MG7700, MG8200 .br PIXMA MP140, MP150, MP160, MP170, MP180, MP190 .br @@ -51,7 +51,7 @@ PIXMA MX410, MX420, MX470, MX510, MX520, MX530, MX700, MX720 .br PIXMA MX850, MX860, MX870, MX882, MX885, MX890, MX920, MX7600 .br -PIXMA TS3100, TS5000, TS6100, TS8000, TS8200 +PIXMA TS3100, TS5000, TS6100, TS6200, TS8000, TS8200 .br PIXUS MP10 .br @@ -65,13 +65,15 @@ imageCLASS MF4270, MF4350d, MF4370dn, MF4380dn .br imageCLASS MF4410, MF4430, MF4570dw, MF4660, MF4690 .br -imageCLASS MF5730, MF5770, MF6550, MPC200, D420, D480, D530 +imageCLASS MF5730, MF5770, MF6550, MPC200 .br -i-SENSYS MF210, MF230, MF240, MF620, MF730, MF731/733, MF3010 +imageCLASS D420, D480, D530, D570 .br -i-SENSYS MF4320d, MF4330d, MF4500, MF4700, MF4800, MF6100 +i-SENSYS MF210, MF230, MF240, MF620, MF630, MF640, MF645C, MF730 .br -i-SENSYS MF8030, MF8200C, MF8300 +i-SENSYS MF731/733, MF741/743, MF3010, MF4320d, MF4330d, MF4500 +.br +i-SENSYS MF4700, MF4800, MF6100, MF8030, MF8200C, MF8300 .br imageRUNNER 1020/1024/1025, 1133 .br @@ -79,7 +81,7 @@ CanoScan 8800F, 9000F, 9000F Mark II .br CanoScan LiDE 300, 400 .br -MAXIFY MB2000, MB2100, MB2300, MB2700, MB5000 +MAXIFY MB2000, MB2100, MB2300, MB2700, MB5000, MB5400 .RE .PP The following models are not well tested and/or the scanner sometimes hangs @@ -97,46 +99,49 @@ Feedback in the sane\-devel mailing list welcome. .RS PIXMA E400, E410, E460, E470, E480, E500, E560, E600, E610 .br -PIXMA E3100, E4200 +PIXMA E3100, E3300, E4200 .br -PIXMA MG3000, MG4100, MG6500, MG6600, MG6800, MG6900, MG8100 +PIXMA MG4100, MG6500, MG6600, MG6800, MG6900, MG8100 .br PIXMA MP375R, MP493, MP495, MP740 .br PIXMA MX320, MX390, MX430, MX450, MX490, MX710 .br -PIXMA G3000, G3010, G4000, G4010 +PIXMA G3000, G3010, G4000, G4010, G6000, G6080 .br PIXMA TR4500, TR7500, TR7530, TR8500, TR8530, TR8580, TR9530 .br -PIXMA TS5100, TS6000, TS6130, TS6180, TS6200, TS6230, TS6280 +PIXMA TS5100, TS6000, TS6130, TS6180, TS6230, TS6280, TS6300 +.br +PIXMA TS6330, TS6380, TS7330, TS8100, TS8130, TS8180, TS8230 .br -PIXMA TS8100, TS8130, TS8180, TS8230, TS8280, TS9000, TS9100 +PIXMA TS8280,, TS8300, TS8330, TS8380, TS9000, TS9100, TS9180 .br -PIXMA TS9180, TS9500, TS9580 +PIXMA TS9500, TS9580 .br -PIXUS MP5, XK50, XK70, XK80 +PIXUS MP5, XK50, XK60, XK70, XK80 .br imageCLASS MF810/820, MF5630, MF5650, MF5750, MF8170c .br -imageCLASS MPC190, D550, D570 +imageCLASS MPC190, D550 .br -i-SENSYS MF110, MF220, MF260, MF410, MF420, MF510, MF520, MF630 +i-SENSYS MF110, MF220, MF260, MF410, MF420, MF510, MF520, MF740 .br -i-SENSYS MF640, MF740, MF5880dn, MF5900, MF6680dn, MF8500C +i-SENSYS MF5880dn, MF5900, MF6680dn, MF8500C .br -MAXIFY MB5100, MB5300, MB5400 +MAXIFY MB5100, MB5300 +.RE +.PP +The following models may use partly the same Pixma protocol as other devices +listed above, but may still need some work. They are declared in the backend +as experimental and need the environment variable PIXMA_EXPERIMENT=1 to get +recognized and activated. Snoop logs are required to further investigate, +please contact the sane\-devel mailing list. +.PP +.RS +\-\- none \-\- .RE .PP -\#The following models may use partly the same Pixma protocol as other devices -\#listed above, but may still need some work. They are declared in the backend -\#as experimental. Snoop logs are required to further investigate, please contact -\#the sane\-devel mailing list. -\#.PP -\#.RS -\#PIXMA MP--- -\#.RE -\#.PP The backend supports: .PP .RS @@ -245,12 +250,15 @@ support dynamic loading). .I @CONFIGDIR@/pixma.conf The backend configuration file (see also description of .B SANE_CONFIG_DIR -below). The file contains an optional list of networked scanners. Normally +below). +.RS +.PP +The file contains an optional list of networked scanners using the BJNP or MFNP protools +(See below for datails on networking support for scanners). Normally only scanners that cannot be auto-detected because they are on a different -subnet shall be listed here. If your OS does not allow enumeration of +subnet shall be listed here. If you do not use Linux and your OS does not allow enumeration of interfaces (i.e. it does not support the getifaddrs() function) you also may need to add your scanner here as well. -.RS .PP .I Scanners shall be listed in the configuration file as follows: .PP @@ -287,11 +295,32 @@ If not explicitly set, the default 1000ms setting will apply. .PP Setting timeouts should only be required in exceptional cases. .PP +.RE +.PP +If so desired networking can be disbled as follows: +.RS +.IP - +If the first non-commented line contains +.B networking=no +all networking will be disabled. +This will cause all further statements in the configuration file to be ignored. +.IP - +A line that contains +.B auto_detection=no +will cause auto-detection to be skipped. Explicitely defined network scanners will still be probed. .SH USB SUPPORT USB scanners will be auto-detected and require no configuration. .SH NETWORKING SUPPORT The pixma backend supports network scanners using the so called Canon BJNP -protocol and MFNP protocol. Both IPv4 and IPv6 are supported, but IPv6 is as +and MFNP protocols. +.PP +Canon seems to be dropping support for these protocols in recent scanners. +To verify if your scanner supports one of these protocols, check the content of +the _scanner._tcp service entry in mDNS/DNS-SD (using for example avahi-discover). +If that does not list port 8610 +or 8612 your scanner probably does not support the mfmp or bjnp protols. +.PP +Both IPv4 and IPv6 are supported, but IPv6 is as yet untested with MFNP. Please report your results on the mailing list. .PP Configuration is normally not required. diff --git a/doc/sane-ricoh2.man b/doc/sane-ricoh2.man index 86db7c6..ff74974 100644 --- a/doc/sane-ricoh2.man +++ b/doc/sane-ricoh2.man @@ -1,4 +1,4 @@ -.TH sane\-ricoh2 5 "28 Sep 2018" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" +.TH sane\-ricoh2 5 "04 Sep 2019" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" .IX sane\-ricoh2 .SH NAME sane\-ricoh2 \- SANE backend for Ricoh flatbed scanners @@ -9,11 +9,13 @@ library implements a SANE (Scanner Access Now Easy) backend that provides access to the following Ricoh flatbed scanners: .PP .RS +SG-3110SFNw +.br SG-3100SNw .br SP-100SU .br -SP-111SU +SP-111SU (SP-112SU) .RE .PP .SH FILES diff --git a/doc/sane.man b/doc/sane.man index a9fd50a..070a993 100644 --- a/doc/sane.man +++ b/doc/sane.man @@ -1,4 +1,4 @@ -.TH sane 7 "14 Jul 2008" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" +.TH sane 7 "03 Jan 2020" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy" .IX sane .SH NAME @@ -238,8 +238,6 @@ for details. This is a SANE backend for Nikon Coolscan film-scanners. See .BR sane\-coolscan2 (5) -or -.I http://coolscan2.sourceforge.net for details. .TP .B epjitsu @@ -421,10 +419,10 @@ SCSI flatbed scanners. See for details. .TP .B pixma -The pixma backend supports Canon PIXMA MP series (multi-function devices). See +The pixma backend supports Canon PIXMA MP series (multi-function devices), +Canon imageCLASS series (laser devices), Canon MAXIFY series and some Canon +CanoScan series. See .BR sane\-pixma (5) -or -.I http://home.arcor.de/wittawat/pixma/ for details. .TP .B plustek diff --git a/frontend/saned.c b/frontend/saned.c index ac5e700..6c3c40d 100644 --- a/frontend/saned.c +++ b/frontend/saned.c @@ -2674,6 +2674,9 @@ saned_avahi_callback (AvahiClient *c, AvahiClientState state, void *userdata) case AVAHI_CLIENT_S_COLLISION: DBG (DBG_INFO, "saned_avahi_callback: AVAHI_CLIENT_S_COLLISION\n"); + if (avahi_group) + avahi_entry_group_reset (avahi_group); + break; case AVAHI_CLIENT_S_REGISTERING: DBG (DBG_INFO, "saned_avahi_callback: AVAHI_CLIENT_S_REGISTERING\n"); diff --git a/frontend/scanimage.c b/frontend/scanimage.c index 6906f90..ae65ebf 100644 --- a/frontend/scanimage.c +++ b/frontend/scanimage.c @@ -32,6 +32,7 @@ #include <assert.h> #include "lgetopt.h" +#include <inttypes.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -204,51 +205,30 @@ auth_callback (SANE_String_Const resource, if ((strlen (tmp) > 0) && (tmp[strlen (tmp) - 1] == '\r')) tmp[strlen (tmp) - 1] = 0; - if (strchr (tmp, ':') != NULL) + char *colon1 = strchr (tmp, ':'); + if (colon1 != NULL) { + char *tmp_username = tmp; + *colon1 = '\0'; - if (strchr (strchr (tmp, ':') + 1, ':') != NULL) + char *colon2 = strchr (colon1 + 1, ':'); + if (colon2 != NULL) { + char *tmp_password = colon1 + 1; + *colon2 = '\0'; - if ((strncmp - (strchr (strchr (tmp, ':') + 1, ':') + 1, - resource, len) == 0) - && - ((int) strlen - (strchr (strchr (tmp, ':') + 1, ':') + 1) == - len)) + if ((strncmp (colon2 + 1, resource, len) == 0) + && ((int) strlen (colon2 + 1) == len)) { - - if ((strchr (tmp, ':') - tmp) < - SANE_MAX_USERNAME_LEN) - { - - if ((strchr (strchr (tmp, ':') + 1, ':') - - (strchr (tmp, ':') + 1)) < - SANE_MAX_PASSWORD_LEN) - { - - strncpy (username, tmp, - strchr (tmp, ':') - tmp); - - username[strchr (tmp, ':') - tmp] = 0; - - strncpy (password, - strchr (tmp, ':') + 1, - strchr (strchr (tmp, ':') + 1, - ':') - - (strchr (tmp, ':') + 1)); - password[strchr - (strchr (tmp, ':') + 1, - ':') - (strchr (tmp, - ':') + 1)] = - 0; - - query_user = 0; - break; - } - } - + if ((strlen (tmp_username) < SANE_MAX_USERNAME_LEN) && + (strlen (tmp_password) < SANE_MAX_PASSWORD_LEN)) + { + strncpy (username, tmp_username, SANE_MAX_USERNAME_LEN); + strncpy (password, tmp_password, SANE_MAX_PASSWORD_LEN); + + query_user = 0; + break; + } } } } @@ -1317,7 +1297,8 @@ advance (Image * image) static SANE_Status scan_it (FILE *ofp) { - int i, len, first_frame = 1, offset = 0, must_buffer = 0, hundred_percent; + int i, len, first_frame = 1, offset = 0, must_buffer = 0; + uint64_t hundred_percent = 0; SANE_Byte min = 0xff, max = 0; SANE_Parameters parm; SANE_Status status; @@ -1325,7 +1306,7 @@ scan_it (FILE *ofp) static const char *format_name[] = { "gray", "RGB", "red", "green", "blue" }; - SANE_Word total_bytes = 0, expected_bytes; + uint64_t total_bytes = 0, expected_bytes; SANE_Int hang_over = -1; #ifdef HAVE_LIBPNG int pngrow = 0; @@ -1486,7 +1467,7 @@ scan_it (FILE *ofp) offset = parm.format - SANE_FRAME_RED; image.x = image.y = 0; } - hundred_percent = parm.bytes_per_line * parm.lines + hundred_percent = ((uint64_t)parm.bytes_per_line) * parm.lines * ((parm.format == SANE_FRAME_RGB || parm.format == SANE_FRAME_GRAY) ? 1:3); while (1) @@ -1498,7 +1479,12 @@ scan_it (FILE *ofp) if (progr > 100.) progr = 100.; if (progress) - fprintf (stderr, "Progress: %3.1f%%\r", progr); + { + if (parm.lines >= 0) + fprintf(stderr, "Progress: %3.1f%%\r", progr); + else + fprintf(stderr, "Progress: (unknown)\r"); + } if (status != SANE_STATUS_GOOD) { @@ -1760,7 +1746,7 @@ cleanup: free (image.data); - expected_bytes = parm.bytes_per_line * parm.lines * + expected_bytes = ((uint64_t)parm.bytes_per_line) * parm.lines * ((parm.format == SANE_FRAME_RGB || parm.format == SANE_FRAME_GRAY) ? 1 : 3); if (parm.lines < 0) @@ -1769,10 +1755,10 @@ cleanup: { fprintf (stderr, "%s: WARNING: read more data than announced by backend " - "(%u/%u)\n", prog_name, total_bytes, expected_bytes); + "(%" PRIu64 "/%" PRIu64 ")\n", prog_name, total_bytes, expected_bytes); } else if (verbose) - fprintf (stderr, "%s: read %u bytes in total\n", prog_name, total_bytes); + fprintf (stderr, "%s: read %" PRIu64 " bytes in total\n", prog_name, total_bytes); return status; } @@ -2260,15 +2246,15 @@ main (int argc, char **argv) if (defdevname) printf ("default device is `%s'\n", defdevname); scanimage_exit (0); + break; } - case 'V': printf ("scanimage (%s) %s; backend version %d.%d.%d\n", PACKAGE, VERSION, SANE_VERSION_MAJOR (version_code), SANE_VERSION_MINOR (version_code), SANE_VERSION_BUILD (version_code)); scanimage_exit (0); - + break; default: break; /* ignore device specific options for now */ } diff --git a/frontend/tstbackend.c b/frontend/tstbackend.c index 37ba660..985684d 100644 --- a/frontend/tstbackend.c +++ b/frontend/tstbackend.c @@ -46,10 +46,10 @@ static struct option basic_options[] = { {"device-name", required_argument, NULL, 'd'}, {"level", required_argument, NULL, 'l'}, - {"scan", NULL, NULL, 's'}, + {"scan", no_argument, NULL, 's'}, {"recursion", required_argument, NULL, 'r'}, {"get-devices", required_argument, NULL, 'g'}, - {"help", 0, NULL, 'h'} + {"help", no_argument, NULL, 'h'} }; static void diff --git a/include/sane/sanei_usb.h b/include/sane/sanei_usb.h index ce389ca..1c1699d 100644 --- a/include/sane/sanei_usb.h +++ b/include/sane/sanei_usb.h @@ -180,6 +180,57 @@ struct sanei_usb_dev_descriptor SANE_Byte max_packet_size; }; +/** Initialize sanei_usb for replay testing. + + Initializes sanei_usb for testing by mocking whole USB stack. This function + must be called before sanei_usb_init(). + + The sanei_usb subsystem also implements a "development mode". It modifies + the XML data file with the actual commands of the test run and attemps to + proceed testing until a mismatching input command is found for which + input data is required. + + A <known_commands_end/> node in the data XML file will cause sanei_usb not + to continue to the subsequent command in the XML file and instead it will + prepend all output commands before that node before an output command is + encountered. + + @param path Path to the XML data file. + @param development_mode Enables development mode. + */ +extern SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path, + int development_mode); + +/** Initialize sanei_usb for recording. + * + * Initializes sanei_usb for recording communication with the scanner. This + * function must be called before sanei_usb_init(). + * + * @param path Path to the XML data file. + * @param be_name The name of the backend to enable recording for. + */ +extern SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, + SANE_String_Const be_name); + +/** Returns backend name for testing. + * + * Returns backend name for the file registered in sanei_usb_testing_enable. + * The caller is responsible for freeing it. + */ +extern SANE_String sanei_usb_testing_get_backend(); + +/** Returns SANE_TRUE if replay testing mode is enabled, i.e. whether we are working with fake + * scan data. + */ +extern SANE_Bool sanei_usb_is_replay_mode_enabled(); + +/** Records a debug message in the captured USB data if testing mode is enabled. If testing mode + * is not enabled, this function does nothing. + * + * @param msg Message to record + */ +extern void sanei_usb_testing_record_message(SANE_String_Const message); + /** Initialize sanei_usb. * * Call this before any other sanei_usb function. diff --git a/include/sane/sanei_wire.h b/include/sane/sanei_wire.h index 95be5cf..679814e 100644 --- a/include/sane/sanei_wire.h +++ b/include/sane/sanei_wire.h @@ -96,7 +96,7 @@ Wire; extern void sanei_w_init (Wire *w, void (*codec_init)(Wire *)); extern void sanei_w_exit (Wire *w); extern void sanei_w_space (Wire *w, size_t howmuch); -extern void sanei_w_void (Wire *w); +extern void sanei_w_void (Wire *w, void *); extern void sanei_w_byte (Wire *w, SANE_Byte *v); extern void sanei_w_char (Wire *w, SANE_Char *v); extern void sanei_w_word (Wire *w, SANE_Word *v); diff --git a/include/sane/saneopts.h b/include/sane/saneopts.h index 37ba177..4a4b8cc 100644 --- a/include/sane/saneopts.h +++ b/include/sane/saneopts.h @@ -243,7 +243,7 @@ /* Descriptive/help strings for above options: */ #define SANE_DESC_NUM_OPTIONS \ SANE_I18N("Read-only option that specifies how many options a specific " \ -"devices supports.") +"device supports.") #define SANE_DESC_STANDARD SANE_I18N("Source, mode and resolution options") #define SANE_DESC_GEOMETRY SANE_I18N("Scan area and media size options") @@ -412,7 +412,7 @@ SANE_I18N("Analog gamma-correction for blue") #define SANE_DESC_ANALOG_GAMMA_BIND \ SANE_I18N("In RGB-mode use same values for each color") #define SANE_DESC_WARMUP \ -SANE_I18N("Warmup lamp before scanning") +SANE_I18N("Warm up lamp before scanning") #define SANE_DESC_CAL_EXPOS_TIME \ SANE_I18N("Define exposure-time for calibration") #define SANE_DESC_CAL_EXPOS_TIME_R \ diff --git a/japi/Makefile.am b/japi/Makefile.am index d48a8a6..e32c906 100644 --- a/japi/Makefile.am +++ b/japi/Makefile.am @@ -31,12 +31,12 @@ EXTRA_DIST = README.JAVA lib_LTLIBRARIES = libsanej.la -BUILT_SOURCES = Sane.h -CLEANFILES = Sane.h -nodist_libsanej_la_SOURCES = Sane.h libsanej_la_SOURCES = Sane.c libsanej_la_LIBADD = $(LIBSANE) -# Make sure that java classes get created before create Sane.h -Sane.h: classdist_noinst.stamp +# Explicit dependencies +nodist_libsanej_la_SOURCES: Sane.h +Sane.h: classnoinst.stamp $(JAVAH) Sane + +CLEANFILES = Sane.h diff --git a/ltmain.sh.patch b/ltmain.sh.patch index de0a798..1187e81 100644 --- a/ltmain.sh.patch +++ b/ltmain.sh.patch @@ -5,10 +5,10 @@ Author: Henning Meirer-Geinitz diff --git a/ltmain.sh b/ltmain.sh --- a/ltmain.sh +++ b/ltmain.sh -@@ -9615,6 +9615,23 @@ EOF +@@ -9708,6 +9708,23 @@ dlname=$soname fi - + + # If -module or -export-dynamic was specified, set the dlname + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. @@ -29,7 +29,7 @@ diff --git a/ltmain.sh b/ltmain.sh lib=$output_objdir/$realname linknames= for link -@@ -10073,12 +10090,6 @@ EOF +@@ -10166,12 +10183,6 @@ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done @@ -41,4 +41,4 @@ diff --git a/ltmain.sh b/ltmain.sh - fi fi ;; - + diff --git a/po/POTFILES.in b/po/POTFILES.in index 08bf126..d91341b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,110 +1,86 @@ -# List of source files containing translatable strings -# paths relative to the top source directory +# po/POTFILES.in -- files containing translatable strings +# File names relative to the top source directory + +# Standardized, translatable option titles and descriptions + include/sane/saneopts.h + +# Translatable SANE status strings + backend/sane_strstatus.c -backend/artec_eplus48u.c +# Remainder of this file created with +# +# git grep -l SANE_I18N -- backend/*.[ch]* backend/*/*.[ch]* \ +# | sed '/backend\/sane_strstatus.c/d' +backend/artec_eplus48u.c backend/avision.h - -backend/canon630u.c -backend/canon.c backend/canon-sane.c - +backend/canon.c +backend/canon630u.c backend/canon_dr.c -backend/canon_dr.h - -backend/cardscan.c -backend/cardscan.h - backend/epjitsu.c -backend/epjitsu.h - backend/epson.c backend/epson.h +backend/epson2-ops.c backend/epson2.c backend/epson2.h - +backend/epsonds-ops.c +backend/epsonds.c +backend/epsonds.h backend/fujitsu.c -backend/fujitsu.h - -backend/genesys.cc - +backend/genesys/genesys.cpp +backend/genesys/genesys.h backend/gt68xx.c backend/gt68xx_low.h - +backend/hp-option.c +backend/hp-option.h backend/hp3500.c backend/hp3900_sane.c backend/hp5400_sane.c backend/hp5590.c -backend/hp-option.c -backend/hp-option.h - backend/kodak.c -backend/kodak.h - +backend/kodakaio.c backend/kvs1025.h backend/kvs1025_opt.c backend/kvs20xx.c - backend/kvs20xx_opt.c - backend/kvs40xx.c backend/kvs40xx_opt.c - backend/leo.c -backend/leo.h - backend/lexmark.c - backend/ma1509.c - backend/magicolor.c - backend/matsushita.c backend/matsushita.h - -backend/microtek2.c backend/microtek2.h - backend/mustek.c backend/mustek_usb.c backend/mustek_usb2.c - +backend/mustek_usb2.h backend/niash.c - -backend/pixma.c -backend/pixma_sane_options.c - +backend/p5.c +backend/p5.h +backend/p5_device.c +backend/pixma/pixma.c +backend/pixma/pixma_sane_options.c backend/plustek.c backend/plustek_pp.c - backend/pnm.c - backend/rts8891.c - +backend/rts8891.h backend/sceptre.c -backend/sceptre.h - backend/sm3840.c - -backend/snapscan.c backend/snapscan-options.c - +backend/snapscan.c backend/stv680.c backend/stv680.h - backend/teco1.c -backend/teco1.h backend/teco2.c -backend/teco2.h backend/teco3.c -backend/teco3.h - backend/test.c - backend/u12.c - -backend/umax1220u.c backend/umax.c +backend/umax1220u.c backend/umax_pp.c @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.11\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-12-17 22:59+0100\n" "Last-Translator: Pavel Constantinov <pavelconstantinov@bigfoot.com>\n" "Language-Team: <>\n" @@ -25,31 +25,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "ГеометриÑ" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Повишение" @@ -83,7 +83,7 @@ msgid "Bit depth" msgstr "Дълбочина на бита" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Режим на Ñканиране" @@ -124,7 +124,7 @@ msgid "Bottom-right y" msgstr "Долен деÑен y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Ð ÐµÐ·Ð¾Ð»ÑŽÑ†Ð¸Ñ Ð½Ð° Ñканиране" @@ -279,7 +279,7 @@ msgstr "Име на файла" msgid "Halftone pattern size" msgstr "Размер на Ð¿Ð¾Ð»ÑƒÑ‚Ð¾Ð½Ð¾Ð²Ð¸Ñ Ð´ÐµÑен" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Полутонов деÑен" @@ -289,10 +289,10 @@ msgstr "Полутонов деÑен" msgid "Bind X and Y resolution" msgstr "Вържи резолюциÑта по X и Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Ðегатив" @@ -413,9 +413,9 @@ msgid "Lamp off at exit" msgstr "Изкл. лампа при изход" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "ÐžÐ¿Ñ†Ð¸Ñ Ñамо за четене, коÑто указва колко опции поддържа дадено " @@ -744,8 +744,8 @@ msgid "Analog gamma-correction for blue" msgstr "Ðналогова гама-ÐºÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð·Ð° Ñиньо" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Загрей лампата преди Ñканиране" #: include/sane/saneopts.h:417 @@ -895,7 +895,7 @@ msgstr "ÐÑма поддръжка на полутонове" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -988,10 +988,10 @@ msgid "Only perform shading-correction" msgstr "Извърши Ñамо ÐºÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð° отÑенките" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Ðко това е позволено, Ñамо ÐºÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð° отÑенките Ñе извършва през " @@ -1022,80 +1022,40 @@ msgstr "ДуплекÑно" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Калибрирай Ñкенера" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Задължителна ÐºÐ°Ð»Ð¸Ð±Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¸ Ñканиране" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Сканиране в Ñива Ñкала" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Ðаправи Ñканиране в Ñива Ñкала, не цветно" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Ðналогово увеличение" - -#: backend/canon630u.c:307 -#, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Повиши или намали аналоговото увеличение на CCD матрицата" - -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "ÐšÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð° гамата" - -#: backend/canon630u.c:348 -#, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Избира кривата на коригираната гама" +msgid "Correction according to transparency ratio" +msgstr "" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Raw" +msgid "Correction according to film type" msgstr "" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 #: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format msgid "Fine color" msgstr "" -#: backend/canon.c:169 +#: backend/canon-sane.c:776 backend/canon.c:176 #, fuzzy, no-c-format -msgid "No transparency correction" -msgstr "Цветова корекциÑ." - -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" +msgid "Negatives" +msgstr "Ðегатив" -#: backend/canon.c:171 backend/canon-sane.c:674 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format -msgid "Correction according to transparency ratio" +msgid "Raw" msgstr "" -#: backend/canon.c:176 backend/canon-sane.c:776 +#: backend/canon.c:169 #, fuzzy, no-c-format -msgid "Negatives" -msgstr "Ðегатив" +msgid "No transparency correction" +msgstr "Цветова корекциÑ." #: backend/canon.c:176 #, fuzzy, no-c-format @@ -1230,9 +1190,9 @@ msgid "invalid bit IDENTIFY message" msgstr "" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" -msgstr "" +#, fuzzy, no-c-format +msgid "option not correct" +msgstr "ÐÑма поддръжка на полутонове" #: backend/canon.c:474 #, no-c-format @@ -1519,133 +1479,184 @@ msgstr "Тип екран (film)" msgid "Select the film type" msgstr "Избира полутона" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Калибрирай Ñкенера" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Задължителна ÐºÐ°Ð»Ð¸Ð±Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¸ Ñканиране" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Сканиране в Ñива Ñкала" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Ðаправи Ñканиране в Ñива Ñкала, не цветно" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Ðналогово увеличение" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Повиши или намали аналоговото увеличение на CCD матрицата" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "ÐšÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð° гамата" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Избира кривата на коригираната гама" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Flatbed" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "ADF" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, fuzzy, no-c-format msgid "ADF Duplex" msgstr "ДуплекÑно" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Печат" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "ДуплекÑно" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Червено" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Зелено" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Синьо" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Повишение" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Повишение" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Повишение" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ðищо" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "СимплекÑно" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "ДуплекÑно" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "ПрозрачноÑÑ‚" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Ðвтоматично подаване на документи" @@ -1757,7 +1768,7 @@ msgstr "МаÑтиленоÑтруйни принтери" msgid "CRT monitors" msgstr "CRT монитори" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1821,8 +1832,9 @@ msgstr "A4" msgid "Max" msgstr "МакÑ." -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1995,17 +2007,17 @@ msgstr "ÐžÐ¿Ñ€ÐµÐ´ÐµÐ»Ñ Ñ„Ð°ÐºÑ‚Ð¾Ñ€Ð° на увеличение за ÑкенРmsgid "Quick format" msgstr "Бързо форматиране" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Оборудване по избор" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Извади" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Извади лиÑта от ADF" @@ -2020,12 +2032,14 @@ msgstr "Ðвто изваждане" msgid "Eject document after scanning" msgstr "Извади документа Ñлед Ñканиране" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2076,14 +2090,14 @@ msgstr "" "След изпращане на команда за Ñканиране, изчакай, докато бутонът на " "Ñкенера не е натиÑнат, преди да започнеш Ñамото Ñканиране." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2106,492 +2120,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "По потребителÑка дефинициÑ" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Извади лиÑта от ADF" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Без корекциÑ" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "ÐšÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð° аналоговата гама" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Вкл." -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Изкл." -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Dither" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "РазÑейка на грешките" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Степен на бÑлото" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Степен на черното" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "Кондиционално" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Хоризонтално" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Хоризонтално" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Хоризонтално" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "8x8 вертикална черта" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "8x8 вертикална черта" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Печат" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Полутон" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Груба калибрациÑ" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Подчертаване на образа" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "ÐаÑитеноÑÑ‚" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "ПозволÑва автоматично определÑне на прага за lineart Ñканиране." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Огледален образ" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Прави хоризонтален огледален образ." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Степен на бÑлото - Ñиньо" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "ÐаглаÑÑ Ñтепента на червено" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Цветно Lineart" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Изглаждане" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "СтойноÑÑ‚ на гамата" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Праг" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Праг" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Редуциране на шума" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Без корекциÑ" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Без корекциÑ" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Режим на захранване" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Обнови опциите" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Без корекциÑ" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Dropout" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Режим на захранване" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2599,65 +2633,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Изкл. лампа" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "ОфÑет - Ñиньо" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "ОфÑет - зелено" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "ОфÑет - зелено" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "ОфÑет - Ñиньо" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "ÐаглаÑÑ Ð¾Ñ„Ñета на ÑÐ¸Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2666,507 +2700,514 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "ДуплекÑно" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Обнови опциите" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Редуциране на шума" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "От хартиÑ" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "От хартиÑ" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "От хартиÑ" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "От хартиÑ" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Ръчен предв. фокуÑ" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Ръчен предв. фокуÑ" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "Ð ÐµÐ·Ð¾Ð»ÑŽÑ†Ð¸Ñ Ð½Ð° Ñканиране" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Степен на бÑлото" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Интензитет - червено" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "ДуплекÑно" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, fuzzy, no-c-format msgid "Extras" msgstr "ЕкÑтра бързо" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, fuzzy, no-c-format msgid "Disable interpolation" msgstr "Забрани връщане на главата" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Цветно Lineart" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "КалибрациÑ" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Дефинирай режима на калибрациÑ" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Режим калибрациÑ" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, fuzzy, no-c-format msgid "Lamp off time" msgstr "Изкл. лампа" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " "of 0 means, that the lamp won't be turned off." msgstr "" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Груба калибрациÑ" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "Изчакай натиÑкане на бутона" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "Изчакай натиÑкане на бутона" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Изчакай натиÑкане на бутона" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Груба калибрациÑ" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Задължителна ÐºÐ°Ð»Ð¸Ð±Ñ€Ð°Ñ†Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¸ Ñканиране" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Калибриране" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Започване на калибрациÑта." -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Груба калибрациÑ" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Режим калибрациÑ" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Груба калибрациÑ" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "ОфÑет - зелено" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Ðдаптиране на прозрачноÑтта" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Ðдаптиране на прозрачноÑтта" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3267,6 +3308,310 @@ msgstr "СтойноÑÑ‚ на гамата" msgid "Sets the gamma value of all channels." msgstr "ÐаглаÑÑ ÑтойноÑтта на гамата за вÑички канали." +#: backend/hp-option.c:2987 +#, fuzzy, no-c-format +msgid "Advanced Options" +msgstr "Обнови опциите" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "8Ñ…8 грубо" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Име на файла" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "8Ñ…8 по избор" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Ðвто" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, fuzzy, no-c-format +msgid "Pass-through" +msgstr "Pass-through" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC Ñиво" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA Ñиво" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "По-бавно" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Ðормално" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "По-бързо" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "ЕкÑтра бързо" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-пикÑелно" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-пикÑелно" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-пикÑелно" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Печат" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Солидно бÑло" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Тип филм" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Кондиционално" + +#: backend/hp-option.c:3417 +#, fuzzy, no-c-format +msgid "Experiment" +msgstr "Време за екÑпонациÑ" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "ИзоÑÑ‚Ñ€Ñне" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "ÐаглаÑи ÑтойноÑтта за изоÑÑ‚Ñ€Ñне." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Ðвтоматичен праг" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "ПозволÑва автоматично определÑне на прага за lineart Ñканиране." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Избира полутона" + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Отзареждане на медиÑта Ñлед Ñканиране." + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Отзарежда медиÑта Ñлед Ñканиране." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Смени документа" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Смени документа." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Отзареди" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Отзареди документа." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Започване на калибрациÑта." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "МедиÑ" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "ÐаглаÑи типа медиÑ." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Време за екÑпонациÑ" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"По-дългото време на екÑÐ¿Ð¾Ð½Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñва на Ñкенера да Ñъбере повече " +"Ñветлина. Предложената употреба е 175% за разпечатки, 150% за нормални " +"Ñлайдове и \"Ðегатив\" за негативен филм. За тъмни (подекÑпонирани) " +"Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ да завишите тази ÑтойноÑÑ‚." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Цветна матрица" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "ÐаглаÑÑ Ñ†Ð²ÐµÑ‚Ð½Ð°Ñ‚Ð° матрица на Ñкенера." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Цветна матрица по избор." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Едноцветна матрица" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Цветна матрица по избор за Ñканиране в Ñива Ñкала." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Огледало хоризонтално" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Прави хоризонтален огледален образ." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Огледало вертикално" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Прави вертикален огледален образ" + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Обнови опциите" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Обнови опциите." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8-битово извеждане." + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Вътрешно използвай по-голÑма дълбочина от оÑем бита, но извеждай Ñамо " +"оÑем бита." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Изчакай бутона" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Изчакай за натиÑкане на бутона преди Ñканиране." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Изключи лампата" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Изключва лампата на Ñкенера" + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3277,12 +3622,6 @@ msgstr "ГеометриÑ" msgid "Scan Mode Group" msgstr "Режим на Ñканиране" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Солидно бÑло" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3290,12 +3629,12 @@ msgstr "Режим на Ñканиране" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3476,11 +3815,6 @@ msgstr "Включва/изключва лампата." msgid "Calibrates for black and white level." msgstr "" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3591,299 +3925,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, fuzzy, no-c-format -msgid "Advanced Options" -msgstr "Обнови опциите" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "8Ñ…8 грубо" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Име на файла" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "8Ñ…8 по избор" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Ðвто" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, fuzzy, no-c-format -msgid "Pass-through" -msgstr "Pass-through" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC Ñиво" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA Ñиво" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "По-бавно" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Ðормално" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "По-бързо" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "ЕкÑтра бързо" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-пикÑелно" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-пикÑелно" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-пикÑелно" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Печат" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Тип филм" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Кондиционално" - -#: backend/hp-option.c:3417 -#, fuzzy, no-c-format -msgid "Experiment" -msgstr "Време за екÑпонациÑ" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "ИзоÑÑ‚Ñ€Ñне" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "ÐаглаÑи ÑтойноÑтта за изоÑÑ‚Ñ€Ñне." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Ðвтоматичен праг" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "ПозволÑва автоматично определÑне на прага за lineart Ñканиране." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Избира полутона" - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Отзареждане на медиÑта Ñлед Ñканиране." - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Отзарежда медиÑта Ñлед Ñканиране." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Смени документа" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Смени документа." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Отзареди" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Отзареди документа." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Започване на калибрациÑта." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "МедиÑ" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "ÐаглаÑи типа медиÑ." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Време за екÑпонациÑ" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"По-дългото време на екÑÐ¿Ð¾Ð½Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð·Ð²Ð¾Ð»Ñва на Ñкенера да Ñъбере повече " -"Ñветлина. Предложената употреба е 175% за разпечатки, 150% за нормални " -"Ñлайдове и \"Ðегатив\" за негативен филм. За тъмни (подекÑпонирани) " -"Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚Ðµ да завишите тази ÑтойноÑÑ‚." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Цветна матрица" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "ÐаглаÑÑ Ñ†Ð²ÐµÑ‚Ð½Ð°Ñ‚Ð° матрица на Ñкенера." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Цветна матрица по избор." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Едноцветна матрица" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Цветна матрица по избор за Ñканиране в Ñива Ñкала." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Огледало хоризонтално" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Прави хоризонтален огледален образ." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Огледало вертикално" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Прави вертикален огледален образ" - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Обнови опциите" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Обнови опциите." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8-битово извеждане." - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Вътрешно използвай по-голÑма дълбочина от оÑем бита, но извеждай Ñамо " -"оÑем бита." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Изчакай бутона" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Изчакай за натиÑкане на бутона преди Ñканиране." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Изключи лампата" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Изключва лампата на Ñкенера" - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3982,7 +4023,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4150,9 +4191,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Lineart" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4281,7 +4322,7 @@ msgstr "ÐаглаÑÑ Ð¿Ð¾Ð´Ñ‡ÐµÑ€Ñ‚Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ на образа" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Гама" @@ -4348,11 +4389,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4384,12 +4425,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Принтиране Ñ Ð²Ð¸Ñока гъÑтота" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Принтиране Ñ Ð½Ð¸Ñка гъÑтота" #: backend/kvs40xx_opt.c:243 @@ -4412,6 +4453,13 @@ msgstr "Ðормално" msgid "Enhanced mode" msgstr "Повишение" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4471,7 +4519,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4506,12 +4554,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4521,13 +4569,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Огледален образ" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4564,52 +4612,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 вертикална черта" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Увеличение" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "ÐаÑтройки по увеличение на цветните канали" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Увеличение - Ñиво" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "ÐаглаÑÑ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ðµ на ÑÐ¸Ð²Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Увеличение - червено" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "ÐаглаÑÑ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ðµ на Ñ‡ÐµÑ€Ð²ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Увеличение - зелено" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "ÐаглаÑÑ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ðµ на Ð·ÐµÐ»ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Увеличение - Ñиньо" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "ÐаглаÑÑ ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ðµ на ÑÐ¸Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" @@ -4695,7 +4743,7 @@ msgstr "Една Ñтраница" msgid "All pages" msgstr "Ð’Ñички Ñтраници" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, fuzzy, no-c-format msgid "sheetfed scanner" msgstr "Ñкенер Ñ sheetfeed" @@ -5198,39 +5246,44 @@ msgstr "" "ЗагрÑвай, докато ÑркоÑтта на лампата е поÑтоÑнна, вмеÑто да наÑтоÑваш за " "40 Ñекундно загрÑване." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Груба калибрациÑ" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Ðегативен филм" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Ðегатив" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5238,40 +5291,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5360,7 +5413,7 @@ msgstr "Ðналогова гама - червено" msgid "Red gain value of the AFE" msgstr "" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "ОфÑет - червено" @@ -5635,7 +5688,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Вкл. лампа" @@ -5645,12 +5698,12 @@ msgstr "Вкл. лампа" msgid "Turn on scanner lamp" msgstr "Включи лампата на Ñкенера" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Изкл. лампа" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Изключва лампата на Ñкенера" @@ -5795,13 +5848,13 @@ msgid "Focus point" msgstr "ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð½Ð° фокуÑа" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Цветни линии на четене" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Линии на четене по Ñива Ñкала" #: backend/stv680.c:974 @@ -6455,52 +6508,52 @@ msgstr "Режим калибрациÑ" msgid "Define calibration mode" msgstr "Дефинирай режима на калибрациÑ" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Включва/изключва лампата" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA вкл." -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Включва/изключва UTA" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "ОфÑет" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "ÐаÑтройки по офÑета на цветните канали" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "ОфÑет - Ñиво" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "ÐаглаÑÑ Ð¾Ñ„Ñета на ÑÐ¸Ð²Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "ÐаглаÑÑ Ð¾Ñ„Ñета на Ñ‡ÐµÑ€Ð²ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "ÐаглаÑÑ Ð¾Ñ„Ñета на Ð·ÐµÐ»ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "ÐаглаÑÑ Ð¾Ñ„Ñета на ÑÐ¸Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»" @@ -1,13 +1,13 @@ -# Copyright (C) 2018 The SANE developers +# Copyright (C) 2018-2020 The SANE developers # This file is distributed under the same license as the sane-backends package. # -# Antoni Bella Pérez <antonibella5@yahoo.com>, 2018. +# Antoni Bella Pérez <antonibella5@yahoo.com>, 2018, 2020. msgid "" msgstr "" -"Project-Id-Version: sane-backends 1.0.27git\n" +"Project-Id-Version: sane-backends 1.0.29\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" -"PO-Revision-Date: 2018-09-10 00:37+0100\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" +"PO-Revision-Date: 2020-01-17 11:40+0100\n" "Last-Translator: Antoni Bella Pérez <antonibella5@yahoo.com>\n" "Language-Team: Catalan <kde-i18n-ca@kde.org>\n" "Language: ca\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Lokalize 2.0\n" +"X-Generator: Lokalize 20.03.70\n" #: include/sane/saneopts.h:154 #, no-c-format @@ -28,31 +28,31 @@ msgid "Standard" msgstr "Està ndard" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometria" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Millora" @@ -86,7 +86,7 @@ msgid "Bit depth" msgstr "Bits de profunditat" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Mode d'escaneig" @@ -127,7 +127,7 @@ msgid "Bottom-right y" msgstr "A baix-dreta Y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Resolució de l'escà ner" @@ -282,7 +282,7 @@ msgstr "Nom de fitxer" msgid "Halftone pattern size" msgstr "Mida del patró per al semi to" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Patró per al semi to" @@ -292,10 +292,10 @@ msgstr "Patró per al semi to" msgid "Bind X and Y resolution" msgstr "Enllaça les resolucions X i Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negatiu" @@ -418,7 +418,7 @@ msgstr "Apaga la là mpada en sortir" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Opció de només lectura que especifica quantes opcions admet un " @@ -769,7 +769,7 @@ msgstr "Correcció de la gamma analògica per al blau" #: include/sane/saneopts.h:415 #, no-c-format -msgid "Warmup lamp before scanning" +msgid "Warm up lamp before scanning" msgstr "Escalfament de la là mpada abans d'escanejar" #: include/sane/saneopts.h:417 @@ -919,8 +919,8 @@ msgstr "Operació no admesa" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" -msgstr "L'operació ha estat cancel·lada" +msgid "Operation was canceled" +msgstr "S'ha cancel·lat l'operació" #: backend/sane_strstatus.c:68 #, no-c-format @@ -1016,7 +1016,7 @@ msgstr "Realitza només la correcció de les ombres" #, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Si està habilitada, només es realitzarà la correcció de les ombres " @@ -1047,84 +1047,43 @@ msgstr "Escaneja a dues cares" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "L'escanejat de les dues cares proporciona un escanejat de l'anvers i el " "revers del document" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibratge de l'escà ner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Força el calibratge de l'escà ner abans de l'escaneig" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Escaneja en escala de grisos" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Fes un escaneig en escala de grisos en lloc d'en color" +msgid "Correction according to transparency ratio" +msgstr "Correcció d'acord amb la relació de transparència" -#: backend/canon630u.c:306 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Analog Gain" -msgstr "Guany analògic" - -#: backend/canon630u.c:307 -#, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Augmenta o disminueix el guany analògic per a la matriu del CCD" +msgid "Correction according to film type" +msgstr "Correcció d'acord amb el tipus de pel·lÃcula" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Correcció de la gamma" +msgid "Fine color" +msgstr "Color fi" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "" -"Selecciona la corba de transferència per a la correcció de la gamma" +msgid "Negatives" +msgstr "Negatius" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "En brut" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Color fi" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Sense correcció de la transparència" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Correcció d'acord amb el tipus de pel·lÃcula" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Correcció d'acord amb la relació de transparència" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negatius" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1261,8 +1220,8 @@ msgstr "Missatge «IDENTIFY» del bit no và lid" #: backend/canon.c:460 #, no-c-format -msgid "option not connect" -msgstr "L'opció no connectar" +msgid "option not correct" +msgstr "Opció no correcta" #: backend/canon.c:474 #, no-c-format @@ -1560,135 +1519,187 @@ msgstr "Selecciona el tipus de pel·lÃcula" msgid "Select the film type" msgstr "Selecciona el tipus de pel·lÃcula" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibratge de l'escà ner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Força el calibratge de l'escà ner abans de l'escaneig" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Escaneja en escala de grisos" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Fes un escaneig en escala de grisos en lloc d'en color" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Guany analògic" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Augmenta o disminueix el guany analògic per a la matriu del CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Correcció de la gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "" +"Selecciona la corba de transferència per a la correcció de la gamma" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "De superfÃcie plana" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "ADF per a l'anvers" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "ADF per al revers" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "ADF per a les dues cares" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "Targeta per a l'anvers" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "Targeta per al revers" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "Targeta per a les dues cares" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Vermell" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Verd" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Blau" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Vermell realçat" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Verd realçat" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Blau realçat" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Cap" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "El percentatge per a saltar el blanc del programari" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" "Sol·licita al controlador que descarti les pà gines amb un percentatge " "baix de pÃxels foscos" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Una cara" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Dues cares" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Unitat per a la transparència" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Alimentador automà tic de documents" @@ -1800,7 +1811,7 @@ msgstr "Impressores d'injecció de tinta" msgid "CRT monitors" msgstr "Monitors CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1864,8 +1875,9 @@ msgstr "A4" msgid "Max" msgstr "Mà x" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2039,17 +2051,17 @@ msgstr "Defineix el factor de zoom que usarà l'escà ner" msgid "Quick format" msgstr "Format rà pid" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Equipament opcional" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Expulsa" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Expulsa el full de l'ADF" @@ -2064,12 +2076,14 @@ msgstr "Expulsa automà ticament" msgid "Eject document after scanning" msgstr "Expulsa el document després de l'escaneig" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Mode ADF" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Seleccionar el mode de l'ADF (una cara/dues cares)" @@ -2121,17 +2135,17 @@ msgstr "" "Després d'enviar l'ordre d'escaneig, s'ha d'esperar fins que es premi el " "botó de l'escà ner per iniciar realment el procés d'escaneig." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Infraroigs" - # Nota: https://github.com/Scan-o-Matic/scanomatic/wiki/Installing-scanners -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "TPU8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Infraroigs" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2153,243 +2167,263 @@ msgstr "Incorpora el perfil CCT" msgid "User defined CCT profile" msgstr "Perfil CCT definit per l'usuari" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "Carrega" + +#: backend/epsonds.c:751 +#, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Carrega un full a l'ADF" + +#: backend/epsonds.c:771 +#, no-c-format +msgid "ADF Skew Correction" +msgstr "Correcció de la inclinació a l'ADF" + +#: backend/epsonds.c:773 +#, no-c-format +msgid "Enables ADF skew correction" +msgstr "Habilita la correcció de la inclinació a l'ADF" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Actiu" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Inactiu" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Tramat" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Difusió" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Blanc" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Negre" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Continua" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Atura" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10 mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15 mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20 mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horitzontal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Horitzontal en negre" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Horitzontal estreta" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertical" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Vertical en negre" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "De dalt a baix" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "De baix a dalt" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Anvers" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Revers" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "Exponent de la funció gamma" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "Canvia la intensitat dels semi tons" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "RIF" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "Format d'imatge inversa" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "Tipus de semi to" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "Controla el tipus de filtre del semi to" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "Controla el patró del filtre del semi to" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "Contorn" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, no-c-format msgid "Perform outline extraction" msgstr "Realitza l'extracció del contorn" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "Èmfasi" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "Negatiu per a suavitzar o positiu per aguditzar la imatge" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, no-c-format msgid "Separation" msgstr "Separació" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "Habilita la separació automà tica de les imatges i el text" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "Emmiralla" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "Reflecteix horitzontalment la imatge de sortida" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, no-c-format msgid "White level follower" msgstr "Seguidor del nivell de blanc" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, no-c-format msgid "Control white level follower" msgstr "Controla el seguidor del nivell de blanc" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, no-c-format msgid "BP filter" msgstr "Filtre per al bolÃgraf" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "Millora la qualitat del text del bolÃgraf amb alta resolució" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Suavitzat" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "Habilita el suavitzat per a millorar l'OCR" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, no-c-format msgid "Gamma curve" msgstr "Corba amb interval" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" "La corba amb interval, des de la llum a la foscor, però la part superior " "de les dues podria no funcionar" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Corba del llindar" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" @@ -2397,116 +2431,116 @@ msgstr "" "La corba del llindar, des de la llum a la foscor, però la part superior " "de les dues podria no ser lineal" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "Llindar al blanc" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" "Estableix els pÃxels iguals al llindar al blanc en comptes de negre" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "Eliminació del soroll" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "Matriu 5x5" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "Elimina el soroll quadrat de 5 pÃxels" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "Matriu 4x4" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "Elimina el soroll quadrat de 4 pÃxels" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "Matriu 3x3" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "Elimina el soroll quadrat de 3 pÃxels" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "Matriu 2x2" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "Elimina el soroll quadrat de 2 pÃxels" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "Varià ncia" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" "Estableix la velocitat de la varià ncia SDTC (sensibilitat), 0 és igual " "que 127" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, no-c-format msgid "Auto width detection" msgstr "Detecció automà tica de l'amplada" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" "L'escà ner detectarà els costats del paper. Pot reduir la velocitat de " "l'escaneig." -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, no-c-format msgid "Auto length detection" msgstr "Detecció automà tica de la llargada" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" "L'escà ner detectarà la vora inferior del paper. Pot confondre alguns " "frontals." -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "Compressió" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" "Habilita les dades comprimides. Pot fer fallar el vostre programa de " "frontal" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "Argument per a la compressió" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " @@ -2515,110 +2549,110 @@ msgstr "" "Nivell de la compressió JPEG. 1 és un fitxer petit, 7 és un fitxer gran. " "0 (predeterminat) és igual que 4" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "Acció per a la doble alimentació" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "Acció per a després de l'error de doble alimentació" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "Inclinació per la doble alimentació" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "Habilita l'error de doble alimentació que causa inclinació" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "Gruix del paper per la doble alimentació" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Habilita l'error de doble alimentació causat pel gruix del paper" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "Longitud del paper causant doble alimentació" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" "Habilita l'error de doble alimentació causat per la longitud del paper" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "Diferència en la longitud per a causar doble alimentació" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" "Diferència en la longitud de la pà gina per activar l'error de doble " "alimentació" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "El mode recuperació causa doble alimentació" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" "Sol·licita a l'escà ner que l'alimentador recuperi el paper en embussar-se" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "Protecció del paper" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "Pregunta a l'escà ner per a predir les embussades a l'ADF" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, no-c-format msgid "Advanced paper protection" msgstr "Protecció avançada del paper" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" "Pregunta a l'escà ner per a predir les embussades a l'ADF usant sensors " "millorats" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, no-c-format msgid "Staple detection" msgstr "Detecció de les grapes" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" "Pregunta a l'escà ner per a detectar les embussades a l'ADF causades per " "les grapes" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "Color de fons" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" @@ -2626,12 +2660,12 @@ msgstr "" "Estableix un color de fons per a l'escaneig. Pot entrar en conflicte amb " "l'opció de sobreexploració" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "Descarta el color" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " @@ -2640,34 +2674,34 @@ msgstr "" "Els escà ners d'una sola passada només usen un color durant l'escaneig " "amb gris o binari, útil per a paper amb colors o tinta" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "Mode de memòria intermèdia" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" "Sol·licita a l'escà ner que llegeixi les pà gines rà pidament des de l'ADF " "a la memòria interna" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "Preselecciona" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "Sol·licita a l'escà ner que agafi la pà gina següent des de l'ADF" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "Sobreexploració" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2679,12 +2713,12 @@ msgstr "" "de la mida del paper, per a permetre recollir els costats restants. Pot " "entrar en conflicte amb l'opció Color de fons" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "Temporitzador de suspensió" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" @@ -2692,12 +2726,12 @@ msgstr "" "Temps en minuts fins que la font d'alimentació interna canviarà al mode " "de suspensió" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "Temporitzador per apagar" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " @@ -2707,42 +2741,42 @@ msgstr "" "S'arrodonirà fins als 15 minuts més propers. Zero significa que no " "s'apagarà mai." -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, no-c-format msgid "Duplex offset" msgstr "Desplaçament de la doble cara" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "Ajusta el desplaçament per a l'anvers/revers" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Desplaçament del verd" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, no-c-format msgid "Adjust green/red offset" msgstr "Ajusta el desplaçament del verd/vermell" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Desplaçament del blau" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "Ajusta el desplaçament del blau/vermell" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "Memòria baixa" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2756,12 +2790,12 @@ msgstr "" "es pot usar per a determinar la imatge correcta. Aquesta opció només " "s'hauria d'usar amb el programari de frontal personalitzat." -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, no-c-format msgid "Duplex side" msgstr "Cara per a les dues cares" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " @@ -2770,58 +2804,58 @@ msgstr "" "Indica a quina cara (0=anvers, 1=revers) en un escaneig de dues cares " "retornarà la següent crida al «sane_read()»." -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "Desinclina i escapça per maquinari" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" "Sol·licita a l'escà ner que giri i escapci les pà gines de forma digital." -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Desinclina per programari" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" "Sol·licita al controlador que giri les pà gines inclinades de forma " "digital." -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Dià metre per eliminar els pics per programari" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" "Dià metre mà xim dels punts solitaris per eliminar-los de l'escaneig." -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "Escapça per programari" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" "Sol·licita al controlador que elimini la vora de les pà gines de forma " "digital." -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "Atura en cancel·lar" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." @@ -2829,108 +2863,108 @@ msgstr "" "Sol·licita al controlador que aturi l'alimentador de paper en lloc " "d'expulsar-lo durant una cancel·lació." -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, no-c-format msgid "Endorser Options" msgstr "Opcions per a l'aprovador" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "Controls per a la unitat aprovadora" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "Aprovador" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "Habilita la unitat aprovadora" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "Bits de l'aprovació" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "Determina el valor mà xim del comptador de l'aprovació." -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "Valor de l'aprovació" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "Valor inicial del comptador de l'aprovació." -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "Pas de l'aprovació" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" "Canvia el valor del comptador de l'aprovació en aquest tant per a cada " "pà gina." -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "Aprovació Y" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" "Desplaçament de la impressió de l'aprovador des de la part superior del " "paper." -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "Tipus de lletra per a l'aprovador" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "El tipus de lletra amb el que imprimirà l'aprovador." -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, no-c-format msgid "Endorser direction" msgstr "Direcció de l'aprovador" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "Direcció amb la qual imprimirà l'aprovador." -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "Costat de l'aprovador" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" "El costat de la impressió de l'aprovador, requereix maquinari per " "canviar-lo" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "Cadena de l'aprovador" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " @@ -2939,220 +2973,206 @@ msgstr "" "Format d'impressió alfanumèric de l'aprovador. %05ud o %08ud al final " "serà substituït pel valor del comptador." -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "Vora superior" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "El paper s'ha retirat parcialment dins de l'ADF" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "Paper A3" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "S'ha detectat un paper A3" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "Paper B4" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "S'ha detectat un paper B4" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "Paper A4" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "S'ha detectat un paper A4" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "Paper B5" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "S'ha detectat un paper B5" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "OMR o DF" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" "S'ha detectat una OMR (reconeixement de marca òptica) o alimentació de " "doble cara" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "Estalvi d'energia" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "Escà ner en el mode estalvi d'energia" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "Alimentació manual" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "S'ha seleccionat una alimentació manual" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "Funció" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "Funció carà cter a la pantalla" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "Tinta baixa" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "La impressora s'està executant amb la tinta baixa" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "Alimentació de doble cara" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "S'ha detectat una alimentació de doble cara" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "Codi d'error" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "Codi d'error del maquinari" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "Angle d'inclinació" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "Requereix un fons negre per escanejar" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "Tinta restant" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, no-c-format msgid "Imprinter ink level" msgstr "Nivell de tinta de la impressora" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, no-c-format msgid "Density" msgstr "Densitat" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "Marcador de la densitat" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, no-c-format msgid "Duplex switch" msgstr "Commuta a doble cara" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" "Sol·licita al dorsal que elimini la vora de les pà gines de forma digital" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" "Sol·licita al controlador que descarti les pà gines amb un nombre baix de " "pÃxels foscos" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "Treu el gir per programari" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" "Sol·licita al controlador que detecti i corregeixi el gir de 90 graus de " "la imatge" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extres" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" "La corba dinà mica del llindar, des de la llum a la foscor, normalment de " "50 a 65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Inhabilita l'art lineal dinà mic" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"Inhabilita l'ús d'un algorisme adaptatiu per programari que genera art " -"lineal en comptes de per maquinari." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Inhabilita la interpolació" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3162,33 +3182,33 @@ msgstr "" "més petita que la vertical, això inhabilitarà la interpolació " "horitzontal." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, no-c-format msgid "Color filter" msgstr "Filtre de color" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "Quan s'usa gris o art lineal, aquesta opció seleccionarà el color a usar." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, no-c-format msgid "Calibration file" msgstr "Fitxer de calibratge" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, no-c-format msgid "Specify the calibration file to use" msgstr "Especifica el fitxer de calibratge a usar" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, no-c-format msgid "Calibration cache expiration time" msgstr "Temps de caducitat per a la memòria cau del calibratge" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " @@ -3198,12 +3218,12 @@ msgstr "" "memòria cau. Un valor de 0 indicarà que no s'usarà la memòria cau. Un " "valor negatiu indicarà que la memòria cau no caducarà mai." -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Temps per apagar la là mpada" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3212,89 +3232,111 @@ msgstr "" "La llum s'apagarà després del temps determinat (en minuts). Un valor de " "0 indicarà que no s'apagarà la là mpada." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "Apaga la là mpada durant l'escaneig" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "La llum s'apagarà durant l'escaneig." -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Botó de fitxer" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Botó OCR" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Botó d'encesa" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, no-c-format msgid "Extra button" msgstr "Botó extra" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Necessita calibratge" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "L'escà ner necessita calibratge per als ajustaments actuals" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Botons" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Calibratge" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Comença el calibratge emprant un full especial" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Neteja el calibratge" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Neteja la memòria cau del calibratge" -#: backend/genesys.cc:5769 -#, fuzzy, no-c-format +#: backend/genesys/genesys.cpp:4476 +#, no-c-format msgid "Force calibration" -msgstr "Calibratge tosc" +msgstr "Força el calibratge" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" +"Força el calibratge ignorant-ho tot i qualsevol memòria cau del " +"calibratge" + +#: backend/genesys/genesys.cpp:4487 +#, no-c-format +msgid "Ignore internal offsets" +msgstr "Ignora els desplaçaments interns" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" +"Adquireix la imatge, incloses les à rees de calibratge intern de l'escà ner" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Adaptador de transparència" +#: backend/genesys/genesys.h:80 +#, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Adaptador infraroig de transparència" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3404,6 +3446,314 @@ msgstr "Valor de la gamma" msgid "Sets the gamma value of all channels." msgstr "Estableix el valor de la gamma de tots els canals." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Opcions avançades" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Tosc" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fina" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "A mida" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Auto" + +# Nota: https://ca.wikipedia.org/wiki/NTSC +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "RGB del NTSC" + +# Nota: https://support.hp.com/gb-en/document/c01275842 +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "RGB amb el XPA" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Passa a través" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "Gris del NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Gris amb el XPA" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lent" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rà pid" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Extrarà pid" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2 pÃxels" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4 pÃxels" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8 pÃxels" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Imprimeix" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositiva" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Tira de pel·lÃcules" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Condicional" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experimental" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Aguditzant" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Estableix el valor de l'agudització." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Llindar automà tic" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Habilita la determinació automà tica del llindar pels escaneigs amb art " +"lineal." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Selecciona el filtre de suavitzat." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Descarrega el suport després de l'escaneig" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Descarrega el suport després d'un escaneig." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Canvia el document" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Canvia el document." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Descarrega" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Descarrega el document." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Inicia el procés de calibratge." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Suport" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Estableix el tipus de suport." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Temps d'exposició" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Un temps d'exposició més llarg permet que l'escà ner recopili més llum. " +"L'ús aconsellat és el 175% per a impressions, el 150% per a diapositives " +"normals i «Negatiu» per a pel·lÃcules en negatiu. Per a imatges fosques " +"(sota exposades), podeu augmentar aquest valor." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matriu de color" + +#: backend/hp-option.h:121 +#, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Estableix la matriu de color de l'escà ner." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Matriu de color a mida." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Matriu de color monocrom" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Matriu de color a mida pels escaneigs en escala de grisos." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Emmiralla horitzontalment" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Emmiralla horitzontalment la imatge." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Emmiralla verticalment" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Emmiralla verticalment la imatge." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Opcions per a l'actualització" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Opcions per a l'actualització." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "Sortida de 8 bits" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Usa internament una profunditat de bits més gran que vuit, però a la " +"sortida usa només vuit bits." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Espera al botó del frontal" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Espera per escanejar que es premi el botó del panell frontal." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Apaga la là mpada" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Apaga la llum de l'escà ner." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3414,12 +3764,6 @@ msgstr "Grup de geometria" msgid "Scan Mode Group" msgstr "Grup de mode d'escaneig" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositiva" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3427,14 +3771,14 @@ msgstr "Model de l'escà ner" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" "Permet comprovar el comportament del dispositiu amb els altres models " "admesos" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "Els colors de la imatge seran invertits" #: backend/hp3900_sane.c:1436 @@ -3624,11 +3968,6 @@ msgstr "Apaga o encén la llum." msgid "Calibrates for black and white level." msgstr "Calibra per al nivell de blanc i negre." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - # Nota: https://en.wikipedia.org/wiki/Tissue_microarray #: backend/hp5590.c:95 #, no-c-format @@ -3676,34 +4015,36 @@ msgid "Get ID of last button pressed (read only)" msgstr "Obtén l'ID de l'últim botó premut (només lectura)" #: backend/hp5590.c:121 -#, fuzzy, no-c-format +#, no-c-format msgid "LCD counter" -msgstr "Comptador d'escaneigs" +msgstr "Comptador LCD" #: backend/hp5590.c:122 -#, fuzzy, no-c-format +#, no-c-format msgid "Get value of LCD counter (read only)" -msgstr "Obtén l'ID de l'últim botó premut (només lectura)" +msgstr "Obtén el valor del comptador LCD (només lectura)" #: backend/hp5590.c:124 -#, fuzzy, no-c-format +#, no-c-format msgid "Color LED indicator" -msgstr "Color per a l'art lineal" +msgstr "Indicador LED del color" #: backend/hp5590.c:125 -#, fuzzy, no-c-format +#, no-c-format msgid "Get value of LED indicator (read only)" -msgstr "Obtén l'ID de l'últim botó premut (només lectura)" +msgstr "Obtén el valor del comptador LED (només lectura)" #: backend/hp5590.c:127 #, no-c-format msgid "Document available in ADF" -msgstr "" +msgstr "Document disponible a l'ADF" #: backend/hp5590.c:128 #, no-c-format msgid "Get state of document-available indicator in ADF (read only)" msgstr "" +"Obtén l'estat de l'indicador de document disponible a l'ADF (només " +"lectura)" #: backend/hp5590.c:130 #, no-c-format @@ -3749,303 +4090,6 @@ msgstr "" "Valor del «color» per al mode d'ompliment al final de les lÃnies. Color " "RGB com a valor r*65536+256*g+b o gris (predeterminat=violeta o gris)" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Opcions avançades" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Tosc" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fina" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "A mida" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Auto" - -# Nota: https://ca.wikipedia.org/wiki/NTSC -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "RGB del NTSC" - -# Nota: https://support.hp.com/gb-en/document/c01275842 -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "RGB amb el XPA" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Passa a través" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "Gris del NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Gris amb el XPA" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lent" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rà pid" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Extrarà pid" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2 pÃxels" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4 pÃxels" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8 pÃxels" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Imprimeix" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Tira de pel·lÃcules" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Condicional" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experimental" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Aguditzant" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Estableix el valor de l'agudització." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Llindar automà tic" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Habilita la determinació automà tica del llindar pels escaneigs amb art " -"lineal." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Selecciona el filtre de suavitzat." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Descarrega el suport després de l'escaneig" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Descarrega el suport després d'un escaneig." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Canvia el document" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Canvia el document." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Descarrega" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Descarrega el document." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Inicia el procés de calibratge." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Suport" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Estableix el tipus de suport." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Temps d'exposició" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Un temps d'exposició més llarg permet que l'escà ner recopili més llum. " -"L'ús aconsellat és el 175% per a impressions, el 150% per a diapositives " -"normals i «Negatiu» per a pel·lÃcules en negatiu. Per a imatges fosques " -"(sota exposades), podeu augmentar aquest valor." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matriu de color" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Estableix la matriu de color dels escà ners." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Matriu de color a mida." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Matriu de color monocrom" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Matriu de color a mida pels escaneigs en escala de grisos." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Emmiralla horitzontalment" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Emmiralla horitzontalment la imatge." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Emmiralla verticalment" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Emmiralla verticalment la imatge." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Opcions per a l'actualització" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Opcions per a l'actualització." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "Sortida de 8 bits" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Usa internament una profunditat de bits més gran que vuit, però a la " -"sortida usa només vuit bits." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Espera al botó del frontal" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Espera per escanejar que es premi el botó del panell frontal." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Apaga la là mpada" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Apaga la llum de l'escà ner." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4144,7 +4188,7 @@ msgid "single" msgstr "individual" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4313,7 +4357,7 @@ msgstr "CRT" #: backend/kvs1025_opt.c:229 #, no-c-format -msgid "linier" +msgid "linear" msgstr "Lineal" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 @@ -4446,7 +4490,7 @@ msgstr "Estableix l'èmfasi de la imatge" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4519,14 +4563,14 @@ msgstr "" "Sol·licita al controlador que elimini la vora de les pà gines de forma " "digital" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" -"El mode control de la longitud és un mode on l'escà ner llegirà fins a la " -"longitud més curta del paper real o la longitud lògica del document." +"El mode control de la longitud fa que l'escà ner llegeixi la longitud més " +"curta real del paper o la longitud lògica del document." #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 #: backend/kvs40xx_opt.c:668 backend/kvs40xx_opt.c:669 @@ -4557,13 +4601,13 @@ msgstr "B4" #: backend/kvs40xx_opt.c:231 #, no-c-format -msgid "High sensivity" -msgstr "Alta sensibilitat" +msgid "High sensitivity" +msgstr "Sensibilitat alta" #: backend/kvs40xx_opt.c:232 #, no-c-format -msgid "Low sensivity" -msgstr "Baixa sensibilitat" +msgid "Low sensitivity" +msgstr "Sensibilitat baixa" #: backend/kvs40xx_opt.c:243 #, no-c-format @@ -4585,6 +4629,15 @@ msgstr "Mode normal" msgid "Enhanced mode" msgstr "Mode millorat" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"El mode control de la longitud fa que l'escà ner llegeixi la longitud més " +"curta real del paper o la longitud lògica del document" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4647,9 +4700,9 @@ msgstr "Compressió del JPEG" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" -"Compressió del JPEG (l'aplicació vostra l'haurà de poder descomprimir)" +"Compressió del JPEG (la vostra aplicació haurà de poder descomprimir)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 #, no-c-format @@ -4683,12 +4736,12 @@ msgstr "Ajustament de la inclinació" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "Atura l'escà ner quan un paper estigui inclinat" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "S'aturarà l'escà ner quan un paper estigui inclinat" #: backend/kvs40xx_opt.c:816 @@ -4698,14 +4751,14 @@ msgstr "Escapça una à rea de la imatge real" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" "L'escà ner detectarà automà ticament l'à rea de la imatge i l'escapçarà " #: backend/kvs40xx_opt.c:827 #, no-c-format -msgid "It is right and left reversing" -msgstr "Torna a la dreta i a l'esquerra" +msgid "Left/right mirror image" +msgstr "Emmiralla la imatge d'esquerra/dreta" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4742,52 +4795,52 @@ msgstr "Bayer 8x8" msgid "8x8 Vertical Line" msgstr "LÃnia vertical 8x8" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Guany" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Ajustaments del guany per als canals de color" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Guany del gris" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Estableix el guany del canal gris" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Guany del vermell" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Estableix el guany del canal vermell" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Guany del verd" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Estableix el guany del canal verd" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Guany del blau" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Estableix el guany del canal blau" @@ -4873,7 +4926,7 @@ msgstr "Una pà gina" msgid "All pages" msgstr "Totes les pà gines" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "escà ner alimentat per fulls" @@ -5396,27 +5449,32 @@ msgstr "" "Escalfa fins que la brillantor de la là mpada sigui constant en comptes " "d'insistir en el temps d'escalfament de 40 segons." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, no-c-format +msgid "Need calibration" +msgstr "Necessita calibratge" + +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "Color en negatiu" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "Gris en negatiu" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "Color de 48 bits" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "Gris de 16 bits" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " @@ -5426,12 +5484,12 @@ msgstr "" "Estableix la font abans del mode i la resolució. Restaura el mode i la " "resolució als valors automà tics." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Escaneig controlat pels botons" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5442,43 +5500,43 @@ msgstr "" "Per a continuar, premeu el botó «Escaneja» (per a MP150) o el botó " "«Color» (per a altres models). Per a cancel·lar, premeu el botó «Gris»." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Actualitza l'estat del botó" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Botó 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Botó 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "Tipus de l'original a escanejar" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "Tipus de l'operació de destinació" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "Temps d'espera per a l'ADF" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" -"Quan s'estableix, l'escà ner cerca el temps d'espera en segons perquè " +"Quan s'estableix, l'escà ner espera el temps especificat en segons perquè " "s'insereixi un document nou a l'alimentador automà tic de documents." #: backend/plustek.c:235 backend/plustek_pp.c:204 backend/u12.c:156 @@ -5566,7 +5624,7 @@ msgstr "Frontal analògic" msgid "Red gain value of the AFE" msgstr "Valor de guany del vermell de l'AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Desplaçament del vermell" @@ -5843,7 +5901,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Aquesta opció reflecteix l'estat d'un botó de l'escà ner." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Encén la là mpada" @@ -5853,12 +5911,12 @@ msgstr "Encén la là mpada" msgid "Turn on scanner lamp" msgstr "Encén la llum de l'escà ner" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Apaga la là mpada" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Apaga la llum de l'escà ner" @@ -6006,12 +6064,12 @@ msgstr "Punt d'enfocament" #: backend/snapscan-options.c:930 #, no-c-format -msgid "Colour lines per read" +msgid "Color lines per read" msgstr "LÃnies de color per a la lectura" #: backend/snapscan-options.c:942 #, no-c-format -msgid "Greyscale lines per read" +msgid "Grayscale lines per read" msgstr "LÃnies en escala de grisos per a la lectura" #: backend/stv680.c:974 @@ -6682,52 +6740,68 @@ msgstr "Mode del calibratge" msgid "Define calibration mode" msgstr "Defineix el mode del calibratge" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Estableix la là mpada a encesa/apagada" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "Activa l'UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Estableix l'UTA a actiu/inactiu" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Desplaçament" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Ajustaments del desplaçament per als canals de color" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Desplaçament del gris" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Estableix el desplaçament del canal gris" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Estableix el desplaçament del canal vermell" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Estableix el desplaçament del canal verd" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Estableix el desplaçament del canal blau" + +#~ msgid "Disable dynamic lineart" +#~ msgstr "Inhabilita l'art lineal dinà mic" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "Inhabilita l'ús d'un algorisme adaptatiu per programari que genera " +#~ "art lineal en comptes de per maquinari." + +#~ msgid "linier" +#~ msgstr "Lineal" + +#~ msgid "It is right and left reversing" +#~ msgstr "Torna a la dreta i a l'esquerra" diff --git a/po/ca@valencia.po b/po/ca@valencia.po index 1ec2034..8111f09 100644 --- a/po/ca@valencia.po +++ b/po/ca@valencia.po @@ -1,13 +1,13 @@ -# Copyright (C) 2018 The SANE developers +# Copyright (C) 2018-2020 The SANE developers # This file is distributed under the same license as the sane-backends package. # -# Antoni Bella Pérez <antonibella5@yahoo.com>, 2018. +# Antoni Bella Pérez <antonibella5@yahoo.com>, 2018, 2020. msgid "" msgstr "" -"Project-Id-Version: sane-backends 1.0.27git\n" +"Project-Id-Version: sane-backends 1.0.29\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" -"PO-Revision-Date: 2018-09-10 00:37+0100\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" +"PO-Revision-Date: 2020-01-17 11:40+0100\n" "Last-Translator: Antoni Bella Pérez <antonibella5@yahoo.com>\n" "Language-Team: Catalan <kde-i18n-ca@kde.org>\n" "Language: ca@valencia\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Lokalize 2.0\n" +"X-Generator: Lokalize 20.03.70\n" #: include/sane/saneopts.h:154 #, no-c-format @@ -28,31 +28,31 @@ msgid "Standard" msgstr "Està ndard" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometria" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Millora" @@ -86,7 +86,7 @@ msgid "Bit depth" msgstr "Bits de profunditat" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Mode d'escaneig" @@ -127,7 +127,7 @@ msgid "Bottom-right y" msgstr "A baix-dreta Y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Resolució de l'escà ner" @@ -282,7 +282,7 @@ msgstr "Nom de fitxer" msgid "Halftone pattern size" msgstr "Mida del patró per al semi to" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Patró per al semi to" @@ -292,10 +292,10 @@ msgstr "Patró per al semi to" msgid "Bind X and Y resolution" msgstr "Enllaça les resolucions X i Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negatiu" @@ -418,7 +418,7 @@ msgstr "Apaga la là mpada en eixir" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Opció de només lectura que especifica quantes opcions admet un " @@ -769,7 +769,7 @@ msgstr "Correcció de la gamma analògica per al blau" #: include/sane/saneopts.h:415 #, no-c-format -msgid "Warmup lamp before scanning" +msgid "Warm up lamp before scanning" msgstr "Escalfament de la là mpada abans d'escanejar" #: include/sane/saneopts.h:417 @@ -919,8 +919,8 @@ msgstr "Operació no admesa" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" -msgstr "L'operació ha estat cancel·lada" +msgid "Operation was canceled" +msgstr "S'ha cancel·lat l'operació" #: backend/sane_strstatus.c:68 #, no-c-format @@ -1016,7 +1016,7 @@ msgstr "Realitza només la correcció de les ombres" #, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Si està habilitada, només es realitzarà la correcció de les ombres " @@ -1047,84 +1047,43 @@ msgstr "Escaneja a dues cares" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "L'escanejat de les dues cares proporciona un escanejat de l'anvers i el " "revers del document" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibratge de l'escà ner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Força el calibratge de l'escà ner abans de l'escaneig" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Escaneja en escala de grisos" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Fes un escaneig en escala de grisos en lloc d'en color" +msgid "Correction according to transparency ratio" +msgstr "Correcció d'acord amb la relació de transparència" -#: backend/canon630u.c:306 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Analog Gain" -msgstr "Guany analògic" - -#: backend/canon630u.c:307 -#, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Augmenta o disminueix el guany analògic per a la matriu del CCD" +msgid "Correction according to film type" +msgstr "Correcció d'acord amb el tipus de pel·lÃcula" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Correcció de la gamma" +msgid "Fine color" +msgstr "Color fi" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "" -"Selecciona la corba de transferència per a la correcció de la gamma" +msgid "Negatives" +msgstr "Negatius" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "En brut" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Color fi" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Sense correcció de la transparència" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Correcció d'acord amb el tipus de pel·lÃcula" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Correcció d'acord amb la relació de transparència" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negatius" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1261,8 +1220,8 @@ msgstr "Missatge «IDENTIFY» del bit no và lid" #: backend/canon.c:460 #, no-c-format -msgid "option not connect" -msgstr "L'opció no connectar" +msgid "option not correct" +msgstr "Opció no correcta" #: backend/canon.c:474 #, no-c-format @@ -1560,135 +1519,187 @@ msgstr "Selecciona el tipus de pel·lÃcula" msgid "Select the film type" msgstr "Selecciona el tipus de pel·lÃcula" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibratge de l'escà ner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Força el calibratge de l'escà ner abans de l'escaneig" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Escaneja en escala de grisos" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Fes un escaneig en escala de grisos en lloc d'en color" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Guany analògic" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Augmenta o disminueix el guany analògic per a la matriu del CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Correcció de la gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "" +"Selecciona la corba de transferència per a la correcció de la gamma" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "De superfÃcie plana" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "ADF per a l'anvers" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "ADF per al revers" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "ADF per a les dues cares" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "Targeta per a l'anvers" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "Targeta per al revers" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "Targeta per a les dues cares" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Roig" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Verd" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Blau" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Roig realçat" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Verd realçat" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Blau realçat" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Cap" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "El percentatge per a saltar el blanc del programari" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" "Sol·licita al controlador que descarti les pà gines amb un percentatge " "baix de pÃxels foscos" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Una cara" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Dues cares" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Unitat per a la transparència" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Alimentador automà tic de documents" @@ -1800,7 +1811,7 @@ msgstr "Impressores d'injecció de tinta" msgid "CRT monitors" msgstr "Monitors CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1864,8 +1875,9 @@ msgstr "A4" msgid "Max" msgstr "Mà x" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2039,17 +2051,17 @@ msgstr "Defineix el factor de zoom que usarà l'escà ner" msgid "Quick format" msgstr "Format rà pid" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Equipament opcional" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Expulsa" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Expulsa el full de l'ADF" @@ -2064,12 +2076,14 @@ msgstr "Expulsa automà ticament" msgid "Eject document after scanning" msgstr "Expulsa el document després de l'escaneig" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Mode ADF" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Seleccionar el mode de l'ADF (una cara/dues cares)" @@ -2121,17 +2135,17 @@ msgstr "" "Després d'enviar l'ordre d'escaneig, s'ha d'esperar fins que es prema el " "botó de l'escà ner per iniciar realment el procés d'escaneig." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Infraroigs" - # Nota: https://github.com/Scan-o-Matic/scanomatic/wiki/Installing-scanners -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "TPU8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Infraroigs" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2153,243 +2167,263 @@ msgstr "Incorpora el perfil CCT" msgid "User defined CCT profile" msgstr "Perfil CCT definit per l'usuari" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "Carrega" + +#: backend/epsonds.c:751 +#, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Carrega un full a l'ADF" + +#: backend/epsonds.c:771 +#, no-c-format +msgid "ADF Skew Correction" +msgstr "Correcció de la inclinació a l'ADF" + +#: backend/epsonds.c:773 +#, no-c-format +msgid "Enables ADF skew correction" +msgstr "Habilita la correcció de la inclinació a l'ADF" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Actiu" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Inactiu" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Tramat" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Difusió" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Blanc" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Negre" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Continua" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Atura" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10 mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15 mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20 mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horitzontal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Horitzontal en negre" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Horitzontal estreta" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertical" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Vertical en negre" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "De dalt a baix" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "De baix a dalt" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Anvers" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Revers" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "Exponent de la funció gamma" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "Canvia la intensitat dels semi tons" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "RIF" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "Format d'imatge inversa" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "Tipus de semi to" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "Controla el tipus de filtre del semi to" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "Controla el patró del filtre del semi to" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "Contorn" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, no-c-format msgid "Perform outline extraction" msgstr "Realitza l'extracció del contorn" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "Èmfasi" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "Negatiu per a suavitzar o positiu per aguditzar la imatge" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, no-c-format msgid "Separation" msgstr "Separació" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "Habilita la separació automà tica de les imatges i el text" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "Emmiralla" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "Reflecteix horitzontalment la imatge d'eixida" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, no-c-format msgid "White level follower" msgstr "Seguidor del nivell de blanc" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, no-c-format msgid "Control white level follower" msgstr "Controla el seguidor del nivell de blanc" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, no-c-format msgid "BP filter" msgstr "Filtre per al bolÃgraf" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "Millora la qualitat del text del bolÃgraf amb alta resolució" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Suavitzat" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "Habilita el suavitzat per a millorar l'OCR" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, no-c-format msgid "Gamma curve" msgstr "Corba amb interval" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" "La corba amb interval, des de la llum a la foscor, però la part superior " "de les dues podria no funcionar" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Corba del llindar" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" @@ -2397,116 +2431,116 @@ msgstr "" "La corba del llindar, des de la llum a la foscor, però la part superior " "de les dues podria no ser lineal" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "Llindar al blanc" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" "Estableix els pÃxels iguals al llindar al blanc en comptes de negre" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "Eliminació del soroll" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "Matriu 5x5" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "Elimina el soroll quadrat de 5 pÃxels" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "Matriu 4x4" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "Elimina el soroll quadrat de 4 pÃxels" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "Matriu 3x3" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "Elimina el soroll quadrat de 3 pÃxels" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "Matriu 2x2" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "Elimina el soroll quadrat de 2 pÃxels" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "Varià ncia" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" "Estableix la velocitat de la varià ncia SDTC (sensibilitat), 0 és igual " "que 127" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, no-c-format msgid "Auto width detection" msgstr "Detecció automà tica de l'amplà ria" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" "L'escà ner detectarà els costats del paper. Pot reduir la velocitat de " "l'escaneig." -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, no-c-format msgid "Auto length detection" msgstr "Detecció automà tica de la llargada" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" "L'escà ner detectarà la vora inferior del paper. Pot confondre alguns " "frontals." -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "Compressió" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" "Habilita les dades comprimides. Pot fer fallar el vostre programa de " "frontal" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "Argument per a la compressió" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " @@ -2515,110 +2549,110 @@ msgstr "" "Nivell de la compressió JPEG. 1 és un fitxer petit, 7 és un fitxer gran. " "0 (predeterminat) és igual que 4" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "Acció per a la doble alimentació" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "Acció per a després de l'error de doble alimentació" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "Inclinació per la doble alimentació" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "Habilita l'error de doble alimentació que causa inclinació" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "Gruix del paper per la doble alimentació" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Habilita l'error de doble alimentació causat pel gruix del paper" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "Longitud del paper causant doble alimentació" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" "Habilita l'error de doble alimentació causat per la longitud del paper" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "Diferència en la longitud per a causar doble alimentació" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" "Diferència en la longitud de la pà gina per activar l'error de doble " "alimentació" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "El mode recuperació causa doble alimentació" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" "Sol·licita a l'escà ner que l'alimentador recuperi el paper en embussar-se" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "Protecció del paper" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "Pregunta a l'escà ner per a predir les embussades a l'ADF" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, no-c-format msgid "Advanced paper protection" msgstr "Protecció avançada del paper" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" "Pregunta a l'escà ner per a predir les embussades a l'ADF usant sensors " "millorats" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, no-c-format msgid "Staple detection" msgstr "Detecció de les grapes" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" "Pregunta a l'escà ner per a detectar les embussades a l'ADF causades per " "les grapes" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "Color de fons" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" @@ -2626,12 +2660,12 @@ msgstr "" "Estableix un color de fons per a l'escaneig. Pot entrar en conflicte amb " "l'opció de sobreexploració" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "Descarta el color" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " @@ -2640,34 +2674,34 @@ msgstr "" "Els escà ners d'una sola passada només usen un color durant l'escaneig " "amb gris o binari, útil per a paper amb colors o tinta" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "Mode de memòria intermèdia" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" "Sol·licita a l'escà ner que llija les pà gines rà pidament des de l'ADF a " "la memòria interna" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "Preselecciona" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "Sol·licita a l'escà ner que agafi la pà gina següent des de l'ADF" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "Sobreexploració" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2679,12 +2713,12 @@ msgstr "" "de la mida del paper, per a permetre recollir els costats restants. Pot " "entrar en conflicte amb l'opció Color de fons" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "Temporitzador de suspensió" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" @@ -2692,12 +2726,12 @@ msgstr "" "Temps en minuts fins que la font d'alimentació interna canviarà al mode " "de suspensió" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "Temporitzador per apagar" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " @@ -2707,42 +2741,42 @@ msgstr "" "S'arrodonirà fins als 15 minuts més propers. Zero significa que no " "s'apagarà mai." -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, no-c-format msgid "Duplex offset" msgstr "Desplaçament de la doble cara" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "Ajusta el desplaçament per a l'anvers/revers" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Desplaçament del verd" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, no-c-format msgid "Adjust green/red offset" msgstr "Ajusta el desplaçament del verd/roig" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Desplaçament del blau" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "Ajusta el desplaçament del blau/roig" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "Memòria baixa" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2756,12 +2790,12 @@ msgstr "" "es pot usar per a determinar la imatge correcta. Aquesta opció només " "s'hauria d'usar amb el programari de frontal personalitzat." -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, no-c-format msgid "Duplex side" msgstr "Cara per a les dues cares" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " @@ -2770,58 +2804,58 @@ msgstr "" "Indica a quina cara (0=anvers, 1=revers) en un escaneig de dues cares " "retornarà la següent crida al «sane_read()»." -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "Desinclina i escapça per maquinari" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" "Sol·licita a l'escà ner que giri i escapci les pà gines de forma digital." -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Desinclina per programari" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" "Sol·licita al controlador que giri les pà gines inclinades de forma " "digital." -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Dià metre per eliminar els pics per programari" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" "Dià metre mà xim dels punts solitaris per eliminar-los de l'escaneig." -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "Escapça per programari" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" "Sol·licita al controlador que elimini la vora de les pà gines de forma " "digital." -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "Atura en cancel·lar" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." @@ -2829,108 +2863,108 @@ msgstr "" "Sol·licita al controlador que pare l'alimentador de paper en lloc " "d'expulsar-lo durant una cancel·lació." -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, no-c-format msgid "Endorser Options" msgstr "Opcions per a l'aprovador" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "Controls per a la unitat aprovadora" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "Aprovador" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "Habilita la unitat aprovadora" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "Bits de l'aprovació" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "Determina el valor mà xim del comptador de l'aprovació." -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "Valor de l'aprovació" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "Valor inicial del comptador de l'aprovació." -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "Pas de l'aprovació" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" "Canvia el valor del comptador de l'aprovació en aquest tant per a cada " "pà gina." -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "Aprovació Y" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" "Desplaçament de la impressió de l'aprovador des de la part superior del " "paper." -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "Tipus de lletra per a l'aprovador" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "El tipus de lletra amb el que imprimirà l'aprovador." -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, no-c-format msgid "Endorser direction" msgstr "Direcció de l'aprovador" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "Direcció amb la qual imprimirà l'aprovador." -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "Costat de l'aprovador" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" "El costat de la impressió de l'aprovador, requereix maquinari per " "canviar-lo" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "Cadena de l'aprovador" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " @@ -2939,220 +2973,206 @@ msgstr "" "Format d'impressió alfanumèric de l'aprovador. %05ud o %08ud al final " "serà substituït pel valor del comptador." -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "Vora superior" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "El paper s'ha retirat parcialment dins de l'ADF" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "Paper A3" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "S'ha detectat un paper A3" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "Paper B4" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "S'ha detectat un paper B4" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "Paper A4" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "S'ha detectat un paper A4" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "Paper B5" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "S'ha detectat un paper B5" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "OMR o DF" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" "S'ha detectat una OMR (reconeixement de marca òptica) o alimentació de " "doble cara" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "Estalvi d'energia" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "Escà ner en el mode estalvi d'energia" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "Alimentació manual" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "S'ha seleccionat una alimentació manual" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "Funció" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "Funció carà cter a la pantalla" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "Tinta baixa" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "La impressora s'està executant amb la tinta baixa" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "Alimentació de doble cara" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "S'ha detectat una alimentació de doble cara" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "Codi d'error" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "Codi d'error del maquinari" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "Angle d'inclinació" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "Requereix un fons negre per escanejar" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "Tinta restant" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, no-c-format msgid "Imprinter ink level" msgstr "Nivell de tinta de la impressora" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, no-c-format msgid "Density" msgstr "Densitat" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "Marcador de la densitat" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, no-c-format msgid "Duplex switch" msgstr "Commuta a doble cara" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" "Sol·licita al dorsal que elimini la vora de les pà gines de forma digital" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" "Sol·licita al controlador que descarti les pà gines amb un nombre baix de " "pÃxels foscos" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "Treu el gir per programari" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" "Sol·licita al controlador que detecti i corregisca el gir de 90 graus de " "la imatge" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extres" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" "La corba dinà mica del llindar, des de la llum a la foscor, normalment de " "50 a 65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Inhabilita l'art lineal dinà mic" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"Inhabilita l'ús d'un algorisme adaptatiu per programari que genera art " -"lineal en comptes de per maquinari." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Inhabilita la interpolació" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3162,33 +3182,33 @@ msgstr "" "més petita que la vertical, això inhabilitarà la interpolació " "horitzontal." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, no-c-format msgid "Color filter" msgstr "Filtre de color" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "Quan s'usa gris o art lineal, aquesta opció seleccionarà el color a usar." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, no-c-format msgid "Calibration file" msgstr "Fitxer de calibratge" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, no-c-format msgid "Specify the calibration file to use" msgstr "Especifica el fitxer de calibratge a usar" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, no-c-format msgid "Calibration cache expiration time" msgstr "Temps de caducitat per a la memòria cau del calibratge" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " @@ -3198,12 +3218,12 @@ msgstr "" "memòria cau. Un valor de 0 indicarà que no s'usarà la memòria cau. Un " "valor negatiu indicarà que la memòria cau no caducarà mai." -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Temps per apagar la là mpada" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3212,89 +3232,111 @@ msgstr "" "La llum s'apagarà després del temps determinat (en minuts). Un valor de " "0 indicarà que no s'apagarà la là mpada." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "Apaga la là mpada durant l'escaneig" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "La llum s'apagarà durant l'escaneig." -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Botó de fitxer" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Botó OCR" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Botó d'encesa" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, no-c-format msgid "Extra button" msgstr "Botó extra" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Necessita calibratge" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "L'escà ner necessita calibratge per als ajustaments actuals" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Botons" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Calibratge" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Comença el calibratge emprant un full especial" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Neteja el calibratge" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Neteja la memòria cau del calibratge" -#: backend/genesys.cc:5769 -#, fuzzy, no-c-format +#: backend/genesys/genesys.cpp:4476 +#, no-c-format msgid "Force calibration" -msgstr "Calibratge tosc" +msgstr "Força el calibratge" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" +"Força el calibratge ignorant-ho tot i qualsevol memòria cau del " +"calibratge" + +#: backend/genesys/genesys.cpp:4487 +#, no-c-format +msgid "Ignore internal offsets" +msgstr "Ignora els desplaçaments interns" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" +"Adquireix la imatge, incloses les à rees de calibratge intern de l'escà ner" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Adaptador de transparència" +#: backend/genesys/genesys.h:80 +#, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Adaptador infraroig de transparència" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3404,6 +3446,314 @@ msgstr "Valor de la gamma" msgid "Sets the gamma value of all channels." msgstr "Estableix el valor de la gamma de tots els canals." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Opcions avançades" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Tosc" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fina" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "A mida" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Auto" + +# Nota: https://ca.wikipedia.org/wiki/NTSC +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "RGB del NTSC" + +# Nota: https://support.hp.com/gb-en/document/c01275842 +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "RGB amb el XPA" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Passa a través" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "Gris del NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Gris amb el XPA" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lent" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rà pid" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Extrarà pid" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2 pÃxels" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4 pÃxels" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8 pÃxels" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Imprimeix" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositiva" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Tira de pel·lÃcules" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Condicional" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experimental" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Aguditzant" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Estableix el valor de l'agudització." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Llindar automà tic" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Habilita la determinació automà tica del llindar pels escaneigs amb art " +"lineal." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Selecciona el filtre de suavitzat." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Descarrega el suport després de l'escaneig" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Descarrega el suport després d'un escaneig." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Canvia el document" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Canvia el document." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Descarrega" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Descarrega el document." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Inicia el procés de calibratge." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Suport" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Estableix el tipus de suport." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Temps d'exposició" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Un temps d'exposició més llarg permet que l'escà ner recopili més llum. " +"L'ús aconsellat és el 175% per a impressions, el 150% per a diapositives " +"normals i «Negatiu» per a pel·lÃcules en negatiu. Per a imatges fosques " +"(sota exposades), podeu augmentar aquest valor." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matriu de color" + +#: backend/hp-option.h:121 +#, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Estableix la matriu de color de l'escà ner." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Matriu de color a mida." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Matriu de color monocrom" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Matriu de color a mida pels escaneigs en escala de grisos." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Emmiralla horitzontalment" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Emmiralla horitzontalment la imatge." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Emmiralla verticalment" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Emmiralla verticalment la imatge." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Opcions per a l'actualització" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Opcions per a l'actualització." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "Eixida de 8 bits" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Usa internament una profunditat de bits més gran que vuit, però a " +"l'eixida usa només vuit bits." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Espera al botó del frontal" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Espera per escanejar que es prema el botó del panell frontal." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Apaga la là mpada" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Apaga la llum de l'escà ner." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3414,12 +3764,6 @@ msgstr "Grup de geometria" msgid "Scan Mode Group" msgstr "Grup de mode d'escaneig" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositiva" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3427,14 +3771,14 @@ msgstr "Model de l'escà ner" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" "Permet comprovar el comportament del dispositiu amb els altres models " "admesos" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "Els colors de la imatge seran invertits" #: backend/hp3900_sane.c:1436 @@ -3624,11 +3968,6 @@ msgstr "Apaga o encén la llum." msgid "Calibrates for black and white level." msgstr "Calibra per al nivell de blanc i negre." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - # Nota: https://en.wikipedia.org/wiki/Tissue_microarray #: backend/hp5590.c:95 #, no-c-format @@ -3676,34 +4015,36 @@ msgid "Get ID of last button pressed (read only)" msgstr "Obtén l'ID de l'últim botó premut (només lectura)" #: backend/hp5590.c:121 -#, fuzzy, no-c-format +#, no-c-format msgid "LCD counter" -msgstr "Comptador d'escaneigs" +msgstr "Comptador LCD" #: backend/hp5590.c:122 -#, fuzzy, no-c-format +#, no-c-format msgid "Get value of LCD counter (read only)" -msgstr "Obtén l'ID de l'últim botó premut (només lectura)" +msgstr "Obtén el valor del comptador LCD (només lectura)" #: backend/hp5590.c:124 -#, fuzzy, no-c-format +#, no-c-format msgid "Color LED indicator" -msgstr "Color per a l'art lineal" +msgstr "Indicador LED del color" #: backend/hp5590.c:125 -#, fuzzy, no-c-format +#, no-c-format msgid "Get value of LED indicator (read only)" -msgstr "Obtén l'ID de l'últim botó premut (només lectura)" +msgstr "Obtén el valor del comptador LED (només lectura)" #: backend/hp5590.c:127 #, no-c-format msgid "Document available in ADF" -msgstr "" +msgstr "Document disponible a l'ADF" #: backend/hp5590.c:128 #, no-c-format msgid "Get state of document-available indicator in ADF (read only)" msgstr "" +"Obtén l'estat de l'indicador de document disponible a l'ADF (només " +"lectura)" #: backend/hp5590.c:130 #, no-c-format @@ -3749,303 +4090,6 @@ msgstr "" "Valor del «color» per al mode d'ompliment al final de les lÃnies. Color " "RGB com a valor r*65536+256*g+b o gris (predeterminat=violeta o gris)" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Opcions avançades" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Tosc" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fina" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "A mida" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Auto" - -# Nota: https://ca.wikipedia.org/wiki/NTSC -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "RGB del NTSC" - -# Nota: https://support.hp.com/gb-en/document/c01275842 -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "RGB amb el XPA" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Passa a través" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "Gris del NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Gris amb el XPA" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lent" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rà pid" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Extrarà pid" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2 pÃxels" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4 pÃxels" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8 pÃxels" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Imprimeix" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Tira de pel·lÃcules" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Condicional" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experimental" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Aguditzant" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Estableix el valor de l'agudització." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Llindar automà tic" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Habilita la determinació automà tica del llindar pels escaneigs amb art " -"lineal." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Selecciona el filtre de suavitzat." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Descarrega el suport després de l'escaneig" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Descarrega el suport després d'un escaneig." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Canvia el document" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Canvia el document." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Descarrega" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Descarrega el document." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Inicia el procés de calibratge." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Suport" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Estableix el tipus de suport." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Temps d'exposició" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Un temps d'exposició més llarg permet que l'escà ner recopili més llum. " -"L'ús aconsellat és el 175% per a impressions, el 150% per a diapositives " -"normals i «Negatiu» per a pel·lÃcules en negatiu. Per a imatges fosques " -"(sota exposades), podeu augmentar aquest valor." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matriu de color" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Estableix la matriu de color dels escà ners." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Matriu de color a mida." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Matriu de color monocrom" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Matriu de color a mida pels escaneigs en escala de grisos." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Emmiralla horitzontalment" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Emmiralla horitzontalment la imatge." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Emmiralla verticalment" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Emmiralla verticalment la imatge." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Opcions per a l'actualització" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Opcions per a l'actualització." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "Eixida de 8 bits" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Usa internament una profunditat de bits més gran que vuit, però a " -"l'eixida usa només vuit bits." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Espera al botó del frontal" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Espera per escanejar que es prema el botó del panell frontal." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Apaga la là mpada" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Apaga la llum de l'escà ner." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4144,7 +4188,7 @@ msgid "single" msgstr "individual" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4313,7 +4357,7 @@ msgstr "CRT" #: backend/kvs1025_opt.c:229 #, no-c-format -msgid "linier" +msgid "linear" msgstr "Lineal" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 @@ -4446,7 +4490,7 @@ msgstr "Estableix l'èmfasi de la imatge" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4519,14 +4563,14 @@ msgstr "" "Sol·licita al controlador que elimini la vora de les pà gines de forma " "digital" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" -"El mode control de la longitud és un mode on l'escà ner llegirà fins a la " -"longitud més curta del paper real o la longitud lògica del document." +"El mode control de la longitud fa que l'escà ner llija la longitud més " +"curta real del paper o la longitud lògica del document." #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 #: backend/kvs40xx_opt.c:668 backend/kvs40xx_opt.c:669 @@ -4557,13 +4601,13 @@ msgstr "B4" #: backend/kvs40xx_opt.c:231 #, no-c-format -msgid "High sensivity" -msgstr "Alta sensibilitat" +msgid "High sensitivity" +msgstr "Sensibilitat alta" #: backend/kvs40xx_opt.c:232 #, no-c-format -msgid "Low sensivity" -msgstr "Baixa sensibilitat" +msgid "Low sensitivity" +msgstr "Sensibilitat baixa" #: backend/kvs40xx_opt.c:243 #, no-c-format @@ -4585,6 +4629,15 @@ msgstr "Mode normal" msgid "Enhanced mode" msgstr "Mode millorat" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"El mode control de la longitud fa que l'escà ner llija la longitud més " +"curta real del paper o la longitud lògica del document" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4647,9 +4700,9 @@ msgstr "Compressió del JPEG" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" -"Compressió del JPEG (l'aplicació vostra l'haurà de poder descomprimir)" +"Compressió del JPEG (la vostra aplicació haurà de poder descomprimir)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 #, no-c-format @@ -4683,12 +4736,12 @@ msgstr "Ajustament de la inclinació" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "Atura l'escà ner quan un paper estiga inclinat" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "S'aturarà l'escà ner quan un paper estiga inclinat" #: backend/kvs40xx_opt.c:816 @@ -4698,14 +4751,14 @@ msgstr "Escapça una à rea de la imatge real" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" "L'escà ner detectarà automà ticament l'à rea de la imatge i l'escapçarà " #: backend/kvs40xx_opt.c:827 #, no-c-format -msgid "It is right and left reversing" -msgstr "Torna a la dreta i a l'esquerra" +msgid "Left/right mirror image" +msgstr "Emmiralla la imatge d'esquerra/dreta" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4742,52 +4795,52 @@ msgstr "Bayer 8x8" msgid "8x8 Vertical Line" msgstr "LÃnia vertical 8x8" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Guany" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Ajustaments del guany per als canals de color" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Guany del gris" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Estableix el guany del canal gris" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Guany del roig" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Estableix el guany del canal roig" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Guany del verd" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Estableix el guany del canal verd" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Guany del blau" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Estableix el guany del canal blau" @@ -4873,7 +4926,7 @@ msgstr "Una pà gina" msgid "All pages" msgstr "Totes les pà gines" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "escà ner alimentat per fulls" @@ -5395,27 +5448,32 @@ msgstr "" "Escalfa fins que la brillantor de la là mpada siga constant en comptes " "d'insistir en el temps d'escalfament de 40 segons." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, no-c-format +msgid "Need calibration" +msgstr "Necessita calibratge" + +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "Color en negatiu" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "Gris en negatiu" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "Color de 48 bits" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "Gris de 16 bits" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " @@ -5425,12 +5483,12 @@ msgstr "" "Estableix la font abans del mode i la resolució. Restaura el mode i la " "resolució als valors automà tics." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Escaneig controlat pels botons" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5441,43 +5499,43 @@ msgstr "" "Per a continuar, premeu el botó «Escaneja» (per a MP150) o el botó " "«Color» (per a altres models). Per a cancel·lar, premeu el botó «Gris»." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Actualitza l'estat del botó" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Botó 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Botó 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "Tipus de l'original a escanejar" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "Tipus de l'operació de destinació" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "Temps d'espera per a l'ADF" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" -"Quan s'estableix, l'escà ner cerca el temps d'espera en segons perquè " +"Quan s'estableix, l'escà ner espera el temps especificat en segons perquè " "s'inserisca un document nou a l'alimentador automà tic de documents." #: backend/plustek.c:235 backend/plustek_pp.c:204 backend/u12.c:156 @@ -5565,7 +5623,7 @@ msgstr "Frontal analògic" msgid "Red gain value of the AFE" msgstr "Valor de guany del roig de l'AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Desplaçament del roig" @@ -5842,7 +5900,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Aquesta opció reflecteix l'estat d'un botó de l'escà ner." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Encén la là mpada" @@ -5852,12 +5910,12 @@ msgstr "Encén la là mpada" msgid "Turn on scanner lamp" msgstr "Encén la llum de l'escà ner" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Apaga la là mpada" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Apaga la llum de l'escà ner" @@ -6005,12 +6063,12 @@ msgstr "Punt d'enfocament" #: backend/snapscan-options.c:930 #, no-c-format -msgid "Colour lines per read" +msgid "Color lines per read" msgstr "LÃnies de color per a la lectura" #: backend/snapscan-options.c:942 #, no-c-format -msgid "Greyscale lines per read" +msgid "Grayscale lines per read" msgstr "LÃnies en escala de grisos per a la lectura" #: backend/stv680.c:974 @@ -6681,52 +6739,68 @@ msgstr "Mode del calibratge" msgid "Define calibration mode" msgstr "Defineix el mode del calibratge" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Estableix la là mpada a encesa/apagada" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "Activa l'UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Estableix l'UTA a actiu/inactiu" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Desplaçament" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Ajustaments del desplaçament per als canals de color" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Desplaçament del gris" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Estableix el desplaçament del canal gris" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Estableix el desplaçament del canal roig" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Estableix el desplaçament del canal verd" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Estableix el desplaçament del canal blau" + +#~ msgid "Disable dynamic lineart" +#~ msgstr "Inhabilita l'art lineal dinà mic" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "Inhabilita l'ús d'un algorisme adaptatiu per programari que genera " +#~ "art lineal en comptes de per maquinari." + +#~ msgid "linier" +#~ msgstr "Lineal" + +#~ msgid "It is right and left reversing" +#~ msgstr "Torna a la dreta i a l'esquerra" @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends.cs\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-12-17 22:59+0100\n" "Last-Translator: Josef <joeprusa@volny.cz>\n" "Language-Team: \n" @@ -26,31 +26,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometrie" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "VylepÅ¡enÃ" @@ -84,7 +84,7 @@ msgid "Bit depth" msgstr "Bitová hloubka" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Režim skenu" @@ -125,7 +125,7 @@ msgid "Bottom-right y" msgstr "Pravý dolnà roh y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "RozliÅ¡enÃ" @@ -280,7 +280,7 @@ msgstr "Jméno souboru" msgid "Halftone pattern size" msgstr "RozmÄ›r vzorku polotónu" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Vzorek polotónu" @@ -290,10 +290,10 @@ msgstr "Vzorek polotónu" msgid "Bind X and Y resolution" msgstr "Svázat rozliÅ¡enà X a Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativ" @@ -414,9 +414,9 @@ msgid "Lamp off at exit" msgstr "Vypnout lampu pÅ™i ukonÄenÃ" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Hodnota pouze pro ÄtenÃ, která udává, kolik voleb dané zaÅ™Ãzenà " @@ -745,8 +745,8 @@ msgid "Analog gamma-correction for blue" msgstr "Analogová korekce gama pro modrou" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Zahřát lampu pÅ™ed skenovánÃm" #: include/sane/saneopts.h:417 @@ -896,7 +896,7 @@ msgstr "Polotón nenà podporován" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -989,10 +989,10 @@ msgid "Only perform shading-correction" msgstr "Provést pouze korekci stÃnů" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Pokud je tato volba zapnuta, pÅ™i kalibraci se provede pouze korekce " @@ -1022,80 +1022,40 @@ msgstr "OboustranÄ›" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibrovat skener" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Vynutit kalibraci skeneru pÅ™ed skenovánÃm" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "StupnÄ› Å¡edé" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Skenovat ve stupnÃch Å¡edé mÃsto v barvÄ›" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analogový zisk" - -#: backend/canon630u.c:307 -#, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Zvýšit nebo snÞit analogový zisk CCD pole" - -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "Korekce gama" - -#: backend/canon630u.c:348 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Nastavà gama korekci pÅ™enosové kÅ™ivky" +msgid "Correction according to transparency ratio" +msgstr "" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Raw" +msgid "Correction according to film type" msgstr "" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 #: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format msgid "Fine color" msgstr "" -#: backend/canon.c:169 +#: backend/canon-sane.c:776 backend/canon.c:176 #, fuzzy, no-c-format -msgid "No transparency correction" -msgstr "Barevná korekce" - -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" +msgid "Negatives" +msgstr "Negativ" -#: backend/canon.c:171 backend/canon-sane.c:674 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format -msgid "Correction according to transparency ratio" +msgid "Raw" msgstr "" -#: backend/canon.c:176 backend/canon-sane.c:776 +#: backend/canon.c:169 #, fuzzy, no-c-format -msgid "Negatives" -msgstr "Negativ" +msgid "No transparency correction" +msgstr "Barevná korekce" #: backend/canon.c:176 #, fuzzy, no-c-format @@ -1230,9 +1190,9 @@ msgid "invalid bit IDENTIFY message" msgstr "" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" -msgstr "" +#, fuzzy, no-c-format +msgid "option not correct" +msgstr "Polotón nenà podporován" #: backend/canon.c:474 #, no-c-format @@ -1519,133 +1479,184 @@ msgstr "Typ filmu" msgid "Select the film type" msgstr "Zvolit polotóny" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibrovat skener" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Vynutit kalibraci skeneru pÅ™ed skenovánÃm" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "StupnÄ› Å¡edé" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Skenovat ve stupnÃch Å¡edé mÃsto v barvÄ›" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analogový zisk" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Zvýšit nebo snÞit analogový zisk CCD pole" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Korekce gama" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Nastavà gama korekci pÅ™enosové kÅ™ivky" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "StolnÃ" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, fuzzy, no-c-format msgid "ADF Duplex" msgstr "OboustranÄ›" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "OboustranÄ›" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "ÄŒervená" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Zelená" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Modrá" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "VylepÅ¡enÃ" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "VylepÅ¡enÃ" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "VylepÅ¡enÃ" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Žádné" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "JednostranÄ›" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "OboustranÄ›" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "ProsvÄ›tlovacà jednotka" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatický podavaÄ dokumentů" @@ -1757,7 +1768,7 @@ msgstr "Inkoustové tiskárny" msgid "CRT monitors" msgstr "CRT monitory" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1821,8 +1832,9 @@ msgstr "A4" msgid "Max" msgstr "Max" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1994,17 +2006,17 @@ msgstr "Nastavà faktor pÅ™iblÞenÃ, který skener použije" msgid "Quick format" msgstr "Rychlý formát" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Volitelné pÅ™ÃsluÅ¡enstvÃ" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Vysunout" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Vysunout papÃr z automatického podavaÄe" @@ -2019,12 +2031,14 @@ msgstr "Automaticky vysunout" msgid "Eject document after scanning" msgstr "Vysunout dokument po naskenovánÃ" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2073,14 +2087,14 @@ msgstr "" "Po odeslánà pÅ™Ãkazu ke skenovánà se s vlastnÃm skenem Äeká až na stisk " "tlaÄÃtka na skeneru." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2103,492 +2117,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "Uživatelské nastavenÃ" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Vysunout papÃr z automatického podavaÄe" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Bez korekce" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Analogová korekce gama" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Rozptyl" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "Chybový rozptyl" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Úroveň bÃlé" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Úroveň Äerné" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "HorizontálnÃ" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "HorizontálnÃ" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "HorizontálnÃ" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "VertikálnÃ" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "VertikálnÃ" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Polotóny" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Hrubá kalibrace" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "ZvýraznÄ›nà obrázku" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Sytost" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Zrcadlit obrázek" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Zrcadlit obrázek" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Úroveň bÃlé modré" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Ovládá úroveň Äervené" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Barevná perokresba" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, fuzzy, no-c-format msgid "Smoothing" msgstr "Jemný" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Hodnota gama" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Prahová hodnota" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Prahová hodnota" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Redukce Å¡umu" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Bez korekce" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Bez korekce" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Režim podavaÄe" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Zvláštnà volby" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Bez korekce" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Výpadek" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Režim podavaÄe" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2596,65 +2630,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Vypnout lampu" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Odstup modré" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Odstup zelené" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Odstup zelené" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Odstup modré" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Nastavuje odstup modrého kanálu" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2663,507 +2697,514 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "OboustranÄ›" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Zvláštnà volby" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Redukce Å¡umu" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Z papÃru" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Z papÃru" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Z papÃru" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Z papÃru" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Manuálnà pÅ™edběžné zaostÅ™enÃ" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Manuálnà pÅ™edběžné zaostÅ™enÃ" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "RozliÅ¡enÃ" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Úroveň bÃlé" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Intenzita Äervené" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "OboustranÄ›" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, fuzzy, no-c-format msgid "Extras" msgstr "Velmi rychlý" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, fuzzy, no-c-format msgid "Disable interpolation" msgstr "VyÅ™adit zpÄ›tný chod" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Barevná perokresba" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibrace" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Definovat režim kalibrace" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Režim kalibrace" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, fuzzy, no-c-format msgid "Lamp off time" msgstr "Vypnout lampu" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " "of 0 means, that the lamp won't be turned off." msgstr "" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Hrubá kalibrace" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "ÄŒekat na tlaÄÃtko" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "ÄŒekat na tlaÄÃtko" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "ÄŒekat na tlaÄÃtko" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Hrubá kalibrace" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Vynutit kalibraci skeneru pÅ™ed skenovánÃm" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, fuzzy, no-c-format msgid "Buttons" msgstr "Stav tlaÄÃtek" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibrovat" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Hrubá kalibrace" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Hrubá kalibrace" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Režim kalibrace" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Hrubá kalibrace" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Odstup zelené" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "ProsvÄ›tlovacà adaptér" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "ProsvÄ›tlovacà adaptér" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3264,6 +3305,304 @@ msgstr "Hodnota gama" msgid "Sets the gamma value of all channels." msgstr "Nastavuje hodnotu gama pro vÅ¡echny kanály." +#: backend/hp-option.c:2987 +#, fuzzy, no-c-format +msgid "Advanced Options" +msgstr "Zvláštnà volby" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Hrubý" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Jemný" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Volitelný" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automaticky" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC Å¡edá" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA Å¡edá" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Pomalý" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "NormálnÃ" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rychlý" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Velmi rychlý" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, fuzzy, no-c-format +msgid "Slide" +msgstr "Zcela bÃlá" + +#: backend/hp-option.c:3178 +#, fuzzy, no-c-format +msgid "Film-strip" +msgstr "Typ filmu" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "" + +#: backend/hp-option.c:3417 +#, fuzzy, no-c-format +msgid "Experiment" +msgstr "ExpoziÄnà Äas" + +#: backend/hp-option.h:60 +#, fuzzy, no-c-format +msgid "Sharpening" +msgstr "ZaostÅ™enÃ" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "" + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Automatické nastavenà prahových hodnot" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" + +#: backend/hp-option.h:74 +#, fuzzy, no-c-format +msgid "Select smoothing filter." +msgstr "Zvolit polotóny" + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "" + +#: backend/hp-option.h:80 +#, fuzzy, no-c-format +msgid "Unloads the media after a scan." +msgstr "NaÄÃst obrázek v úrovnÃch Å¡edé." + +#: backend/hp-option.h:85 +#, fuzzy, no-c-format +msgid "Change document" +msgstr "VylepÅ¡enÃ" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "" + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "" + +#: backend/hp-option.h:98 +#, fuzzy, no-c-format +msgid "Start calibration process." +msgstr "Hrubá kalibrace" + +#: backend/hp-option.h:103 +#, fuzzy, no-c-format +msgid "Media" +msgstr "StÅ™ednÃ" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "" + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "ExpoziÄnà Äas" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, fuzzy, no-c-format +msgid "Color Matrix" +msgstr "Barevný vzorek" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Nastavuje kontrast Äerveného kanálu" + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "" + +#: backend/hp-option.h:132 +#, fuzzy, no-c-format +msgid "Mono Color Matrix" +msgstr "Barevný vzorek" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "" + +#: backend/hp-option.h:138 +#, fuzzy, no-c-format +msgid "Mirror horizontal" +msgstr "Zrcadlit obrázek" + +#: backend/hp-option.h:139 +#, fuzzy, no-c-format +msgid "Mirror image horizontally." +msgstr "Zrcadlit obrázek" + +#: backend/hp-option.h:144 +#, fuzzy, no-c-format +msgid "Mirror vertical" +msgstr "Zrcadlit obrázek" + +#: backend/hp-option.h:145 +#, fuzzy, no-c-format +msgid "Mirror image vertically." +msgstr "Zrcadlit obrázek" + +#: backend/hp-option.h:150 +#, fuzzy, no-c-format +msgid "Update options" +msgstr "Zvláštnà volby" + +#: backend/hp-option.h:151 +#, fuzzy, no-c-format +msgid "Update options." +msgstr "Testovacà volby s pevnou des. Äárkou" + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Vypnout lampu" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Vypnout lampu skeneru." + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3274,12 +3613,6 @@ msgstr "Geometrie" msgid "Scan Mode Group" msgstr "Režim skenovánÃ" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, fuzzy, no-c-format -msgid "Slide" -msgstr "Zcela bÃlá" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3287,12 +3620,12 @@ msgstr "Režim skenu" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3473,11 +3806,6 @@ msgstr "ZapÃná a vypÃná lampu." msgid "Calibrates for black and white level." msgstr "Kalibruje úrovnÄ› Äerné a bÃlé." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3588,293 +3916,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, fuzzy, no-c-format -msgid "Advanced Options" -msgstr "Zvláštnà volby" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Hrubý" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Jemný" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Volitelný" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automaticky" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC Å¡edá" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA Å¡edá" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Pomalý" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "NormálnÃ" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rychlý" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Velmi rychlý" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "" - -#: backend/hp-option.c:3178 -#, fuzzy, no-c-format -msgid "Film-strip" -msgstr "Typ filmu" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "" - -#: backend/hp-option.c:3417 -#, fuzzy, no-c-format -msgid "Experiment" -msgstr "ExpoziÄnà Äas" - -#: backend/hp-option.h:60 -#, fuzzy, no-c-format -msgid "Sharpening" -msgstr "ZaostÅ™enÃ" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "" - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Automatické nastavenà prahových hodnot" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" - -#: backend/hp-option.h:74 -#, fuzzy, no-c-format -msgid "Select smoothing filter." -msgstr "Zvolit polotóny" - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "" - -#: backend/hp-option.h:80 -#, fuzzy, no-c-format -msgid "Unloads the media after a scan." -msgstr "NaÄÃst obrázek v úrovnÃch Å¡edé." - -#: backend/hp-option.h:85 -#, fuzzy, no-c-format -msgid "Change document" -msgstr "VylepÅ¡enÃ" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "" - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "" - -#: backend/hp-option.h:98 -#, fuzzy, no-c-format -msgid "Start calibration process." -msgstr "Hrubá kalibrace" - -#: backend/hp-option.h:103 -#, fuzzy, no-c-format -msgid "Media" -msgstr "StÅ™ednÃ" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "" - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "ExpoziÄnà Äas" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, fuzzy, no-c-format -msgid "Color Matrix" -msgstr "Barevný vzorek" - -#: backend/hp-option.h:121 -#, fuzzy, no-c-format -msgid "Set the scanners color matrix." -msgstr "Nastavuje kontrast Äerveného kanálu" - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "" - -#: backend/hp-option.h:132 -#, fuzzy, no-c-format -msgid "Mono Color Matrix" -msgstr "Barevný vzorek" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "" - -#: backend/hp-option.h:138 -#, fuzzy, no-c-format -msgid "Mirror horizontal" -msgstr "Zrcadlit obrázek" - -#: backend/hp-option.h:139 -#, fuzzy, no-c-format -msgid "Mirror image horizontally." -msgstr "Zrcadlit obrázek" - -#: backend/hp-option.h:144 -#, fuzzy, no-c-format -msgid "Mirror vertical" -msgstr "Zrcadlit obrázek" - -#: backend/hp-option.h:145 -#, fuzzy, no-c-format -msgid "Mirror image vertically." -msgstr "Zrcadlit obrázek" - -#: backend/hp-option.h:150 -#, fuzzy, no-c-format -msgid "Update options" -msgstr "Zvláštnà volby" - -#: backend/hp-option.h:151 -#, fuzzy, no-c-format -msgid "Update options." -msgstr "Testovacà volby s pevnou des. Äárkou" - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Vypnout lampu" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Vypnout lampu skeneru." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3973,7 +4014,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4141,9 +4182,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Perokresba" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4272,7 +4313,7 @@ msgstr "Nastavà zvýraznÄ›nà obrázku" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gama" @@ -4339,11 +4380,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4375,12 +4416,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Tisk ve vysoké kvalitÄ›" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Tisk v nÃzké kvalitÄ›" #: backend/kvs40xx_opt.c:243 @@ -4403,6 +4444,13 @@ msgstr "NormálnÃ" msgid "Enhanced mode" msgstr "VylepÅ¡enÃ" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4462,7 +4510,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4497,12 +4545,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4512,13 +4560,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Zrcadlit obrázek" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4555,52 +4603,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 vertikála" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Zisk" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Nastavenà zisku barevných kanálů" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Zisk Å¡edé" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Nastavuje zisk Å¡edého kanálu" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Zisk Äervené" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Nastavuje zisk Äerveného kanálu" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Zisk zelené" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Nastavuje zisk zeleného kanálu" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Zisk modré" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Nastavuje zisk modrého kanálu" @@ -4686,7 +4734,7 @@ msgstr "Jedna strana" msgid "All pages" msgstr "VÅ¡echny strany" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "skener s podavaÄem" @@ -5186,39 +5234,44 @@ msgstr "" "Zahřát lampu dokud jejà jas nenà konstantnà namÃsto standardnÃho 40ti " "sekundového zahÅ™ÃvánÃ." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Hrubá kalibrace" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Negativnà film" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativ" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5226,40 +5279,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, fuzzy, no-c-format msgid "Update button state" msgstr "Stav tlaÄÃtek" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, fuzzy, no-c-format msgid "Button 1" msgstr "Stav tlaÄÃtek" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, fuzzy, no-c-format msgid "Button 2" msgstr "Stav tlaÄÃtek" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5348,7 +5401,7 @@ msgstr "Analogová korekce gama pro Äervenou" msgid "Red gain value of the AFE" msgstr "" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Odstup Äervené" @@ -5623,7 +5676,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Zapnout lampu" @@ -5633,12 +5686,12 @@ msgstr "Zapnout lampu" msgid "Turn on scanner lamp" msgstr "Zapnout lampu skeneru" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Vypnout lampu" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Vypnout lampu skeneru" @@ -5782,13 +5835,13 @@ msgid "Focus point" msgstr "Pozice zaostÅ™enÃ" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "PoÄet barevných Äar na jedno ÄtenÃ" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "PoÄet Äar ve stupnÃch Å¡edi na jedno ÄtenÃ" #: backend/stv680.c:974 @@ -6432,52 +6485,52 @@ msgstr "Režim kalibrace" msgid "Define calibration mode" msgstr "Definovat režim kalibrace" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "ZapÃná/vypÃná lampu" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA zapnuto" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "ZapÃná/vypÃná UTA" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Odstup" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Nastavenà odstupu barevných kanálů" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Odstup Å¡edé" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Nastavuje odstup Å¡edého kanálu" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Nastavuje odstup Äerveného kanálu" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Nastavuje odstup zeleného kanálu" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Nastavuje odstup modrého kanálu" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.17\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-12-17 22:59+0100\n" "Last-Translator: Mogens Jaeger <mogensjaeger@get2net.dk>\n" "Language-Team: Danish <dansk@klid.dk>\n" @@ -31,31 +31,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "SkanomrÃ¥de" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Forbedring" @@ -89,7 +89,7 @@ msgid "Bit depth" msgstr "Bit dybde" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Skannertilstand" @@ -130,7 +130,7 @@ msgid "Bottom-right y" msgstr "Nederst-højre y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Skanningsopløsning" @@ -285,7 +285,7 @@ msgstr "Filnavn" msgid "Halftone pattern size" msgstr "Halvtonemønster størrelse" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Halvtonemønster" @@ -295,10 +295,10 @@ msgstr "Halvtonemønster" msgid "Bind X and Y resolution" msgstr "Sammenbind X- og Y-opløsning" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativ" @@ -419,9 +419,9 @@ msgid "Lamp off at exit" msgstr "Lampe slukkes ved afslutning" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Skrivebeskyttet indstilling der specificerer hvor mange indstillinger en " @@ -748,8 +748,8 @@ msgid "Analog gamma-correction for blue" msgstr "Analog gammakorrektion for blÃ¥" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Varm lampen op før skanning" #: include/sane/saneopts.h:417 @@ -899,7 +899,7 @@ msgstr "Halvtone er ikke understøttet" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -992,10 +992,10 @@ msgid "Only perform shading-correction" msgstr "Udfør kun skyggekorrektion" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Hvis aktiveret, bliver der kun gennemført skyggekorrektion under " @@ -1024,82 +1024,42 @@ msgid "Duplex scan" msgstr "Duplex skan" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "Duplex skan, skanner begge sider af dokumentet" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibrér skanner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Gennemtving kalibrering før skanning" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "GrÃ¥skalaskanning" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Udfør en grÃ¥skalaskanning fremfor en farveskanning" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analog forstærkning" - -#: backend/canon630u.c:307 -#, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Forøg eller formindsk CCD sensorens analoge forstærkning" - -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "Gammakorrektion" - -#: backend/canon630u.c:348 -#, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Vælger gammakorrigeret overføringskurve" +msgid "Correction according to transparency ratio" +msgstr "" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Raw" +msgid "Correction according to film type" msgstr "" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 #: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format msgid "Fine color" msgstr "" -#: backend/canon.c:169 +#: backend/canon-sane.c:776 backend/canon.c:176 #, fuzzy, no-c-format -msgid "No transparency correction" -msgstr "Farvekorrektion" - -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" +msgid "Negatives" +msgstr "Negativ" -#: backend/canon.c:171 backend/canon-sane.c:674 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format -msgid "Correction according to transparency ratio" +msgid "Raw" msgstr "" -#: backend/canon.c:176 backend/canon-sane.c:776 +#: backend/canon.c:169 #, fuzzy, no-c-format -msgid "Negatives" -msgstr "Negativ" +msgid "No transparency correction" +msgstr "Farvekorrektion" #: backend/canon.c:176 #, fuzzy, no-c-format @@ -1234,9 +1194,9 @@ msgid "invalid bit IDENTIFY message" msgstr "" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" -msgstr "" +#, fuzzy, no-c-format +msgid "option not correct" +msgstr "Halvtone er ikke understøttet" #: backend/canon.c:474 #, no-c-format @@ -1523,133 +1483,184 @@ msgstr "Filmtype" msgid "Select the film type" msgstr "Vælger halvtone." -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibrér skanner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Gennemtving kalibrering før skanning" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "GrÃ¥skalaskanning" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Udfør en grÃ¥skalaskanning fremfor en farveskanning" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analog forstærkning" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Forøg eller formindsk CCD sensorens analoge forstærkning" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gammakorrektion" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Vælger gammakorrigeret overføringskurve" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Flatbed" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "ADF" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, fuzzy, no-c-format msgid "ADF Duplex" msgstr "Dobbeltsidet" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Print" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Dobbeltsidet" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Rød" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Grøn" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "BlÃ¥" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Forbedring" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Forbedring" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Forbedring" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ingen" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Enkeltsidet" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Dobbeltsidet" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Filmenhed" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatisk dokumentføder" @@ -1761,7 +1772,7 @@ msgstr "Blæk printere" msgid "CRT monitors" msgstr "CRT skærme" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1825,8 +1836,9 @@ msgstr "A4" msgid "Max" msgstr "Maks" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1998,17 +2010,17 @@ msgstr "Angiver zoomfaktoren som skanneren skal bruge" msgid "Quick format" msgstr "Hurtig format" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Tilvalgsudstyr" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Skub ud" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Skub arket i den automatiske arkføder ud" @@ -2023,12 +2035,14 @@ msgstr "Automatisk skub ud" msgid "Eject document after scanning" msgstr "Skub dokumentet ud efter skanning" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "ADF-tilstand" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Vælger ADF tilstand (enkeltsidet/dobbeltsidet)" @@ -2078,14 +2092,14 @@ msgstr "" "NÃ¥r skankommando er sendt, starter skanningen først nÃ¥r der er trykket " "pÃ¥ knappen pÃ¥ skanneren." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2108,494 +2122,514 @@ msgstr "" msgid "User defined CCT profile" msgstr "Brugerdefineret" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Skub arket i den automatiske arkføder ud" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Ingen korrektion" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Analog gammakorrektion" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Tændt" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Slukket" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Dither" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "Fejlspredning" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Hvid niveau" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Sort niveau" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "Betinget" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Vandret" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Vandret" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Vandret" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Lodret" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "Lodret" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Print" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Halvtone" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Grovkalibrering" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Billedbetoning" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Mætning" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "" "Aktiver automatisk fastsættelse af tærskelværdi for " "stregtegningsskanninger." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Spejl billedet" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Spejlvend billedet vandret." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Hvid niveau for blÃ¥" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Fastsætter rødt niveau" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Farve stregtegning" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Udglatning" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Gamma værdi" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Tærskelværdi" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Tærskelværdi" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Støjreduktion" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Ingen korrektion" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Ingen korrektion" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Arkføder tilstand" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Avancerede indstillinger" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Ingen korrektion" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Udfald" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Arkføder tilstand" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2603,65 +2637,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Sluk-lampe tid" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "BlÃ¥ forskydning" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Grøn forskydning" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Grøn forskydning" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "BlÃ¥ forskydning" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Indstillinger for blÃ¥-kanals forskydning" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2670,418 +2704,406 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Duplex skan" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Avancerede indstillinger" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Støjreduktion" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Manuel pre-fokus" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Manuel pre-fokus" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "Skanningsopløsning" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Hvid niveau" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Rød intensitet" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Duplex skan" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Ekstra" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, fuzzy, no-c-format msgid "Disable interpolation" msgstr "Deaktiver bagudrettet sporing" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Farve stregtegning" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibrering" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Definer kalibreringstilstand" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Kalibreringsdatacache" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Sluk-lampe tid" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3090,89 +3112,108 @@ msgstr "" "Lampen bliver slukket efter den angivne tid (i minutter). Værdien 0 " "bevirker, at lampen ikke bliver slukket." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Grovkalibrering" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "Vent pÃ¥ knap" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "Vent pÃ¥ knap" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Vent pÃ¥ knap" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Grovkalibrering" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Gennemtving kalibrering før skanning" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Knapper" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibrering" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Begynd kalibreringsprocessen." -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Grovkalibrering" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Kalibreringsdatacache" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Grovkalibrering" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Grøn forskydning" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Filmadapter" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Filmadapter" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3279,6 +3320,309 @@ msgstr "Gamma værdi" msgid "Sets the gamma value of all channels." msgstr "Fastsætter gamma værdien for alle kanaler." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Avancerede indstillinger" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Grov" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fin" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Tilpasset" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatisk" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Uforandret" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC grÃ¥" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA GrÃ¥" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Langsom" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Hurtig" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Meget hurtig" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-pixel" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-pixel" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-pixel" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Print" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositiv" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Film-stribe" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Betinget" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Eksperiment" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Gør skarpere" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Angiv niveau for skærpning" + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Automatisk tærskelværdi" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Aktiver automatisk fastsættelse af tærskelværdi for " +"stregtegningsskanninger." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Vælg udglatningsfilter." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Skub mediet ud efter skanning" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Skubber mediet ud efter gennemført skanning." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Skift dokument" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Skift dokument." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Skub ud" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Skubber dokumentet ud." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Begynd kalibreringsprocessen." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Medie" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Vælg medietype." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Eksponeringstid" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"En længere eksponeringstid lader skanneren indsamle mere lys. Anbefalet " +"brug er 175% for papirbilleder, 150% for diapositiver og \"Negativ\" for " +"negativer. Ved mørke (undereksponerede) billeder, kan denne værdi øges." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Farve matrix" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Fastlægger skannerens farve matrix." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Tilpasset farve matrix." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "En farve matrix" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Tilpasset farve matrix for grÃ¥toneskanning." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Spejlvend vandret" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Spejlvend billedet vandret." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Spejlvend lodret" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Spejlvend billedet lodret." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Opdatér indstillinger" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Opdatér indstillinger." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8 bit uddata" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "Brug bit dybde større end 8 internt, men uddata kun 8 bit." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Vent pÃ¥ frontknap" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Vent med at begynde skanning, til frontknappen trykkes." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Sluk lampen" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Slukker for skannerens lampe." + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3289,12 +3633,6 @@ msgstr "SkanomrÃ¥de" msgid "Scan Mode Group" msgstr "Skanner tilstand" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositiv" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3302,12 +3640,12 @@ msgstr "Skannertilstand" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3488,11 +3826,6 @@ msgstr "Tænder/slukker for lampen" msgid "Calibrates for black and white level." msgstr "Kalibrerer for sort og hvidt niveau." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3603,298 +3936,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Avancerede indstillinger" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Grov" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fin" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Tilpasset" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatisk" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Uforandret" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC grÃ¥" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA GrÃ¥" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Langsom" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Hurtig" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Meget hurtig" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-pixel" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-pixel" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-pixel" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Print" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Film-stribe" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Betinget" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Eksperiment" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Gør skarpere" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Angiv niveau for skærpning" - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Automatisk tærskelværdi" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Aktiver automatisk fastsættelse af tærskelværdi for " -"stregtegningsskanninger." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Vælg udglatningsfilter." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Skub mediet ud efter skanning" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Skubber mediet ud efter gennemført skanning." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Skift dokument" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Skift dokument." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Skub ud" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Skubber dokumentet ud." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Begynd kalibreringsprocessen." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Medie" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Vælg medietype." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Eksponeringstid" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"En længere eksponeringstid lader skanneren indsamle mere lys. Anbefalet " -"brug er 175% for papirbilleder, 150% for diapositiver og \"Negativ\" for " -"negativer. Ved mørke (undereksponerede) billeder, kan denne værdi øges." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Farve matrix" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Fastlægger skannerens farve matrix." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Tilpasset farve matrix." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "En farve matrix" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Tilpasset farve matrix for grÃ¥toneskanning." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Spejlvend vandret" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Spejlvend billedet vandret." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Spejlvend lodret" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Spejlvend billedet lodret." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Opdatér indstillinger" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Opdatér indstillinger." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8 bit uddata" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "Brug bit dybde større end 8 internt, men uddata kun 8 bit." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Vent pÃ¥ frontknap" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Vent med at begynde skanning, til frontknappen trykkes." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Sluk lampen" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Slukker for skannerens lampe." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3993,7 +4034,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4161,9 +4202,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Stregtegning" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4292,7 +4333,7 @@ msgstr "Fastsætter billedbetoning" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4359,11 +4400,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4395,12 +4436,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Udskrift med høj opløsning" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Udskrift med lav opløsning" #: backend/kvs40xx_opt.c:243 @@ -4423,6 +4464,13 @@ msgstr "Normal" msgid "Enhanced mode" msgstr "Forbedring" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4482,7 +4530,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4517,12 +4565,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4532,13 +4580,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Spejl billedet" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4575,52 +4623,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 lodret linie" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Forstærk" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Farvekanalforstærkningsindstillinger" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "GrÃ¥-forstærkning" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Fastsætter grÃ¥-kanals forstærkning" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Rød forstærkning" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Fastsætter rød-kanals forstærkning" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Grøn forstærkning" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Fastsætter grøn-kanals forstærkning" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "BlÃ¥ forstærkning" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Fastsætter blÃ¥-kanals forstærkning" @@ -4706,7 +4754,7 @@ msgstr "En side" msgid "All pages" msgstr "Alle sider" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "arkføder skanner" @@ -5208,39 +5256,44 @@ msgstr "" "Varm op indtil lampens lyshed er konstant, i stedet for at insistere pÃ¥ " "40 sekunders opvarmningstid." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Grovkalibrering" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Negativ film" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativ" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5248,40 +5301,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, fuzzy, no-c-format msgid "Update button state" msgstr "Knap tilstand" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Knap 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Knap 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5370,7 +5423,7 @@ msgstr "Analog forende" msgid "Red gain value of the AFE" msgstr "Rød forstærkningsværdi for den analoge forende" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Rød forskydning" @@ -5645,7 +5698,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Denne indstilling reflekterer skannerknappernes status." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lampe tændt" @@ -5655,12 +5708,12 @@ msgstr "Lampe tændt" msgid "Turn on scanner lamp" msgstr "Tænd for skannerlampen" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Sluk lampe" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Sluk for skannerens lampe" @@ -5803,13 +5856,13 @@ msgid "Focus point" msgstr "Fokuseringspunkt" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Farvelinier pr. læsning" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "GrÃ¥skalalinier pr. læsning" #: backend/stv680.c:974 @@ -6460,52 +6513,52 @@ msgstr "Kalibreringstilstand" msgid "Define calibration mode" msgstr "Definer kalibreringstilstand" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Tænder/slukker for lampen" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA tændt" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Tænder/slukker for UTA'en" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Forskydning" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Indstillinger for farvekanalernes forskydning" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "GrÃ¥-forskydning" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Indstillinger for grÃ¥-kanals forskydning" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Indstillinger for rød-kanals forskydning" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Indstillinger for grøn-kanals forskydning" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Indstillinger for blÃ¥-kanals forskydning" @@ -12,11 +12,11 @@ # Rolf Bensch <rolf at bensch hyphen online dot de>, 2012-2019. msgid "" msgstr "" -"Project-Id-Version: sane-backends\n" +"Project-Id-Version: sane-backends 1.0.29\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-26 22:23+0200\n" -"PO-Revision-Date: 2019-07-28 23:01+0200\n" -"Last-Translator: Rolf Bensch <rolf@bensch-online.de>\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" +"PO-Revision-Date: 2020-01-26 16:29+0900\n" +"Last-Translator: Ulf Zibis <Ulf.Zibis@CoSoCo.de>\n" "Language-Team: \n" "Language: de\n" "MIME-Version: 1.0\n" @@ -36,37 +36,39 @@ msgid "Standard" msgstr "Standard" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 -#: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 backend/umax.c:5176 -#: backend/umax_pp.c:580 +#: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Scanbereich" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 #: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 -#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:629 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Farbverbesserung" #: include/sane/saneopts.h:159 backend/epson.c:3197 backend/epson2.c:1215 -#: backend/kvs20xx_opt.c:366 backend/kvs40xx_opt.c:597 backend/rts8891.c:2831 -#: backend/snapscan-options.c:923 backend/umax.c:5565 +#: backend/kvs20xx_opt.c:366 backend/kvs40xx_opt.c:597 +#: backend/rts8891.c:2831 backend/snapscan-options.c:923 +#: backend/umax.c:5565 #, no-c-format msgid "Advanced" msgstr "Erweitert" @@ -92,7 +94,7 @@ msgid "Bit depth" msgstr "Bittiefe" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Scanmodus" @@ -133,7 +135,7 @@ msgid "Bottom-right y" msgstr "Rechts Unten y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Scanauflösung" @@ -288,7 +290,7 @@ msgstr "Dateiname" msgid "Halftone pattern size" msgstr "Größe der Halbton-Matrix" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Halbton-Matrix" @@ -298,10 +300,10 @@ msgstr "Halbton-Matrix" msgid "Bind X and Y resolution" msgstr "Verbinde X- und Y-Auflösung" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativ" @@ -424,7 +426,8 @@ msgstr "Lampe beim Beenden ausschalten" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices supports." +"Read-only option that specifies how many options a specific device " +"supports." msgstr "" "Nur-Lese-Option, die angibt, wieviele Optionen ein bestimmtes Gerät " "unterstützt." @@ -466,15 +469,16 @@ msgid "" "scanner this cuts down the number of passes to one and on a one-pass " "scanner, it reduces the memory requirements and scan-time of the preview." msgstr "" -"Legt fest, dass alle Vorschauscans im Graustufenmodus durchgeführt werden. " -"Bei einem Three-Pass-Scanner wird dadurch nur ein Pass benötigt, bei einem " -"Single-Pass-Scanner wird der Speicherverbrauch und die Scanzeit verringert." +"Legt fest, dass alle Vorschauscans im Graustufenmodus durchgeführt " +"werden. Bei einem Three-Pass-Scanner wird dadurch nur ein Pass benötigt, " +"bei einem Single-Pass-Scanner wird der Speicherverbrauch und die " +"Scanzeit verringert." #: include/sane/saneopts.h:264 #, no-c-format msgid "" -"Number of bits per sample, typical values are 1 for \"line-art\" and 8 for " -"multibit scans." +"Number of bits per sample, typical values are 1 for \"line-art\" and 8 " +"for multibit scans." msgstr "" "Anzahl der Bits pro Farbwert, typische Werte sind 1 für Strichzeichnung- " "sowie 8 für Graustufen- und Farb-Scans." @@ -537,8 +541,8 @@ msgstr "Bestimmt die vertikale Auflösung des Bildes." #: include/sane/saneopts.h:301 #, no-c-format msgid "" -"Specifies the width of the media. Required for automatic centering of sheet-" -"fed scans." +"Specifies the width of the media. Required for automatic centering of " +"sheet-fed scans." msgstr "" "Legt die Breite des Mediums fest. Erforderlich für die automatische " "Zentrierung bei Einzelblatt-Scans." @@ -550,7 +554,8 @@ msgstr "Legt die Höhe der Medien fest." #: include/sane/saneopts.h:308 #, no-c-format -msgid "Determines whether a builtin or a custom gamma-table should be used." +msgid "" +"Determines whether a builtin or a custom gamma-table should be used." msgstr "" "Bestimmt ob die scannerinterne oder eine benutzerdefinierte Gammatabelle " "verwendet wird." @@ -558,12 +563,12 @@ msgstr "" #: include/sane/saneopts.h:312 #, no-c-format msgid "" -"Gamma-correction table. In color mode this option equally affects the red, " -"green, and blue channels simultaneously (i.e., it is an intensity gamma " -"table)." +"Gamma-correction table. In color mode this option equally affects the " +"red, green, and blue channels simultaneously (i.e., it is an intensity " +"gamma table)." msgstr "" -"Gamma-Korrekturtabelle. Im Farbmodus wirkt sich diese Option auf die rote, " -"grüne und blaue Farbkomponente aus. Es ist also eine Helligkeits-" +"Gamma-Korrekturtabelle. Im Farbmodus wirkt sich diese Option auf die " +"rote, grüne und blaue Farbkomponente aus. Es ist also eine Helligkeits-" "Gammatabelle." #: include/sane/saneopts.h:317 @@ -594,11 +599,11 @@ msgstr "Stellt den Kontrast des Bildes ein." #: include/sane/saneopts.h:332 #, no-c-format msgid "" -"Selects the \"graininess\" of the acquired image. Smaller values result in " -"sharper images." +"Selects the \"graininess\" of the acquired image. Smaller values result " +"in sharper images." msgstr "" -"Legt die \"Körnigkeit\" des gescannten Bildes fest. Kleinere Werte ergeben " -"schärfere Bilder." +"Legt die \"Körnigkeit\" des gescannten Bildes fest. Kleinere Werte " +"ergeben schärfere Bilder." #: include/sane/saneopts.h:336 #, no-c-format @@ -608,7 +613,8 @@ msgstr "Legt fest, ob das Bild im Halbtonmodus (Dithering) gescannt wird." #: include/sane/saneopts.h:339 include/sane/saneopts.h:354 #, no-c-format msgid "Selects what radiance level should be considered \"black\"." -msgstr "Bestimmt, welcher Helligkeitswert als Schwarz angesehen werden soll." +msgstr "" +"Bestimmt, welcher Helligkeitswert als Schwarz angesehen werden soll." #: include/sane/saneopts.h:342 include/sane/saneopts.h:363 #, no-c-format @@ -640,8 +646,8 @@ msgstr "" #, no-c-format msgid "Selects what red radiance level should be considered \"black\"." msgstr "" -"Bestimmt, welcher Helligkeitswert der roten Komponente als Schwarz angesehen " -"werden soll." +"Bestimmt, welcher Helligkeitswert der roten Komponente als Schwarz " +"angesehen werden soll." #: include/sane/saneopts.h:358 #, no-c-format @@ -661,22 +667,24 @@ msgstr "" #, no-c-format msgid "Selects what red radiance level should be considered \"full red\"." msgstr "" -"Bestimmt, welcher Helligkeitswert der roten Komponente als Weiß angesehen " -"werden soll." +"Bestimmt, welcher Helligkeitswert der roten Komponente als Weiß " +"angesehen werden soll." #: include/sane/saneopts.h:367 #, no-c-format -msgid "Selects what green radiance level should be considered \"full green\"." +msgid "" +"Selects what green radiance level should be considered \"full green\"." msgstr "" -"Bestimmt, welcher Helligkeitswert der grünen Komponente als Weiß angesehen " -"werden soll." +"Bestimmt, welcher Helligkeitswert der grünen Komponente als Weiß " +"angesehen werden soll." #: include/sane/saneopts.h:370 #, no-c-format -msgid "Selects what blue radiance level should be considered \"full blue\"." +msgid "" +"Selects what blue radiance level should be considered \"full blue\"." msgstr "" -"Bestimmt, welcher Helligkeitswert der blauen Komponente als Weiß angesehen " -"werden soll." +"Bestimmt, welcher Helligkeitswert der blauen Komponente als Weiß " +"angesehen werden soll." #: include/sane/saneopts.h:374 #, no-c-format @@ -686,8 +694,8 @@ msgstr "Legt den Farbwert (Blauwert) des gescannten Bildes fest." #: include/sane/saneopts.h:377 #, no-c-format msgid "" -"The saturation level controls the amount of \"blooming\" that occurs when " -"acquiring an image with a camera. Larger values cause more blooming." +"The saturation level controls the amount of \"blooming\" that occurs " +"when acquiring an image with a camera. Larger values cause more blooming." msgstr "" "Der Sättigungsgrad steuert die Belichtung einesmit einer Kamera " "aufgenommenen Bildes. Höhere Werte sorgen für eine stärkere Belichtung." @@ -702,7 +710,8 @@ msgstr "Der Dateiname des zu ladenden Bildes." msgid "" "Sets the size of the halftoning (dithering) pattern used when scanning " "halftoned images." -msgstr "Legt die Größe der für den Scanvorgang verwendeten Halbtonmatrix fest." +msgstr "" +"Legt die Größe der für den Scanvorgang verwendeten Halbtonmatrix fest." #: include/sane/saneopts.h:389 #, no-c-format @@ -762,8 +771,8 @@ msgstr "Analoge Gammakorrektur für Blau" #: include/sane/saneopts.h:415 #, no-c-format -msgid "Warmup lamp before scanning" -msgstr "Wärme die Lampe vor dem Scannen auf" +msgid "Warm up lamp before scanning" +msgstr "Lampe vor dem Scannen aufwärmen" #: include/sane/saneopts.h:417 #, no-c-format @@ -915,7 +924,7 @@ msgstr "Operation nicht unterstützt" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "Operation wurde abgebrochen" #: backend/sane_strstatus.c:68 @@ -996,8 +1005,8 @@ msgstr "Vor dem nächsten Scan kalibrieren" #: backend/artec_eplus48u.c:2943 #, no-c-format msgid "" -"If enabled, the device will be calibrated before the next scan. Otherwise, " -"calibration is performed only before the first start." +"If enabled, the device will be calibrated before the next scan. " +"Otherwise, calibration is performed only before the first start." msgstr "" "Wenn diese Option eingeschaltet ist, wird vor dem nächsten Scan eine " "Kalibrierung durchgeführt. Ansonsten findet die Kalibrierung nur vor dem " @@ -1011,13 +1020,14 @@ msgstr "Nur Shading-Korrektur durchführen" #: backend/artec_eplus48u.c:2956 #, no-c-format msgid "" -"If enabled, only the shading correction is performed during calibration. The " -"default values for gain, offset and exposure time, either build-in or from " -"the configuration file, are used." +"If enabled, only the shading correction is performed during calibration. " +"The default values for gain, offset and exposure time, either built-in " +"or from the configuration file, are used." msgstr "" -"Ist diese Option eingeschaltet, dann wird während der Kalibrierung nur die " -"Shading-Korrektur durchgeführt. Andere Kalibrierungswerte werden aus der " -"Konfigurationsdatei oder aus den Voreinstellungen des Backends übernommen." +"Ist diese Option eingeschaltet, dann wird während der Kalibrierung nur " +"die Shading-Korrektur durchgeführt. Andere Kalibrierungswerte werden aus " +"der Konfigurationsdatei oder aus den Voreinstellungen des Backends " +"übernommen." #: backend/artec_eplus48u.c:2967 #, no-c-format @@ -1041,82 +1051,44 @@ msgstr "Duplexscan" #: backend/avision.h:783 #, no-c-format -msgid "Duplex scan provide a scan of the front and back side of the document" +msgid "" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" -"Duplex Scan ermöglicht das Scannen der Vorder- und Rückseite eines Dokuments" - -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Scanner kalibrieren" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Erzwinge Scannerkalibrierung vor dem Scannen" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Graustufen-Scan" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Führe einen Graustufen-Scan statt eines Farb-Scans durch" +"Duplex Scan ermöglicht das Scannen der Vorder- und Rückseite eines " +"Dokuments" -#: backend/canon630u.c:306 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Analog Gain" -msgstr "Analoge Verstärkung" +msgid "Correction according to transparency ratio" +msgstr "Korrektur entsprechend des Seitenverhältnisses" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Vergrößere oder verkleinere die analoge Verstärkung des CCD-Sensors" +msgid "Correction according to film type" +msgstr "Korrektur entsprechend des Filmtyps" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Gammakorrektur" +msgid "Fine color" +msgstr "Farbe" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Wählt die korrigierte Gammakurve aus" +msgid "Negatives" +msgstr "Negative" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Rohdaten" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Farbe" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Keine Transparenzkorrektur" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Korrektur entsprechend des Filmtyps" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Korrektur entsprechend des Seitenverhältnisses" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negative" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1251,8 +1223,8 @@ msgstr "Ungültige IDENTIFY Nachricht" #: backend/canon.c:460 #, no-c-format -msgid "option not connect" -msgstr "Option nicht verbunden" +msgid "option not correct" +msgstr "Option nicht korrekt" #: backend/canon.c:474 #, no-c-format @@ -1380,7 +1352,8 @@ msgstr "Manuelle Einstellung des Fokus" #: backend/canon.c:1341 #, no-c-format msgid "Set the optical system's focus position by hand (default: 128)." -msgstr "Setzt die Fokusposition des optischen System von Hand (Standard: 128)." +msgstr "" +"Setzt die Fokusposition des optischen System von Hand (Standard: 128)." #: backend/canon.c:1351 #, no-c-format @@ -1465,7 +1438,8 @@ msgstr "Film vor Beenden auswerfen" #: backend/canon.c:1676 #, no-c-format -msgid "Automatically eject the film from the device before exiting the program" +msgid "" +"Automatically eject the film from the device before exiting the program" msgstr "" "Den Film automatisch aus dem Gerät auswerfen bevor das Programm schließt" @@ -1492,7 +1466,8 @@ msgstr "Nur Flachbett" #: backend/canon.c:1703 #, no-c-format msgid "Disable auto document feeder and use flatbed only" -msgstr "Automatischen Dokumenteneinzug abschalten und nur Flachbett benutzen" +msgstr "" +"Automatischen Dokumenteneinzug abschalten und nur Flachbett benutzen" #: backend/canon.c:1713 backend/canon.c:1723 #, no-c-format @@ -1539,133 +1514,185 @@ msgstr "Filmtyp auswählen" msgid "Select the film type" msgstr "Wählt den Filmtyp aus" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Scanner kalibrieren" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Erzwinge Scannerkalibrierung vor dem Scannen" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Graustufen-Scan" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Führe einen Graustufen-Scan statt eines Farb-Scans durch" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analoge Verstärkung" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "" +"Vergrößere oder verkleinere die analoge Verstärkung des CCD-Sensors" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gammakorrektur" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Wählt die korrigierte Gammakurve aus" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Flachbett" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "Automatischer Dokumenteneinzug vorne" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "Automatischer Dokumenteneinzug hinten" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Dokumenteneinzug mit Duplex" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "Karte Vorderseite" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "Karte Rückseite" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "Karte Duplex" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Rot" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Grün" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Blau" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Rot verstärken" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Grün verstärken" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Blau verstärken" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Kein" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "Schwellwert für Leerseitenerkennung" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "Seiten mit geringer Pixeldichte überspringen" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Einseitig" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 #: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Duplex" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Durchlichtaufsatz" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatischer Dokumenteneinzug" @@ -1777,7 +1804,7 @@ msgstr "Tintenstrahldrucker" msgid "CRT monitors" msgstr "Monitore" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1841,14 +1868,16 @@ msgstr "A4" msgid "Max" msgstr "Maximal" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 #: backend/plustek.c:721 backend/plustek_pp.c:658 backend/sceptre.c:673 -#: backend/snapscan-options.c:354 backend/stv680.c:1030 backend/teco2.c:1882 -#: backend/test.c:306 backend/u12.c:473 backend/umax.c:5054 +#: backend/snapscan-options.c:354 backend/stv680.c:1030 +#: backend/teco2.c:1882 backend/test.c:306 backend/u12.c:473 +#: backend/umax.c:5054 #, no-c-format msgid "Scan Mode" msgstr "Scanmodus" @@ -2013,17 +2042,17 @@ msgstr "Definiert den Vergrösserungsfaktor, der vom Scanner benutzt wird" msgid "Quick format" msgstr "Schnellformat" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Optionales Zubehör" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Auswerfen" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Wirft das Blatt aus dem automatischen Dokumenteneinzug aus" @@ -2038,12 +2067,14 @@ msgstr "Automatischer Auswurf" msgid "Eject document after scanning" msgstr "Dokument nach dem Scannen auswerfen" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Dokumenteneinzug Modus" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Wählt den ADF-Modus aus (einseitig/doppelseitig)" @@ -2061,11 +2092,12 @@ msgstr "Wähle den Schacht zum Scannen aus" #: backend/epson.h:69 backend/epson2.h:68 #, no-c-format msgid "" -"Selects the gamma correction value from a list of pre-defined devices or the " -"user defined table, which can be downloaded to the scanner" +"Selects the gamma correction value from a list of pre-defined devices or " +"the user defined table, which can be downloaded to the scanner" msgstr "" -"Wählt die Gammakorrektur aus einer Liste von vordefinierten Geräten aus oder " -"eine benutzerdefinierte Tabelle, die in den Scanner geladen werden kann" +"Wählt die Gammakorrektur aus einer Liste von vordefinierten Geräten aus " +"oder eine benutzerdefinierte Tabelle, die in den Scanner geladen werden " +"kann" #: backend/epson.h:72 backend/epson2.h:71 #, no-c-format @@ -2074,7 +2106,8 @@ msgstr "Fokus Position" #: backend/epson.h:73 backend/epson2.h:72 #, no-c-format -msgid "Sets the focus position to either the glass or 2.5mm above the glass" +msgid "" +"Sets the focus position to either the glass or 2.5mm above the glass" msgstr "Setzt den Fokus entweder auf das Glas oder 2.5mm darüber" #: backend/epson.h:75 backend/epson2.h:74 @@ -2091,16 +2124,16 @@ msgstr "" "Beginne mit dem Scannen erst, wenn nach dem Senden des Scankommandos die " "Taste am Scanner gedrückt wird." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Infrarot" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "Durchlichtaufsatz 8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Infrarot" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2121,592 +2154,619 @@ msgstr "Eingebautes CCT-Profil" msgid "User defined CCT profile" msgstr "Benutzerdefiniertes CCT-Profil" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "Lade" + +#: backend/epsonds.c:751 +#, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Lade ein Blatt im automatischen Dokumenteneinzug" + +#: backend/epsonds.c:771 +#, no-c-format +msgid "ADF Skew Correction" +msgstr "ADF-Schräglaufkorrektur" + +#: backend/epsonds.c:773 +#, no-c-format +msgid "Enables ADF skew correction" +msgstr "aktiviert ADF-Schräglaufkorrektur" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "An" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Aus" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Halbton" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Diffusion" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Weiß" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Schwarz" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Fortfahren" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Stopp" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horizontal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Horizontal breit" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Horizontal schmal" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertikal" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Vertikal breit" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "Oben nach unten" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "Unten nach oben" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Vorne" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Hinten" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "Gamma-Exponent" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "Verändert die Intensität der mittleren Farbtöne" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "RIF" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "Reverse Image Format" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "Halbton Typ" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "Halbton Typ einstellen" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "Halbton Muster einstellen" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "Kontur" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, no-c-format msgid "Perform outline extraction" msgstr "Kontur ermitteln" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "Gewichtung" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "Negative Werte zum Weichzeichnen oder positive Werte zum Schärfen" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, no-c-format msgid "Separation" msgstr "Trennung" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "Aktiviere die automatische Trennung von Bild und Text" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "Bild spiegeln" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "Bild horizontal spiegeln" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, no-c-format msgid "White level follower" msgstr "Weißwertfolger" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, no-c-format msgid "Control white level follower" msgstr "Einstellungen für Weißwertfolger" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, no-c-format msgid "BP filter" msgstr "Kugelschreiber Filter" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "Verbessert die Qualität von mit Kugelschreiber geschriebenen Text" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Glättung" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "Aktiviere Glättung zur Verbesserung von OCR" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, no-c-format msgid "Gamma curve" msgstr "Gammakurve" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" "Gammakurve, von hell zu dunkel, die oberen beiden funktionieren nicht " "unbedingt" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Schwellwertkurve" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format -msgid "Threshold curve, from light to dark, but upper two may not be linear" +msgid "" +"Threshold curve, from light to dark, but upper two may not be linear" msgstr "" "Dynamische Schwellwertkurve, von hell zu dunkel, die oberen beiden sind " "nicht unbedingt linear" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "Schwellwert Weiß" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" -msgstr "Pixel unterhalb vom Schwellwert in Weiß anstelle von Schwarz umwandeln" +msgstr "" +"Pixel unterhalb vom Schwellwert in Weiß anstelle von Schwarz umwandeln" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "Rauschunterdrückung" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "Matrix 5x5" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "5x5 Pixel Rauschunterdrückung" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "Matrix 4x4" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "4x4 Pixel Rauschunterdrückung" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "Matrix 3x3" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "3x3 Pixel Rauschunterdrückung" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "Matrix 2x2" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "2x2 Pixel Rauschunterdrückung" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "Streuung" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "Setze SDTC Varianz (Empfindlichkeit), 0 = 127" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, no-c-format msgid "Auto width detection" msgstr "Vorlagenbreite automatisch erkennen" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" "Der Scanner erkennt automatisch die Seitengrößen. Verlangsamt die " "Scanngeschwindigkeit." -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, no-c-format msgid "Auto length detection" msgstr "Vorlagenlänge automatisch erkennen" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -"Der Scanner erkennt die Seitenausrichtung. Kann einige Programme verwirren." +"Der Scanner erkennt die Seitenausrichtung. Kann einige Programme " +"verwirren." -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "Komprimierung" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" "Aktiviere Datenkomprimierung. Kann das verwendete Scanprogramm abstürzen " "lassen." -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "Komprimierungsparameter" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" -"Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) is " -"same as 4" +"Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " +"is same as 4" msgstr "" -"JPEG-Komprimierung: 1 = kleinste Datei, 7 = größte Datei, 0 (Voreinstellung) " -"= 4" +"JPEG-Komprimierung: 1 = kleinste Datei, 7 = größte Datei, 0 " +"(Voreinstellung) = 4" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "Duplex Aktion" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "Aktion bei Duplex Fehler" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "Duplex Schrägeinlauf" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "Aktiviere Duplexfehler bei Schrägeinlauf" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "Duplex Papierdicke" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Aktiviere Duplexfehler bei zu großer Papierdicke" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "Duplex Seitenlänge" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "Aktiviere Duplexfehler bei falscher Seitenlänge" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "Duplex unterschiedliche Seitenlänge" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "Aktiviere Duplexfehler bei unterschiedlicher Seitenlänge" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "Duplex Fehlerbehebung" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "Rücklauf bei Papierstau" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "Dokumentenschutz" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "Papierstau in der Duplexeinheit prognostizieren" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, no-c-format msgid "Advanced paper protection" msgstr "Erweiterter Dokumentenschutz" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" "Papierstau in der Duplexeinheit mit verbesserten Sensoren prognostizieren" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, no-c-format msgid "Staple detection" msgstr "Heftklammer - Erkennung" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" -msgstr "von Heftklammern verursachter Papierstau im Dokumenteneinzug erkennen" +msgstr "" +"von Heftklammern verursachter Papierstau im Dokumenteneinzug erkennen" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "Hintergrundfarbe" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format -msgid "Set color of background for scans. May conflict with overscan option" +msgid "" +"Set color of background for scans. May conflict with overscan option" msgstr "Hintergrundfarbe für Scans. Steht im Konflikt mit Overscan" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "Dropout-Farbe" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" -"One-pass scanners use only one color during gray or binary scanning, useful " -"for colored paper or ink" +"One-pass scanners use only one color during gray or binary scanning, " +"useful for colored paper or ink" msgstr "" -"One-Pass-Scanner scannen nur eine Farbe bei Graustufen und Strichzeichnungs-" -"Scans, hilfreich bei farbigem Papier oder Tinte" +"One-Pass-Scanner scannen nur eine Farbe bei Graustufen und " +"Strichzeichnungs-Scans, hilfreich bei farbigem Papier oder Tinte" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "Scannerspeicher" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "Aktiviere schnelle Duplex Scans in den Scannerspeicher" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "Prepick" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "Nächste Seite vom Dokumenteneinzug einziehen" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "Overscan" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" -"Collect a few mm of background on top side of scan, before paper enters ADF, " -"and increase maximum scan area beyond paper size, to allow collection on " -"remaining sides. May conflict with bgcolor option" +"Collect a few mm of background on top side of scan, before paper enters " +"ADF, and increase maximum scan area beyond paper size, to allow " +"collection on remaining sides. May conflict with bgcolor option" msgstr "" -"Fügt einen Rand vor und nach dem Einzug eines Dokuments hinzu, damit kleine " -"Vorlagen auf einer Seite gesammelt werden können. Steht im Konflikt mit " -"Hintergrundfarbe." +"Fügt einen Rand vor und nach dem Einzug eines Dokuments hinzu, damit " +"kleine Vorlagen auf einer Seite gesammelt werden können. Steht im " +"Konflikt mit Hintergrundfarbe." -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "Sleep Timer" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format -msgid "Time in minutes until the internal power supply switches to sleep mode" +msgid "" +"Time in minutes until the internal power supply switches to sleep mode" msgstr "Zeit in Minuten nachdem der Scanner in den Ruhezustand wechselt" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "Ausschalt Timer" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" -"Time in minutes until the internal power supply switches the scanner off. " -"Will be rounded to nearest 15 minutes. Zero means never power off." +"Time in minutes until the internal power supply switches the scanner " +"off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -"Zeit in Minuten, nachdem sich der Scanner selbständig ausschaltet. Wird auf " -"die nächsten 15 Minuten gerundet. 0 = deaktiviert." +"Zeit in Minuten, nachdem sich der Scanner selbständig ausschaltet. Wird " +"auf die nächsten 15 Minuten gerundet. 0 = deaktiviert." -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, no-c-format msgid "Duplex offset" msgstr "Duplex Offset" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "Vorder-/Rückseiten Offset" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Offset grüner Kanal" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, no-c-format msgid "Adjust green/red offset" msgstr "Rot/Grün Offset" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Offset blauer Kanal" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "Blau/Rot Offset" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "Nicht genügend Speicher" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" -"Limit driver memory usage for use in embedded systems. Causes some duplex " -"transfers to alternate sides on each call to sane_read. Value of option " -"'side' can be used to determine correct image. This option should only be " -"used with custom front-end software." +"Limit driver memory usage for use in embedded systems. Causes some " +"duplex transfers to alternate sides on each call to sane_read. Value of " +"option 'side' can be used to determine correct image. This option should " +"only be used with custom front-end software." msgstr "" "Speicherbedarf für Treiber in Embedded Systems begrenzen. Kann bei jedem " -"Aufruf von sane_read die Seitenreihenfolge bei Duplexscans vertauschen. Mit " -"der Option 'Duplex Seite' kann die korrekte Seitenreihenfolge gewährleistet " -"werden. Diese Option funktioniert nur mit selbst erstellter Scansoftware." +"Aufruf von sane_read die Seitenreihenfolge bei Duplexscans vertauschen. " +"Mit der Option 'Duplex Seite' kann die korrekte Seitenreihenfolge " +"gewährleistet werden. Diese Option funktioniert nur mit selbst " +"erstellter Scansoftware." -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, no-c-format msgid "Duplex side" msgstr "Duplex Seite" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " @@ -2715,154 +2775,155 @@ msgstr "" "Wählt die Seite vom nächsten Duplexscan aus aus (0 = Vorderseite, 1 = " "Rückseite), welche von sane_read zurückgegeben wird." -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "Hardware Entzerrung und Zuschnitt" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "Scanner rotiert und beschneidet den Scan digital." -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Software Entzerrung" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "Treiber rotiert verzerrte Scans." -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Software Fehlerkorrektur" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "Max. Durchmesser einzelner zu entfernender Fehlstellen im Scan." -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "Software Zuschnitt" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "Treiber entfernt Ränder von Scans." -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "Einzugshalt bei Abbruch" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format -msgid "Request driver to halt the paper feed instead of eject during a cancel." +msgid "" +"Request driver to halt the paper feed instead of eject during a cancel." msgstr "" "Bei einem Abbruch verbleibt die Seite im Dukumenteneinzug und wird nicht " "ausgeworfen." -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, no-c-format msgid "Endorser Options" msgstr "Stempel Optionen" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "Einstellungen für Stempel" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "Stempel" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "Aktiviere Stempel" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "Stempelgröße" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "Max. Wert für Stempelzähler." -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "Stempelwert" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "Anfangswert für Stempelzähler," -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "Schrittweite für Stempelzähler" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "Schrittweite für Stempelzähler." -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "Stempel Y" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "Stempelabstand zum oberen Seitenrand." -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "Stempel Schriftart" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "Stempel Schriftart." -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, no-c-format msgid "Endorser direction" msgstr "Stempel Ausrichtung" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "Stempel Druckrichtung" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "Stempelseite" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "Druckseite für Stempel; muss vom Scanner unterstützt werden" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "Stempel Zeichenkette" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " @@ -2871,354 +2932,360 @@ msgstr "" "Stempel als alphanumerische Zeichenkette. %05ud oder %08ud am Ende wird " "durch den Stempelzähler ersetzt." -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "Obere Kante" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "Papier wurde teilweise in den Dokumenteneinzug eingezogen" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "A3 Vorlage" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "A3 Vorlage erkannt" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "B4 Vorlage" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "B4 Vorlage erkannt" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "A4 Vorlage" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "A4 Vorlage erkannt" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "B5 Vorlage" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "B5 Vorlage erkannt" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "OMR oder DF" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "OMR oder Double Feed erkannt" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "Energiesparmodus" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "Der Scanner befindet im Energiesparmodus" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "Manueller Einzug" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "Manueller Einzug ausgewählt" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "Funktion" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "Funktionszeichen auf dem Bildschirm" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "wenig Tinte" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "Wenig Imprinter Tinte" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "Double Feed" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "Double Feed erkannt" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "Fehlercode" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "Hardwarefehler" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "Schräglaufwinkel" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "Schwarzer Hintergrund erforderlich" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "verbleibende Tinte" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, no-c-format msgid "Imprinter ink level" msgstr "Imprinter Tintenstand" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, no-c-format msgid "Density" msgstr "Dichte" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "Dichte Einstellung" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, no-c-format msgid "Duplex switch" msgstr "Duplexscan" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "Treiber entfernt digital Ränder vom Scan" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "Treiber verwirft Scans mit geringer Schwarzfärbung" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "Software Dokumentendrehung" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "Treiber erkennt und dreht um 90° verdrehte Vorlagen" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extras" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" -msgstr "Dynamische Schwellwertkurve, von hell zu dunkel, nomalerweise 50-65" - -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Deaktiviere dynamische Strichzeichnung" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." msgstr "" -"Deaktiviere Software angepassten Algorithmus zur Erstellung von " -"Strichzeichnungen anstelle von Hardware-Strichzeichnungen." +"Dynamische Schwellwertkurve, von hell zu dunkel, nomalerweise 50-65" -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Interpolation abschalten" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" -"When using high resolutions where the horizontal resolution is smaller than " -"the vertical resolution this disables horizontal interpolation." +"When using high resolutions where the horizontal resolution is smaller " +"than the vertical resolution this disables horizontal interpolation." msgstr "" "Deaktiviere horizontale Interpolation bei hoher Auflösung, bei denen die " "horizontale Auflösung kleiner ist als die vertikale." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, no-c-format msgid "Color filter" msgstr "Farbfilter" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -"Diese Option wählt die verwendete Farbe für Strichzeichnungs- und Graustufen-" -"Scans." +"Diese Option wählt die verwendete Farbe für Strichzeichnungs- und " +"Graustufen-Scans." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, no-c-format msgid "Calibration file" msgstr "Kalibrierungsdatei" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, no-c-format msgid "Specify the calibration file to use" msgstr "Kalibrierungsdatei auswählen" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, no-c-format msgid "Calibration cache expiration time" msgstr "Gültigkeitszeitraum für Kalibrierungszwischenspeicher" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" -"Time (in minutes) before a cached calibration expires. A value of 0 means " -"cache is not used. A negative value means cache never expires." +"Time (in minutes) before a cached calibration expires. A value of 0 " +"means cache is not used. A negative value means cache never expires." msgstr "" "Gültigkeitszeitraum für Kalibrierungszwischenspeicher in Minuten. 0 = " -"Zwischenspeicher deaktiviert. Ein negativer Wert lässt die Gültigkeit nie " -"ablaufen." +"Zwischenspeicher deaktiviert. Ein negativer Wert lässt die Gültigkeit " +"nie ablaufen." -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Lampenausschaltzeit" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" -"The lamp will be turned off after the given time (in minutes). A value of 0 " -"means, that the lamp won't be turned off." +"The lamp will be turned off after the given time (in minutes). A value " +"of 0 means, that the lamp won't be turned off." msgstr "" "Die Lampe wird nach der angegebenen Zeit (in Minuten) ausgeschaltet. Ein " "Wert von 0 bedeutet, dass die Lampe nich ausgeschaltet wird." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "während Scan Lampe ausschalten" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "Die Lampe wird beim Scannen abgeschaltet. " -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Datei Taste" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "OCR Taste" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Einschalt Taste" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, no-c-format msgid "Extra button" msgstr "Zusatztaste" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, no-c-format -msgid "Need calibration" -msgstr "Benötigt Kalibirierung" +msgid "Needs calibration" +msgstr "Benötigt Kalibrierung" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "" "Der Scanner benötigt eine Kalibrierung für die momentanen Einstellungen" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Tasten" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibrierung" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Starte den Kalibrierungsprozess mit einem Spezialblatt" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Kalibrierung zurücksetzen" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Kalibrierungszwischenspeicher löschen" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, no-c-format msgid "Force calibration" msgstr "Kalibrierung erzwingen" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "Kalibrierung trotz Daten im Zwischenspeicher erzwingen" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, no-c-format +msgid "Ignore internal offsets" +msgstr "Interne Offsets ignorieren" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "Bild mit Kalibrierungsbereichen scannen" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Durchlichteinheit" +#: backend/genesys/genesys.h:80 +#, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Infrarot-Durchlichteinheit" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3231,7 +3298,8 @@ msgstr "" "Legt fest, welche SCanfarbe im Garustufen-Modus verwendet wird " "(Standardwert: Grün)." -#: backend/gt68xx.c:553 backend/hp3900_sane.c:1392 backend/mustek_usb2.c:410 +#: backend/gt68xx.c:553 backend/hp3900_sane.c:1392 +#: backend/mustek_usb2.c:410 #, no-c-format msgid "Debugging Options" msgstr "Optionen zur Fehlersuche" @@ -3244,11 +3312,11 @@ msgstr "Automatisches Aufwärmen" #: backend/gt68xx.c:566 #, no-c-format msgid "" -"Warm-up until the lamp's brightness is constant instead of insisting on 60 " -"seconds warm-up time." +"Warm-up until the lamp's brightness is constant instead of insisting on " +"60 seconds warm-up time." msgstr "" -"Warte solange, bis die Helligkeit der Lampe konstant ist anstatt einfach 60 " -"Sekunden zu warten." +"Warte solange, bis die Helligkeit der Lampe konstant ist anstatt einfach " +"60 Sekunden zu warten." #: backend/gt68xx.c:578 #, no-c-format @@ -3262,8 +3330,8 @@ msgid "" "Don't select the full height. For testing only." msgstr "" "Scanne den gesamten möglichen Scanbereich inklusive des " -"Kalibrierungsstreifens. Vorsicht, keine zu große Länge auswählen. Nur für " -"Testzwecke." +"Kalibrierungsstreifens. Vorsicht, keine zu große Länge auswählen. Nur " +"für Testzwecke." #: backend/gt68xx.c:591 #, no-c-format @@ -3274,8 +3342,8 @@ msgstr "Grobkalibrierung" #, no-c-format msgid "" "Setup gain and offset for scanning automatically. If this option is " -"disabled, options for setting the analog frontend parameters manually are " -"provided. This option is enabled by default. For testing only." +"disabled, options for setting the analog frontend parameters manually " +"are provided. This option is enabled by default. For testing only." msgstr "" "Stelle Verstärkung und Versatz automatisch ein. Wenn dies Option " "ausgeschaltet ist, können die Parameter des AFE (\"Analog Frontend\") " @@ -3290,14 +3358,14 @@ msgstr "Grobkalibrierung nur für ersten Scan" #: backend/gt68xx.c:614 #, no-c-format msgid "" -"Coarse calibration is only done for the first scan. Works with most scanners " -"and can save scanning time. If the image brightness is different with each " -"scan, disable this option. For testing only." +"Coarse calibration is only done for the first scan. Works with most " +"scanners and can save scanning time. If the image brightness is " +"different with each scan, disable this option. For testing only." msgstr "" "Die Grobkalibrierung wird nur für den ersten Scan durchgeführt. Das " -"funktioniert mit den meisten Scannern und kann einiges an Scanzeit sparen. " -"Wenn die Helligkeit der Bilder von Scan zu Scan schwankt, sollte diese " -"Option ausgeschaltet werden. Nur für Testzwecke." +"funktioniert mit den meisten Scannern und kann einiges an Scanzeit " +"sparen. Wenn die Helligkeit der Bilder von Scan zu Scan schwankt, sollte " +"diese Option ausgeschaltet werden. Nur für Testzwecke." #: backend/gt68xx.c:647 #, no-c-format @@ -3307,14 +3375,15 @@ msgstr "Backtrack-Zeilen" #: backend/gt68xx.c:649 #, no-c-format msgid "" -"Number of lines the scan slider moves back when backtracking occurs. That " -"happens when the scanner scans faster than the computer can receive the " -"data. Low values cause faster scans but increase the risk of omitting lines." +"Number of lines the scan slider moves back when backtracking occurs. " +"That happens when the scanner scans faster than the computer can receive " +"the data. Low values cause faster scans but increase the risk of " +"omitting lines." msgstr "" "Anzahl der Zeilen, die der Scanschlitten zurückfährt, wenn Backtracking " -"auftritt. Das passiert, wenn der Scanner schneller scant, als der Computer " -"die Daten aufnehmen kann. Niedrigere Werte sorgen für schnellere Scans, " -"erhöhen jedoch das Risiko, Zeilen zu überspringen." +"auftritt. Das passiert, wenn der Scanner schneller scant, als der " +"Computer die Daten aufnehmen kann. Niedrigere Werte sorgen für " +"schnellere Scans, erhöhen jedoch das Risiko, Zeilen zu überspringen." #: backend/gt68xx.c:674 backend/mustek_usb2.c:452 #, no-c-format @@ -3326,6 +3395,311 @@ msgstr "Gammawert" msgid "Sets the gamma value of all channels." msgstr "Legt den Gammawert für alle Kanäle fest." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Erweiterte Optionen" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Grob" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fein" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatisch" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Unverändert" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC Grau" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA Grau" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Langsam" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Schnell" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Besonders schnell" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2 Pixel" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4 Pixel" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8 Pixel" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Foto" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Dia" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Film-Streifen" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "Automatischer Dokumenteneinzug" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Bedingt" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experiment" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Schärfen" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Legt den Wert für die Schärfe fest." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Automatischer Schwellwert" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Schaltet die automatische Bestimmung des Schwellwerts für den Schwarz-" +"Weiß-Modus ein." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Wählt den Glättungs-Filter aus." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Medium nach dem Scannen auswerfen" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Wirft das Medium nach dem Scan aus." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Dokument wechseln" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Dokument wechseln." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Auswerfen" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Dokument auswerfen." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Startet den Kalibrierungsprozess." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Medium" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Legt den Typ des Mediums fest." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Belichtungszeit" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Bei einer längeren Belichtungszeit kann der Scanner mehr Licht " +"auffangen. Empfohlene Werte: 175% für Fotos, 150% für normale Dias und " +"\"Negativ\" für Negativ-Filme. Für dunkle (unterentwickelte) Bilder kann " +"dieser Wert vergrößert werden." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Farbmatrix" + +#: backend/hp-option.h:121 +#, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Legt die Farbmatrix für den Scanner fest." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Benutzerdefinierte Farbmatrix." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Graue Farbmatrix" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Benutzerdefinierte Farbmatrix für Graustufenscans." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Horizontal spiegeln" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Bild horizontal spiegeln." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Vertikal spiegeln" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Bild vertikal spiegeln." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Optionen aktualisieren" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Optionen aktualisieren." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8-Bit-Ausgabe" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Benutze intern eine Frabtiefe von mehr als 8 Bit, extern aber nur 8 Bit." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Warten auf vordere Taste" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Warte mit dem Scan auf das Drücken der vorderen Taste." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Lampe ausschalten" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Schalte Scannerlampe aus." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3336,12 +3710,6 @@ msgstr "Geometrie" msgid "Scan Mode Group" msgstr "Scanmodus" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Dia" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3349,12 +3717,13 @@ msgstr "Scannermodell" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" -msgstr "Erlaubt Geräteverhalten mit anderen unterstützten Modellen zu testen" +msgid "Allows one to test device behavior with other supported models" +msgstr "" +"Erlaubt Geräteverhalten mit anderen unterstützten Modellen zu testen" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "Bildfarben werden invertiert" #: backend/hp3900_sane.c:1436 @@ -3395,9 +3764,9 @@ msgstr "Erzwinge echte Tiefe" #: backend/hp3900_sane.c:1485 #, no-c-format msgid "" -"If gamma is enabled, scans are always made in 16 bits depth to improve image " -"quality and then converted to the selected depth. This option avoids depth " -"emulation." +"If gamma is enabled, scans are always made in 16 bits depth to improve " +"image quality and then converted to the selected depth. This option " +"avoids depth emulation." msgstr "" "Falls Gamma verwendet wird, werden Scans mit einer Farbtiefe von 16 Bit " "ausgeführt und danach in die gewählte Farbtiefe umgewandelt, um die " @@ -3412,11 +3781,12 @@ msgstr "Graustufen emulieren" #, no-c-format msgid "" "If enabled, image will be scanned in color mode and then converted to " -"grayscale by software. This may improve image quality in some circumstances." +"grayscale by software. This may improve image quality in some " +"circumstances." msgstr "" -"Falls verwendet, wird das Bild im Farbmodus gescannt und dann per Software " -"in Graustufen umgewandelt. Unter manchen Umständen verbessert dies die " -"Bildqualität." +"Falls verwendet, wird das Bild im Farbmodus gescannt und dann per " +"Software in Graustufen umgewandelt. Unter manchen Umständen verbessert " +"dies die Bildqualität." #: backend/hp3900_sane.c:1516 #, no-c-format @@ -3426,8 +3796,8 @@ msgstr "Debugging Bilder abspeichern" #: backend/hp3900_sane.c:1519 #, no-c-format msgid "" -"If enabled, some images involved in scanner processing are saved to analyze " -"them." +"If enabled, some images involved in scanner processing are saved to " +"analyze them." msgstr "" "Wenn aktiviert werden einige Bilder im Scanprozess gespeichert um sie zu " "analysieren." @@ -3542,11 +3912,6 @@ msgstr "Schaltet die Lampe an oder aus." msgid "Calibrates for black and white level." msgstr "Kalibriert Schwarz- und Weisswert." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "Automatischer Dokumenteneinzug" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3629,7 +3994,8 @@ msgstr "Ignoriere Seiten Ende Pixel" #: backend/hp5590.c:131 #, no-c-format -msgid "Hide end-of-page indicator pixels and overwrite with neighbor pixels" +msgid "" +"Hide end-of-page indicator pixels and overwrite with neighbor pixels" msgstr "" "Ignoriere Seiten Ende Pixel und überschreibe diese mit der umgebenden " "Hintergrundfarbe" @@ -3645,8 +4011,8 @@ msgid "" "raw = raw scan data, last = repeat last scan line, raster = b/w raster, " "white = white color, black = black color, color = RGB or gray color value" msgstr "" -"raw = Scandaten, letzte = wiederhole letzte Scanzeile, Raster = s/w Raster, " -"Weiß, Schwarz, Farbe = RGB oder Grau Wert" +"raw = Scandaten, letzte = wiederhole letzte Scanzeile, Raster = s/w " +"Raster, Weiß, Schwarz, Farbe = RGB oder Grau Wert" #: backend/hp5590.c:137 #, no-c-format @@ -3662,298 +4028,6 @@ msgstr "" "Farbwerte für Füllmodus 'Farbe'. RGB = r*65536+256*g+b oder Grauwert " "(Vorgabe = Violet oder Grau)" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Erweiterte Optionen" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Grob" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fein" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Benutzerdefiniert" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatisch" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Unverändert" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC Grau" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA Grau" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Langsam" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 backend/kvs40xx_opt.c:230 -#: backend/matsushita.c:244 backend/mustek.c:149 backend/plustek.c:234 -#: backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Schnell" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Besonders schnell" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2 Pixel" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4 Pixel" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8 Pixel" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Foto" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Film-Streifen" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Bedingt" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experiment" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Schärfen" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Legt den Wert für die Schärfe fest." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Automatischer Schwellwert" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Schaltet die automatische Bestimmung des Schwellwerts für den Schwarz-Weiß-" -"Modus ein." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Wählt den Glättungs-Filter aus." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Medium nach dem Scannen auswerfen" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Wirft das Medium nach dem Scan aus." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Dokument wechseln" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Dokument wechseln." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Auswerfen" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Dokument auswerfen." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Startet den Kalibrierungsprozess." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Medium" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Legt den Typ des Mediums fest." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Belichtungszeit" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested use is " -"175% for prints, 150% for normal slides and \"Negative\" for negative film. " -"For dark (underexposed) images you can increase this value." -msgstr "" -"Bei einer längeren Belichtungszeit kann der Scanner mehr Licht auffangen. " -"Empfohlene Werte: 175% für Fotos, 150% für normale Dias und \"Negativ\" für " -"Negativ-Filme. Für dunkle (unterentwickelte) Bilder kann dieser Wert " -"vergrößert werden." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Farbmatrix" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Legt die Farbmatrix für den Scanner fest." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Benutzerdefinierte Farbmatrix." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Graue Farbmatrix" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Benutzerdefinierte Farbmatrix für Graustufenscans." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Horizontal spiegeln" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Bild horizontal spiegeln." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Vertikal spiegeln" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Bild vertikal spiegeln." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Optionen aktualisieren" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Optionen aktualisieren." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8-Bit-Ausgabe" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Benutze intern eine Frabtiefe von mehr als 8 Bit, extern aber nur 8 Bit." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Warten auf vordere Taste" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Warte mit dem Scan auf das Drücken der vorderen Taste." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Lampe ausschalten" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Schalte Scannerlampe aus." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4039,81 +4113,87 @@ msgstr "Farbe" msgid "adf" msgstr "Automatischer Dokumenteneinzug" -#: backend/kvs1025_opt.c:62 backend/kvs40xx_opt.c:50 backend/kvs40xx_opt.c:109 +#: backend/kvs1025_opt.c:62 backend/kvs40xx_opt.c:50 +#: backend/kvs40xx_opt.c:109 #, no-c-format msgid "fb" msgstr "Flachbett" -#: backend/kvs1025_opt.c:72 backend/kvs20xx_opt.c:55 backend/kvs40xx_opt.c:101 +#: backend/kvs1025_opt.c:72 backend/kvs20xx_opt.c:55 +#: backend/kvs40xx_opt.c:101 #, no-c-format msgid "single" msgstr "einzeln" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" msgstr "endlos" -#: backend/kvs1025_opt.c:83 backend/kvs20xx_opt.c:62 backend/kvs40xx_opt.c:115 +#: backend/kvs1025_opt.c:83 backend/kvs20xx_opt.c:62 +#: backend/kvs40xx_opt.c:115 #, no-c-format msgid "off" msgstr "aus" -#: backend/kvs1025_opt.c:84 backend/kvs20xx_opt.c:63 backend/kvs40xx_opt.c:116 +#: backend/kvs1025_opt.c:84 backend/kvs20xx_opt.c:63 +#: backend/kvs40xx_opt.c:116 #, no-c-format msgid "wait_doc" msgstr "Warte auf Dokument" -#: backend/kvs1025_opt.c:85 backend/kvs20xx_opt.c:64 backend/kvs40xx_opt.c:118 +#: backend/kvs1025_opt.c:85 backend/kvs20xx_opt.c:64 +#: backend/kvs40xx_opt.c:118 #, no-c-format msgid "wait_key" msgstr "Warte auf Tastendruck" -#: backend/kvs1025_opt.c:96 backend/kvs20xx_opt.c:70 backend/kvs40xx_opt.c:124 -#: backend/kvs40xx_opt.c:141 +#: backend/kvs1025_opt.c:96 backend/kvs20xx_opt.c:70 +#: backend/kvs40xx_opt.c:124 backend/kvs40xx_opt.c:141 #, no-c-format msgid "user_def" msgstr "Benutzerdefiniert" -#: backend/kvs1025_opt.c:97 backend/kvs20xx_opt.c:71 backend/kvs40xx_opt.c:125 -#: backend/kvs40xx_opt.c:142 +#: backend/kvs1025_opt.c:97 backend/kvs20xx_opt.c:71 +#: backend/kvs40xx_opt.c:125 backend/kvs40xx_opt.c:142 #, no-c-format msgid "business_card" msgstr "Visitenkarte" -#: backend/kvs1025_opt.c:98 backend/kvs40xx_opt.c:126 backend/kvs40xx_opt.c:143 +#: backend/kvs1025_opt.c:98 backend/kvs40xx_opt.c:126 +#: backend/kvs40xx_opt.c:143 #, no-c-format msgid "Check" msgstr "Prüfe" -#: backend/kvs1025_opt.c:101 backend/kvs20xx_opt.c:75 backend/kvs40xx_opt.c:129 -#: backend/kvs40xx_opt.c:146 +#: backend/kvs1025_opt.c:101 backend/kvs20xx_opt.c:75 +#: backend/kvs40xx_opt.c:129 backend/kvs40xx_opt.c:146 #, no-c-format msgid "A5" msgstr "A5" -#: backend/kvs1025_opt.c:102 backend/kvs20xx_opt.c:76 backend/kvs40xx_opt.c:130 -#: backend/kvs40xx_opt.c:147 +#: backend/kvs1025_opt.c:102 backend/kvs20xx_opt.c:76 +#: backend/kvs40xx_opt.c:130 backend/kvs40xx_opt.c:147 #, no-c-format msgid "A6" msgstr "A6" -#: backend/kvs1025_opt.c:106 backend/kvs20xx_opt.c:80 backend/kvs40xx_opt.c:134 -#: backend/kvs40xx_opt.c:151 +#: backend/kvs1025_opt.c:106 backend/kvs20xx_opt.c:80 +#: backend/kvs40xx_opt.c:134 backend/kvs40xx_opt.c:151 #, no-c-format msgid "B5" msgstr "B5" -#: backend/kvs1025_opt.c:107 backend/kvs20xx_opt.c:81 backend/kvs40xx_opt.c:135 -#: backend/kvs40xx_opt.c:152 +#: backend/kvs1025_opt.c:107 backend/kvs20xx_opt.c:81 +#: backend/kvs40xx_opt.c:135 backend/kvs40xx_opt.c:152 #, no-c-format msgid "B6" msgstr "B6" -#: backend/kvs1025_opt.c:108 backend/kvs20xx_opt.c:82 backend/kvs40xx_opt.c:136 -#: backend/kvs40xx_opt.c:153 +#: backend/kvs1025_opt.c:108 backend/kvs20xx_opt.c:82 +#: backend/kvs40xx_opt.c:136 backend/kvs40xx_opt.c:153 #, no-c-format msgid "Legal" msgstr "Legal" @@ -4166,7 +4246,8 @@ msgstr "Dunkel" msgid "From scanner" msgstr "Vom Scanner" -#: backend/kvs1025_opt.c:179 backend/kvs40xx_opt.c:272 backend/matsushita.c:177 +#: backend/kvs1025_opt.c:179 backend/kvs40xx_opt.c:272 +#: backend/matsushita.c:177 #, no-c-format msgid "From paper" msgstr "Vom Papier" @@ -4214,8 +4295,8 @@ msgstr "Monitor" #: backend/kvs1025_opt.c:229 #, no-c-format -msgid "linier" -msgstr "Lineal" +msgid "linear" +msgstr "linear" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4312,11 +4393,11 @@ msgstr "Automatischer Schwellwert" #: backend/kvs1025_opt.c:737 backend/matsushita.c:1227 #, no-c-format msgid "" -"Automatically sets brightness, contrast, white level, gamma, noise reduction " -"and image emphasis" +"Automatically sets brightness, contrast, white level, gamma, noise " +"reduction and image emphasis" msgstr "" -"Legt automatisch Helligkeit, Kontrast, Weißwert, Gamma, Rauschunterdrückung " -"und Bildgewichtung fest" +"Legt automatisch Helligkeit, Kontrast, Weißwert, Gamma, " +"Rauschunterdrückung und Bildgewichtung fest" #: backend/kvs1025_opt.c:782 backend/kvs40xx_opt.c:764 #: backend/matsushita.c:1275 @@ -4344,7 +4425,7 @@ msgstr "Wählt die Bildgewichtung" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4411,17 +4492,18 @@ msgstr "Automatischer Zuschnitt per Software" msgid "Request driver to remove border from pages digitally" msgstr "Treiber entfernt Seitenränder" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" -"Bei der Längenkontrolle verwendet der Scanner die kürzere Länge, entweder " -"von der Vorlage oder der vorgegebenen Seitenlänge." +"Bei der Längenkontrolle verwendet der Scanner die kürzere Länge, " +"entweder von der Vorlage oder der vorgegebenen Seitenlänge." #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 -#: backend/kvs40xx_opt.c:668 backend/kvs40xx_opt.c:669 backend/microtek2.h:640 +#: backend/kvs40xx_opt.c:668 backend/kvs40xx_opt.c:669 +#: backend/microtek2.h:640 #, no-c-format msgid "Gamma correction" msgstr "Gammakorrektur" @@ -4448,12 +4530,12 @@ msgstr "B4" #: backend/kvs40xx_opt.c:231 #, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Hohe Auflösung" #: backend/kvs40xx_opt.c:232 #, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Geringe Auflösung" #: backend/kvs40xx_opt.c:243 @@ -4476,11 +4558,20 @@ msgstr "Normal" msgid "Enhanced mode" msgstr "Erweiterter Mode" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"Bei der Längenkontrolle verwendet der Scanner die kürzere Länge, " +"entweder von der Vorlage oder der vorgegebenen Seitenlänge." + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" -"Long Paper Mode is a mode that the scanner reads the image after it divides " -"long paper by the length which is set in Document Size option." +"Long Paper Mode is a mode that the scanner reads the image after it " +"divides long paper by the length which is set in Document Size option." msgstr "" "Im Endlospapier Mode wird die Vorlage auf mehrere voreingestellte " "Dokumentengrößen aufgeteilt." @@ -4537,7 +4628,7 @@ msgstr "JPEG Komprimierung" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "JPEG Komprimierung (Ihr Programm muss dekomprimieren können)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4572,12 +4663,12 @@ msgstr "Schräglauferkennunng" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "Scanner bei schräg eingezogener Seite anhalten" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "Scanner hält bei schräg eingelaufener Seite an" #: backend/kvs40xx_opt.c:816 @@ -4587,13 +4678,13 @@ msgstr "Beschneide Bild" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "Scanner erkennt und verwendet Vorlagengröße" #: backend/kvs40xx_opt.c:827 #, no-c-format -msgid "It is right and left reversing" -msgstr "Das ist rechter und linker Rücklauf" +msgid "Left/right mirror image" +msgstr "Bild spiegeln" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4630,52 +4721,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 Vertikale Linie" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Verstärkung" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Farbkanal Verstärkungseinstellungen" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Verstärkung grauer Kanal" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Legt die Verstärkung des grauen Kanals fest" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Verstärkung roter Kanal" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Legt die Verstärkung des roten Kanals fest" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Verstärkung grüner Kanal" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Legt die Verstärkung des grünen Kanals fest" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Verstärkung blauer Kanal" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Legt die Verstärkung des blauen Kanals fest" @@ -4735,7 +4826,8 @@ msgstr "Glatt" msgid "Low" msgstr "Niedrig" -#: backend/matsushita.c:215 backend/matsushita.c:230 backend/matsushita.c:1296 +#: backend/matsushita.c:215 backend/matsushita.c:230 +#: backend/matsushita.c:1296 #, no-c-format msgid "Medium" msgstr "Mittel" @@ -4760,7 +4852,7 @@ msgstr "Eine Seite" msgid "All pages" msgstr "Alle Seiten" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "Einzugsscanner" @@ -4819,8 +4911,10 @@ msgstr "Software - Kalibrierung" #: backend/microtek2.h:617 #, no-c-format -msgid "If checked the color calibration before a scan is done by the backend" -msgstr "Wenn aktiviert, wird die Farbkalibrierung durch den Treiber ausgeführt" +msgid "" +"If checked the color calibration before a scan is done by the backend" +msgstr "" +"Wenn aktiviert, wird die Farbkalibrierung durch den Treiber ausgeführt" #: backend/microtek2.h:621 #, no-c-format @@ -4831,8 +4925,9 @@ msgstr "Benutzung des LIGHTLID 35" #, no-c-format msgid "This option turns off the lamp of the flatbed during a scan" msgstr "" -"Bei der Benutzung des LIGHTLID 35 Durchlichtadapters wird während des Scans " -"die Flachbett - Lampe ausgeschaltet um besseren Kontrast zu erreichen" +"Bei der Benutzung des LIGHTLID 35 Durchlichtadapters wird während des " +"Scans die Flachbett - Lampe ausgeschaltet um besseren Kontrast zu " +"erreichen" #: backend/microtek2.h:626 backend/snapscan-options.c:421 #, no-c-format @@ -4862,8 +4957,8 @@ msgstr "Automatische schwarz/weiß - Schwelle" #: backend/microtek2.h:635 #, no-c-format msgid "" -"If checked the backend automatically tries to determine an optimal value for " -"the threshold." +"If checked the backend automatically tries to determine an optimal value " +"for the threshold." msgstr "" "Wenn aktiviert, versucht der Treiber einen optimalen Wert für den " "Schwellwert zu bestimmen." @@ -5139,12 +5234,12 @@ msgstr "Scanne im schnellen Graumodus (geringere Bildqualität)." #: backend/mustek.c:4345 #, no-c-format msgid "" -"Request that all previews are done in the fastest (low-quality) mode. This " -"may be a non-color mode or a low resolution mode." +"Request that all previews are done in the fastest (low-quality) mode. " +"This may be a non-color mode or a low resolution mode." msgstr "" "Legt fest, dass alle Vorschau-Scans im schnellsten Modus (mit geringer " -"Qualität) durchgeführt werden. Das kann ein Schwarzweißmodus oder ein Modus " -"mit niedriger Auflösung sein." +"Qualität) durchgeführt werden. Das kann ein Schwarzweißmodus oder ein " +"Modus mit niedriger Auflösung sein." #: backend/mustek.c:4353 #, no-c-format @@ -5175,7 +5270,8 @@ msgstr "Helligkeit des Rotwerts" #: backend/mustek.c:4444 #, no-c-format msgid "Controls the brightness of the red channel of the acquired image." -msgstr "Stellt die Helligkeit der roten Komponente des gescannten Bildes ein." +msgstr "" +"Stellt die Helligkeit der roten Komponente des gescannten Bildes ein." #: backend/mustek.c:4456 #, no-c-format @@ -5185,7 +5281,8 @@ msgstr "Helligkeit des Grünwerts" #: backend/mustek.c:4457 #, no-c-format msgid "Controls the brightness of the green channel of the acquired image." -msgstr "Stellt die Helligkeit der grünen Komponente des gescannten Bildes ein." +msgstr "" +"Stellt die Helligkeit der grünen Komponente des gescannten Bildes ein." #: backend/mustek.c:4469 #, no-c-format @@ -5195,7 +5292,8 @@ msgstr "Helligkeit des Blauwerts" #: backend/mustek.c:4470 #, no-c-format msgid "Controls the brightness of the blue channel of the acquired image." -msgstr "Stellt die Helligkeit der blauen Komponente des gescannten Bildes ein." +msgstr "" +"Stellt die Helligkeit der blauen Komponente des gescannten Bildes ein." #: backend/mustek.c:4495 #, no-c-format @@ -5205,7 +5303,8 @@ msgstr "Kontrast der grünen Komponente" #: backend/mustek.c:4496 #, no-c-format msgid "Controls the contrast of the red channel of the acquired image." -msgstr "Stellt den Kontrast der roten Komponente des gescannten Bildes ein." +msgstr "" +"Stellt den Kontrast der roten Komponente des gescannten Bildes ein." #: backend/mustek.c:4508 #, no-c-format @@ -5215,7 +5314,8 @@ msgstr "Kontrast der grünen Komponente" #: backend/mustek.c:4509 #, no-c-format msgid "Controls the contrast of the green channel of the acquired image." -msgstr "Stellt den Kontrast der grünen Komponente des gescannten Bildes ein." +msgstr "" +"Stellt den Kontrast der grünen Komponente des gescannten Bildes ein." #: backend/mustek.c:4521 #, no-c-format @@ -5225,7 +5325,8 @@ msgstr "Kontrast der blauen Komponente" #: backend/mustek.c:4522 #, no-c-format msgid "Controls the contrast of the blue channel of the acquired image." -msgstr "Stellt den Kontrast der blauen Komponente des gescannten Bildes ein." +msgstr "" +"Stellt den Kontrast der blauen Komponente des gescannten Bildes ein." #: backend/mustek_usb2.c:105 #, no-c-format @@ -5260,48 +5361,53 @@ msgstr "Positiv" #: backend/mustek_usb2.c:421 #, no-c-format msgid "" -"Warm-up until the lamp's brightness is constant instead of insisting on 40 " -"seconds warm-up time." +"Warm-up until the lamp's brightness is constant instead of insisting on " +"40 seconds warm-up time." msgstr "" -"Warte solange, bis die Helligkeit der Lampe konstant ist anstatt einfach 40 " -"Sekunden zu warten." +"Warte solange, bis die Helligkeit der Lampe konstant ist anstatt einfach " +"40 Sekunden zu warten." + +#: backend/p5.c:1926 +#, no-c-format +msgid "Need calibration" +msgstr "Benötigt Kalibrierung" -#: backend/pixma.c:397 +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "Negativfilm Farbe" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "Negativfilm Graustufen" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "48 Bit Farbe" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "16 Bit Graustufen" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" -"Selects the scan source (such as a document-feeder). Set source before mode " -"and resolution. Resets mode and resolution to auto values." +"Selects the scan source (such as a document-feeder). Set source before " +"mode and resolution. Resets mode and resolution to auto values." msgstr "" -"Legt die Scanquelle fest (wie z.B. Dokumenteneinzug). Die Scanquelle muss " -"vor Scanmodus und Scanauflösung ausgewählt werden. Setzt die Einstellungen " -"für Scanmodus und Scanauflösung zurück." +"Legt die Scanquelle fest (wie z.B. Dokumenteneinzug). Die Scanquelle " +"muss vor Scanmodus und Scanauflösung ausgewählt werden. Setzt die " +"Einstellungen für Scanmodus und Scanauflösung zurück." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Scannen auf Tastendruck" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5312,44 +5418,44 @@ msgstr "" "drücken Sie die Taste \"SCAN\" beim MP1500 oder \"COLOR\" bei anderen " "Modellen. Zum Abbrechen drücken Sie die Taste \"GRAY\"." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Tastenstatus aktualisieren" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Taste 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Taste 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "Vorlagentyp" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "Scanziel" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "Wartezeit Dokumenteneinzug" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" -"Der Scanner sucht während der Wartezeit (in Sekunden) nach einem Dokument, " -"welches in den Scanschacht eingelegt wird." +"Der Scanner sucht während der Wartezeit (in Sekunden) nach einem " +"Dokument, welches in den Scanschacht eingelegt wird." #: backend/plustek.c:235 backend/plustek_pp.c:204 backend/u12.c:156 #, no-c-format @@ -5436,7 +5542,7 @@ msgstr "Analog Frontend" msgid "Red gain value of the AFE" msgstr "Verstärkung roter Kanal des AD-Wandlers" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Offset roter Kanal" @@ -5549,11 +5655,11 @@ msgstr "Three-Pass Simulation" #: backend/pnm.c:255 #, no-c-format msgid "" -"Simulate a three-pass scanner by returning 3 separate frames. For kicks, it " -"returns green, then blue, then red." +"Simulate a three-pass scanner by returning 3 separate frames. For " +"kicks, it returns green, then blue, then red." msgstr "" -"Simuliere einen Three-Pass Scanner, indem hintereinander je ein Frame für " -"jede Grundfarbe übertragen wird. Die Reihenfolge ist grün-blau-rot." +"Simuliere einen Three-Pass Scanner, indem hintereinander je ein Frame " +"für jede Grundfarbe übertragen wird. Die Reihenfolge ist grün-blau-rot." #: backend/pnm.c:267 #, no-c-format @@ -5563,18 +5669,19 @@ msgstr "Handscanner Simulation" #: backend/pnm.c:268 #, no-c-format msgid "" -"Simulate a hand-scanner. Hand-scanners often do not know the image height a " -"priori. Instead, they return a height of -1. Setting this option allows " -"one to test whether a frontend can handle this correctly." +"Simulate a hand-scanner. Hand-scanners often do not know the image " +"height a priori. Instead, they return a height of -1. Setting this " +"option allows one to test whether a frontend can handle this correctly." msgstr "" -"Simuliere einen Handscanner. Bei Handscannern steht meistens die Bildhöhe " -"nicht von vornherein fest. Stattdessen geben sie eine Höhe von -1 zurück. " -"Mit dieser Option kann man prüfen, ob das Frontend damit richtig umgehen " -"kann." +"Simuliere einen Handscanner. Bei Handscannern steht meistens die " +"Bildhöhe nicht von vornherein fest. Stattdessen geben sie eine Höhe von " +"-1 zurück. Mit dieser Option kann man prüfen, ob das Frontend damit " +"richtig umgehen kann." #: backend/pnm.c:283 #, no-c-format -msgid "Set default values for enhancement controls (brightness & contrast)." +msgid "" +"Set default values for enhancement controls (brightness & contrast)." msgstr "" "Stellt die Farbverbesserungseinstellungen (Helligkeit und Kontrast) auf " "Defaultwerte." @@ -5620,8 +5727,8 @@ msgid "" "Force the backend to return the status code SANE_STATUS_EOF after " "sane_read() has been called." msgstr "" -"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den Statuscode " -"SANE_STATUS_EOF zurückzuliefern." +"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den " +"Statuscode SANE_STATUS_EOF zurückzuliefern." #: backend/pnm.c:416 #, no-c-format @@ -5634,8 +5741,8 @@ msgid "" "Force the backend to return the status code SANE_STATUS_JAMMED after " "sane_read() has been called." msgstr "" -"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den Statuscode " -"SANE_STATUS_JAMMED zurückzuliefern." +"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den " +"Statuscode SANE_STATUS_JAMMED zurückzuliefern." #: backend/pnm.c:430 #, no-c-format @@ -5648,8 +5755,8 @@ msgid "" "Force the backend to return the status code SANE_STATUS_NO_DOCS after " "sane_read() has been called." msgstr "" -"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den Statuscode " -"SANE_STATUS_NO_DOCS zurückzuliefern." +"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den " +"Statuscode SANE_STATUS_NO_DOCS zurückzuliefern." #: backend/pnm.c:443 #, no-c-format @@ -5662,8 +5769,8 @@ msgid "" "Force the backend to return the status code SANE_STATUS_COVER_OPEN after " "sane_read() has been called." msgstr "" -"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den Statuscode " -"SANE_STATUS_COVER_OPEN zurückzuliefern." +"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den " +"Statuscode SANE_STATUS_COVER_OPEN zurückzuliefern." #: backend/pnm.c:456 #, no-c-format @@ -5676,8 +5783,8 @@ msgid "" "Force the backend to return the status code SANE_STATUS_IO_ERROR after " "sane_read() has been called." msgstr "" -"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den Statuscode " -"SANE_STATUS_IO_ERROR zurückzuliefern." +"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den " +"Statuscode SANE_STATUS_IO_ERROR zurückzuliefern." #: backend/pnm.c:469 #, no-c-format @@ -5690,8 +5797,8 @@ msgid "" "Force the backend to return the status code SANE_STATUS_NO_MEM after " "sane_read() has been called." msgstr "" -"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den Statuscode " -"SANE_STATUS_NO_MEM zurückzuliefern." +"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den " +"Statuscode SANE_STATUS_NO_MEM zurückzuliefern." #: backend/pnm.c:483 #, no-c-format @@ -5701,18 +5808,18 @@ msgstr "Liefere SANE_STATUS_ACCESS_DENIED zurück" #: backend/pnm.c:484 #, no-c-format msgid "" -"Force the backend to return the status code SANE_STATUS_ACCESS_DENIED after " -"sane_read() has been called." +"Force the backend to return the status code SANE_STATUS_ACCESS_DENIED " +"after sane_read() has been called." msgstr "" -"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den Statuscode " -"SANE_STATUS_ACCESS_DENIED zurückzuliefern." +"Zwinge das Backend dazu, nach einem Aufruf von sane_read() den " +"Statuscode SANE_STATUS_ACCESS_DENIED zurückzuliefern." #: backend/rts8891.c:2809 #, no-c-format msgid "This option reflects the status of a scanner button." msgstr "Diese Option zeigt den Zustand einer Scannertaste an." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lampe an" @@ -5722,12 +5829,12 @@ msgstr "Lampe an" msgid "Turn on scanner lamp" msgstr "Schalte Scannerlampe ein" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Lampe aus" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Schalte Scannerlampe aus" @@ -5786,18 +5893,18 @@ msgstr "DispersedDot16x16" #, no-c-format msgid "" "Number of scan lines to request in a SCSI read. Changing this parameter " -"allows you to tune the speed at which data is read from the scanner during " -"scans. If this is set too low, the scanner will have to stop periodically in " -"the middle of a scan; if it's set too high, X-based frontends may stop " -"responding to X events and your system could bog down." +"allows you to tune the speed at which data is read from the scanner " +"during scans. If this is set too low, the scanner will have to stop " +"periodically in the middle of a scan; if it's set too high, X-based " +"frontends may stop responding to X events and your system could bog down." msgstr "" "Anzahl der Zeilen, die pro SCSI Lesevorgang angefordert werden. Eine " -"Änderung dieses Parameters erlaubt die Feineinstellung der Geschwindigkeit, " -"mit der Daten vom Scanner gelesen werden. Wenn die Geschwindigkeit zu " -"niedrig ist, muss der Scanner in regelmäßigen Abständen mitten im " -"Scanvorgang anhalten. Falls sie zu groß ist, reagiert die Scan-Anwendung " -"möglicherweise nicht mehr auf Eingaben und das System kann unbenutzbar " -"werden." +"Änderung dieses Parameters erlaubt die Feineinstellung der " +"Geschwindigkeit, mit der Daten vom Scanner gelesen werden. Wenn die " +"Geschwindigkeit zu niedrig ist, muss der Scanner in regelmäßigen " +"Abständen mitten im Scanvorgang anhalten. Falls sie zu groß ist, " +"reagiert die Scan-Anwendung möglicherweise nicht mehr auf Eingaben und " +"das System kann unbenutzbar werden." #: backend/snapscan-options.c:111 #, no-c-format @@ -5836,9 +5943,11 @@ msgstr "Vordefinierte Einstellungen" #: backend/snapscan-options.c:603 #, no-c-format msgid "" -"Provides standard scanning areas for photographs, printed pages and the like." +"Provides standard scanning areas for photographs, printed pages and the " +"like." msgstr "" -"Stellt Standardgrößen für Fotographien, bedruckte Seiten etc. zur Verfügung." +"Stellt Standardgrößen für Fotographien, bedruckte Seiten etc. zur " +"Verfügung." #: backend/snapscan-options.c:884 #, no-c-format @@ -5872,12 +5981,12 @@ msgstr "Fokus Position" #: backend/snapscan-options.c:930 #, no-c-format -msgid "Colour lines per read" +msgid "Color lines per read" msgstr "Farbzeilen pro Lesevorgang" #: backend/snapscan-options.c:942 #, no-c-format -msgid "Greyscale lines per read" +msgid "Grayscale lines per read" msgstr "Graustufenzeilen pro Lesevorgang" #: backend/stv680.c:974 @@ -5936,8 +6045,8 @@ msgid "" "This is the very long third entry. Maybe the frontend has an idea how to " "display it" msgstr "" -"Dies ist der sehr lange dritte Eintrag; vielleicht weiß das Frontend, wie " -"man ihn darstellen kann" +"Dies ist der sehr lange dritte Eintrag; vielleicht weiß das Frontend, " +"wie man ihn darstellen kann" #: backend/test.c:348 #, no-c-format @@ -5948,14 +6057,14 @@ msgstr "Handscanner-Simulation" #, no-c-format msgid "" "Simulate a hand-scanner. Hand-scanners do not know the image height a " -"priori. Instead, they return a height of -1. Setting this option allows " -"one to test whether a frontend can handle this correctly. This option also " -"enables a fixed width of 11 cm." +"priori. Instead, they return a height of -1. Setting this option " +"allows one to test whether a frontend can handle this correctly. This " +"option also enables a fixed width of 11 cm." msgstr "" -"Simuliere einen Handscanner. Bei Handscannern steht meistens die Bildhöhe " -"nicht von vornherein fest. Stattdessen geben sie eine Höhe von -1 zurück. " -"Mit dieser Option kann man prüfen, ob das Frontend damit richtig umgehen " -"kann." +"Simuliere einen Handscanner. Bei Handscannern steht meistens die " +"Bildhöhe nicht von vornherein fest. Stattdessen geben sie eine Höhe von " +"-1 zurück. Mit dieser Option kann man prüfen, ob das Frontend damit " +"richtig umgehen kann." #: backend/test.c:366 #, no-c-format @@ -5965,7 +6074,8 @@ msgstr "Three-Pass Simulation" #: backend/test.c:367 #, no-c-format msgid "" -"Simulate a three-pass scanner. In color mode, three frames are transmitted." +"Simulate a three-pass scanner. In color mode, three frames are " +"transmitted." msgstr "" "Simuliere einen Three-Pass-Scanner. Im Farbmodus werden drei Frames " "übertragen." @@ -5983,11 +6093,11 @@ msgstr "Legt die Reihenfolge der Frames im Three-Pass-Modus fest." #: backend/test.c:416 #, no-c-format msgid "" -"If Automatic Document Feeder is selected, the feeder will be 'empty' after " -"10 scans." +"If Automatic Document Feeder is selected, the feeder will be 'empty' " +"after 10 scans." msgstr "" -"Falls der automatische Dokumenteneinzug ausgewählt ist, meldet der Einzug " -"\"leer\" nach 10 Scans." +"Falls der automatische Dokumenteneinzug ausgewählt ist, meldet der " +"Einzug \"leer\" nach 10 Scans." #: backend/test.c:431 #, no-c-format @@ -6006,7 +6116,8 @@ msgid "" "Solid black: fills the whole scan with black.\n" "Solid white: fills the whole scan with white.\n" "Color pattern: draws various color test patterns depending on the mode.\n" -"Grid: draws a black/white grid with a width and height of 10 mm per square." +"Grid: draws a black/white grid with a width and height of 10 mm per " +"square." msgstr "" "Wählt die Art des Testbildes aus. Verfügbare Testbilder:\n" "Komplett schwarz: füllt das ganze Bild schwarz.\n" @@ -6024,9 +6135,9 @@ msgstr "Endianness umkehren" #: backend/test.c:468 #, no-c-format msgid "" -"Exchange upper and lower byte of image data in 16 bit modes. This option can " -"be used to test the 16 bit modes of frontends, e.g. if the frontend uses the " -"correct endianness." +"Exchange upper and lower byte of image data in 16 bit modes. This option " +"can be used to test the 16 bit modes of frontends, e.g. if the frontend " +"uses the correct endianness." msgstr "" "Tausche das untere und das obere Byte der Bilddaten im 16-Bit-Modus aus. " "Diese Option kann dazu benutzt werden, den 16-Bit-Modus der Frontends zu " @@ -6042,8 +6153,8 @@ msgstr "Lesebegrenzung" #, no-c-format msgid "Limit the amount of data transferred with each call to sane_read()." msgstr "" -"Begrenzt die Menge an Daten, die mit jedem Aufruf von sane_read() übertragen " -"wird." +"Begrenzt die Menge an Daten, die mit jedem Aufruf von sane_read() " +"übertragen wird." #: backend/test.c:498 #, no-c-format @@ -6052,7 +6163,8 @@ msgstr "Größe der Lesebegrenzung" #: backend/test.c:499 #, no-c-format -msgid "The (maximum) amount of data transferred with each call to sane_read()." +msgid "" +"The (maximum) amount of data transferred with each call to sane_read()." msgstr "" "Die (maximale) Menge and Daten, die bei jedem Aufruf von sane_read() " "übertragen wird." @@ -6077,8 +6189,8 @@ msgstr "Dauer der Leseverzögerung" msgid "" "How long to wait after transferring each buffer of data through the pipe." msgstr "" -"Legt fest, wie lange nach der Ãœbertragung eines Datenpuffers durch die Pipe " -"gewartet wird." +"Legt fest, wie lange nach der Ãœbertragung eines Datenpuffers durch die " +"Pipe gewartet wird." #: backend/test.c:543 #, no-c-format @@ -6088,9 +6200,9 @@ msgstr "Rückgabewert von sane_read" #: backend/test.c:545 #, no-c-format msgid "" -"Select the return-value of sane_read(). \"Default\" is the normal handling " -"for scanning. All other status codes are for testing how the frontend " -"handles them." +"Select the return-value of sane_read(). \"Default\" is the normal " +"handling for scanning. All other status codes are for testing how the " +"frontend handles them." msgstr "" "Legt den Rückgabewert von sane_read() fest. \"Default\" ist die normale " "Einstellung für's Scannen. Alle anderen Rückgabewerte dienen dazu, das " @@ -6129,8 +6241,8 @@ msgstr "Nichtblockierendes IO" #, no-c-format msgid "Use non-blocking IO for sane_read() if supported by the frontend." msgstr "" -"Verwende nichtblockierndes IO für sane_read(), wenn das durch das Frontend " -"unterstützt wird." +"Verwende nichtblockierndes IO für sane_read(), wenn das durch das " +"Frontend unterstützt wird." #: backend/test.c:605 #, no-c-format @@ -6140,10 +6252,11 @@ msgstr "Biete Select-Dateideskriptor an" #: backend/test.c:606 #, no-c-format msgid "" -"Offer a select filedescriptor for detecting if sane_read() will return data." +"Offer a select filedescriptor for detecting if sane_read() will return " +"data." msgstr "" -"Biete einen Select-Dateideskriptor an, damit das Frontend erkennen kann, ob " -"sane_read() Daten zurückliefern würde." +"Biete einen Select-Dateideskriptor an, damit das Frontend erkennen kann, " +"ob sane_read() Daten zurückliefern würde." #: backend/test.c:619 #, no-c-format @@ -6153,8 +6266,8 @@ msgstr "Test-Optionen einschalten" #: backend/test.c:620 #, no-c-format msgid "" -"Enable various test options. This is for testing the ability of frontends to " -"view and modify all the different SANE option types." +"Enable various test options. This is for testing the ability of " +"frontends to view and modify all the different SANE option types." msgstr "" "Schalte verschiedene Testoptionen ein. Mit diesen Optionen kann man die " "Fähigkeit des Frontends feststellen, die verschiedenen Typen von SANE-" @@ -6183,12 +6296,12 @@ msgstr "(1/6) Bool soft select soft detect" #: backend/test.c:727 #, no-c-format msgid "" -"(1/6) Bool test option that has soft select and soft detect (and advanced) " -"capabilities. That's just a normal bool option." +"(1/6) Bool test option that has soft select and soft detect (and " +"advanced) capabilities. That's just a normal bool option." msgstr "" -"(1/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"soft select\" " -"und \"soft detect\" (und \"advanced\") hat. Also eine ganz normale Bool-" -"Option." +"(1/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"soft select" +"\" und \"soft detect\" (und \"advanced\") hat. Also eine ganz normale " +"Bool-Option." #: backend/test.c:743 #, no-c-format @@ -6198,14 +6311,14 @@ msgstr "(2/6) Bool hard select soft detect" #: backend/test.c:745 #, no-c-format msgid "" -"(2/6) Bool test option that has hard select and soft detect (and advanced) " -"capabilities. That means the option can't be set by the frontend but by the " -"user (e.g. by pressing a button at the device)." +"(2/6) Bool test option that has hard select and soft detect (and " +"advanced) capabilities. That means the option can't be set by the " +"frontend but by the user (e.g. by pressing a button at the device)." msgstr "" -"(2/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"hard select\" " -"und \"soft detect\" (und \"advanced\") hat. Das bedeutet, dass die Option " -"nicht vom Frontend geändert werden kann, sondern vom Benutzer (z. B. indem " -"er eine Taste am Gerät drückt)." +"(2/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"hard select" +"\" und \"soft detect\" (und \"advanced\") hat. Das bedeutet, dass die " +"Option nicht vom Frontend geändert werden kann, sondern vom Benutzer (z. " +"B. indem er eine Taste am Gerät drückt)." #: backend/test.c:762 #, no-c-format @@ -6216,12 +6329,13 @@ msgstr "(3/6) Bool hard select" #, no-c-format msgid "" "(3/6) Bool test option that has hard select (and advanced) capabilities. " -"That means the option can't be set by the frontend but by the user (e.g. by " -"pressing a button at the device) and can't be read by the frontend." +"That means the option can't be set by the frontend but by the user (e.g. " +"by pressing a button at the device) and can't be read by the frontend." msgstr "" "(3/6) Dies is eine Bool-Testoption, welche die Fähigkieten \"hard select" -"\" (und \"advanced\") hat. Das bedeutet, dass die Option nicht vom Frontend " -"geändert werden kann, sondern vom Benutzer (z. B. indem er eine Taste am " +"\" (und \"advanced\") hat. Das bedeutet, dass die Option " +"nicht vom Frontend geändert " +"werden kann, sondern vom Benutzer (z. B. indem er eine Taste am " "Gerät drückt). Außerdem kann sie nicht vom Frontend gelesen werden." #: backend/test.c:781 @@ -6246,11 +6360,11 @@ msgstr "(5/6) Bool soft select soft detect emulated" #: backend/test.c:799 #, no-c-format msgid "" -"(5/6) Bool test option that has soft select, soft detect, and emulated (and " -"advanced) capabilities." +"(5/6) Bool test option that has soft select, soft detect, and emulated " +"(and advanced) capabilities." msgstr "" -"(5/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"soft select\", " -"\"soft detect\", und \"emulated\" (und \"advanced\") hat." +"(5/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"soft select" +"\", \"soft detect\", und \"emulated\" (und \"advanced\") hat." #: backend/test.c:815 #, no-c-format @@ -6260,12 +6374,13 @@ msgstr "(6/6) Bool soft select soft detect auto" #: backend/test.c:816 #, no-c-format msgid "" -"(6/6) Bool test option that has soft select, soft detect, and automatic (and " -"advanced) capabilities. This option can be automatically set by the backend." +"(6/6) Bool test option that has soft select, soft detect, and automatic " +"(and advanced) capabilities. This option can be automatically set by the " +"backend." msgstr "" -"(6/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"soft select\", " -"\"soft detect\", und \"automatic\" (und \"advanced\") hat. Diese Option kann " -"vom Backend automatisch gesetzt werden." +"(6/6) Dies ist eine Bool-Testoption, welche die Fähigkeiten \"soft select" +"\", \"soft detect\", und \"automatic\" (und \"advanced\") hat. Diese " +"Option kann vom Backend automatisch gesetzt werden." #: backend/test.c:833 #, no-c-format @@ -6290,8 +6405,8 @@ msgstr "(2/6) Int constraint range" #: backend/test.c:863 #, no-c-format msgid "" -"(2/6) Int test option with unit pixel and constraint range set. Minimum is " -"4, maximum 192, and quant is 2." +"(2/6) Int test option with unit pixel and constraint range set. Minimum " +"is 4, maximum 192, and quant is 2." msgstr "" "(2/6) Int-Testoption mit der Einheit \"Pixel\" und einer " "Bereichsbeschränkung. Das Minimum ist 4, das Maximum 192, und die " @@ -6317,9 +6432,11 @@ msgstr "(4/6) Int array" #: backend/test.c:896 #, no-c-format msgid "" -"(4/6) Int test option with unit mm and using an array without constraints." +"(4/6) Int test option with unit mm and using an array without " +"constraints." msgstr "" -"(4/6) Int-Testoption mit der Einheit \"mm\" und einem Feld ohne Beschränkung." +"(4/6) Int-Testoption mit der Einheit \"mm\" und einem Feld ohne " +"Beschränkung." #: backend/test.c:911 #, no-c-format @@ -6344,11 +6461,11 @@ msgstr "(6/6) Int array constraint word list" #: backend/test.c:930 #, no-c-format msgid "" -"(6/6) Int test option with unit percent and using an array with a word list " -"constraint." +"(6/6) Int test option with unit percent and using an array with a word " +"list constraint." msgstr "" -"(6/6) Int-Testoption mit der Einheit \"Prozent\" und einem Feld mit einer " -"Wort-Beschränkung." +"(6/6) Int-Testoption mit der Einheit \"Prozent\" und einem Feld mit " +"einer Wort-Beschränkung." #: backend/test.c:946 #, no-c-format @@ -6377,8 +6494,8 @@ msgid "" "Minimum is -42.17, maximum 32767.9999, and quant is 2.0." msgstr "" "(2/3) Fixed-Testoption mit der Einheit \"Mikrosekunde\" und einer " -"Bereichsbeschränkung. Das Minimum ist -42.17, das Maximum 32767.9999, und " -"die Schrittweite ist 2.0." +"Bereichsbeschränkung. Das Minimum ist -42.17, das Maximum 32767.9999, " +"und die Schrittweite ist 2.0." #: backend/test.c:992 #, no-c-format @@ -6389,7 +6506,8 @@ msgstr "(3/3) Fixed constraint word list" #, no-c-format msgid "(3/3) Fixed test option with no unit and constraint word list set." msgstr "" -"(3/3) Fixed-Testoption ohne Einheit und mit einer Wortlisten-Beschränkung." +"(3/3) Fixed-Testoption ohne Einheit und mit einer Wortlisten-" +"Beschränkung." #: backend/test.c:1008 #, no-c-format @@ -6530,56 +6648,72 @@ msgstr "Kalibrierungs Modus" msgid "Define calibration mode" msgstr "Kalibriermodus definieren" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Schaltet die Lampe an/aus" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA ein" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Schaltet den UTA ein/aus" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Offset" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Einstellungen des Offsets der Farbkanäle" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Offset grüner Kanal" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Legt den Offset des grauen Kanals fest" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Legt den Offset des roten Kanals fest" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Legt den Offset des grünen Kanals fest" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Legt den Offset des blauen Kanals fest" +#~ msgid "Disable dynamic lineart" +#~ msgstr "Deaktiviere dynamische Strichzeichnung" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "Deaktiviere Software angepassten Algorithmus zur Erstellung von " +#~ "Strichzeichnungen anstelle von Hardware-Strichzeichnungen." + +#~ msgid "linier" +#~ msgstr "Lineal" + +#~ msgid "It is right and left reversing" +#~ msgstr "Das ist rechter und linker Rücklauf" + #, fuzzy #~ msgid "IPC mode" #~ msgstr "Vorschaumodus" diff --git a/po/en_GB.po b/po/en_GB.po index 28695ac..bffc8b3 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -4,10 +4,10 @@ # Andrew Coles <andrew_coles@yahoo.co.uk>, 2009. msgid "" msgstr "" -"Project-Id-Version: \n" +"Project-Id-Version: sane-backends 1.0.29\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" -"PO-Revision-Date: 2019-07-26 09:45-0700\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" +"PO-Revision-Date: 2020-01-26 16:27+0900\n" "Last-Translator: Ralph Little <littlesincanada@yahoo.co.uk>\n" "Language-Team: British English <kde-i18n-doc@kde.org>\n" "Language: en_GB\n" @@ -28,31 +28,31 @@ msgid "Standard" msgstr "Standard" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometry" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Enhancement" @@ -86,7 +86,7 @@ msgid "Bit depth" msgstr "Bit depth" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Scan mode" @@ -127,7 +127,7 @@ msgid "Bottom-right y" msgstr "Bottom-right y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Scan resolution" @@ -282,7 +282,7 @@ msgstr "Filename" msgid "Halftone pattern size" msgstr "Halftone pattern size" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Halftone pattern" @@ -292,10 +292,10 @@ msgstr "Halftone pattern" msgid "Bind X and Y resolution" msgstr "Bind X and Y resolution" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negative" @@ -345,7 +345,6 @@ msgstr "Analogue gamma blue" msgid "Bind analog gamma" msgstr "Bind analogue gamma" -# Warm->Warm up? #: include/sane/saneopts.h:216 #, no-c-format msgid "Warmup lamp" @@ -419,10 +418,10 @@ msgstr "Lamp off at exit" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." #: include/sane/saneopts.h:248 @@ -747,7 +746,7 @@ msgstr "Analogue gamma-correction for blue" #: include/sane/saneopts.h:415 #, no-c-format -msgid "Warmup lamp before scanning" +msgid "Warm up lamp before scanning" msgstr "Warm up lamp before scanning" #: include/sane/saneopts.h:417 @@ -897,7 +896,7 @@ msgstr "Operation not supported" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "Operation was cancelled" #: backend/sane_strstatus.c:68 @@ -989,12 +988,11 @@ msgstr "" msgid "Only perform shading-correction" msgstr "Only perform shading-correction" -# "build" should really be "built" in original text #: backend/artec_eplus48u.c:2956 #, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "If enabled, only the shading correction is performed during calibration. " @@ -1021,86 +1019,45 @@ msgstr "Selects the number of the frame to scan" msgid "Duplex scan" msgstr "Duplex scan" -# Original should be "Duplex scan provides..." #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "Duplex scan provides a scan of the front and back side of the document" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibrate Scanner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Force scanner calibration before scan" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Greyscale scan" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Do a greyscale rather than colour scan" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analogue Gain" +msgid "Correction according to transparency ratio" +msgstr "Correction according to transparency ratio" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Increase or decrease the analogue gain of the CCD array" +msgid "Correction according to film type" +msgstr "Correction according to film type" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Gamma Correction" +msgid "Fine color" +msgstr "Fine colour" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Selects the gamma corrected transfer curve" +msgid "Negatives" +msgstr "Negatives" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Raw" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Fine colour" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "No transparency correction" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Correction according to film type" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Correction according to transparency ratio" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negatives" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1233,11 +1190,10 @@ msgstr "medium not present" msgid "invalid bit IDENTIFY message" msgstr "invalid bit IDENTIFY message" -# Check this text. Does it make sense? #: backend/canon.c:460 #, no-c-format -msgid "option not connect" -msgstr "option not connect" +msgid "option not correct" +msgstr "option not correct" #: backend/canon.c:474 #, no-c-format @@ -1525,133 +1481,184 @@ msgstr "Select film type" msgid "Select the film type" msgstr "Select the film type" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibrate Scanner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Force scanner calibration before scan" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Greyscale scan" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Do a greyscale rather than colour scan" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analogue Gain" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Increase or decrease the analogue gain of the CCD array" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gamma Correction" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Selects the gamma corrected transfer curve" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Flatbed" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "ADF Front" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "ADF Back" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "ADF Duplex" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "Card Front" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "Card Back" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "Card Duplex" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Red" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Green" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Blue" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Enhance Red" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Enhance Green" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Enhance Blue" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "None" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "Software blank skip percentage" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "Request driver to discard pages with low percentage of dark pixels" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Simplex" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Duplex" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Transparency Unit" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatic Document Feeder" @@ -1763,7 +1770,7 @@ msgstr "Ink-jet printers" msgid "CRT monitors" msgstr "CRT monitors" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1827,8 +1834,9 @@ msgstr "A4" msgid "Max" msgstr "Max" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2000,17 +2008,17 @@ msgstr "Defines the zoom factor the scanner will use" msgid "Quick format" msgstr "Quick format" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Optional equipment" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Eject" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Eject the sheet in the ADF" @@ -2025,12 +2033,14 @@ msgstr "Auto eject" msgid "Eject document after scanning" msgstr "Eject document after scanning" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "ADF Mode" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Selects the ADF mode (simplex/duplex)" @@ -2080,16 +2090,16 @@ msgstr "" "After sending the scan command, wait until the button on the scanner is " "pressed to actually start the scan process." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Infrared" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "TPU8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Infrared" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2110,348 +2120,368 @@ msgstr "Built in CCT profile" msgid "User defined CCT profile" msgstr "User defined CCT profile" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "Load" + +#: backend/epsonds.c:751 +#, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Load a sheet in the ADF" + +#: backend/epsonds.c:771 +#, no-c-format +msgid "ADF Skew Correction" +msgstr "ADF Skew Correction" + +#: backend/epsonds.c:773 +#, no-c-format +msgid "Enables ADF skew correction" +msgstr "Enables ADF skew correction" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "On" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Off" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Dither" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Diffusion" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "White" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Black" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Continue" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Stop" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horizontal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Horizontal bold" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Horizontal narrow" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertical" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Vertical bold" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "Top to bottom" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "Bottom to top" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Front" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Back" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "Gamma function exponent" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "Changes intensity of midtones" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "RIF" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "Reverse image format" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "Halftone type" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "Control type of halftone filter" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "Control pattern of halftone filter" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "Outline" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, no-c-format msgid "Perform outline extraction" msgstr "Perform outline extraction" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "Emphasis" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "Negative to smooth or positive to sharpen image" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, no-c-format msgid "Separation" msgstr "Separation" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "Enable automatic separation of image and text" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "Mirroring" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "Reflect output image horizontally" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, no-c-format msgid "White level follower" msgstr "White level follower" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, no-c-format msgid "Control white level follower" msgstr "Control white level follower" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, no-c-format msgid "BP filter" msgstr "BP filter" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "Improves quality of high resolution ball-point pen text" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Smoothing" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "Enable smoothing for improved OCR" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, no-c-format msgid "Gamma curve" msgstr "Gamma curve" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "Gamma curve, from light to dark, but upper two may not work" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Threshold curve" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" "Threshold curve, from light to dark, but upper two may not be linear" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "Threshold white" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "Set pixels equal to threshold to white instead of black" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "Noise removal" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "Matrix 5x5" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "Remove 5 pixel square noise" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "Matrix 4x4" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "Remove 4 pixel square noise" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "Matrix 3x3" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "Remove 3 pixel square noise" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "Matrix 2x2" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "Remove 2 pixel square noise" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "Variance" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "Set SDTC variance rate (sensitivity), 0 equals 127" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, no-c-format msgid "Auto width detection" msgstr "Auto width detection" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "Scanner detects paper sides. May reduce scanning speed." -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, no-c-format msgid "Auto length detection" msgstr "Auto length detection" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "Scanner detects paper lower edge. May confuse some frontends." -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "Compression" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "Enable compressed data. May crash your front-end program" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "Compression argument" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " @@ -2460,114 +2490,114 @@ msgstr "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "DF action" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "Action following double feed error" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "DF skew" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "Enable double feed error due to skew" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "DF thickness" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Enable double feed error due to paper thickness" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "DF length" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "Enable double feed error due to paper length" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "DF length difference" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "Difference in page length to trigger double feed error" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "DF recovery mode" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "Request scanner to reverse feed on paper jam" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "Paper protection" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "Request scanner to predict jams in the ADF" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, no-c-format msgid "Advanced paper protection" msgstr "Advanced paper protection" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "Request scanner to predict jams in the ADF using improved sensors" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, no-c-format msgid "Staple detection" msgstr "Staple detection" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "Request scanner to detect jams in the ADF caused by staples" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "Background colour" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" "Set colour of background for scans. May conflict with overscan option" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "Dropout colour" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " @@ -2576,33 +2606,33 @@ msgstr "" "One-pass scanners use only one colour during grey or binary scanning, " "useful for coloured paper or ink" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "Buffer mode" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" "Request scanner to read pages quickly from ADF into internal memory" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "Prepick" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "Request scanner to grab next page from ADF" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "Overscan" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2613,24 +2643,24 @@ msgstr "" "ADF, and increase maximum scan area beyond paper size, to allow " "collection on remaining sides. May conflict with bgcolor option" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "Sleep timer" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" "Time in minutes until the internal power supply switches to sleep mode" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "Off timer" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " @@ -2639,42 +2669,42 @@ msgstr "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, no-c-format msgid "Duplex offset" msgstr "Duplex offset" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "Adjust front/back offset" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Green offset" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, no-c-format msgid "Adjust green/red offset" msgstr "Adjust green/red offset" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Blue offset" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "Adjust blue/red offset" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "Low Memory" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2687,12 +2717,12 @@ msgstr "" "option 'side' can be used to determine correct image. This option should " "only be used with custom front-end software." -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, no-c-format msgid "Duplex side" msgstr "Duplex side" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " @@ -2701,154 +2731,154 @@ msgstr "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "Hardware deskew and crop" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "Request scanner to rotate and crop pages digitally." -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Software deskew" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "Request driver to rotate skewed pages digitally." -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Software despeckle diameter" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "Maximum diameter of lone dots to remove from scan." -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "Software crop" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "Request driver to remove border from pages digitally." -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "Halt on Cancel" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" "Request driver to halt the paper feed instead of eject during a cancel." -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, no-c-format msgid "Endorser Options" msgstr "Endorser Options" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "Controls for endorser unit" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "Endorser" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "Enable endorser unit" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "Endorser bits" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "Determines maximum endorser counter value." -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "Endorser value" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "Initial endorser counter value." -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "Endorser step" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "Change endorser counter value by this much for each page." -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "Endorser Y" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "Endorser print offset from top of paper." -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "Endorser font" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "Endorser printing font." -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, no-c-format msgid "Endorser direction" msgstr "Endorser direction" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "Endorser printing direction." -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "Endorser side" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "Endorser printing side, requires hardware support to change" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "Endorser string" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " @@ -2857,212 +2887,197 @@ msgstr "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "Top edge" -# Shouldn't we standardise on ADF? i.e. not adf -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "Paper is pulled partly into ADF" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "A3 paper" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "A3 paper detected" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "B4 paper" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "B4 paper detected" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "A4 paper" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "A4 paper detected" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "B5 paper" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "B5 paper detected" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "OMR or DF" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "OMR or double feed detected" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "Power saving" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "Scanner in power saving mode" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "Manual feed" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "Manual feed selected" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "Function" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "Function character on screen" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "Ink low" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "Imprinter ink running low" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "Double feed" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "Double feed detected" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "Error code" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "Hardware error code" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "Skew angle" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "Requires black background for scanning" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "Ink remaining" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, no-c-format msgid "Imprinter ink level" msgstr "Imprinter ink level" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, no-c-format msgid "Density" msgstr "Density" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "Density dial" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, no-c-format msgid "Duplex switch" msgstr "Duplex switch" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "Request backend to remove border from pages digitally" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "Request driver to discard pages with low numbers of dark pixels" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "Software derotate" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "Request driver to detect and correct 90 degree image rotation" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extras" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "Dynamic threshold curve, from light to dark, normally 50-65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Disable dynamic lineart" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Disable interpolation" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3071,32 +3086,32 @@ msgstr "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, no-c-format msgid "Color filter" msgstr "Colour filter" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "When using grey or lineart this option selects the used colour." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, no-c-format msgid "Calibration file" msgstr "Calibration file" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, no-c-format msgid "Specify the calibration file to use" msgstr "Specify the calibration file to use" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, no-c-format msgid "Calibration cache expiration time" msgstr "Calibration cache expiration time" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " @@ -3105,12 +3120,12 @@ msgstr "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Lamp off time" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3119,90 +3134,110 @@ msgstr "" "The lamp will be turned off after the given time (in minutes). A value " "of 0 means, that the lamp won't be turned off." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "Lamp off during scan" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "The lamp will be turned off during scan. " -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "File button" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "OCR button" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Power button" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, no-c-format msgid "Extra button" msgstr "Extra button" -# Need->Needs? -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, no-c-format -msgid "Need calibration" -msgstr "Need calibration" +msgid "Needs calibration" +msgstr "Needs calibration" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "The scanner needs calibration for the current settings" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Buttons" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Calibrate" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Start calibration using special sheet" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Clear calibration" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Clear calibration cache" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, no-c-format msgid "Force calibration" msgstr "Force calibration" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "Force calibration ignoring all and any calibration caches" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, no-c-format +msgid "Ignore internal offsets" +msgstr "Ignore internal offsets" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" +"Acquires the image including the internal calibration areas of the " +"scanner" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Transparency Adapter" +#: backend/genesys/genesys.h:80 +#, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Transparency Adapter Infrared" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3307,6 +3342,309 @@ msgstr "Gamma value" msgid "Sets the gamma value of all channels." msgstr "Sets the gamma value of all channels." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Advanced Options" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Coarse" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fine" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Custom" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Auto" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Pass-through" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC Grey" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA Grey" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Slow" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Fast" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Extra Fast" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-pixel" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-pixel" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-pixel" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Print" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Slide" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Film-strip" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Conditional" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experiment" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Sharpening" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Set sharpening value." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Auto Threshold" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "Enable automatic determination of threshold for line-art scans." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Select smoothing filter." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Unload media after scan" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Unloads the media after a scan." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Change document" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Change Document." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Unload" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Unload Document." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Start calibration process." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Media" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Set type of media." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Exposure time" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Colour Matrix" + +#: backend/hp-option.h:121 +#, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Set the scanner's colour matrix." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Custom colour matrix." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Mono Colour Matrix" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Custom colour matrix for greyscale scans." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Mirror horizontal" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Mirror image horizontally." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Mirror vertical" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Mirror image vertically." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Update options" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Update options." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8 bit output" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Use bit depth greater eight internally, but output only eight bits." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Front button wait" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Wait to scan for front-panel button push." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Shut off lamp" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Shut off scanner lamp." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3317,27 +3655,19 @@ msgstr "Geometry Group" msgid "Scan Mode Group" msgstr "Scan Mode Group" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Slide" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" msgstr "Scanner model" -# US spelling of behaviour is incorrect #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "Allows one to test device behaviour with other supported models" -# US spelling of colour is incorrect #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "Image colours will be inverted" #: backend/hp3900_sane.c:1436 @@ -3526,11 +3856,6 @@ msgstr "Switches the lamp on or off." msgid "Calibrates for black and white level." msgstr "Calibrates for black and white level." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3647,299 +3972,6 @@ msgstr "" "Colour value for trailing lines filling mode 'colour'. RGB colour as " "r*65536+256*g+b or grey value (default=violet or grey)" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Advanced Options" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Coarse" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fine" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Custom" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Auto" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Pass-through" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC Grey" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA Grey" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Slow" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Fast" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Extra Fast" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-pixel" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-pixel" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-pixel" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Print" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Film-strip" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Conditional" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experiment" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Sharpening" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Set sharpening value." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Auto Threshold" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "Enable automatic determination of threshold for line-art scans." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Select smoothing filter." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Unload media after scan" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Unloads the media after a scan." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Change document" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Change Document." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Unload" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Unload Document." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Start calibration process." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Media" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Set type of media." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Exposure time" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Colour Matrix" - -# Requires apostrophe -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Set the scanner's colour matrix." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Custom colour matrix." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Mono Colour Matrix" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Custom colour matrix for greyscale scans." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Mirror horizontal" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Mirror image horizontally." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Mirror vertical" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Mirror image vertically." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Update options" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Update options." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8 bit output" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Use bit depth greater eight internally, but output only eight bits." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Front button wait" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Wait to scan for front-panel button push." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Shut off lamp" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Shut off scanner lamp." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4038,7 +4070,7 @@ msgid "single" msgstr "single" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4205,10 +4237,9 @@ msgstr "high" msgid "crt" msgstr "crt" -# Linear? #: backend/kvs1025_opt.c:229 #, no-c-format -msgid "linier" +msgid "linear" msgstr "linear" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 @@ -4338,7 +4369,7 @@ msgstr "Sets the image emphasis" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4405,14 +4436,14 @@ msgstr "Software automatic cropping" msgid "Request driver to remove border from pages digitally" msgstr "Request driver to remove border from pages digitally" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 #: backend/kvs40xx_opt.c:668 backend/kvs40xx_opt.c:669 @@ -4441,16 +4472,14 @@ msgstr "Double letter 11x17 in" msgid "B4" msgstr "B4" -# sensivity->sensitivity #: backend/kvs40xx_opt.c:231 #, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "High sensitivity" -# sensivity->sensitivity #: backend/kvs40xx_opt.c:232 #, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Low sensitivity" #: backend/kvs40xx_opt.c:243 @@ -4473,6 +4502,15 @@ msgstr "Normal mode" msgid "Enhanced mode" msgstr "Enhanced mode" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" + # The grammar is a bit suspect here. #: backend/kvs40xx_opt.c:405 #, no-c-format @@ -4533,10 +4571,9 @@ msgstr "Inverse image in B/W mode" msgid "JPEG compression" msgstr "JPEG compression" -# yours->your #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "JPEG compression (your application must be able to uncompress)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4569,34 +4606,30 @@ msgstr "Set chroma of blue" msgid "Skew adjustment" msgstr "Skew adjustment" -# Grammar? #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "Stop scanner if a sheet is skewed" -# stop->stopped #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" -msgstr "Scanner will be stopped if sheet is skewed" +msgid "Scanner will stop if a sheet is skewed" +msgstr "Scanner will stop if a sheet is skewed" #: backend/kvs40xx_opt.c:816 #, no-c-format msgid "Crop actual image area" msgstr "Crop actual image area" -# detect->detects; crop->crops #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" -msgstr "Scanner automatically detects image area and crops it" +msgid "Scanner will automatically detect image area and crop to it" +msgstr "Scanner will automatically detect image area and crop to it" -# Grammar? #: backend/kvs40xx_opt.c:827 #, no-c-format -msgid "It is right and left reversing" -msgstr "It is right and left reversing" +msgid "Left/right mirror image" +msgstr "Left/right mirror image" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4633,52 +4666,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 Vertical Line" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Gain" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Colour channels gain settings" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Grey gain" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Sets grey channel gain" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Red gain" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Sets red channel gain" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Green gain" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Sets green channel gain" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Blue gain" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Sets blue channel gain" @@ -4764,7 +4797,7 @@ msgstr "One page" msgid "All pages" msgstr "All pages" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "sheetfed scanner" @@ -5266,27 +5299,33 @@ msgstr "" "Warm-up until the lamp's brightness is constant instead of insisting on " "40 seconds warm-up time." -#: backend/pixma.c:397 +# Original would be better as "Needs calibration". "Need calibration" is a command rather than a statement of fact which is what is required here, as in "You must need calibration, or else" +#: backend/p5.c:1926 +#, no-c-format +msgid "Need calibration" +msgstr "Needs calibration" + +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "Negative colour" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "Negative grey" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "48 bits colour" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "16 bits grey" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " @@ -5295,12 +5334,12 @@ msgstr "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Button-controlled scan" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5311,45 +5350,44 @@ msgstr "" "\"SCAN\" button (for MP150) or \"COLOUR\" button (for other models). To " "cancel, press \"GREY\" button." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Update button state" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Button 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Button 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "Type of original to scan" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "Target operation type" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "ADF Waiting Time" -# Grammar could be improved. -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" -"When set, the scanner waits the specified time in seconds for a new " -"document to be inserted into the automatic document feeder." +"When set, the scanner waits upto the specified time in seconds for a new " +"document inserted into the automatic document feeder." #: backend/plustek.c:235 backend/plustek_pp.c:204 backend/u12.c:156 #, no-c-format @@ -5436,7 +5474,7 @@ msgstr "Analogue frontend" msgid "Red gain value of the AFE" msgstr "Red gain value of the AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Red offset" @@ -5711,7 +5749,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "This option reflects the status of a scanner button." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lamp on" @@ -5721,12 +5759,12 @@ msgstr "Lamp on" msgid "Turn on scanner lamp" msgstr "Turn on scanner lamp" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Lamp off" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Turn off scanner lamp" @@ -5869,16 +5907,14 @@ msgstr "Focus-point" msgid "Focus point" msgstr "Focus point" -# Original should specify "color" not colour. #: backend/snapscan-options.c:930 #, no-c-format -msgid "Colour lines per read" +msgid "Color lines per read" msgstr "Colour lines per read" -# Original should specify gray #: backend/snapscan-options.c:942 #, no-c-format -msgid "Greyscale lines per read" +msgid "Grayscale lines per read" msgstr "Greyscale lines per read" #: backend/stv680.c:974 @@ -6522,56 +6558,72 @@ msgstr "Calibration mode" msgid "Define calibration mode" msgstr "Define calibration mode" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Sets lamp on/off" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA on" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Sets UTA on/off" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Offset" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Colour channels offset settings" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Grey offset" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Sets grey channel offset" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Sets red channel offset" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Sets green channel offset" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Sets blue channel offset" +#~ msgid "Disable dynamic lineart" +#~ msgstr "Disable dynamic lineart" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." + +#~ msgid "linier" +#~ msgstr "linear" + +#~ msgid "It is right and left reversing" +#~ msgstr "It is right and left reversing" + #, fuzzy #~ msgid "IPC mode" #~ msgstr "Preview mode" @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends.eo\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-12-08 13:28+0100\n" "Last-Translator: A.C.Codazzi\n" "Language-Team: <it@li.org>\n" @@ -31,31 +31,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometrio" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Plibonigo" @@ -89,7 +89,7 @@ msgid "Bit depth" msgstr "Profundeco en bitoj" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Moduso de skanado" @@ -130,7 +130,7 @@ msgid "Bottom-right y" msgstr "Sube-dekstre Y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Difino de skanado" @@ -285,7 +285,7 @@ msgstr "Dosiernomo" msgid "Halftone pattern size" msgstr "Grado de modelo por meznuancoj" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Modelo por meznuanco" @@ -295,10 +295,10 @@ msgstr "Modelo por meznuanco" msgid "Bind X and Y resolution" msgstr "Bindu distindon de X kaj Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativo" @@ -419,9 +419,9 @@ msgid "Lamp off at exit" msgstr "ElÅaltu lampon kaj eliru" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Äœi estas nurlega opcio kiu priskribas kiom da opcioj subtenas specifa " @@ -761,8 +761,8 @@ msgid "Analog gamma-correction for blue" msgstr "Analoga korektado de gama por bluo" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Varmigu lampon antaÅ la skanado" #: include/sane/saneopts.h:417 @@ -912,7 +912,7 @@ msgstr "Mez-nuancoj Nesubtenitaj" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -1005,10 +1005,10 @@ msgid "Only perform shading-correction" msgstr "Plenumu nur korektadon de ombroj" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Se Äi estas ebligita, oni plemunas nur la korektadon de ombroj dum " @@ -1036,83 +1036,43 @@ msgid "Duplex scan" msgstr "Fronta-dorsa skanado" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "Äœi plenumas frontan-dorsan skanadon de la dokumento" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibrigu Skanilon" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Äœi devigas kalibrigon de skanilon antaÅ la skanado" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Grizgama skanado" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Äœi plenumas grizgaman anstataÅ kolora skanadon" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analoga Gajno" +msgid "Correction according to transparency ratio" +msgstr "Korektado rilata al la rejÅo de diafaneco" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Äœi pliigas aÅ malpliigas la analogan gajnon de la CCD-sentilo" +msgid "Correction according to film type" +msgstr "Korektado rilata al la filmospeco" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Korektado de Gama" +msgid "Fine color" +msgstr "Fajna koloro" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Äœi elektas la kurbon de korektado de gama" +msgid "Negatives" +msgstr "Negativoj" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Kruda" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Fajna koloro" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Neniu korektado de diafaneco" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Korektado rilata al la filmospeco" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Korektado rilata al la rejÅo de diafaneco" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negativoj" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1246,8 +1206,8 @@ msgid "invalid bit IDENTIFY message" msgstr "mesaÄo kun nevalida IDENTIFY-bito" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "opcio de ne-konektado" #: backend/canon.c:474 @@ -1537,133 +1497,184 @@ msgstr "Elektu specon de filmo" msgid "Select the film type" msgstr "Äœi elektas specon de filmo" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibrigu Skanilon" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Äœi devigas kalibrigon de skanilon antaÅ la skanado" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Grizgama skanado" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Äœi plenumas grizgaman anstataÅ kolora skanadon" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analoga Gajno" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Äœi pliigas aÅ malpliigas la analogan gajnon de la CCD-sentilo" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Korektado de Gama" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Äœi elektas la kurbon de korektado de gama" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Fiksa ebeno" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, fuzzy, no-c-format msgid "ADF Front" msgstr "Kovrilo de ADF estas malfermita" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "ADF estas blokita" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Fronta-dorsa ADF" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Presu" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Fronta-dorsa" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "RuÄo" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Verdo" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Bluo" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Plibonigo" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Plibonigo" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Plibonigo" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Nenio" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Unuopa" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Fronta-dorsa" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Reguligilo de Diafaneco" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "AÅtomata Provizilo de Dokumentoj" @@ -1775,7 +1786,7 @@ msgstr "InkoÅprucaj printiloj" msgid "CRT monitors" msgstr "CRT ekranoj" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1839,8 +1850,9 @@ msgstr "A4" msgid "Max" msgstr "Maks" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2013,17 +2025,17 @@ msgstr "Äœi agordas la faktoron de zomo kiun la skanilo uzos" msgid "Quick format" msgstr "Formato rapido" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Akcesora ekipaĵo" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Elpelo" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Äœi elpelas la folion el aÅtomata provizilo" @@ -2038,12 +2050,14 @@ msgstr "Mem-elpelo" msgid "Eject document after scanning" msgstr "Äœi elpelas la dokumento post la skanado" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Moduso por ADF" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Äœi elektas la ADF-moduso (unuopa/fronta-dorsa)" @@ -2093,14 +2107,14 @@ msgstr "" "Post la sendo de la skan-komando, Äi atendas la premon de la butono de " "la skanilo por startigi la skanadon." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2123,492 +2137,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "Agordita de la uzanto" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Äœi elpelas la folion el aÅtomata provizilo" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Neniu korektado" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Korektado de analoga gama" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Kondukta" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Elkluda" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Punktismo" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "Difuzo de Eraro" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Nivelo de blanko" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Nivelo de nigro" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "Kondiĉa" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horizontala" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Horizontala" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Horizontala" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertikala" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "Vertikala" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Presu" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Meznuancoj" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Plenumu kalibrigon" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Emfazo de bildo" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Saturado" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "Äœi elbligas aÅtomatan elekton de sojlo por duuma skanado." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Spegula bildo" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Äœi reflektas bildon horizontale." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Nivelo de blanko laÅ bluo" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Mastrumu nivelon de ruÄo" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Filtrilo de Koloro" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Glatigo" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Valoro de Gama" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Sojlo" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Sojlo" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Redukto de bruo" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Neniu korektado" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Neniu korektado" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Kovrilo de ADF estas malfermita" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Avanaj Opcioj" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Neniu korektado" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Eskludado" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Moduso de provizilo" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2616,65 +2650,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Ripozo de lampo" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "DeÅovo laÅ bluo" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "DeÅovo laÅ verdo" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "DeÅovo laÅ verdo" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "DeÅovo laÅ bluo" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Äœi agordas la deÅovon de la blua kanalo" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2683,374 +2717,362 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Fronta-dorsa skanado" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Avanaj Opcioj" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Redukto de bruo" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "El papero" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "El papero" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "El papero" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "El papero" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "Kovrilo de ADF estas malfermita" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Mana prepara fokusigo" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Mana prepara fokusigo" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "Eraro de kontrolo de la aparataro" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Nivelo de blanko" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Regilo de denseco" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "Regilo de denseco" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Fronta-dorsa skanado" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Ekstraĵoj" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Malebligu interpoladon" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3059,45 +3081,45 @@ msgstr "" "Kiam oni uzas altajn distingojn kun la horizontala malpli alta ol la " "verticala, la horizontala interpolado estas malebligata." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Filtrilo de Koloro" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "Kiam oni uzas grizan aÅ duuman kolorojn, tiu elektas uzatan koloron." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibrigo" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Difinu moduson de kalibrigo" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "KaÅmemoro por kalibrigo" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Ripozo de lampo" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3106,90 +3128,109 @@ msgstr "" "La lampo estos elÅaltata post la fiksita tempo (en minutoj). La valoro " "signifas ke la lampo neniam ripozos." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "ElÅaltita lampo dum kalibrigo de nigro" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, fuzzy, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" "Nombro da minutoj pasantaj inter la skanado kaj la elÅalto de la lampo" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "Atendu butonon" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "Atendu butonon" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Atendu butonon" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Grajneca kalibrigo" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Äœi devigas kalibrigon de skanilon antaÅ la skanado" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Butonoj" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibrigu" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Startigu kalibrigadon." -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Grajneca kalibrigo" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "KaÅmemoro por kalibrigo" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Grajneca kalibrigo" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "DeÅovo laÅ verdo" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "reguligilo de Diafaneco" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "reguligilo de Diafaneco" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3296,6 +3337,310 @@ msgstr "Valoro de Gama" msgid "Sets the gamma value of all channels." msgstr "Äœi agordas valoron de gama por ĉiuj kanaloj." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Avanaj Opcioj" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Grajna" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fajna" + +# Bayer è il nome della persona che ha inventato questa matrice per il +# dithering. +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Personigita" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "AÅtomata" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Trapasanta" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC-Grizo" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA-Grizo" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Malrapida" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normala" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rapida" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Tre Rapida" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-bilderoj" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-bilderoj" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-bilderoj" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Presu" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Lumbildo" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Filmo" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Kondiĉa" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Eksperimento" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Neteco" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Äœi agordas la valoron de neteco." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "AÅtomata Sojlo" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "Äœi elbligas aÅtomatan elekton de sojlo por duuma skanado." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Elektu filtrilon por glatigi." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Elpelu bazon post skanado" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Äœi elpelas la bazon post skanado." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Åœangu dokumenton" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Äœi Åangas dokumenton." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Elpelu" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Elpelu Dokumenton." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Startigu kalibrigadon." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Bazo" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Agordu specon de bazo." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Ekspontempo" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Pli longa ekspontempo ebligas la skanilon preni pli multe da lumo. " +"Oportunajvaloroj estas 175% por presaĵoj, 150% por normalaj lumbildoj " +"kaj \"Negativo\" por filmoj. Por malhelaj bildoj (subeksponitaj) pliigu " +"tiun ĉi valoro." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matrico de Koloro" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Äœi agordas matricon de koloro." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Personigita matrico de koloro." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Matrico de Monokromata Koloro" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Personigita matrico de koloro por grizgamaj skanadoj." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Spegulu horizontale" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Äœi reflektas bildon horizontale." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Spegulu vertikale" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Äœi reflektas bildon vertikale." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Opcioj de Äisdatigo" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Opcioj de Äisdatigo." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8-bita eligo" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "Uzu ene pli ol 8 bitoj de profundeco, sed eligu nur 8-bitojn." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Atendante frontan butonon" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Äœi atendas premon de la fronta butono de lo skanilo por skani." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "ElÅaltu lampon" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Äœi elÅaltas la lampon de la skanilo." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3306,12 +3651,6 @@ msgstr "Geometria Grupo" msgid "Scan Mode Group" msgstr "Grupo de Moduso de Skanado" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Lumbildo" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3319,12 +3658,12 @@ msgstr "Moduso de skanado" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3505,11 +3844,6 @@ msgstr "Åœaltu aÅ elÅaltu la lampon." msgid "Calibrates for black and white level." msgstr "Kalibrigu la nivelojn de nigro kaj blanko." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3620,299 +3954,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Avanaj Opcioj" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Grajna" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fajna" - -# Bayer è il nome della persona che ha inventato questa matrice per il -# dithering. -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Personigita" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "AÅtomata" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Trapasanta" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC-Grizo" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA-Grizo" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Malrapida" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normala" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rapida" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Tre Rapida" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-bilderoj" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-bilderoj" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-bilderoj" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Presu" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Filmo" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Kondiĉa" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Eksperimento" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Neteco" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Äœi agordas la valoron de neteco." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "AÅtomata Sojlo" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "Äœi elbligas aÅtomatan elekton de sojlo por duuma skanado." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Elektu filtrilon por glatigi." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Elpelu bazon post skanado" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Äœi elpelas la bazon post skanado." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Åœangu dokumenton" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Äœi Åangas dokumenton." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Elpelu" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Elpelu Dokumenton." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Startigu kalibrigadon." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Bazo" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Agordu specon de bazo." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Ekspontempo" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Pli longa ekspontempo ebligas la skanilon preni pli multe da lumo. " -"Oportunajvaloroj estas 175% por presaĵoj, 150% por normalaj lumbildoj " -"kaj \"Negativo\" por filmoj. Por malhelaj bildoj (subeksponitaj) pliigu " -"tiun ĉi valoro." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matrico de Koloro" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Äœi agordas matricon de koloro." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Personigita matrico de koloro." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Matrico de Monokromata Koloro" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Personigita matrico de koloro por grizgamaj skanadoj." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Spegulu horizontale" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Äœi reflektas bildon horizontale." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Spegulu vertikale" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Äœi reflektas bildon vertikale." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Opcioj de Äisdatigo" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Opcioj de Äisdatigo." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8-bita eligo" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "Uzu ene pli ol 8 bitoj de profundeco, sed eligu nur 8-bitojn." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Atendante frontan butonon" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Äœi atendas premon de la fronta butono de lo skanilo por skani." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "ElÅaltu lampon" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Äœi elÅaltas la lampon de la skanilo." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4011,7 +4052,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4183,9 +4224,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Duuma" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4314,7 +4355,7 @@ msgstr "Äœiu ebligas emfazon de bildo" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gama" @@ -4381,11 +4422,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4417,12 +4458,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Altdensa printado" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Malaltdensa printado" #: backend/kvs40xx_opt.c:243 @@ -4445,6 +4486,13 @@ msgstr "Normala" msgid "Enhanced mode" msgstr "Plibonigo" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4504,7 +4552,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4539,12 +4587,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4554,13 +4602,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Spegula bildo" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4597,52 +4645,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 vertikal-linia" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Gajno" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Agordaĵoj pri la gajno de la kanaloj de koloro" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Gajno laÅ grizo" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Äœi agordas la gajnon de la griza kanalo" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Gajno laÅ ruÄo" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Äœi agordas la gajnon de la ruÄa kanalo" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Gajno laÅ verdo" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Äœi agordas la gajnon de la verda kanalo" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Gajno laÅ bluo" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Äœi agordas la gajnon de la blua kanalo" @@ -4728,7 +4776,7 @@ msgstr "Unu paÄo" msgid "All pages" msgstr "Ĉiuj paÄoj" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "skaner kun aÅtomata provizilo" @@ -5235,39 +5283,44 @@ msgstr "" "Äœi varmigas la lampon tiel ke Äia heleco estas sensanÄa anstataŠĉiufoja " "varmigo je 40 sekundoj." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Grajneca kalibrigo" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Negativa filmo" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativo" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, fuzzy, no-c-format msgid "48 bits color" msgstr "Fajna koloro" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Skanado mastrumita de butono" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5278,40 +5331,40 @@ msgstr "" "butonon \"SCAN\" (por ML150) aÅ \"COLOR\" (por aliaj modeloj). Por " "refuzi, premu la butonon \"GRAY\"." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Äœisdatigu staton de butono" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Butono 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Butono 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5400,7 +5453,7 @@ msgstr "Analoga fasado" msgid "Red gain value of the AFE" msgstr "Valoro de gajno laÅ ruÄo de la analoga fasado" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "DeÅovo laÅ ruÄo" @@ -5675,7 +5728,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Tiuj ĉi opcioj agas sur la stato de la butonoj de la skanilo." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Åœaltu lampon" @@ -5685,12 +5738,12 @@ msgstr "Åœaltu lampon" msgid "Turn on scanner lamp" msgstr "Äœi Åaltas la lampon de la skanilo" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "ElÅaltu lampon" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Äœi elÅaltas la lampon de la skanilo" @@ -5835,13 +5888,13 @@ msgid "Focus point" msgstr "LokiÄo de Fokusigo" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Koloraj linioj por ĉiu legado" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Äœrizgamaj linioj por ĉiu legado" #: backend/stv680.c:974 @@ -6497,52 +6550,52 @@ msgstr "Moduso de kalibrigo" msgid "Define calibration mode" msgstr "Difinu moduson de kalibrigo" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Äœi Åaltas/elÅaltas la lampon" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "Åœaltu UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Äœi Åaltas/elÅaltas la reguligilon de diafaneco" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "DeÅovo" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Agordoj de deÅovo laÅ kanaloj de koloro" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "DeÅovo laÅ grizo" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Äœi agordas la deÅovon de la griza kanalo" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Äœi agordas la deÅovon de la ruÄa kanalo" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Äœi agordas la deÅovon de la verda kanalo" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Äœi agordas la deÅovon de la blua kanalo" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2009-06-25 10:22+0100\n" "Last-Translator: Miguel Anxo Bouzada <mbouzada@gmail.com>\n" "Language-Team: GALPon MiniNo <minino@galpon.org>\n" @@ -30,31 +30,31 @@ msgid "Standard" msgstr "Estándar" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "GeometrÃa" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Mejora" @@ -88,7 +88,7 @@ msgid "Bit depth" msgstr "Bit de profundidad" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Modo de escaneo" @@ -129,7 +129,7 @@ msgid "Bottom-right y" msgstr "Abajo-derecha Y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Resolución de escaneo" @@ -284,7 +284,7 @@ msgstr "Nombre de archivo" msgid "Halftone pattern size" msgstr "Tamaño del patrón de medios tonos" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Patrón de medios tonos" @@ -294,10 +294,10 @@ msgstr "Patrón de medios tonos" msgid "Bind X and Y resolution" msgstr "Enlazar resoluciones X e Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativo" @@ -418,9 +418,9 @@ msgid "Lamp off at exit" msgstr "Apagar la lámpara al salir" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Opción de sólo lectura que establece cuantas opciones soporta un " @@ -763,8 +763,8 @@ msgid "Analog gamma-correction for blue" msgstr "Corrección gamma analógica para azul" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Calentar la lámpara antes de escanear" #: include/sane/saneopts.h:417 @@ -913,8 +913,8 @@ msgid "Operation not supported" msgstr "Operación no soportada" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "La operación va a ser cancelada" #: backend/sane_strstatus.c:68 @@ -1008,10 +1008,10 @@ msgid "Only perform shading-correction" msgstr "Realizar sólo correcciones de sombras" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Si está activado, sólo se realizarán correcciones de sombras durante la " @@ -1040,85 +1040,45 @@ msgid "Duplex scan" msgstr "Escaneo a dos caras" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "El escaneo a dos caras proporciona un escaneo del anverso y el reverso " "del documento" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibrar el escáner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Fuerza la calibración del escáner antes de realizar el escaneo" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Escaneo en escala de grises" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Escanea en escala de grises, no en color" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Ganancia analógica" +msgid "Correction according to transparency ratio" +msgstr "Corrección conforme con la tasa de transparencia" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Aumenta o disminuye la ganancia analógica de la gama CCD" +msgid "Correction according to film type" +msgstr "Correción de acuerdo con el tipo de pelÃcula" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Corrección gamma" +msgid "Fine color" +msgstr "Color fino" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Selecciona la curva de transferencia de la corrección gamma" +msgid "Negatives" +msgstr "Negativos" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "En bruto" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Color fino" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Sin corrección de transparencia" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Correción de acuerdo con el tipo de pelÃcula" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Corrección conforme con la tasa de transparencia" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negativos" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1253,8 +1213,8 @@ msgid "invalid bit IDENTIFY message" msgstr "mensaje de bit de IDENTIFICACIÓN incorrecto" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "la opción no conecta" #: backend/canon.c:474 @@ -1551,133 +1511,184 @@ msgstr "Seleccionar tipo de pelÃcula" msgid "Select the film type" msgstr "Seleccionar el tipo de pelÃcula" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibrar el escáner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Fuerza la calibración del escáner antes de realizar el escaneo" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Escaneo en escala de grises" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Escanea en escala de grises, no en color" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Ganancia analógica" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Aumenta o disminuye la ganancia analógica de la gama CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Corrección gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Selecciona la curva de transferencia de la corrección gamma" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Plana" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, fuzzy, no-c-format msgid "ADF Front" msgstr "la tapa del alimentador está abierta" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "atasco en el alimentador" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Alimentador a dos caras" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Imprimir" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Dos caras" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Rojo" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Verde" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Azul" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Mejora" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Mejora" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Mejora" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ninguno" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Una cara" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Dos caras" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Unidad de transparencias" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Alimentador automático de documentos (ADF)" @@ -1789,7 +1800,7 @@ msgstr "Impresoras de inyección de tinta" msgid "CRT monitors" msgstr "Monitores CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1853,8 +1864,9 @@ msgstr "A4" msgid "Max" msgstr "Máx" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2028,17 +2040,17 @@ msgstr "Define el factor de zoom que usará el escáner" msgid "Quick format" msgstr "Formato rápido" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Equipamiento opcional" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Expulsar" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Expulsar la hoja del alimentador" @@ -2053,12 +2065,14 @@ msgstr "Expulsión automática" msgid "Eject document after scanning" msgstr "Expulsar el documento después del escaneo" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Modo alimentador" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Seleccionar el modo del alimentador (una cara/dos caras)" @@ -2110,14 +2124,14 @@ msgstr "" "Después de enviar la orden de escanear, esperar hasta que se presione el " "botón del escáner para empezar realmente el proceso de escaneo." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2140,494 +2154,514 @@ msgstr "" msgid "User defined CCT profile" msgstr "Definida por el usuario" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Expulsar la hoja del alimentador" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Sin corrección" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Desactivar corrección gamma" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Activo" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Apagado" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Difuminado" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "Difusión de error" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Nivel de blanco" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Nivel de negro" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "Condicional" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horizontal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Horizontal" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Horizontal" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertical" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "Vertical" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Imprimir" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Medios tonos" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Calibración de precisión" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Resalte de imagen" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Saturación" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "" "Activar la determinación automática de umbral para escaneos como lÃnea " "de arte." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Invertir imagen" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Invertir la imagen horizontalmente." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Nivel de blanco para azul" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Controla el nivel de rojo" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Filtro de color" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Suavizado" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Valor gamma" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Umbral" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Umbral" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Reducción de ruido" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Sin corrección" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Sin corrección" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "la tapa del alimentador está abierta" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Opciones avanzadas" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Sin corrección" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Exclusión" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Modo de alimentación" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2635,65 +2669,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Tiempo de espera de la lámpara" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Desviación azul" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Desviación verde" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Desviación verde" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Desviación azul" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Ajusta el desplazamiento del canal de azul" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, fuzzy, no-c-format msgid "Low Memory" msgstr "No queda memoria" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2702,374 +2736,362 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Escaneo a dos caras" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Opciones avanzadas" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Reducción de ruido" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Del papel" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Del papel" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Del papel" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Del papel" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "La tapa del escáner está abierta" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Foco previo manual" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Foco previo manual" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "error de verificación de hardware" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Nivel de blanco" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Control de densidad" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "Control de densidad" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Escaneo a dos caras" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extras" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Desactivar interpolación" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3078,45 +3100,45 @@ msgstr "" "Cuando se usan altas resoluciones en las que la resolución horizontal es " "más pequeña que la vertical, esto desactiva la interpolación horizontal." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Filtro de color" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "Cuando se usa gris o lÃnea de arte esta opción selecciona el color usado." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Calibración" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Define el modo de calibración" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Caché de datos de calibración" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Tiempo de espera de la lámpara" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3125,89 +3147,108 @@ msgstr "" "La lámpara será apagada después del tiempo dado (en minutos). Un valor " "de 0 significa que la lámpara no será apagada" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Apagar la lámpara durante la calibración de oscuridad" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, fuzzy, no-c-format msgid "The lamp will be turned off during scan. " msgstr "Minutos que tardará la lámpara en apagarse tras el escaneo" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Botón de archivo" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Botón de OCR" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Botón de energÃa" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Botón de correo-e" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Limpiar la calibración" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Fuerza la calibración del escáner antes de realizar el escaneo" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Botones" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Calibrar" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Iniciar calibración usando una hoja especial" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Limpiar la calibración" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Limpiar la caché de datos de calibración" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Calibración tosca" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Desviación verde" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Adaptador de transparencias" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Adaptador de transparencias" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3315,6 +3356,312 @@ msgstr "Valor gamma" msgid "Sets the gamma value of all channels." msgstr "Ajusta el valor gamma para todos los canales." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Opciones avanzadas" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Gruesa" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fina" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Personalizado" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Auto" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "Adaptador de transparencias RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "A través" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC Gris" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Adaptador de transparencias gris" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lento" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rápido" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Muy rápido" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-pÃxeles" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-pÃxeles" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-pÃxeles" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Imprimir" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositiva" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Tira de pelÃcula" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "Alimentador automático de documentos (ADF)" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "Adaptador de transparencias (XPA)" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Condicional" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experimento" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Nitidez" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Ajustar el valor de nitidez." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Umbral automático" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Activar la determinación automática de umbral para escaneos como lÃnea " +"de arte." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Seleccionar filtro de suavizado." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Descargar soporte después de escanear" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Descargar los soportes después de escanear." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Cambiar documento" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Cambiar documento." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Descargar" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Descargar documento" + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Iniciar proceso de calibración" + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Soporte" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Ajustar tipo de soporte." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Tiempo de exposición" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Una exposición prolongada permite al escáner recoger más luz. Se sugiere " +"usar 175% para impresiones, 150% para diapositivas normales y «Negativo» " +"para pelÃcula en negativo. Para imágenes oscuras (subexpuestas) puede " +"incrementar este valor." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matriz de color" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Ajustar la matriz de color del escáner." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Matriz de color personalizada." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Matriz monocromo" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Matriz de color personalizada para escáneres en escala de grises." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Inversión horizontal" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Invertir la imagen horizontalmente." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Inversión vertical" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Invertir la imagen verticalmente." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Actualizar opciones" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Actualizar opciones." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "Salida de 8 bits" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Usar bit de profundidad mayor de ocho internamente, pero en la salida " +"usar sólo ocho bits." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Esperar botón frontal" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Esperar a que se presione en el botón frontal para escanear." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Apagar lámpara" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Apagar la lámpara del escáner." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3325,12 +3672,6 @@ msgstr "Grupo de geometrÃa" msgid "Scan Mode Group" msgstr "Grupo de modo de escaneo" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositiva" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3338,14 +3679,14 @@ msgstr "Modelo de escáner" #: backend/hp3900_sane.c:1408 #, fuzzy, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" "Permite comprobar el comportamiento del dispositivo con otros modelos " "soportados" #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "Las imágenes de color se invertirán" #: backend/hp3900_sane.c:1436 @@ -3534,11 +3875,6 @@ msgstr "Enciende o apaga la lámpara" msgid "Calibrates for black and white level." msgstr "Calibrar el nivel de blanco y negro." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "Alimentador automático de documentos (ADF)" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3650,301 +3986,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Opciones avanzadas" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Gruesa" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fina" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Personalizado" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Auto" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "Adaptador de transparencias RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "A través" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC Gris" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Adaptador de transparencias gris" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lento" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rápido" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Muy rápido" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-pÃxeles" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-pÃxeles" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-pÃxeles" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Imprimir" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Tira de pelÃcula" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "Adaptador de transparencias (XPA)" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Condicional" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experimento" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Nitidez" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Ajustar el valor de nitidez." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Umbral automático" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Activar la determinación automática de umbral para escaneos como lÃnea " -"de arte." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Seleccionar filtro de suavizado." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Descargar soporte después de escanear" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Descargar los soportes después de escanear." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Cambiar documento" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Cambiar documento." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Descargar" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Descargar documento" - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Iniciar proceso de calibración" - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Soporte" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Ajustar tipo de soporte." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Tiempo de exposición" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Una exposición prolongada permite al escáner recoger más luz. Se sugiere " -"usar 175% para impresiones, 150% para diapositivas normales y «Negativo» " -"para pelÃcula en negativo. Para imágenes oscuras (subexpuestas) puede " -"incrementar este valor." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matriz de color" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Ajustar la matriz de color del escáner." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Matriz de color personalizada." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Matriz monocromo" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Matriz de color personalizada para escáneres en escala de grises." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Inversión horizontal" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Invertir la imagen horizontalmente." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Inversión vertical" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Invertir la imagen verticalmente." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Actualizar opciones" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Actualizar opciones." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "Salida de 8 bits" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Usar bit de profundidad mayor de ocho internamente, pero en la salida " -"usar sólo ocho bits." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Esperar botón frontal" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Esperar a que se presione en el botón frontal para escanear." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Apagar lámpara" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Apagar la lámpara del escáner." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4043,7 +4084,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4211,9 +4252,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "LÃnea de arte" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4342,7 +4383,7 @@ msgstr "Ajusta el resalte de la imagen" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4409,11 +4450,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4445,12 +4486,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Impresión de alta densidad" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Impresión de baja densidad" #: backend/kvs40xx_opt.c:243 @@ -4473,6 +4514,13 @@ msgstr "Normal" msgid "Enhanced mode" msgstr "Mejora" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4532,7 +4580,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4567,12 +4615,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4582,13 +4630,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Invertir imagen" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4625,52 +4673,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 LÃnea vertical" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Ganancia" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Ajustes de ganancia de los canales de color" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Ganancia de gris" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Ajusta la ganancia del canal de gris" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Ganancia de rojo" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Ajusta la ganancia del canal de rojo" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Ganancia de Verde" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Ajusta la ganancia del canal de verde" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Ganancia de Azul" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Ajusta la ganancia del canal de azul" @@ -4756,7 +4804,7 @@ msgstr "Una página" msgid "All pages" msgstr "Todas las páginas" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "escáner con cargador automático" @@ -5267,39 +5315,44 @@ msgstr "" "Calentar hasta que el brillo de la lámpara sea constante en vez de " "esperar por los 40 segundos de calentamiento." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Limpiar la calibración" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "PelÃcula en negativo" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativo" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, fuzzy, no-c-format msgid "48 bits color" msgstr "Color fino" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Botón de control de escaneo" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5310,40 +5363,40 @@ msgstr "" "proceder, haga clic en el botón \"SCAN\" (para MP150) o \"COLOR\" (para " "otros modelos). Para cancelar, haga clic en el botón \"GRAY\"." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Actualizar estado del botón" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Botón 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Botón 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5432,7 +5485,7 @@ msgstr "Interfaz analógica (AFE)" msgid "Red gain value of the AFE" msgstr "Valor de ganancia de rojo en el AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Desviación rojo" @@ -5709,7 +5762,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Esta opción refleja el estado de los botones del escáner" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Encender lámpara" @@ -5719,12 +5772,12 @@ msgstr "Encender lámpara" msgid "Turn on scanner lamp" msgstr "Enciende la lámpara del escáner" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Apagar lámpara" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Apaga la lámpara del escáner" @@ -5870,13 +5923,13 @@ msgid "Focus point" msgstr "Posición del foco" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Color, lÃneas por lectura" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Escala de grises, lÃneas de por lectura" #: backend/stv680.c:974 @@ -6536,52 +6589,52 @@ msgstr "Modo de calibración" msgid "Define calibration mode" msgstr "Define el modo de calibración" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Enciende/apaga la lámpara" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA Activado" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Ajusta el encendido/apagado UTA" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Desplazamiento" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Ajustes del desplazamiento de los canales de color" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Desplazamiento de gris" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Ajusta el desplazamiento del canal de gris" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Ajusta el desplazamiento del canal de rojo" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Ajusta el desplazamiento del canal de verde" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Ajusta el desplazamiento del canal de azul" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.11\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-12-17 23:00+0100\n" "Last-Translator: Harri Järvi <harri.jarvi@tut.fi>\n" "Language-Team: Debian l10n Finnish <debian-l10n-finnish@lists.debian." @@ -27,31 +27,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometria" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Parannus" @@ -85,7 +85,7 @@ msgid "Bit depth" msgstr "Bittisyvyys" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Lukutapa" @@ -126,7 +126,7 @@ msgid "Bottom-right y" msgstr "Oikea alakulma y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Kuvanluvun tarkkuus" @@ -281,7 +281,7 @@ msgstr "Tiedostonimi" msgid "Halftone pattern size" msgstr "Rasterikuvion koko" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Rasterikuvio" @@ -291,10 +291,10 @@ msgstr "Rasterikuvio" msgid "Bind X and Y resolution" msgstr "Sido X- ja Y-tarkkuus" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negatiivi" @@ -415,9 +415,9 @@ msgid "Lamp off at exit" msgstr "Valo pois lopetettaessa" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "Asetus, joka määrää kuinka monta asetusta tietty laite tukee." @@ -741,8 +741,8 @@ msgid "Analog gamma-correction for blue" msgstr "Analoginen gamma-korjaus siniselle" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Lämmitä lamppu ennen kuvanlukua" #: include/sane/saneopts.h:417 @@ -892,7 +892,7 @@ msgstr "Rasterointi ei ole tuettu" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -985,10 +985,10 @@ msgid "Only perform shading-correction" msgstr "Vain sävykorjaus" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Jos asetus on päällä, kalibroinnissa suoritetaan vain sävykorjaus. " @@ -1018,80 +1018,40 @@ msgstr "Kaksipuolinen" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibroi kuvanlukija" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Pakottaa kalibroinnin ennen kuvanlukua." - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Harmaasävy" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Lue harmaasävykuva värikuvan sijaan" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analoginen vahvistus" - -#: backend/canon630u.c:307 -#, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Kasvattaa tai vähentää analogista vahvistusta CCD-kennossa." - -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "Gamma-korjaus" - -#: backend/canon630u.c:348 -#, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Valitsee gamma-korjauskäyrän" +msgid "Correction according to transparency ratio" +msgstr "" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Raw" +msgid "Correction according to film type" msgstr "" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 #: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format msgid "Fine color" msgstr "" -#: backend/canon.c:169 +#: backend/canon-sane.c:776 backend/canon.c:176 #, fuzzy, no-c-format -msgid "No transparency correction" -msgstr "Värikorjaus" - -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" +msgid "Negatives" +msgstr "Negatiivi" -#: backend/canon.c:171 backend/canon-sane.c:674 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format -msgid "Correction according to transparency ratio" +msgid "Raw" msgstr "" -#: backend/canon.c:176 backend/canon-sane.c:776 +#: backend/canon.c:169 #, fuzzy, no-c-format -msgid "Negatives" -msgstr "Negatiivi" +msgid "No transparency correction" +msgstr "Värikorjaus" #: backend/canon.c:176 #, fuzzy, no-c-format @@ -1226,9 +1186,9 @@ msgid "invalid bit IDENTIFY message" msgstr "" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" -msgstr "" +#, fuzzy, no-c-format +msgid "option not correct" +msgstr "Rasterointi ei ole tuettu" #: backend/canon.c:474 #, no-c-format @@ -1515,133 +1475,184 @@ msgstr "Filmin tyyppi" msgid "Select the film type" msgstr "Valitsee rasterin" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibroi kuvanlukija" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Pakottaa kalibroinnin ennen kuvanlukua." + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Harmaasävy" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Lue harmaasävykuva värikuvan sijaan" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analoginen vahvistus" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Kasvattaa tai vähentää analogista vahvistusta CCD-kennossa." + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gamma-korjaus" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Valitsee gamma-korjauskäyrän" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Taso" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "ADF" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, fuzzy, no-c-format msgid "ADF Duplex" msgstr "Kaksipuolinen" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Tulosta" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Kaksipuolinen" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Punainen" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Vihreä" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Sininen" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Parannus" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Parannus" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Parannus" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ei mikään" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Yksipuolinen" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Kaksipuolinen" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Läpinäkyvyysyksikkö" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automaattinen syöttö" @@ -1753,7 +1764,7 @@ msgstr "Mustesuihkutulostimet" msgid "CRT monitors" msgstr "Loisteputkinäytöt" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1817,8 +1828,9 @@ msgstr "A4" msgid "Max" msgstr "Koko alue" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1990,17 +2002,17 @@ msgstr "Määrää kuvanlukijan käyttämän zoom-kertoimen" msgid "Quick format" msgstr "Nopea formaatti" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Lisävaruste" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Poista" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Poista kohde syöttölaitteesta" @@ -2015,12 +2027,14 @@ msgstr "Automaattinen poisto" msgid "Eject document after scanning" msgstr "Poista kohde kuvanluvun jälkeen" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Syötttapa" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Valitsee syöttötavan (yksi-/kaksipuolinen)" @@ -2069,14 +2083,14 @@ msgstr "" "Kuvanlukukomennon lähettämisen jälkeen, odota kunnes kuvanlukijan " "painiketta todella painetaan, ennen kuvanluvun aloittamista." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2099,492 +2113,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "Käyttäjän määrittelemä" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Poista kohde syöttölaitteesta" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Ei korjausta" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Analoginen gammakorjaus" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Päällä" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Poissa" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Rasteri" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Valkotaso" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Mustataso" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "Ehdollinen" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Vaaka" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Vaaka" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Vaaka" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Pysty" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "Pysty" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Tulosta" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Rasteri" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Raakakalibrointi" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Kuvan korostus" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Kylläisyys" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "Aseta automaattinen kynnysarvon päättely viivapiirrosta varten." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Peilikuva" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Peilaa kuvan vaakasuunnassa" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Sinisen valkotaso" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Määrää punaisen määrän" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Väriviivapiirros" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Pehmennys" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Gamma" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Kynnys" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Kynnys" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Kohinan poisto" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Ei korjausta" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Ei korjausta" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Syöttötapa" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Päivitä asetukset" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Ei korjausta" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Valo päälle" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Syöttötapa" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2592,65 +2626,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Valo pois" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Sinisen siirtymä" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Vihreän siirtymä" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Vihreän siirtymä" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Sinisen siirtymä" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Asettaa sinisen kanavan siirtymän" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2659,507 +2693,514 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Kaksipuolinen" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Päivitä asetukset" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Kohinan poisto" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Paperilta" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Paperilta" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Paperilta" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Paperilta" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Manuaalinen esitarkennus" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Manuaalinen esitarkennus" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "Kuvanluvun tarkkuus" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Valkotaso" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Punaisen voimakkuus" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Kaksipuolinen" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, fuzzy, no-c-format msgid "Extras" msgstr "Hyvin nopea" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, fuzzy, no-c-format msgid "Disable interpolation" msgstr "Poista peruutus." -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Väriviivapiirros" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibrointi" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Määrää kalibraatiotavan" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Kalibrointitila" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, fuzzy, no-c-format msgid "Lamp off time" msgstr "Valo pois" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " "of 0 means, that the lamp won't be turned off." msgstr "" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Raakakalibrointi" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "Odota painiketta" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "Odota painiketta" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Odota painiketta" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Raakakalibrointi" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Pakottaa kalibroinnin ennen kuvanlukua." -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, fuzzy, no-c-format msgid "Buttons" msgstr "Painikkeen tila" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibroi" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Aloita kalibrointi." -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Raakakalibrointi" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Kalibrointitila" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Raakakalibrointi" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Vihreän siirtymä" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Läpinäkyvyysyksikkö" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Läpinäkyvyysyksikkö" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3261,6 +3302,311 @@ msgstr "Gamma" msgid "Sets the gamma value of all channels." msgstr "Asettaa gamma-arvon kaikille kanaville." +#: backend/hp-option.c:2987 +#, fuzzy, no-c-format +msgid "Advanced Options" +msgstr "Päivitä asetukset" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Raaka" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Hieno" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Oma" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automaattinen" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC-RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA-RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC-harmaa" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA-harmaa" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Hidas" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normaali" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Nopea" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Hyvin nopea" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2 pikseliä" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4 pikseliä" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8 pikseliä" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Tulosta" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Dia" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Filmiliuska" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Ehdollinen" + +#: backend/hp-option.c:3417 +#, fuzzy, no-c-format +msgid "Experiment" +msgstr "Valotusaika" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Terävöinti" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Aseta terävöintiarvo." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Automaatinen kynnys" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "Aseta automaattinen kynnysarvon päättely viivapiirrosta varten." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Valitse pehmennyssuodatin." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Poista media kuvanluvun jälkeen" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Poistaa median kuvanluvun jälkeen." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Vaihda kohde" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Vaihda kohde." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Poista" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Poista kohde." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Aloita kalibrointi." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Media" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Valitse media" + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Valotusaika" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Pidempi valotusaika antaa kuvanlukijan kerätä enemmän valoa. Ehdotetut " +"arvot ovat 175% painotuotteille, 150% normaaleille dioille ja \"Negatiivi" +"\" negatiivifilmeille. Tummille (alivalottuneille) kuville, voit " +"kasvattaa tätä arvoa." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Värimatriisi" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Aseta kuvanlukijan värimatriisi." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Oma värimatriisi." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Yksivärinen matriisi" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Oma värimatriisi harmaasävy lukua varten." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Peilaa vaakasuunnassa" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Peilaa kuvan vaakasuunnassa" + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Peilaa pystysuunnassa" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Peilaa kuvan pystysuunnassa." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Päivitä asetukset" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Päivittää asetukset." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8-bittinen tulos" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Käyttää sisäisesti kahdeksaa bittiä syvempää esitystä, mutta antaa " +"tuloksen vain kahdeksanbittisenä." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Odota painiketta" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" +"Odottaa kuvanlukijan painikkeen painamista ennen kuvanluvun alkamista." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Sulje lamppu" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Sulkee kuvanlukijan lampun." + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3271,12 +3617,6 @@ msgstr "Geometria" msgid "Scan Mode Group" msgstr "Lukutapa" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Dia" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3284,12 +3624,12 @@ msgstr "Lukutapa" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3470,11 +3810,6 @@ msgstr "Asettaa valon päälle/pois" msgid "Calibrates for black and white level." msgstr "" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3585,300 +3920,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, fuzzy, no-c-format -msgid "Advanced Options" -msgstr "Päivitä asetukset" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Raaka" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Hieno" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Oma" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automaattinen" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC-RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA-RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC-harmaa" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA-harmaa" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Hidas" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normaali" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Nopea" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Hyvin nopea" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2 pikseliä" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4 pikseliä" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8 pikseliä" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Tulosta" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Filmiliuska" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Ehdollinen" - -#: backend/hp-option.c:3417 -#, fuzzy, no-c-format -msgid "Experiment" -msgstr "Valotusaika" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Terävöinti" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Aseta terävöintiarvo." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Automaatinen kynnys" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "Aseta automaattinen kynnysarvon päättely viivapiirrosta varten." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Valitse pehmennyssuodatin." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Poista media kuvanluvun jälkeen" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Poistaa median kuvanluvun jälkeen." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Vaihda kohde" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Vaihda kohde." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Poista" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Poista kohde." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Aloita kalibrointi." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Media" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Valitse media" - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Valotusaika" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Pidempi valotusaika antaa kuvanlukijan kerätä enemmän valoa. Ehdotetut " -"arvot ovat 175% painotuotteille, 150% normaaleille dioille ja \"Negatiivi" -"\" negatiivifilmeille. Tummille (alivalottuneille) kuville, voit " -"kasvattaa tätä arvoa." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Värimatriisi" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Aseta kuvanlukijan värimatriisi." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Oma värimatriisi." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Yksivärinen matriisi" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Oma värimatriisi harmaasävy lukua varten." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Peilaa vaakasuunnassa" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Peilaa kuvan vaakasuunnassa" - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Peilaa pystysuunnassa" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Peilaa kuvan pystysuunnassa." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Päivitä asetukset" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Päivittää asetukset." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8-bittinen tulos" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Käyttää sisäisesti kahdeksaa bittiä syvempää esitystä, mutta antaa " -"tuloksen vain kahdeksanbittisenä." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Odota painiketta" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" -"Odottaa kuvanlukijan painikkeen painamista ennen kuvanluvun alkamista." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Sulje lamppu" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Sulkee kuvanlukijan lampun." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3977,7 +4018,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4145,9 +4186,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Viivapiirros" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4276,7 +4317,7 @@ msgstr "Asettaa kuvan korostuksen" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4343,11 +4384,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4379,12 +4420,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Korkeatarkkuuksinen tulostus" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Matalatarkkuuksinen tulostus" #: backend/kvs40xx_opt.c:243 @@ -4407,6 +4448,13 @@ msgstr "Normaali" msgid "Enhanced mode" msgstr "Parannus" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4466,7 +4514,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4501,12 +4549,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4516,13 +4564,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Peilikuva" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4559,52 +4607,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 pystyviiva" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Vahvistus" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Värikanavien vahvistus" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Harmaan vahvistus" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Asettaa harmaan kanavan vahvistusta" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Punaisen vahvistus" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Asettaa punaisen kanavan vahvistusta" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Vihreän vahvistus" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Asettaa vihreän kanavan vahvistusta" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Sinisen vahvistus" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Asettaa sinisen kanavan vahvistusta" @@ -4690,7 +4738,7 @@ msgstr "Yksi sivu" msgid "All pages" msgstr "Kaikki sivut" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "arkkisyöttöinen" @@ -5188,39 +5236,44 @@ msgstr "" "Lämmittää kunnes lampun kirkkaus tasaantuu. Muuten lämmitetään 40 " "sekuntia." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Raakakalibrointi" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Negatiivifilmi" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negatiivi" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5228,40 +5281,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, fuzzy, no-c-format msgid "Update button state" msgstr "Painikkeen tila" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, fuzzy, no-c-format msgid "Button 1" msgstr "Painikkeen tila" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, fuzzy, no-c-format msgid "Button 2" msgstr "Painikkeen tila" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5350,7 +5403,7 @@ msgstr "Analoginen gamma (punainen)" msgid "Red gain value of the AFE" msgstr "" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Punaisen siirtymä" @@ -5624,7 +5677,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Valo päälle" @@ -5634,12 +5687,12 @@ msgstr "Valo päälle" msgid "Turn on scanner lamp" msgstr "Laittaa kuvanlukijan valon päälle" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Valo pois" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Sammuttaa kuvanlukijan valon" @@ -5783,13 +5836,13 @@ msgid "Focus point" msgstr "Kohdistuspiste" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Väririvejä / luku" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Harmaasävyrivejä / luku" #: backend/stv680.c:974 @@ -6425,52 +6478,52 @@ msgstr "Kalibrointitila" msgid "Define calibration mode" msgstr "Määrää kalibraatiotavan" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Asettaa valon päälle/pois" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA päällä" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Asettaa UTAN päälle/pois" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Siirtymä" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Värikanavien siirtymä" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Harmaan siirtymä" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Asettaa harmaan kanavan siirtymän" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Asettaa punaisen kanavan siirtymän" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Asettaa vihreän kanavan siirtymän" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Asettaa sinisen kanavan siirtymän" @@ -44,7 +44,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.19\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2008-01-17 22:25+0100\n" "Last-Translator: Yann E. MORIN <yann dot morin dot 1998 at anciens dot " "enib dot fr>\n" @@ -66,31 +66,31 @@ msgid "Standard" msgstr "Général" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Aire de numérisation" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Réglages fins" @@ -124,7 +124,7 @@ msgid "Bit depth" msgstr "Profondeur" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Mode de numérisation" @@ -165,7 +165,7 @@ msgid "Bottom-right y" msgstr "Y bas-droit" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Echantillonnage" @@ -320,7 +320,7 @@ msgstr "Nom de fichier" msgid "Halftone pattern size" msgstr "Taille du motif demi-teinte" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Motif demi-teinte" @@ -330,10 +330,10 @@ msgstr "Motif demi-teinte" msgid "Bind X and Y resolution" msgstr "Lier les échantillonnage X et Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Négatif" @@ -454,9 +454,9 @@ msgid "Lamp off at exit" msgstr "Eteindre la lampe à la sortie" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Option, lecture seule, qui indique le nombre d'options supportées par un " @@ -809,8 +809,8 @@ msgid "Analog gamma-correction for blue" msgstr "Correction gamma analogique pour le bleu" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Préchauffer la lampe avant la numérisation" #: include/sane/saneopts.h:417 @@ -959,8 +959,8 @@ msgid "Operation not supported" msgstr "Opération non-supportée" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "Opération annulée" #: backend/sane_strstatus.c:68 @@ -1055,10 +1055,10 @@ msgid "Only perform shading-correction" msgstr "Effectuer uniquement la correction des ombres" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Si activé, seule la correction des ombres est effectuée pendant la " @@ -1087,85 +1087,45 @@ msgid "Duplex scan" msgstr "Numérisation recto-verso" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "La numérisation recto-verso permet de numériser les deux cotés d'un " "document" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibrer le scanner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Forcer la calibration du scanner avant la numérisation" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Niveaux de gris" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Effectue une numérisation en niveaux de gris plutôt qu'en couleurs" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Gain analogique" +msgid "Correction according to transparency ratio" +msgstr "Correction en fonction du rapport de transparence" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Augmenter/diminuer le gain analogique du capteur CCD" +msgid "Correction according to film type" +msgstr "Correction en fonction du support" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Correction gamma" +msgid "Fine color" +msgstr "Couleurs précises" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Sélectionne la courbe de correction gamma" +msgid "Negatives" +msgstr "Négatifs" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Brut" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Couleurs précises" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Pas de correction de transparence" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Correction en fonction du support" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Correction en fonction du rapport de transparence" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Négatifs" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1299,8 +1259,8 @@ msgid "invalid bit IDENTIFY message" msgstr "message d'identification (IDENTIFY) invalide" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "option non connectée" #: backend/canon.c:474 @@ -1591,133 +1551,184 @@ msgstr "Type de film" msgid "Select the film type" msgstr "Sélectionne le type de film" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibrer le scanner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Forcer la calibration du scanner avant la numérisation" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Niveaux de gris" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Effectue une numérisation en niveaux de gris plutôt qu'en couleurs" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Gain analogique" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Augmenter/diminuer le gain analogique du capteur CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Correction gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Sélectionne la courbe de correction gamma" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "A plat" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "Chargeur automatique de documents, recto" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "Chargeur automatique de documents, verso" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Chargeur automatique de documents, recto-verso" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Avant" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, fuzzy, no-c-format msgid "Card Back" msgstr "Arrière" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Recto-verso" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Rouge" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Vert" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Bleu" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Augmente le rouge" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Augmente le vert" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Augmente le bleu" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Aucun(e)" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Recto" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Recto-verso" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Adaptateur pour transparents" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Chargeur automatique de document" @@ -1829,7 +1840,7 @@ msgstr "Imprimantes à jet d'encre" msgid "CRT monitors" msgstr "Moniteurs à tube cathodique" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1893,8 +1904,9 @@ msgstr "A4" msgid "Max" msgstr "Max" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2071,17 +2083,17 @@ msgstr "Définit le facteur de zoom utilisé par le scanner" msgid "Quick format" msgstr "Format rapide" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Equipement optionnel" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Ejecter" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Ejecter la feuille du chargeur automatique" @@ -2096,12 +2108,14 @@ msgstr "Ejection automatique" msgid "Eject document after scanning" msgstr "Ejecte le document après la numérisation" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Mode du chargeur automatique de documents" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2153,16 +2167,16 @@ msgstr "" "Aprés avoir envoyé la commande de numérisation, attendre l'appui du " "bouton avant de commencer la numérisation." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Infra-rouge" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Infra-rouge" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2183,495 +2197,515 @@ msgstr "Profil de température de couleurs interne" msgid "User defined CCT profile" msgstr "Profil de température de couleurs utilsateur" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Ejecter la feuille du chargeur automatique" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Pas de correction" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Désactiver la correction gamma" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Activé" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Aucun" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "Seuil dynamique (DTC)" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "Seuil dynamique simplifié (SDTC)" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Tramage" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Diffusion d'erreur" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Blanc" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Noir" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Continuer" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Arréter" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horizontal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Horizontal large" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Horizontal étroit" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertical" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Vertical large" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "De haut en bas" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "De bas en haut" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Avant" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Arrière" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Demi-teinte" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Effectue la calibration" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Accentuation de l'image" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Saturation" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "" "Active la détection automatique du seuil pour la numérisation en mode " "trait." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Image miroir" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Renverse l'image horizontalement." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Niveau blanc des bleus" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Contrôle le niveau de rouge" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Filtre de couleur" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Lissage" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Valeur de gamma" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Courbe du seuil" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, fuzzy, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" "Courbe dynamique de seuil, de clair à foncé, normallement entre 50-65" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Seuil" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Réduction du bruit" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Pas de correction" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Pas de correction" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Couvercle du chargeur automatique ouvert" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Options avancées" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Pas de correction" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Exclusion" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Mode de chargement" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2679,65 +2713,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Temps avant extinction de la lampe" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Décalage des bleus" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Décalage des verts" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Décalage des verts" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Décalage des bleus" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Fixe le décalage pour le bleu" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, fuzzy, no-c-format msgid "Low Memory" msgstr "A court de mémoire" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2746,377 +2780,363 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Numérisation recto-verso" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Options avancées" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Réduction du bruit" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Avec du papier" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Avec du papier" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Avec du papier" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Avec du papier" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "Couvercle du scanner ouvert" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Mise au point manuelle" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Mise au point manuelle" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "erreur de test du matériel" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Niveau blanc" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Contrôle de densité" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "Contrôle de densité" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Numérisation recto-verso" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extras" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" "Courbe dynamique de seuil, de clair à foncé, normallement entre 50-65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Désactiver le mode Trait dynamique" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"Utilise le mode Trait du matériel, au lieu d'utiliser un algorithme " -"logiciel adaptatif." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Désactiver l'interpolation" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3126,45 +3146,45 @@ msgstr "" "plus faible que la résolution verticale, ne pas faire d'interpolation " "horizontale." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Filtre de couleur" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "En niveaux de gris ou en mode trait, sélectionne la couleur à utiliser." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Calibration" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Définit le mode de calibration" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Cache des données de calibration" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Temps avant extinction de la lampe" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3173,89 +3193,108 @@ msgstr "" "La lampe sera éteinte après ce laps de temps (en minutes). Entrer 0 pour " "ne pas éteindre la lampe automatiquement." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Eteindre la lampe durant la calibration des noirs" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, fuzzy, no-c-format msgid "The lamp will be turned off during scan. " msgstr "Délai en minutes avant d'éteindre la lampe après une numérisation." -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Bouton 'fichier'" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Bouton 'reconnaissance de caractères (OCR)'" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Bouton 'marche'" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Bouton 'courrier électronique'" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 -#, no-c-format -msgid "Need calibration" +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 +#, fuzzy, no-c-format +msgid "Needs calibration" msgstr "Calibration requise" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Le scanner a besoin d'être calibré avec les paramètres actuels" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Boutons" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Calibration" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Démarrer la calibration avec la feuille spéciale" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Effacer la calibration" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Efface le cache des données de calibration" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Calibration grossière" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Décalage des verts" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Adaptateur pour transparents" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Adaptateur pour transparents" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3365,6 +3404,311 @@ msgstr "Valeur de gamma" msgid "Sets the gamma value of all channels." msgstr "Sélectionne la valeur de gamma pour tous les canaux." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Options avancées" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Grossier" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Précis" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Personnalisé" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatique" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "RVB NTSC" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "RVB (pour transparents)" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Direct" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "Gris NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Gris (pour transparents)" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lent" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rapide" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Très rapide" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2 pixels" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4 pixels" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8 pixels" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Imprimer" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositive" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Film-strip" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "Chargeur automatique de documents" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "Adaptateur pour transparents" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Conditionnel" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Essais" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Netteté" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Choisir la netteté" + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Seuil automatique" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Active la détection automatique du seuil pour la numérisation en mode " +"trait." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Sélectionne le filtre de lissage." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Ejecter le document après la numérisation" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Ejecte le document après la numérisation." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Changer de document" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Change de document." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Ejecter" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Ejecter le document." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Démarrer la calibration." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Document" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Sélectionne le type de document." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Temps d'exposition" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Un temps d'exposition plus long permet au scanner de recevoir plus de " +"lumière. Les valeurs suggérées sont : 175% pour des impressions, 150% " +"pour des diapositives normales, et \"Négatif\" pour des négatifs. Pour " +"les images sombres (sous-exposées), vous pouvez augmenter cette valeur." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matrice de couleurs" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Sélectionne la matrice de couleurs du scanner." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Matrice personnalisée." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Matrice monochrome" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Matrice personnalisée pour numérisation en niveaux de gris." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Miroir horizontal" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Renverse l'image horizontalement." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Miroir vertical" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Renverse l'image verticalement." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Mettre les options à jour" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Mets à jour les options." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "Sortie en 8 bits" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Utilise plus de 8 bits de profondeur en interne, mais sort en 8 bits." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Attente de bouton avant" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Attendre l'appui sur le bouton du scanner avant de numériser." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Eteindre la lampe" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Eteint la lampe du scanner." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3375,12 +3719,6 @@ msgstr "Géométrie" msgid "Scan Mode Group" msgstr "Mode de numérisation" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositive" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3388,14 +3726,14 @@ msgstr "Modèle de scanner" #: backend/hp3900_sane.c:1408 #, fuzzy, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" "Permet de tester le comportement du périphérique en l'utilisant comme un " "autre modèle compatible" #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "Les couleurs de l'image seront inversées" #: backend/hp3900_sane.c:1436 @@ -3585,11 +3923,6 @@ msgstr "Allume/éteint la lampe." msgid "Calibrates for black and white level." msgstr "Calibration des niveaux noir et blanc." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "Chargeur automatique de documents" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3702,300 +4035,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Options avancées" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Grossier" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Précis" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Personnalisé" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatique" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "RVB NTSC" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "RVB (pour transparents)" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Direct" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "Gris NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Gris (pour transparents)" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lent" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rapide" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Très rapide" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2 pixels" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4 pixels" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8 pixels" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Imprimer" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Film-strip" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "Adaptateur pour transparents" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Conditionnel" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Essais" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Netteté" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Choisir la netteté" - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Seuil automatique" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Active la détection automatique du seuil pour la numérisation en mode " -"trait." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Sélectionne le filtre de lissage." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Ejecter le document après la numérisation" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Ejecte le document après la numérisation." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Changer de document" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Change de document." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Ejecter" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Ejecter le document." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Démarrer la calibration." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Document" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Sélectionne le type de document." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Temps d'exposition" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Un temps d'exposition plus long permet au scanner de recevoir plus de " -"lumière. Les valeurs suggérées sont : 175% pour des impressions, 150% " -"pour des diapositives normales, et \"Négatif\" pour des négatifs. Pour " -"les images sombres (sous-exposées), vous pouvez augmenter cette valeur." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matrice de couleurs" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Sélectionne la matrice de couleurs du scanner." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Matrice personnalisée." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Matrice monochrome" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Matrice personnalisée pour numérisation en niveaux de gris." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Miroir horizontal" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Renverse l'image horizontalement." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Miroir vertical" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Renverse l'image verticalement." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Mettre les options à jour" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Mets à jour les options." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "Sortie en 8 bits" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Utilise plus de 8 bits de profondeur en interne, mais sort en 8 bits." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Attente de bouton avant" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Attendre l'appui sur le bouton du scanner avant de numériser." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Eteindre la lampe" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Eteint la lampe du scanner." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4094,7 +4133,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4262,9 +4301,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Trait" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4393,7 +4432,7 @@ msgstr "Sélectionne l'accentuation de l'image" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4460,11 +4499,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4496,12 +4535,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Impression haute définition" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Impression basse définition" #: backend/kvs40xx_opt.c:243 @@ -4524,6 +4563,13 @@ msgstr "Normal" msgid "Enhanced mode" msgstr "Réglages fins" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4583,7 +4629,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4618,12 +4664,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4633,13 +4679,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Image miroir" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4676,52 +4722,52 @@ msgstr "Bayer 8x8" msgid "8x8 Vertical Line" msgstr "Ligne verticale 8x8" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Gain" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Réglages de gain des couleurs" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Gain des gris" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Fixe le gain pour le gris" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Gain des rouges" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Fixe le gain pour le rouge" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Gain des verts" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Fixe le gain pour le vert" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Gain des bleus" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Fixe le gain pour le bleu" @@ -4807,7 +4853,7 @@ msgstr "Une page" msgid "All pages" msgstr "Toutes les pages" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "scanner avec chargeur automatique" @@ -5315,39 +5361,44 @@ msgstr "" "Préchauffer jusqu'à ce que l'intensité de la lampe soit constante, au " "lieu d'attendre 40 secondes." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Calibration requise" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Film négatif" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Négatif" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, fuzzy, no-c-format msgid "48 bits color" msgstr "Couleurs précises" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Numérisation contrôlée par le bouton du scanner" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5358,40 +5409,40 @@ msgstr "" "\" (MP150), ou du bouton \"COLOR\" (autres modèles). Appuyez sur le " "bouton \"GRAY\" pour annuler la numérisation." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Rafraîchir l'état du bouton" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Bouton 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Bouton 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5480,7 +5531,7 @@ msgstr "Frontal analogique (AFE)" msgid "Red gain value of the AFE" msgstr "Gain des rouges du frontal analogique (AFE)" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Décalage des rouges" @@ -5757,7 +5808,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Cette option affiche l'état d'un bouton du scanner." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lampe allumée" @@ -5767,12 +5818,12 @@ msgstr "Lampe allumée" msgid "Turn on scanner lamp" msgstr "Allume la lampe du scanner" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Lampe éteinte" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Eteint la lampe du scanner" @@ -5917,13 +5968,13 @@ msgid "Focus point" msgstr "Mise-au-point" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Nombre de lignes en couleurs par cycle de lecture" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Nombre de lignes en niveaux de gris par cycle de lecture" #: backend/stv680.c:974 @@ -6578,56 +6629,66 @@ msgstr "Mode de calibration" msgid "Define calibration mode" msgstr "Définit le mode de calibration" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Allume/éteint la lampe." -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "Activer l'UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Activer/déactiver l'adaptateur universel de transparents (UTA)" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Décalage" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Réglages de décalage des couleurs" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Décalage des gris" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Fixe le décalage pour le gris" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Fixe le décalage pour le rouge" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Fixe le décalage pour le vert" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Fixe le décalage pour le bleu" +#~ msgid "Disable dynamic lineart" +#~ msgstr "Désactiver le mode Trait dynamique" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "Utilise le mode Trait du matériel, au lieu d'utiliser un algorithme " +#~ "logiciel adaptatif." + #, fuzzy #~ msgid "IPC mode" #~ msgstr "Aperçu" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2009-06-25 10:22+0100\n" "Last-Translator: Miguel Anxo Bouzada <mbouzada@gmail.com>\n" "Language-Team: Galician <proxecto@trasno.net>\n" @@ -31,31 +31,31 @@ msgid "Standard" msgstr "Estándar" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "XeometrÃa" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Optimización" @@ -89,7 +89,7 @@ msgid "Bit depth" msgstr "Bit de profundidade" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Modo de escaneo" @@ -130,7 +130,7 @@ msgid "Bottom-right y" msgstr "Abaixo-dereita Y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Resolución de escaneo" @@ -285,7 +285,7 @@ msgstr "Nome do ficheiro" msgid "Halftone pattern size" msgstr "Tamaño do patrón de medios tons" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Patrón de medios tons" @@ -295,10 +295,10 @@ msgstr "Patrón de medios tons" msgid "Bind X and Y resolution" msgstr "Ligar resolucións X e Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativo" @@ -419,9 +419,9 @@ msgid "Lamp off at exit" msgstr "Apagar a lámpada ao saÃr" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Opción de só lectura que define cantas opcións soporta un dispositivo " @@ -770,8 +770,8 @@ msgid "Analog gamma-correction for blue" msgstr "Corrección gamma analóxica para azul" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Quecer a lámpada antes de escanear" #: include/sane/saneopts.h:417 @@ -920,8 +920,8 @@ msgid "Operation not supported" msgstr "Operación non compatible" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "A operación vai ser cancelada" #: backend/sane_strstatus.c:68 @@ -1014,10 +1014,10 @@ msgid "Only perform shading-correction" msgstr "Facer só correccións de sombras" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Se está activado, só se farán correccións de sombras durante a " @@ -1046,84 +1046,44 @@ msgid "Duplex scan" msgstr "Escaneo dúplex" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "O escaneo dúplex fornece un escaneo do anverso e o reverso do documento" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibrar o escáner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Forza a calibrar o escáner antes de facer o escaneo" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Escaneo en escala de grises" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Escanea en escala de grises, non en cores" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Ganancia analóxica" +msgid "Correction according to transparency ratio" +msgstr "Corrección conforme coa taxa de transparencia" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Aumenta o diminúe a ganancia analóxica da gama CCD" +msgid "Correction according to film type" +msgstr "Corrección conforme co tipo de filme" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Corrección gamma" +msgid "Fine color" +msgstr "Cor fina" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Selecciona a curva de transferencia da corrección gamma" +msgid "Negatives" +msgstr "Negativos" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "En bruto" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Cor fina" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Sen corrección de transparencia" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Corrección conforme co tipo de filme" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Corrección conforme coa taxa de transparencia" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negativos" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1258,8 +1218,8 @@ msgid "invalid bit IDENTIFY message" msgstr "mensaxe de bit de IDENTIFICACIÓN incorrecta" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "a opción non conecta" #: backend/canon.c:474 @@ -1554,133 +1514,184 @@ msgstr "Escoller tipo de filme" msgid "Select the film type" msgstr "Escoller o tipo de filme" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibrar o escáner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Forza a calibrar o escáner antes de facer o escaneo" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Escaneo en escala de grises" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Escanea en escala de grises, non en cores" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Ganancia analóxica" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Aumenta o diminúe a ganancia analóxica da gama CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Corrección gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Selecciona a curva de transferencia da corrección gamma" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Plano" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, fuzzy, no-c-format msgid "ADF Front" msgstr "A tapa do alimentador está aberta" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "Atoamento no alimentador" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Alimentador dúplex" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Imprimir" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Duas caras" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Vermello" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Verde" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Azul" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Optimización" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Optimización" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Optimización" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ningún" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Unha cara" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Duas caras" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Unidade de transparencias" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Alimentador automático de documentos (ADF)" @@ -1792,7 +1803,7 @@ msgstr "Impresoras de inxección de tinta" msgid "CRT monitors" msgstr "Monitores CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1856,8 +1867,9 @@ msgstr "A4" msgid "Max" msgstr "Máx" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2031,17 +2043,17 @@ msgstr "Define o factor de zoom que vai usar o escáner" msgid "Quick format" msgstr "Formato rápido" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Equipamento opcional" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Expulsar" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Expulsar a folla do alimentador" @@ -2056,12 +2068,14 @@ msgstr "Expulsión automática" msgid "Eject document after scanning" msgstr "Expulsar o documento despois do escaneo" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Modo alimentador" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Escoller o modo do alimentador (unha cara/duas caras)" @@ -2113,14 +2127,14 @@ msgstr "" "Despois de enviar a orde de escaneo, agardar até que se prema no botón " "do escáner para comezar verdadeiramente o proceso de escaneo." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2143,494 +2157,514 @@ msgstr "" msgid "User defined CCT profile" msgstr "Definida polo usuario" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Expulsar a folla do alimentador" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Sen corrección" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Desactivar a corrección gamma" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Activado" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Desactivado" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Esfumado" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "Difusión de erro" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Nivel do branco" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Nivel do negro" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "Condicional" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horizontal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Horizontal" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Horizontal" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Vertical" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "Vertical" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Imprimir" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Medios tons" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Calibración de precisión" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Destaque da imaxe" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Saturación" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "" "Activar a determinación automática do limiar para escaneos como liña de " "arte." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Reflectir a imaxe horizontalmente" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Reflectir a imaxe en horizontal" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Nivel do branco para azul" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Controla o nivel de vermello" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Filtro de cor" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Suavizado" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Valor gamma" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Limiar" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Limiar" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Redución de ruÃdo" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Sen corrección" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Sen corrección" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "A tapa do alimentador está aberta" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Opcions avanzadas" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Sen corrección" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Exclusión" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Modo de alimentación" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2638,65 +2672,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Tempo para apagado da lámpada" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Desviación azul" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Desviación verde" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Desviación verde" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Desviación azul" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Axusta o desprazamento da canle azul" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, fuzzy, no-c-format msgid "Low Memory" msgstr "Non queda memoria" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2705,374 +2739,362 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Escaneo dúplex" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Opcions avanzadas" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Redución de ruÃdo" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "De papel" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "De papel" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "De papel" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "De papel" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "A tapa do escáner está aberta" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Foco previo manual" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Foco previo manual" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "erro de verificación de hardware" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Nivel do branco" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Control de densidade" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "Control de densidade" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Escaneo dúplex" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extras" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Desactivar interpolación" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3081,45 +3103,45 @@ msgstr "" "Cando se usan altas resolucións nas que a resolución horizontal é máis " "pequena que a vertical, isto desactiva a interpolación horizontal." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Filtro de cor" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "Cando se usa gris ou liña de arte esta opción selecciona a cor a usar." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Calibración" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Definir o modo de calibración" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Caché de datos de calibración" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Tempo para apagado da lámpada" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3128,89 +3150,108 @@ msgstr "" "A lámpada vai ser apagada despois do tempo indicado (en minutos). Un " "valor de 0 significa que a lámpada no vai ser apagada." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Apagar a lámpada durante a calibración de escuridade" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, fuzzy, no-c-format msgid "The lamp will be turned off during scan. " msgstr "Minutos que tardará a lámpada en apagarse despois do escaneo" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Botón de ficheiro" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Botón de OCR" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Botón de enerxÃa" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Botón de correo-e" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Limpar a calibración" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Forza a calibrar o escáner antes de facer o escaneo" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Botóns" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Calibrar" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Iniciar a calibración usando unha folla especial" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Limpar a calibración" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Limpar a caché de datos de calibración" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Calibración grosa" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Desviación verde" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Adaptador de transparencias" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Adaptador de transparencias" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3321,6 +3362,312 @@ msgstr "Valor gamma" msgid "Sets the gamma value of all channels." msgstr "Axusta o valor gamma para todas as canles." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Opcions avanzadas" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Groso" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fina" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Personalizado" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automático" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "Adaptador de transparencias RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "A través" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC Gris" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Adaptador de transparencias gris" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lento" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rápido" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Moi rápido" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-pÃxeles" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-pÃxeles" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-pÃxeles" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Imprimir" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositiva" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Tira de filme" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "Alimentador automático de documentos (ADF)" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "Adaptador de transparencias (XPA)" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Condicional" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experimento" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Nitidez" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Axustar o valor de nitidez." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Limiar automático" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Activar a determinación automática do limiar para escaneos como liña de " +"arte." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Escoller filtro de suavizado." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Descargar os soportes despois de escanear." + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Descargar as unidades despois de escanear." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Cambiar o documento" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Cambiar o documento." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Descargar" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Descargar o documento" + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Iniciar proceso de calibración" + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Soporte" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Axustar tipo de soporte." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Tempo de exposición" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Unha exposición prolongada permÃtelle ao escáner recoller máis luz. " +"SuxÃrese usar 175% para impresións, 150% para diapositivas normais e " +"«Negativo» para filme en negativo. Para imaxes escuras (subexpostas) " +"pode incrementar este valor." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matriz de cor" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Axustar a matriz de cor do escáner." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Matriz de cor personalizada." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Matriz monocroma" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Matriz de cor personalizada para escáneres en escala de grises." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Espello horizontal" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Reflectir a imaxe en horizontal" + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Espello vertical" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Reflectir a imaxe en verticalv" + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Actualizar as opcións" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Actualizar as opcións." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "SaÃda de 8 bits" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Usar profundidade de bits maior de oito internamente, mais na saÃda usar " +"só oito bits." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Agardar botón frontal" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Agardar a que se prema no botón frontal para escanear." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Apagar lámpada" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Apagar a lámpada do escáner." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3331,12 +3678,6 @@ msgstr "Grupo de xeometrÃa" msgid "Scan Mode Group" msgstr "Grupo de modo de escaneo" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositiva" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3344,15 +3685,15 @@ msgstr "Modelo de escáner" #: backend/hp3900_sane.c:1408 #, fuzzy, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" "Permite comprobar o comportamento do dispositivo con outros modelos " "compatÃbeisPermite comprobar o comportamento do dispositivo con outros " "modelos compatÃbeis" #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "As imaxes a cor hanse inverter" #: backend/hp3900_sane.c:1436 @@ -3541,11 +3882,6 @@ msgstr "Acende ou apaga a lámpada" msgid "Calibrates for black and white level." msgstr "Calibrar o nivel de branco e negro." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "Alimentador automático de documentos (ADF)" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3656,301 +3992,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Opcions avanzadas" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Groso" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fina" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Personalizado" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automático" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "Adaptador de transparencias RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "A través" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC Gris" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Adaptador de transparencias gris" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lento" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rápido" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Moi rápido" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-pÃxeles" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-pÃxeles" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-pÃxeles" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Imprimir" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Tira de filme" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "Adaptador de transparencias (XPA)" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Condicional" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experimento" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Nitidez" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Axustar o valor de nitidez." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Limiar automático" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Activar a determinación automática do limiar para escaneos como liña de " -"arte." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Escoller filtro de suavizado." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Descargar os soportes despois de escanear." - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Descargar as unidades despois de escanear." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Cambiar o documento" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Cambiar o documento." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Descargar" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Descargar o documento" - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Iniciar proceso de calibración" - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Soporte" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Axustar tipo de soporte." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Tempo de exposición" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Unha exposición prolongada permÃtelle ao escáner recoller máis luz. " -"SuxÃrese usar 175% para impresións, 150% para diapositivas normais e " -"«Negativo» para filme en negativo. Para imaxes escuras (subexpostas) " -"pode incrementar este valor." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matriz de cor" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Axustar a matriz de cor do escáner." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Matriz de cor personalizada." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Matriz monocroma" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Matriz de cor personalizada para escáneres en escala de grises." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Espello horizontal" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Reflectir a imaxe en horizontal" - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Espello vertical" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Reflectir a imaxe en verticalv" - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Actualizar as opcións" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Actualizar as opcións." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "SaÃda de 8 bits" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Usar profundidade de bits maior de oito internamente, mais na saÃda usar " -"só oito bits." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Agardar botón frontal" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Agardar a que se prema no botón frontal para escanear." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Apagar lámpada" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Apagar a lámpada do escáner." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4049,7 +4090,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4217,9 +4258,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Liña de arte" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4348,7 +4389,7 @@ msgstr "Axusta o destaque da imaxe" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4415,11 +4456,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4451,12 +4492,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Impresión de alta densidade" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Impresión de baixa densidade" #: backend/kvs40xx_opt.c:243 @@ -4479,6 +4520,13 @@ msgstr "Normal" msgid "Enhanced mode" msgstr "Optimización" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4538,7 +4586,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4573,12 +4621,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4588,13 +4636,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Reflectir a imaxe horizontalmente" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4631,52 +4679,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 Liña vertical" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Ganancia" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Axustes de ganancia das canles de cor" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Ganancia de gris" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Axusta a ganancia da canle de gris" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Ganancia vermella" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Axustar a ganancia da canle vermella" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Ganancia verde" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Axusta a ganancia da canle verde" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Ganancia azul" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Axusta a ganancia da canle azul" @@ -4762,7 +4810,7 @@ msgstr "Unha páxina" msgid "All pages" msgstr "Todas as páxinas" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "escáner con cargador automático" @@ -5269,39 +5317,44 @@ msgstr "" "Quecer até que o brillo da lámpada sexa constante no canto de agardar " "polos 40 segundos de quecemento." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Limpar a calibración" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Filme en negativo" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativo" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, fuzzy, no-c-format msgid "48 bits color" msgstr "Cor fina" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Botón de control de escaneo" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5312,40 +5365,40 @@ msgstr "" "proceder, faga clic no botón «SCAN» (para MP150) ou «COLOR» (para outros " "modelos). Para cancelar, prema no botón «GRAY»." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Actualizar estado do botón" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Botón 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Botón 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5434,7 +5487,7 @@ msgstr "Interface analóxica (AFE)" msgid "Red gain value of the AFE" msgstr "Valor de ganancia vermella no AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Desviación vermella" @@ -5711,7 +5764,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Esta opción reflicte o estado dos botóns do escáner" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Acender lámpada" @@ -5721,12 +5774,12 @@ msgstr "Acender lámpada" msgid "Turn on scanner lamp" msgstr "Acende a lámpada do escáner" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Apagar lámpada" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Apaga a lámpada do escáner" @@ -5871,13 +5924,13 @@ msgid "Focus point" msgstr "Posición do foco" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Cor, liñas por lectura" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Escala de grises, liñas por lectura" #: backend/stv680.c:974 @@ -6531,52 +6584,52 @@ msgstr "Modo de calibración" msgid "Define calibration mode" msgstr "Definir o modo de calibración" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Acende/apaga a lámpada" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA Activado" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Axusta o acendido/apagado UTA" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Desprazamento" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Axustes do desprazamento das canles de cor" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Desprazamento de gris" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Axusta o desprazamento da canle gris" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Axusta o desprazamento da canle vermello" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Axusta o desprazamento da canle verde" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Axusta o desprazamento da canle azul" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.27git\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2018-09-16 22:30+0300\n" "Last-Translator: Elishai Shkury <e1907@mm.st>\n" "Language-Team: Hebrew\n" @@ -28,31 +28,31 @@ msgid "Standard" msgstr "×¡×˜× ×“×¨×˜" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "×’×™×ומטריה" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "הגדלה" @@ -86,7 +86,7 @@ msgid "Bit depth" msgstr "עומק ביט" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "מצב סריקה" @@ -127,7 +127,7 @@ msgid "Bottom-right y" msgstr "Bottom-right y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "רזולוציית סריקה" @@ -282,7 +282,7 @@ msgstr "×©× ×§×•×‘×¥" msgid "Halftone pattern size" msgstr "גודל ×ª×‘× ×™×ª הדפסת רשת" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "×ª×‘× ×™×ª הדפסת רשת" @@ -292,10 +292,10 @@ msgstr "×ª×‘× ×™×ª הדפסת רשת" msgid "Bind X and Y resolution" msgstr "קשור רזולוציה X ו-Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "תשליל" @@ -416,9 +416,9 @@ msgid "Lamp off at exit" msgstr "×ž× ×•×¨×” כבויה ביצי××”" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "×פשרות קרי××”-בלבד המפרטת כמה ×פשרויות × ×ª×ž×›×•×ª בהתקן מסוי×." @@ -737,8 +737,8 @@ msgid "Analog gamma-correction for blue" msgstr "תיקון גמה ×× ×œ×•×’×™×ª עבור כחול" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "×—×ž× ×ž× ×•×¨×” ×œ×¤× ×™ סריקה" #: include/sane/saneopts.h:417 @@ -887,8 +887,8 @@ msgid "Operation not supported" msgstr "הפעלה ×œ× × ×ª×ž×›×ª" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "הפעלה בוטלה" #: backend/sane_strstatus.c:68 @@ -981,10 +981,10 @@ msgid "Only perform shading-correction" msgstr "בצע רק תיקון הצללה" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "×× ×ž×•×¤×¢×œ×ª, רק תיקון הצללה מבוצע במהלך כיול. ערכי ברירת מחדל עבור הגבר, " @@ -1011,83 +1011,43 @@ msgid "Duplex scan" msgstr "סריקה דו צדדית" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "סריקה דו צדדית מ×פשרת סריקה של העמוד הקדמי וה×חורי של המסמך" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "כייל סורק" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "×לץ כיול סורק ×œ×¤× ×™ סריקה" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "סריקה ×‘×’×•×•× ×™ ×פור" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "בצע סריקה ×‘×’×•×•× ×™ ×פור ×‘×ž×§×•× ×¡×¨×™×§×” בצבע" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "הגבר ×× ×œ×•×’×™" +msgid "Correction according to transparency ratio" +msgstr "תיקון לפי יחס שקיפות" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "×”×¨× ×ו ×”× ×ž×š ×ת ההגבר ×”×× ×œ×•×’×™ של מערך ×”-CCD" +msgid "Correction according to film type" +msgstr "תיקון לפי סוג סרט" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "תיקון גמה" +msgid "Fine color" +msgstr "צבע בהיר" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "בוחר ×ת ×¢×§×•× ×”×”×¢×‘×¨×” מתוקן הגמה" +msgid "Negatives" +msgstr "תשלילי×" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "גולמי" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "צבע בהיר" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "×œ×œ× ×ª×™×§×•×Ÿ שקיפות" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "תיקון לפי סוג סרט" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "תיקון לפי יחס שקיפות" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "תשלילי×" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1221,8 +1181,8 @@ msgid "invalid bit IDENTIFY message" msgstr "הודעת זיהוי ביט ×œ× ×—×•×§×™" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "×פשרות ×œ× ×ž×—×•×‘×¨" #: backend/canon.c:474 @@ -1510,133 +1470,184 @@ msgstr "בחר סוג סרט" msgid "Select the film type" msgstr "בחר ×ת סוג הסרט" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "כייל סורק" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "×לץ כיול סורק ×œ×¤× ×™ סריקה" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "סריקה ×‘×’×•×•× ×™ ×פור" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "בצע סריקה ×‘×’×•×•× ×™ ×פור ×‘×ž×§×•× ×¡×¨×™×§×” בצבע" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "הגבר ×× ×œ×•×’×™" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "×”×¨× ×ו ×”× ×ž×š ×ת ההגבר ×”×× ×œ×•×’×™ של מערך ×”-CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "תיקון גמה" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "בוחר ×ת ×¢×§×•× ×”×”×¢×‘×¨×” מתוקן הגמה" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "סורק שטוח" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "חזית מזין ×ž×¡×ž×›×™× ×וטומטי" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "×חורי מזין ×ž×¡×ž×›×™× ×וטומטי" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "דו צדדי מזין ×ž×¡×ž×›×™× ×וטומטי" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "חזית לוח" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "×חורי לוח" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "דו צדדי לוח" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "×דו×" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "ירוק" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "כחול" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "שפר ×דו×" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "שפר ירוק" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "שפר כחול" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "××£ ×חד" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "×חוז דילוג ×ž×§×•× ×¨×™×§ של ×ª×•×›× ×”" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "בקש מהדרייבר ×œ×–× ×•×— ×¢×ž×•×“×™× ×¢× ×חוז × ×ž×•×š של ×¤×™×§×¡×œ×™× ×›×”×™×" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "חד צדדי" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "דו צדדי" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "יחידת שקיפות" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "מזין ×ž×¡×ž×›×™× ×וטומטי" @@ -1748,7 +1759,7 @@ msgstr "מדפסות הזרקת דיו" msgid "CRT monitors" msgstr "מסכי CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1812,8 +1823,9 @@ msgstr "A4" msgid "Max" msgstr "מירבי" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1985,17 +1997,17 @@ msgstr "מגדיר ×ת ×ž×§×“× ×”×–×•× ×‘×©×™×ž×•×© הסורק" msgid "Quick format" msgstr "פורמט מהיר" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "ציוד ××•×¤×¦×™×•× ×œ×™" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "הוצ×" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "×”×•×¦× ×ת הדף במזין ×”×ž×¡×ž×›×™× ×”×וטומטי" @@ -2010,12 +2022,14 @@ msgstr "הוצ××” ×וטומטית" msgid "Eject document after scanning" msgstr "×”×•×¦× ×ž×¡×ž×š ל×חר סריקה" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "מצב מזין ×ž×¡×ž×›×™× ×וטומטי" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "בוחר ×ת מצב מזין ×”×ž×¡×ž×›×™× ×”×וטומטי (חד צדדי/דו צדדי)" @@ -2064,16 +2078,16 @@ msgstr "" "ל×חר שליחת פקודת הסריקה, ×—×›×” עד שהכפתור על הסורק יילחץ כדי להתחיל בפועל " "×ת תהליך הסריקה." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "××™× ×¤×¨×” ×דו×" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "TPU8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "××™× ×¤×¨×” ×דו×" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2094,347 +2108,367 @@ msgstr "פרופיל CCT ×ž×•×‘× ×”" msgid "User defined CCT profile" msgstr "פרופיל CCT מוגדר משתמש" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "×”×•×¦× ×ת הדף במזין ×”×ž×¡×ž×›×™× ×”×וטומטי" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "×œ×œ× ×ª×™×§×•×Ÿ" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "כבה תיקון גמה" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "דולק" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "כבוי" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Dither" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "דיפוזיה" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "לבן" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "שחור" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "המשך" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "עצור" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10 מילימטר" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15 מילימטר" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20 מילימטר" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "×ופקי" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "×ופקי מודגש" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "×ופקי צר" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "×× ×›×™" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "×× ×›×™ מודגש" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "מלמעלה למטה" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "מלמטה למעלה" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "חזית" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "×חור" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "×¤×•× ×§×¦×™×™×ª גמה ××§×¡×¤×•× × ×˜" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "×ž×©× ×” ×ת העוצמה של ×’×•×•× ×™ ×”×‘×™× ×™×™×" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "RIF" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "הפוך ×ת עיצוב ×”×ª×ž×•× ×”" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "סוג הדפסת רשת" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "סוג בקרה של ×ž×¡× ×Ÿ הדפסת רשת" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "×ª×‘× ×™×ª בקרה של ×ž×¡× ×Ÿ הדפסת רשת" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "תרשי×" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, no-c-format msgid "Perform outline extraction" msgstr "בצע חילוץ תרשי×" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "הדגשה" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "שלילי כדי להחליק ×ו חיובי כדי לחדד ×ת ×”×ª×ž×•× ×”" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, no-c-format msgid "Separation" msgstr "הפרדה" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "הפעל הפרדה ×וטומטית של ×ª×ž×•× ×” וטקסט" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "ביצוע ×ª×ž×•× ×ª ר××™" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "בצע שיקוף ×ופקי של ×ª×ž×•× ×ª הפלט" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, no-c-format msgid "White level follower" msgstr "עוקב רמת לבן" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, no-c-format msgid "Control white level follower" msgstr "שלוט על עוקב רמת לבן" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, no-c-format msgid "BP filter" msgstr "×ž×¡× ×Ÿ כדורי" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "משפר ×יכות טקסט של עט כדורי ברזולוציה גבוהה" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "החלקה" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "הפעל החלקה ל-OCR משופר" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, no-c-format msgid "Gamma curve" msgstr "×¢×§×•× ×’×ž×”" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "×¢×§×•× ×’×ž×”, מבהיר לכהה, ×ך יתכן ×•×©× ×™×™× ×¢×œ×™×•× ×™× ×œ× ×™×¢×‘×“×•" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "×¢×§×•× ×¡×£" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "×¢×§×•× ×¡×£, מבהיר לכהה, ×ך יתכן ×•×©× ×™×™× ×¢×œ×™×•× ×™× ×œ× ×™×”×™×• ×œ×™× ×ריי×" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "לבן סף" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "קבע ×¤×™×§×¡×œ×™× ×©×•×•×™× ×œ×¡×£ ללבן ×‘×ž×§×•× ×œ×©×—×•×¨" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "הסרת רעשי×" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "מטריצה 5x5" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "הסר ×¨×¢×©×™× ×¨×™×‘×•×¢ 5 פיקסל" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "מטריצה 4x4" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "הסר ×¨×¢×©×™× ×¨×™×‘×•×¢ 4 פיקסל" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "מטריצה 3x3" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "הסר ×¨×¢×©×™× ×¨×™×‘×•×¢ 3 פיקסל" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "מטריצה 2x2" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "הסר ×¨×¢×©×™× ×¨×™×‘×•×¢ 2 פיקסל" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "×©×•× ×•×ª" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "קבע קצב ×©×•× ×•×ª SDTC (רגישות), 0 שווה ל-127" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, no-c-format msgid "Auto width detection" msgstr "גילוי רוחב ×וטומטי" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "סורק מגלה צידי × ×™×™×¨. עלול לה×ט מהירות סריקה." -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, no-c-format msgid "Auto length detection" msgstr "גילוי ×ורך ×וטומטי" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "סורק מגלה קצה × ×ž×•×š של × ×™×™×¨. עלול להטעות כמה ממשקי×." -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "דחיסה" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "הפעל מידע דחוס. עלול ×œ×’×¨×•× ×œ× ×¤×™×œ×” של ×™×™×©×•× ×”×ž×ž×©×§" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "××¨×’×•×ž× ×˜ דחיסה" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " @@ -2442,113 +2476,113 @@ msgid "" msgstr "" "רמת דחיסה JPEG. קובץ קטן ×–×” 1, קובץ גדול ×–×” 7. 0 (ברירת מחדל) ×–×” כמו 4" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "פעולת DF" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "פעולה בעקבות תקלת ×”×–× ×” כפולה" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "עיוות DF" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "הפעל תקלת ×”×–× ×” כפולה כתוצ××” מעיוות" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "עובי DF" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "הפעל תקלת ×”×–× ×” כפולה כתוצ××” מעובי × ×™×™×¨" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "×ורך DF" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "הפעל תקלת ×”×–× ×” כפולה כתוצ××” מ×ורך × ×™×™×¨" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "הבדל ×ורך DF" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "הבדל ב×ורך עמוד יגרור תקלת ×”×–× ×” כפולה" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "מצב שחזור DF" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "בקש מהסורק להפוך ×”×–× ×” בעת היתקעות × ×™×™×¨" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "×”×’× ×ª × ×™×™×¨" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "בקש מהסורק ×œ× ×‘× ×ª×§×œ×•×ª במזין ×”×ž×¡×ž×›×™× ×”×וטומטי" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, no-c-format msgid "Advanced paper protection" msgstr "×”×’× ×ª × ×™×™×¨ מתקדמת" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "בקש מהסורק ×œ× ×‘× ×ª×§×œ×•×ª במזין ×”×ž×¡×ž×›×™× ×”×וטומטי בעזרת ×—×™×™×©× ×™× ×ž×©×•×¤×¨×™×" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, no-c-format msgid "Staple detection" msgstr "גילוי סיכת הידוק" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "בקש מהסורק לגלות תקלות במזין ×”×ž×¡×ž×›×™× ×”×וטומטי כתוצ××” מסיכות הידוק" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "צבע רקע" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "קבע צבע רקע לסריקות. עלול ×œ×”×ª× ×’×© ×¢× ×פשרות סריקת יתר" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "צבע × ×•×©×¨" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " @@ -2557,33 +2591,33 @@ msgstr "" "×¡×•×¨×§×™× ×¢× ×ž×¢×‘×¨ ×חד ×ž×©×ª×ž×©×™× ×‘×¦×‘×¢ ×חד בלבד במהלך סריקה ×פורה ×ו ×‘×™× ×¨×™×ª, " "שימושי עבור × ×™×™×¨ ×ו דיו ×¦×‘×¢×•× ×™×™×" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "מצב חוצץ" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" "בקש מהסורק ×œ×§×¨×•× ×¢×ž×•×“×™× ×‘×ž×”×™×¨×•×ª ממזין ×”×ž×¡×ž×›×™× ×”×וטומטי לתוך זיכרון ×¤× ×™×ž×™" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "×יסוף מקדי×" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "בקש מהסורק לתפוס ×ת העמוד ×”×‘× ×ž×ž×–×™×Ÿ ×”×ž×¡×ž×›×™× ×”×וטומטי" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "סריקת יתר" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2594,23 +2628,23 @@ msgstr "" "×”×ž×¡×ž×›×™× ×”×וטומטי, והגדל שטח סריקה מירבי מעבר לגודל ×”× ×™×™×¨, על ×ž× ×ª ל×פשר " "צבירה ×‘×¦×“×“×™× ×”× ×•×ª×¨×™×. עלול ×œ×”×ª× ×’×© ×¢× ×פשרות צבע רקע" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "טיימר ×©×™× ×”" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "זמן בדקות עד שספק הכוח ×”×¤× ×™×ž×™ עובר למצב ×©×™× ×”" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "טיימר כיבוי" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " @@ -2619,42 +2653,42 @@ msgstr "" "זמן בדקות עד שספק הכוח ×”×¤× ×™×ž×™ מכבה ×ת הסורק. יעוגל ל-15 הדקות הקרובות " "ביותר. ×פס ×ומר ××£ ×¤×¢× ×œ× ×œ×›×‘×•×ª." -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, no-c-format msgid "Duplex offset" msgstr "×ופסט דו צדדי" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "כוון ×ופסט חזיתי/×חורי" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "×ופסט ירוק" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, no-c-format msgid "Adjust green/red offset" msgstr "כוון ×ופסט ירוק/×דו×" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "×ופסט כחול" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "כוון ×ופסט כחול/×דו×" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "זיכרון × ×ž×•×š" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2667,12 +2701,12 @@ msgstr "" "לשימוש על ×ž× ×ª לקבוע ×ת ×”×ª×ž×•× ×” ×”× ×›×•× ×”. ×פשרות זו ×מורה להיות בשימוש רק ×¢× " "×ª×•×›× ×•×ª ממשק מות×מות ×ישית." -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, no-c-format msgid "Duplex side" msgstr "צד דו צדדי" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " @@ -2681,153 +2715,153 @@ msgstr "" "×ומר ××™×–×” צד (0=חזית, 1=×חור) של סריקה דו צדדית הקרי××” הב××” ל-sane_read " "תחזיר." -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "הטיה וקיצוץ של חומרה" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "בקש מסורק לסובב ולקצץ ×¢×ž×•×“×™× ×‘×ופן דיגיטלי." -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "קיצוץ של חומרה" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "בקש מהדרייבר לסובב ×¢×ž×•×“×™× ×ž×•×˜×™× ×‘×ופן דיגיטלי." -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "קוטר ×¤×’×ž×™× ×©×œ ×ª×•×›× ×”" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "קוטר מירבי של × ×§×•×“×•×ª בודדות להסרה מהסריקה." -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "קיצוץ של ×ª×•×›× ×”" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "בקש מהדרייבר להסיר ×ת הגבול ×ž×”×¢×ž×•×“×™× ×‘×ופן דיגיטלי." -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "הפסק ×›×שר ביטול" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "בקש מהדרייבר להפסיק ×ת ×”×–× ×ª ×”× ×™×™×¨ ×‘×ž×§×•× ×œ×”×•×¦×™× ×‘×ž×”×œ×š ביטול." -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, no-c-format msgid "Endorser Options" msgstr "×פשרויות תומך" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "שולט על יחידת התמיכה" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "תומך" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "הפעל יחידת תמיכה" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "×‘×™×˜×™× ×©×œ תומך" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "קובע ×ת ערך הספירה המירבי של התומך." -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "ערך תומך" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "ערך ספירה התחלתי של התומך." -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "צעד תומך" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "×©× ×” ×ת ערך הספירה של התומך בכמות זו לכל עמוד." -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "תומך Y" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "×ופסט הדפסה של התומך מהחלק העליון של ×”× ×™×™×¨." -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "גופן תומך" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "גופן הדפסה תומך." -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, no-c-format msgid "Endorser direction" msgstr "כיוון תומך" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "כיוון הדפסה תומך." -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "צד תומך" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "צד הדפסה תומך, דורש תמיכת חומרה ×œ×©×™× ×•×™" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "מחרוזת תומך" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " @@ -2835,211 +2869,197 @@ msgid "" msgstr "" "פורמט הדפסה ××œ×¤× × ×•×ž×¨×™ תומך. ערך ×ž×•× ×” מחליף ×ת %05ud ×ו %08ud בסוף." -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "קצה עליון" -#: backend/fujitsu.c:4380 -#, no-c-format -msgid "Paper is pulled partly into adf" +#: backend/fujitsu.c:4384 +#, fuzzy, no-c-format +msgid "Paper is pulled partly into ADF" msgstr "× ×™×™×¨ משוך בחלקו לתוך מזין ×ž×¡×ž×›×™× ×וטומטי" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "× ×™×™×¨ A3" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "התגלה × ×™×™×¨ A3" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "× ×™×™×¨ B4" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "התגלה × ×™×™×¨ B4" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "× ×™×™×¨ A4" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "התגלה × ×™×™×¨ A4" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "× ×™×™×¨ B5" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "התגלה × ×™×™×¨ B5" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "OMR or DF" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "התגלה OMR ×ו ×”×–× ×” כפולה" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "חיסכון בחשמל" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "סורק במצב חיסכון בחשמל" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "×”×–× ×” ×™×“× ×™×ª" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "× ×‘×—×¨×” ×”×–× ×” ×™×“× ×™×ª" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "×¤×•× ×§×¦×™×”" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "תו ×¤×•× ×§×¦×™×” על מסך" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "דיו × ×ž×•×š" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "דיו ×¨×•×©× ×¢×•×ž×“ להיגמר" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "×”×–× ×” כפולה" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "התגלתה ×”×–× ×” כפולה" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "קוד תקלה" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "קוד תקלה חומרה" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "זווית הטיה" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "דורש רקע שחור עבור סריקה" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "דיו × ×•×ª×¨" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, no-c-format msgid "Imprinter ink level" msgstr "רמת דיו רוש×" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, no-c-format msgid "Density" msgstr "צפיפות" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "לוח צפיפות" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, no-c-format msgid "Duplex switch" msgstr "החלפה דו צדדית" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "בקש מה-backend להסיר גבול ×ž×”×¢×ž×•×“×™× ×‘×ופן דיגיטלי" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "בקש מהדרייבר ×œ×–× ×•×— ×¢×ž×•×“×™× ×¢× ×ž×¡×¤×¨ × ×ž×•×š של ×¤×™×§×¡×œ×™× ×›×”×™×" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "סיבוב ×ª×•×›× ×”" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "בקש מהדרייבר לגלות ולתקן סיבוב ×ª×ž×•× ×” של 90 מעלות" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "תוספות" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "×¢×§×•× ×¡×£ ×“×™× ×ž×™, מבהיר לכהה, בדרך כלל 50-65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "כבה ×¡×’× ×•×Ÿ קווי ×“×™× ×ž×™" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"כבה שימוש של ××œ×’×•×¨×™×ª× ×ž×¡×ª×’×œ ×ª×•×›× ×ª×™ ליצור ×¡×’× ×•×Ÿ קווי ×•×‘×ž×§×•× ×–×ת הסתמך על " -"×¡×’× ×•×Ÿ קווי חומרתי." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "כבה ××™× ×˜×¨×¤×•×œ×¦×™×”" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3048,32 +3068,32 @@ msgstr "" "×›×שר רזולוציות גבוהות בשימוש היכן שהרזולוציה ×”×ופקית ×§×˜× ×” מהרזולוציה " "×”×× ×›×™×ª ×–×” מכבה ××™× ×˜×¨×¤×•×œ×¦×™×” ×ופקית." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, no-c-format msgid "Color filter" msgstr "×ž×¡× ×Ÿ צבע" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "×›×שר ×ž×©×ª×ž×©×™× ×‘×פור ×ו ×‘×¡×’× ×•×Ÿ קווי ×פשרות זו בוחרת ×ת הצבע בשימוש." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, no-c-format msgid "Calibration file" msgstr "קובץ כיול" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, no-c-format msgid "Specify the calibration file to use" msgstr "פרט ×ת קובץ הכיול לשימוש" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, no-c-format msgid "Calibration cache expiration time" msgstr "זמן תפוגה מטמון כיול" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " @@ -3082,12 +3102,12 @@ msgstr "" "זמן (בדקות) ×œ×¤× ×™ שכיול מוטמן פג. ערך של 0 ×ומר שמטמון ××™× ×• בשימוש. ערך " "שלילי ×ומר שמטמון ×œ×¢×•×œ× ×œ× ×¤×’." -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "זמן כיבוי ×ž× ×•×¨×”" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3095,89 +3115,108 @@ msgid "" msgstr "" "×”×ž× ×•×¨×” תיכבה ל×חר הזמן ×”× ×ª×•×Ÿ (בדקות). ערך של 0 ×ומר, ×©×”×ž× ×•×¨×” ×œ× ×ª×™×›×‘×”." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "×ž× ×•×¨×” כבויה במהלך סריקה" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "×”×ž× ×•×¨×” תיכבה במהלך סריקה. " -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "כפתור קובץ" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "כפתור OCR" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "כפתור הדלקה" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, no-c-format msgid "Extra button" msgstr "כפתור ×קסטרה" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 -#, no-c-format -msgid "Need calibration" +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 +#, fuzzy, no-c-format +msgid "Needs calibration" msgstr "דרוש כיול" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "הסורק דורש כיול עבור ההגדרות ×”× ×•×›×—×™×•×ª" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "כפתורי×" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "כייל" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "התחל כיול בעזרת דף מיוחד" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "× ×§×” כיול" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "× ×§×” מטמון כיול" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "כיול גס" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "×ופסט ירוק" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "מת×× ×©×§×™×¤×•×ª" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "מת×× ×©×§×™×¤×•×ª" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3280,6 +3319,307 @@ msgstr "ערך גמה" msgid "Sets the gamma value of all channels." msgstr "קובע ×ת ערך גמה של כל הערוצי×." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "×פשרויות מתקדמות" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "גס" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "עדין" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "מות×× ×ישית" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "×וטומטי" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "חודר" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "×פור NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "×פור XPA" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "ל×ט" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "רגיל" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "מהר" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "מהר מ×וד" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-פיקסל" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-פיקסל" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-פיקסל" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "הדפסה" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "שקף" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "רצועת-סרט" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "מזין ×ž×¡×ž×›×™× ×וטומטי" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "על ×ª× ××™" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "× ×™×¡×•×™" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "חידוד" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "קבע ערך חידוד." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "סף ×וטומטי" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "הפעל קביעה ×וטומטית של סף עבור סריקות ×¡×’× ×•×Ÿ קווי." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "בחר ×ž×¡× ×Ÿ החלקה." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "×”×•×¦× ×ž×“×™×” ל×חר סריקה" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "×ž×•×¦×™× ×ת המדיה ל×חר סריקה." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "×©× ×” מסמך" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "×©× ×” מסמך." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "הוצ×" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "×”×•×¦× ×ž×¡×ž×š." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "התחל תהליך כיול." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "מדיה" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "קבע סוג מדיה." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "זמן חשיפה" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"זמן חשיפה ×רוך יותר מ×פשר לסורק ל×סוף עוד ×ור. שימוש מומלץ ×”×•× 175% " +"להדפסות, 150% ×œ×©×§×¤×™× ×¨×’×™×œ×™× ×•\"תשלילי×\" עבור סרט תשלילי×. עבור ×ª×ž×•× ×•×ª " +"כהות (תת חשיפה) ×תה יכול להגדיל ×ת הערך ×”×–×”." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "מטריצת צבע" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "קבע ×ת מטריצת הצבע של הסורק." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "מטריצת צבע מות×מת ×ישית." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "מטריצת צבע ×ž×•× ×•" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "מטריצת צבע מות×מת ×ישית עבור סריקות ×‘×’×•×•× ×™ ×פור." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "בצע ×ª×ž×•× ×ª ר××™ ×ופקית" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "×ª×ž×•× ×ª ר××™ ×ופקית." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "בצע ×ª×ž×•× ×ª ר××™ ×× ×›×™×ª" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "×ª×ž×•× ×ª ר××™ ×× ×›×™×ª." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "עדכן ×פשרויות" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "עדכן ×פשרויות." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "פלט 8 ביט" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "השתמש בעומק ביט גדול ×ž×©×ž×•× ×” ×¤× ×™×ž×™×ª, ×בל בצע פלט רק של ×©×ž×•× ×” ביטי×." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "×”×ž×ª× ×” כפתור חזיתי" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "המתן לסריקה עד ללחיצה על כפתור בלוח החזיתי." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "כיבוי ×ž× ×•×¨×”" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "כיבוי ×ž× ×•×¨×ª סורק." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3290,25 +3630,19 @@ msgstr "קבוצת ×’×™×ומטריה" msgid "Scan Mode Group" msgstr "קבוצת מצב סריקה" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "שקף" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" msgstr "×“×’× ×¡×•×¨×§" #: backend/hp3900_sane.c:1408 -#, no-c-format -msgid "Allows one to test device behaviour with other supported models" +#, fuzzy, no-c-format +msgid "Allows one to test device behavior with other supported models" msgstr "מ×פשר לבדוק ×”×ª× ×”×’×•×ª ההתקן ×¢× ×“×’×ž×™× × ×ª×ž×›×™× ×חרי×" #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "×”×¦×‘×¢×™× ×©×œ ×”×ª×ž×•× ×” יתהפכו" #: backend/hp3900_sane.c:1436 @@ -3494,11 +3828,6 @@ msgstr "מדליק ×ו מכבה ×ת ×”×ž× ×•×¨×”." msgid "Calibrates for black and white level." msgstr "מכייל עבור רמת שחור ולבן." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "מזין ×ž×¡×ž×›×™× ×וטומטי" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3614,296 +3943,6 @@ msgstr "" "ערך צבע עבור מצב מילוי ×§×•×•×™× ×ž×©×ª×¨×›×™× \"צבע\". צבע RGB לפי r*65536+256*g" "+b ×ו ערך ×פור (ברירת מחדל=סגול ×ו ×פור)" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "×פשרויות מתקדמות" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "גס" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "עדין" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "מות×× ×ישית" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "×וטומטי" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "חודר" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "×פור NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "×פור XPA" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "ל×ט" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "רגיל" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "מהר" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "מהר מ×וד" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-פיקסל" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-פיקסל" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-פיקסל" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "הדפסה" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "רצועת-סרט" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "על ×ª× ××™" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "× ×™×¡×•×™" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "חידוד" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "קבע ערך חידוד." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "סף ×וטומטי" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "הפעל קביעה ×וטומטית של סף עבור סריקות ×¡×’× ×•×Ÿ קווי." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "בחר ×ž×¡× ×Ÿ החלקה." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "×”×•×¦× ×ž×“×™×” ל×חר סריקה" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "×ž×•×¦×™× ×ת המדיה ל×חר סריקה." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "×©× ×” מסמך" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "×©× ×” מסמך." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "הוצ×" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "×”×•×¦× ×ž×¡×ž×š." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "התחל תהליך כיול." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "מדיה" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "קבע סוג מדיה." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "זמן חשיפה" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"זמן חשיפה ×רוך יותר מ×פשר לסורק ל×סוף עוד ×ור. שימוש מומלץ ×”×•× 175% " -"להדפסות, 150% ×œ×©×§×¤×™× ×¨×’×™×œ×™× ×•\"תשלילי×\" עבור סרט תשלילי×. עבור ×ª×ž×•× ×•×ª " -"כהות (תת חשיפה) ×תה יכול להגדיל ×ת הערך ×”×–×”." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "מטריצת צבע" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "קבע ×ת מטריצת הצבע של הסורק." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "מטריצת צבע מות×מת ×ישית." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "מטריצת צבע ×ž×•× ×•" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "מטריצת צבע מות×מת ×ישית עבור סריקות ×‘×’×•×•× ×™ ×פור." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "בצע ×ª×ž×•× ×ª ר××™ ×ופקית" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "×ª×ž×•× ×ª ר××™ ×ופקית." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "בצע ×ª×ž×•× ×ª ר××™ ×× ×›×™×ª" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "×ª×ž×•× ×ª ר××™ ×× ×›×™×ª." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "עדכן ×פשרויות" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "עדכן ×פשרויות." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "פלט 8 ביט" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "השתמש בעומק ביט גדול ×ž×©×ž×•× ×” ×¤× ×™×ž×™×ª, ×בל בצע פלט רק של ×©×ž×•× ×” ביטי×." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "×”×ž×ª× ×” כפתור חזיתי" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "המתן לסריקה עד ללחיצה על כפתור בלוח החזיתי." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "כיבוי ×ž× ×•×¨×”" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "כיבוי ×ž× ×•×¨×ª סורק." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4002,7 +4041,7 @@ msgid "single" msgstr "בודד" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4170,9 +4209,9 @@ msgid "crt" msgstr "crt" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "linier" +#, fuzzy, no-c-format +msgid "linear" +msgstr "×¡×’× ×•×Ÿ קווי" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4300,7 +4339,7 @@ msgstr "קובע הדגשת ×ª×ž×•× ×”" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "גמה" @@ -4367,11 +4406,11 @@ msgstr "קיצוץ ×וטומטי ×ª×•×›× ×”" msgid "Request driver to remove border from pages digitally" msgstr "בקש מהדרייבר להסיר גבול ×ž×”×¢×ž×•×“×™× ×‘×ופן דיגיטלי" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 -#, no-c-format +#: backend/kvs20xx_opt.c:233 +#, fuzzy, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" "מצב בקרת ×ורך ×”×•× ×ž×¦×‘ בו הסורק ×§×•×¨× ×¢×“ ל×ורך הקצר יותר של ×”× ×™×™×¨ בפועל ×ו " "×ורך המסמך הלוגי." @@ -4404,13 +4443,13 @@ msgid "B4" msgstr "B4" #: backend/kvs40xx_opt.c:231 -#, no-c-format -msgid "High sensivity" +#, fuzzy, no-c-format +msgid "High sensitivity" msgstr "רגישות גבוהה" #: backend/kvs40xx_opt.c:232 -#, no-c-format -msgid "Low sensivity" +#, fuzzy, no-c-format +msgid "Low sensitivity" msgstr "רגישות × ×ž×•×›×”" #: backend/kvs40xx_opt.c:243 @@ -4433,6 +4472,15 @@ msgstr "מצב רגיל" msgid "Enhanced mode" msgstr "מצב מועשר" +#: backend/kvs40xx_opt.c:396 +#, fuzzy, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"מצב בקרת ×ורך ×”×•× ×ž×¦×‘ בו הסורק ×§×•×¨× ×¢×“ ל×ורך הקצר יותר של ×”× ×™×™×¨ בפועל ×ו " +"×ורך המסמך הלוגי." + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4493,8 +4541,8 @@ msgid "JPEG compression" msgstr "דחיסת JPEG" #: backend/kvs40xx_opt.c:718 -#, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +#, fuzzy, no-c-format +msgid "JPEG compression (your application must be able to uncompress)" msgstr "דחיסת JPEG (×”×™×™×©×•× ×©×œ×š צריך לדעת לחלץ)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4528,13 +4576,13 @@ msgid "Skew adjustment" msgstr "כיוון הטיה" #: backend/kvs40xx_opt.c:808 -#, no-c-format -msgid "Stop scanner when a paper have been skewed" +#, fuzzy, no-c-format +msgid "Stop scanner if a sheet is skewed" msgstr "עצור סורק ×›×שר × ×™×™×¨ עבר הטיה" #: backend/kvs40xx_opt.c:809 -#, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +#, fuzzy, no-c-format +msgid "Scanner will stop if a sheet is skewed" msgstr "סורק יעצור ×›×שר × ×™×™×¨ עבר הטיה" #: backend/kvs40xx_opt.c:816 @@ -4543,14 +4591,14 @@ msgid "Crop actual image area" msgstr "קצץ ×ת שטח ×”×ª×ž×•× ×” בפועל" #: backend/kvs40xx_opt.c:817 -#, no-c-format -msgid "Scanner automatically detect image area and crop it" +#, fuzzy, no-c-format +msgid "Scanner will automatically detect image area and crop to it" msgstr "סורק מגלה שטח ×ª×ž×•× ×” ×וטומטית וקוצץ ×ותו" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "×–×” היפוך ימין ושמ×ל" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "בצע ×ª×ž×•× ×ª ר××™" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4587,52 +4635,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "קו ×× ×›×™ 8x8" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "הגבר" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "הגדרות הגבר ערוצי צבע" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "הגבר ×פור" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "קובע ×ת הגבר ערוץ ×פור" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "הגבר ×דו×" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "קובע ×ת הגבר ערוץ ×דו×" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "הגבר ירוק" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "קובע ×ת הגבר ערוץ ירוק" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "הגבר כחול" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "קובע ×ת הגבר ערוץ כחול" @@ -4718,7 +4766,7 @@ msgstr "עמוד ×חד" msgid "All pages" msgstr "כל הדפי×" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "סורק מוזן דפי×" @@ -5215,27 +5263,32 @@ msgstr "" "בצע ×—×™×ž×•× ×¢×“ שהבהירות של ×”×ž× ×•×¨×” קבועה ×‘×ž×§×•× ×œ×”×™×¦×ž×“ לזמן ×—×™×ž×•× ×©×œ 40 " "×©× ×™×•×ª." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "דרוש כיול" + +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "צבע תשליל" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "×פור תשליל" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "צבע 48 ביטי×" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "צבע 16 ביטי×" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " @@ -5244,12 +5297,12 @@ msgstr "" "בוחר ×ת מקור הסריקה (כמו מזין מסמכי×). קבע מקור ×œ×¤× ×™ מצב ורזולוציה. " "מ×תחל מצב ורזולוציה ×œ×¢×¨×›×™× ×וטומטי×." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "סריקה מבוקרת כפתור" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5259,40 +5312,40 @@ msgstr "" "×›×שר מופעלת, תהליך הסריקה ×œ× ×™×ª×—×™×œ מיד. להמשך, לחץ על כפתור \"סריקה\" ×ו " "\"צבע\" (תלוי ×‘×“×’× ×”×¡×•×¨×§). לביטול, לחץ על כפתור \"×פור\"." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "עדכן מצב כפתור" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "כפתור 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "כפתור 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "סוג מקור לסריקה" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "סוג פעולת מטרה" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "זמן ×”×ž×ª× ×” מזין ×ž×¡×ž×›×™× ×וטומטי" -#: backend/pixma_sane_options.c:349 -#, no-c-format +#: backend/pixma/pixma_sane_options.c:349 +#, fuzzy, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" "×›×שר × ×§×‘×¢, הסורק מחפש ×ת זמן ×”×”×ž×ª× ×” ×‘×©× ×™×•×ª למסמך חדש ×”×ž×•×›× ×¡ למזין " @@ -5383,7 +5436,7 @@ msgstr "ממשק ×× ×œ×•×’×™" msgid "Red gain value of the AFE" msgstr "ערך הגבר ××“×•× ×©×œ ×”-AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "×ופסט ×דו×" @@ -5657,7 +5710,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "×פשרות זו משקפת ×ת הסטטוס של כפתור בסורק." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "×ž× ×•×¨×” דולקת" @@ -5667,12 +5720,12 @@ msgstr "×ž× ×•×¨×” דולקת" msgid "Turn on scanner lamp" msgstr "הדלק ×ž× ×•×¨×ª סורק" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "×ž× ×•×¨×” כבויה" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "כבה ×ž× ×•×¨×ª סורק" @@ -5813,13 +5866,13 @@ msgid "Focus point" msgstr "× ×§×•×“×ª פוקוס" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "קווי צבע פר קרי××”" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "×§×•×•×™× ×‘×’×•×•× ×™ ×פור פר קרי××”" #: backend/stv680.c:974 @@ -6444,52 +6497,68 @@ msgstr "מצב כיול" msgid "Define calibration mode" msgstr "הגדר מצב כיול" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "מדליק/מכבה ×ž× ×•×¨×”" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "הדלקת UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "קובע UTA דולק/מכובה" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "×ופסט" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "הגדרות ×ופסט ערוצי צבעי×" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "×ופסט ×פור" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "קובע ×ופסט ערוץ ×פור" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "קובע ×ופסט ערוץ ×דו×" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "קובע ×ופסט ערוץ ירוק" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "קובע ×ופסט ערוץ כחול" + +#~ msgid "Disable dynamic lineart" +#~ msgstr "כבה ×¡×’× ×•×Ÿ קווי ×“×™× ×ž×™" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "כבה שימוש של ××œ×’×•×¨×™×ª× ×ž×¡×ª×’×œ ×ª×•×›× ×ª×™ ליצור ×¡×’× ×•×Ÿ קווי ×•×‘×ž×§×•× ×–×ת הסתמך " +#~ "על ×¡×’× ×•×Ÿ קווי חומרתי." + +#~ msgid "linier" +#~ msgstr "linier" + +#~ msgid "It is right and left reversing" +#~ msgstr "×–×” היפוך ימין ושמ×ל" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2011-04-06 19:50+0200\n" "Last-Translator: Németh Tamás <ntomasz@uhuklub.hu>\n" "Language-Team: Hungarian <NONE>\n" @@ -27,31 +27,31 @@ msgid "Standard" msgstr "Ãltalános" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometria" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Haladó" @@ -85,7 +85,7 @@ msgid "Bit depth" msgstr "SzÃnmélység" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Szkennelési üzemmód" @@ -126,7 +126,7 @@ msgid "Bottom-right y" msgstr "Jobb-alsó y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Szkennelés felbontása" @@ -281,7 +281,7 @@ msgstr "Fájlnév" msgid "Halftone pattern size" msgstr "" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "" @@ -291,10 +291,10 @@ msgstr "" msgid "Bind X and Y resolution" msgstr "" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "NegatÃv" @@ -417,7 +417,7 @@ msgstr "" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" @@ -723,7 +723,7 @@ msgstr "" #: include/sane/saneopts.h:415 #, no-c-format -msgid "Warmup lamp before scanning" +msgid "Warm up lamp before scanning" msgstr "" #: include/sane/saneopts.h:417 @@ -872,8 +872,8 @@ msgid "Operation not supported" msgstr "A művelet nem támogatott" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "A művelet megszakÃtva" #: backend/sane_strstatus.c:68 @@ -967,7 +967,7 @@ msgstr "" #, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" @@ -994,81 +994,41 @@ msgstr "Teljes szkennelés" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Szkenner kalibrálása" - -#: backend/canon630u.c:160 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Force scanner calibration before scan" +msgid "Correction according to transparency ratio" msgstr "" -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Szürkeskálás szkennelés" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Do a grayscale rather than color scan" +msgid "Correction according to film type" msgstr "" -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analóg erÅ‘sÃtés" - -#: backend/canon630u.c:307 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" +msgid "Fine color" msgstr "" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "Gamma korrekció" - -#: backend/canon630u.c:348 -#, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "" +#: backend/canon-sane.c:776 backend/canon.c:176 +#, fuzzy, no-c-format +msgid "Negatives" +msgstr "NegatÃv" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Nyers" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "" - #: backend/canon.c:169 #, fuzzy, no-c-format msgid "No transparency correction" msgstr "ErÅ‘sÃtés korrekció" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, fuzzy, no-c-format -msgid "Negatives" -msgstr "NegatÃv" - #: backend/canon.c:176 #, fuzzy, no-c-format msgid "Slides" @@ -1202,9 +1162,9 @@ msgid "invalid bit IDENTIFY message" msgstr "" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" -msgstr "" +#, fuzzy, no-c-format +msgid "option not correct" +msgstr "A művelet nem támogatott" #: backend/canon.c:474 #, no-c-format @@ -1491,133 +1451,184 @@ msgstr "FilmtÃpus" msgid "Select the film type" msgstr "" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Szkenner kalibrálása" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Szürkeskálás szkennelés" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analóg erÅ‘sÃtés" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gamma korrekció" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "SÃkágyas" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Nyomtatás" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Vörös" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Zöld" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Kék" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Haladó" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Haladó" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Haladó" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Nincs" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatikus dokumentum adagoló" @@ -1729,7 +1740,7 @@ msgstr "Tintasugaras nyomtató" msgid "CRT monitors" msgstr "CRT monitor" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1793,8 +1804,9 @@ msgstr "A4" msgid "Max" msgstr "Max" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1966,17 +1978,17 @@ msgstr "" msgid "Quick format" msgstr "" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "" @@ -1991,12 +2003,14 @@ msgstr "" msgid "Eject document after scanning" msgstr "" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2041,14 +2055,14 @@ msgid "" "pressed to actually start the scan process." msgstr "" -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2071,492 +2085,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, no-c-format +msgid "Load a sheet in the ADF" +msgstr "" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Nincs korrekció" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Gamma korrekció" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Be" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Ki" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Fehérszint" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Feketeszint" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Folytatás" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "MegállÃt" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "VÃzszintes" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "VÃzszintes" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "VÃzszintes" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "FüggÅ‘leges" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "FüggÅ‘leges" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Nyomtatás" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Finom beállÃtás" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "TelÃtettség" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Kép tükrözése" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "A kép vÃzszintes tükrözése." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Fehérszint" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "A kék csatorna kontrasztja" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "SzÃnmátrix" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Gamma érték" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Küszöb" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Zajszűrés" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Nincs korrekció" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Nincs korrekció" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "ElÅ‘nézeti mód" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Haladó" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Nincs korrekció" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2564,65 +2598,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Teljes szkennelés" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "A zöld csatorna kontrasztja" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "A kék csatorna kontrasztja" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, fuzzy, no-c-format msgid "Low Memory" msgstr "Nincs elég memória" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2631,507 +2665,514 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Teljes szkennelés" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Haladó" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Zajszűrés" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "Eszköz felbontása" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Fehérszint" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Vörös intenzitás" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Teljes szkennelés" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, fuzzy, no-c-format msgid "Extras" msgstr "Extra gyors" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, fuzzy, no-c-format msgid "Disable interpolation" msgstr "TesztbeállÃtások engedélyezése" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "SzÃnmátrix" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibráció" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "PrecÃz beállÃtás" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Kalibráció" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " "of 0 means, that the lamp won't be turned off." msgstr "" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Finom beállÃtás" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Fájl gomb" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "OCR gomb" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Email gomb" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Finom beállÃtás" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Gombok" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibrálás" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Kalibrálási folyamat indÃtása." -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Finom beállÃtás" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Finom beállÃtás" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Finom beállÃtás" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, no-c-format +msgid "Ignore internal offsets" +msgstr "" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Ãtlátszó" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3222,6 +3263,304 @@ msgstr "Gamma érték" msgid "Sets the gamma value of all channels." msgstr "" +#: backend/hp-option.c:2987 +#, fuzzy, no-c-format +msgid "Advanced Options" +msgstr "Haladó" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Egyedi" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatikus" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lassú" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normál" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Gyors" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Extra gyors" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-pixel" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-pixel" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-pixel" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Nyomtatás" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "" + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "" + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "" + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "" + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "" + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Kalibrálási folyamat indÃtása." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "" + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "SzÃnmátrix" + +#: backend/hp-option.h:121 +#, no-c-format +msgid "Set the scanner's color matrix." +msgstr "" + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Egyéni szÃnmátrix." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "" + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "VÃzszintes tükrözés" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "A kép vÃzszintes tükrözése." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "FüggÅ‘leges tükrözés" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "A kép függÅ‘leges tükrözése." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "" + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "" + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3232,12 +3571,6 @@ msgstr "Geometria" msgid "Scan Mode Group" msgstr " Szkennelési üzemmód " -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3245,12 +3578,12 @@ msgstr "Szkennelési üzemmód" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3431,11 +3764,6 @@ msgstr "" msgid "Calibrates for black and white level." msgstr "" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3546,293 +3874,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, fuzzy, no-c-format -msgid "Advanced Options" -msgstr "Haladó" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Egyedi" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatikus" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lassú" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normál" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Gyors" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Extra gyors" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-pixel" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-pixel" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-pixel" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Nyomtatás" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "" - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "" - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "" - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "" - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "" - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Kalibrálási folyamat indÃtása." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "" - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "SzÃnmátrix" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "" - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Egyéni szÃnmátrix." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "" - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "VÃzszintes tükrözés" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "A kép vÃzszintes tükrözése." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "FüggÅ‘leges tükrözés" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "A kép függÅ‘leges tükrözése." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "" - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "" - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3931,7 +3972,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4099,9 +4140,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Vonalas" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4228,7 +4269,7 @@ msgstr "" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4295,11 +4336,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4331,12 +4372,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "" #: backend/kvs40xx_opt.c:232 #, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "" #: backend/kvs40xx_opt.c:243 @@ -4359,6 +4400,13 @@ msgstr "Normál" msgid "Enhanced mode" msgstr "Haladó" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4418,7 +4466,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4453,12 +4501,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4468,13 +4516,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Kép tükrözése" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4511,52 +4559,52 @@ msgstr "" msgid "8x8 Vertical Line" msgstr "" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, fuzzy, no-c-format msgid "Gray gain" msgstr "Szürke" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, fuzzy, no-c-format msgid "Red gain" msgstr "Vörös balansz" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, fuzzy, no-c-format msgid "Sets red channel gain" msgstr "A vörös csatorna kontrasztja" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, fuzzy, no-c-format msgid "Green gain" msgstr "Zöld balansz" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, fuzzy, no-c-format msgid "Sets green channel gain" msgstr "A zöld csatorna kontrasztja" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, fuzzy, no-c-format msgid "Blue gain" msgstr "Kék balansz" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, fuzzy, no-c-format msgid "Sets blue channel gain" msgstr "A kék csatorna kontrasztja" @@ -4642,7 +4690,7 @@ msgstr "Egy oldal" msgid "All pages" msgstr "Minden oldal" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "" @@ -5135,39 +5183,44 @@ msgid "" "40 seconds warm-up time." msgstr "" -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Finom beállÃtás" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "NegatÃv film" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "NegatÃv" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5175,40 +5228,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5297,7 +5350,7 @@ msgstr "Analóg erÅ‘sÃtés" msgid "Red gain value of the AFE" msgstr "" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "" @@ -5552,7 +5605,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "" @@ -5562,12 +5615,12 @@ msgstr "" msgid "Turn on scanner lamp" msgstr "" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "" @@ -5703,13 +5756,13 @@ msgstr "Fókusz az üvegen" #: backend/snapscan-options.c:930 #, no-c-format -msgid "Colour lines per read" +msgid "Color lines per read" msgstr "" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" -msgstr "" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" +msgstr "Szürkeskálás szkennelés" #: backend/stv680.c:974 #, no-c-format @@ -6293,52 +6346,52 @@ msgstr "" msgid "Define calibration mode" msgstr "" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, fuzzy, no-c-format msgid "Offset" msgstr "Ki" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, fuzzy, no-c-format msgid "Gray offset" msgstr "Szürke kontraszt" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, fuzzy, no-c-format msgid "Sets red channel offset" msgstr "A vörös csatorna kontrasztja" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, fuzzy, no-c-format msgid "Sets green channel offset" msgstr "A zöld csatorna kontrasztja" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, fuzzy, no-c-format msgid "Sets blue channel offset" msgstr "A kék csatorna kontrasztja" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.18\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-08-28 23:11+0200\n" "Last-Translator: Giuseppe Sacco <eppesuig@debian.org>\n" "Language-Team: italian translation project <tp@lists.linux.it>\n" @@ -26,31 +26,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometria" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Miglioramento" @@ -84,7 +84,7 @@ msgid "Bit depth" msgstr "Profondità in bit" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Modalità di scansione" @@ -125,7 +125,7 @@ msgid "Bottom-right y" msgstr "Y in basso a destra" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Risoluzione della scansione" @@ -280,7 +280,7 @@ msgstr "Nome file" msgid "Halftone pattern size" msgstr "Dimensione del modello mezzi-toni" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Modello mezzi-toni" @@ -290,10 +290,10 @@ msgstr "Modello mezzi-toni" msgid "Bind X and Y resolution" msgstr "Lega la risoluzione X e Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativo" @@ -414,9 +414,9 @@ msgid "Lamp off at exit" msgstr "Lampada spenta in uscita" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Opzione che visualizza quante opzioni sono supportate da uno specifico " @@ -768,8 +768,8 @@ msgid "Analog gamma-correction for blue" msgstr "Correzione gamma del blu analogica" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Preriscaldamento della lampada prima della scansione" #: include/sane/saneopts.h:417 @@ -919,7 +919,7 @@ msgstr "Mezzi-toni non supportati" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -1013,10 +1013,10 @@ msgid "Only perform shading-correction" msgstr "Esegue solamente la correzione delle ombre" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Se abilitata verrà eseguita solo la correzione delle ombre, qualora sia " @@ -1045,83 +1045,43 @@ msgid "Duplex scan" msgstr "Scansione Duplex" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "La scansione duplex è quella di entrambi i lati del documento" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibrare lo scanner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Forza la calibrazione dello scanner prima della scansione" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Scansione in scala di grigi" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Effettuare una scansione in scala di grigi invece che a colori" - -#: backend/canon630u.c:306 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Analog Gain" -msgstr "Guadagno analogico" +msgid "Correction according to transparency ratio" +msgstr "Correzione in base al rapporto di trasparenza" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Aumenta o diminuisce il guadagno analogico del sensore CCD" +msgid "Correction according to film type" +msgstr "Correzione in base al tipo di pellicola" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Correzione gamma" +msgid "Fine color" +msgstr "Colore ad alta qualità " -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Selezionare la curva di correzione gamma" +msgid "Negatives" +msgstr "Negativi" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Grezzo" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Colore ad alta qualità " - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Nessuna correzione della trasparenza" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Correzione in base al tipo di pellicola" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Correzione in base al rapporto di trasparenza" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negativi" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1257,8 +1217,8 @@ msgid "invalid bit IDENTIFY message" msgstr "messaggio con bit IDENTIFY non valido" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "opzione non connesso" #: backend/canon.c:474 @@ -1550,133 +1510,184 @@ msgstr "Seleziona tipo pellicola" msgid "Select the film type" msgstr "Seleziona il tipo di pellicola" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibrare lo scanner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Forza la calibrazione dello scanner prima della scansione" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Scansione in scala di grigi" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Effettuare una scansione in scala di grigi invece che a colori" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Guadagno analogico" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Aumenta o diminuisce il guadagno analogico del sensore CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Correzione gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Selezionare la curva di correzione gamma" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Piano fisso" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, fuzzy, no-c-format msgid "ADF Front" msgstr "Coperchio ADF aperto" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "ADF inceppato" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "ADF Duplex" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Stampa" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Fronte e retro" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Rosso" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Verde" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Blu" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Miglioramento" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Miglioramento" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Miglioramento" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Nessuno" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Solo fronte" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Fronte e retro" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Adattatore per trasparenze" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Caricatore automatico fogli" @@ -1788,7 +1799,7 @@ msgstr "Stampanti a getto d'inchiostro" msgid "CRT monitors" msgstr "Monitor CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1852,8 +1863,9 @@ msgstr "A4" msgid "Max" msgstr "Massimo" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2027,17 +2039,17 @@ msgstr "Definisce il fattore di zoom usato dallo scanner" msgid "Quick format" msgstr "Formato rapido" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Dispositivi opzionali" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Espulsione" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Espelle il foglio dall'alimentatore automatico" @@ -2052,12 +2064,14 @@ msgstr "Espulsione automatica" msgid "Eject document after scanning" msgstr "Espelle il documento dopo la sua scansione" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Modalità ADF" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Seleziona la modalità ADF (solo fronte/fronte-retro)" @@ -2109,14 +2123,14 @@ msgstr "" "premuto il tasto dello scanner per fare partire il processo di " "acquisizione." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2139,493 +2153,513 @@ msgstr "" msgid "User defined CCT profile" msgstr "Definito dall'utente" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Espelle il foglio dall'alimentatore automatico" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Nessuna correzione" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Correzione gamma analogica" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Attivo" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Disattivo" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Sfumatura" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "Diffusione d'errore" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Livello bianco" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Livello nero" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "Condizionale" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Orizzontale" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Orizzontale" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Orizzontale" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Verticale" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "Verticale" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "Stampa" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Mezzi toni" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Effettua calibrazione" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Accentuazione dell'immagine" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Saturazione" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "" "Abilita la valutazione automatica della soglia per la scansione binaria." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Immagine riflessa" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Riflette l'immagine orizzontalmente." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Livello di bianco sul blu" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Controlla il livello del rosso" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Filtro colore" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Ammorbidimento" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Valore gamma" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Soglia" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Soglia" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Riduzione del rumore" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Nessuna correzione" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Nessuna correzione" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Coperchio ADF aperto" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Opzioni avanzate" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Nessuna correzione" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Esclusione" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Modalità di caricamento" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2633,65 +2667,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Durata spegnimento lampada" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Scarto sul blu" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Scarto sul verde" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Scarto sul verde" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Scarto sul blu" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Imposta lo scarto sul blu" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2700,374 +2734,362 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Scansione Duplex" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Opzioni avanzate" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Riduzione del rumore" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Da carta" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Da carta" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Da carta" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Da carta" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "Coperchio ADF aperto" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Messa a fuoco preliminare manuale" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Messa a fuoco preliminare manuale" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "errore nei controlli hardware" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Livello bianco" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Controllo della densità " -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "Controllo della densità " -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Scansione Duplex" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extra" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Disattiva interpolazione" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3076,46 +3098,46 @@ msgstr "" "Quando si usano alte risoluzione con quella orizzontale minore della " "verticale, l'interpolazione orizzontale viene disabilitata." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Filtro colore" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "Quando si usano i grigi o il binario questa opzione seleziona il colore " "usato." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Calibrazione" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Definire la modalità di calibrazione" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Cache per la calibrazione" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Durata spegnimento lampada" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3124,90 +3146,109 @@ msgstr "" "La lampada verrà spenta allo scadere del tempo impostato (in minuti). Il " "valore 0 indica che la lampada non deve mai essere spenta." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Calibrazione granulosa" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, fuzzy, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" "Numero di minuti prima che la lampada venga spenta dopo la scansione" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "Attendi il tasto" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "Attendi il tasto" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Attendi il tasto" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Calibrazione granulosa" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Forza la calibrazione dello scanner prima della scansione" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Pulsanti" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Calibrazione" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Inizia la calibrazione." -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Calibrazione granulosa" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Cache per la calibrazione" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Calibrazione granulosa" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Scarto sul verde" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Adattatore per trasparenza" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Adattatore per trasparenza" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3317,6 +3358,313 @@ msgstr "Valore gamma" msgid "Sets the gamma value of all channels." msgstr "Imposta il valore gamma per tutti i canali." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Opzioni avanzate" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Granuloso" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "A grana fine" + +# Bayer è il nome della persona che ha inventato questa matrice per il +# dithering. +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Personalizzato" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatico" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Passante" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "Grigio NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA Grigio" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lento" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normale" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Veloce" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Extra veloce" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-pixel" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-pixel" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-pixel" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Stampa" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositiva" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Pellicola" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Condizionale" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Esperimento" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Nitidezza" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Imposta il valore di nitidezza." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Soglia automatica" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Abilita la valutazione automatica della soglia per la scansione binaria." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Seleziona il filtro per l'ammorbidimento (smoothing)." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Espelle il supporto dopo la scansione" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Estrae il supporto originale dopo aver effettuato la scansione." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Cambia il documento" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Cambia il documento." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Espulsione" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Espelle il documento." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Inizia la calibrazione." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Supporto" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Imposta il tipo di supporto." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Tempo di esposizione" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Un maggiore tempo di esposizione permette allo scanner di raccogliere " +"più luce. I valori suggeriti sono 175% per le stampe, 150% per le " +"normali diapositive e \"Negativo\" per le pellicole. Per immagini scure " +"(sottoesposte) si può aumentare questo valore." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matrice del colore" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Imposta la matrice del colore." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Matrice personalizzata del colore." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Matrice del colore mono" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Matrice personalizzata del colore per scansioni a scale di grigi." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Specchio orizzontale" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Riflette l'immagine orizzontalmente." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Specchio verticale" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Riflette l'immagine verticalmente." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Opzioni di aggiornamento" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Opzioni di aggiornamento." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "uscita a 8 bit" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "Usa internamente più di 8 bit, ma produce solo 8 bit." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Attesa del bottone frontale" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" +"Viene attesa la pressione del bottone frontale prima di effettuare la " +"scansione." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Spegnimento della lampada" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Spegne la lampada dello scanner." + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3327,12 +3675,6 @@ msgstr "Geometria" msgid "Scan Mode Group" msgstr "Modalità di scansione" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositiva" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3340,12 +3682,12 @@ msgstr "Modalità di scansione" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3526,11 +3868,6 @@ msgstr "Accendi o spegni la lampada" msgid "Calibrates for black and white level." msgstr "Calibrare i livelli del bianco e nero" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3641,302 +3978,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Opzioni avanzate" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Granuloso" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "A grana fine" - -# Bayer è il nome della persona che ha inventato questa matrice per il -# dithering. -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Personalizzato" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatico" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Passante" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "Grigio NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA Grigio" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lento" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normale" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Veloce" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Extra veloce" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-pixel" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-pixel" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-pixel" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Stampa" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Pellicola" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Condizionale" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Esperimento" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Nitidezza" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Imposta il valore di nitidezza." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Soglia automatica" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Abilita la valutazione automatica della soglia per la scansione binaria." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Seleziona il filtro per l'ammorbidimento (smoothing)." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Espelle il supporto dopo la scansione" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Estrae il supporto originale dopo aver effettuato la scansione." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Cambia il documento" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Cambia il documento." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Espulsione" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Espelle il documento." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Inizia la calibrazione." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Supporto" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Imposta il tipo di supporto." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Tempo di esposizione" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Un maggiore tempo di esposizione permette allo scanner di raccogliere " -"più luce. I valori suggeriti sono 175% per le stampe, 150% per le " -"normali diapositive e \"Negativo\" per le pellicole. Per immagini scure " -"(sottoesposte) si può aumentare questo valore." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matrice del colore" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Imposta la matrice del colore." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Matrice personalizzata del colore." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Matrice del colore mono" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Matrice personalizzata del colore per scansioni a scale di grigi." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Specchio orizzontale" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Riflette l'immagine orizzontalmente." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Specchio verticale" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Riflette l'immagine verticalmente." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Opzioni di aggiornamento" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Opzioni di aggiornamento." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "uscita a 8 bit" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "Usa internamente più di 8 bit, ma produce solo 8 bit." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Attesa del bottone frontale" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" -"Viene attesa la pressione del bottone frontale prima di effettuare la " -"scansione." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Spegnimento della lampada" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Spegne la lampada dello scanner." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4035,7 +4076,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4207,9 +4248,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Binario" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4339,7 +4380,7 @@ msgstr "Imposta l'accentuazione dell'immagine" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4406,11 +4447,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4442,12 +4483,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Stampa ad alta definizione" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Stampa a bassa definizione" #: backend/kvs40xx_opt.c:243 @@ -4470,6 +4511,13 @@ msgstr "Normale" msgid "Enhanced mode" msgstr "Miglioramento" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4529,7 +4577,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4564,12 +4612,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4579,13 +4627,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Immagine riflessa" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4622,52 +4670,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 linea verticale" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Guadagno" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Regolazione del guadagno sui canali di colore" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Guadagno sul grigio" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Imposta il guadagno sul canale grigio" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Guadagno sul rosso" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Imposta il guadagno sul canale rosso" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Guadagno sul verde" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Imposta il guadagno sul canale verde" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Guadagno sul blu" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Imposta il guadagno sul canale blu" @@ -4753,7 +4801,7 @@ msgstr "Pagina singola" msgid "All pages" msgstr "Tutte le pagine" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "Scanner con alimentatore automatico dei fogli" @@ -5262,39 +5310,44 @@ msgstr "" "Preriscalda fino a che la luminisità della lampada sia costante invece " "di attendere 40 secondi." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Calibrazione granulosa" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Pellicola negativa" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativo" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, fuzzy, no-c-format msgid "48 bits color" msgstr "Colore ad alta qualità " -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Scansione controllata da pulsante" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5305,40 +5358,40 @@ msgstr "" "procedere premere il pulsante \"SCAN\" (per ML150) oppure \"COLOR\" (per " "altri modelli). Per annullare premere il pulsante \"GRAY\"." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Aggiorna lo stato del pulsante" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Pulsante 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Pulsante 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5427,7 +5480,7 @@ msgstr "Frontend analogico" msgid "Red gain value of the AFE" msgstr "Valore del guadagno sul rosso per AFE (Analog FrontEnd)" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Scarto sul rosso" @@ -5706,7 +5759,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Queste opzioni riflettono lo stato dei pulsanti dello scanner." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lampada accesa" @@ -5716,12 +5769,12 @@ msgstr "Lampada accesa" msgid "Turn on scanner lamp" msgstr "Accendere la lampada" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Lampada spenta" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Spegnere la lampada" @@ -5866,13 +5919,13 @@ msgid "Focus point" msgstr "Posizione della messa a fuoco" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Numero di linee colore per ciclo di lettura" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Numero di linee in scala di grigi per ciclo di lettura" #: backend/stv680.c:974 @@ -6529,52 +6582,52 @@ msgstr "Modalità di calibrazione" msgid "Define calibration mode" msgstr "Definire la modalità di calibrazione" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Commuta lo stato della lampada" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "Adattatore per trasparenze acceso" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Accendere/spegnere l'adattatore per trasparenze" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Scarto" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Impostazione dello scarto sui canali del colore" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Scarto sul grigio" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Imposta lo scarto sul grigio" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Imposta lo scarto sul rosso" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Imposta lo scarto sul verde" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Imposta lo scarto sul blu" @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.20\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2009-10-31 10:30+0900\n" "Last-Translator: Hiroshi Miura <miurahr@linux.com>\n" "Language-Team: Japanese <japanese@li.org>\n" @@ -30,31 +30,31 @@ msgid "Standard" msgstr "標準" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "é…ç½®" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "増強" @@ -88,7 +88,7 @@ msgid "Bit depth" msgstr "ビット深度" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "走査モード" @@ -129,7 +129,7 @@ msgid "Bottom-right y" msgstr "å³ä¸‹ã®y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "走査解åƒåº¦" @@ -284,7 +284,7 @@ msgstr "ファイルå" msgid "Halftone pattern size" msgstr "ãƒãƒ¼ãƒ•ãƒˆãƒ¼ãƒ³ãƒ‘ターンã®å¤§ãã•" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "ãƒãƒ¼ãƒ•ãƒˆãƒ¼ãƒ³ã®ãƒ‘ターン" @@ -294,10 +294,10 @@ msgstr "ãƒãƒ¼ãƒ•ãƒˆãƒ¼ãƒ³ã®ãƒ‘ターン" msgid "Bind X and Y resolution" msgstr "Xã¨Y解åƒåº¦ã‚’拘æŸ" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "ãƒã‚¬" @@ -418,9 +418,9 @@ msgid "Lamp off at exit" msgstr "終了時ã«ãƒ©ãƒ³ãƒ—ã‚’åœæ¢ã™ã‚‹" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "特定ã®ãƒ‡ãƒã‚¤ã‚¹ãŒã‚µãƒãƒ¼ãƒˆã™ã‚‹ã‚ªãƒ—ションãŒã©ã‚Œã ã‘ã‚ã‚‹ã‹ã‚’指定ã™ã‚‹èªã¿å–ã‚Š" @@ -727,8 +727,8 @@ msgid "Analog gamma-correction for blue" msgstr "é’ã®ã‚¢ãƒŠãƒã‚°ã‚¬ãƒ³ãƒžè£œæ£" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "走査å‰ã®ãƒ©ãƒ³ãƒ—ã®æš–æ©Ÿ" #: include/sane/saneopts.h:417 @@ -877,8 +877,8 @@ msgid "Operation not supported" msgstr "æ“作ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "æ“作ã¯ã‚ャンセルã•ã‚Œã¾ã—ãŸã€‚" #: backend/sane_strstatus.c:68 @@ -971,10 +971,10 @@ msgid "Only perform shading-correction" msgstr "シェーディング補æ£ã ã‘ã‚’è¡Œã†" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "有効ã®å ´åˆã€è¼ƒæ£ã«ãŠã„ã¦ã¯ã‚·ã‚§ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°è£œæ£ã ã‘ãŒå®Ÿè¡Œã•ã‚Œã¾ã™ã€‚利得ã€ã‚ª" @@ -1002,83 +1002,43 @@ msgid "Duplex scan" msgstr "両é¢ã‚¹ã‚ャン" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "両é¢ã‚¹ã‚ャンã§ã¯ã€æ–‡æ›¸ã®è¡¨é¢ã¨è£é¢ã®èµ°æŸ»ãŒè¡Œã‚ã‚Œã¾ã™ã€‚" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "スã‚ャナーã®æ ¡æ£" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "走査å‰ã«ã‚¹ã‚ャナã®æ ¡æ£ã‚’強制ã™ã‚‹" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "グレースケール走査" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "カラーã®ä»£ã‚ã‚Šã«ã€ã‚°ãƒ¬ãƒ¼ã‚¹ã‚±ãƒ¼ãƒ«ã§èµ°æŸ»ã—ã¾ã™ã€‚" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "アナãƒã‚°åˆ©å¾—" +msgid "Correction according to transparency ratio" +msgstr "é€éŽçŽ‡ã«å¾“ã£ã¦ã€è£œæ£ã•ã‚Œã¾ã™ã€‚" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "CCDé…列ã®ã‚¢ãƒŠãƒã‚°åˆ©å¾—ã‚’å¢—åŠ ã¾ãŸã¯æ¸›å°‘" +msgid "Correction according to film type" +msgstr "フィルムã®ç¨®é¡žã«å¾“ã£ãŸè£œæ£" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "ã‚¬ãƒ³ãƒžæ ¡æ£" +msgid "Fine color" +msgstr "高精彩" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "ガンマ補æ£ã•ã‚ŒãŸå¤‰æ›ã‚«ãƒ¼ãƒ–ã‚’é¸æŠž" +msgid "Negatives" +msgstr "ãƒã‚¬ç”»åƒ" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "ç„¡åŠ å·¥" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "高精彩" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "é€æ˜Žåº¦è£œæ£ã¯è¡Œã‚ãªã„" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "フィルムã®ç¨®é¡žã«å¾“ã£ãŸè£œæ£" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "é€éŽçŽ‡ã«å¾“ã£ã¦ã€è£œæ£ã•ã‚Œã¾ã™ã€‚" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "ãƒã‚¬ç”»åƒ" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1212,8 +1172,8 @@ msgid "invalid bit IDENTIFY message" msgstr "IDENTIFYメッセージã«ä¸æ£ãªãƒ“ット" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "オプションãŒæ£ã—ãã‚ã‚Šã¾ã›ã‚“" #: backend/canon.c:474 @@ -1502,133 +1462,184 @@ msgstr "フィルムã®ç¨®é¡žã‚’é¸æŠž" msgid "Select the film type" msgstr "フィルムã®ç¨®é¡žã‚’é¸ã¶" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "スã‚ャナーã®æ ¡æ£" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "走査å‰ã«ã‚¹ã‚ャナã®æ ¡æ£ã‚’強制ã™ã‚‹" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "グレースケール走査" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "カラーã®ä»£ã‚ã‚Šã«ã€ã‚°ãƒ¬ãƒ¼ã‚¹ã‚±ãƒ¼ãƒ«ã§èµ°æŸ»ã—ã¾ã™ã€‚" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "アナãƒã‚°åˆ©å¾—" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "CCDé…列ã®ã‚¢ãƒŠãƒã‚°åˆ©å¾—ã‚’å¢—åŠ ã¾ãŸã¯æ¸›å°‘" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "ã‚¬ãƒ³ãƒžæ ¡æ£" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "ガンマ補æ£ã•ã‚ŒãŸå¤‰æ›ã‚«ãƒ¼ãƒ–ã‚’é¸æŠž" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "フラットベッド" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "ADF表é¢" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "ADFè£é¢" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "ADF両é¢" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "ADF表é¢" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, fuzzy, no-c-format msgid "Card Back" msgstr "ADFè£é¢" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "両é¢" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "赤" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "ç·‘" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "é’" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "増強" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "増強" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "増強" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr " ãªã—" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "片é¢" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "両é¢" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "é€éŽãƒ¦ãƒ‹ãƒƒãƒˆ" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "自動原稿é€ã‚Šè£…ç½®" @@ -1740,7 +1751,7 @@ msgstr "インクジェットプリンタ" msgid "CRT monitors" msgstr "CRTモニター" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1804,8 +1815,9 @@ msgstr "A4" msgid "Max" msgstr "最大" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1977,17 +1989,17 @@ msgstr "スã‚ャナーãŒä½¿ã†ã¹ãズーム値を定義" msgid "Quick format" msgstr "簡易フォーマット" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "å…‰å¦è£…ç½®" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "排出" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "ADFã®æ›¸é¡žã‚’排出ã™ã‚‹" @@ -2002,12 +2014,14 @@ msgstr "自動排出" msgid "Eject document after scanning" msgstr "走査後ã€æ›¸é¡žã‚’排出" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "ADFモード" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "ADFモードã®é¸æŠžï¼ˆç‰‡é¢ã€ä¸¡é¢ï¼‰" @@ -2054,14 +2068,14 @@ msgstr "" "スã‚ャンコマンドをé€ä¿¡å¾Œã€å®Ÿéš›ã«èµ°æŸ»å‡¦ç†ãŒå§‹ã¾ã‚‹ã€ã‚¹ã‚ャナーã®ãƒœã‚¿ãƒ³ãŒæŠ¼" "ã•ã‚Œã‚‹ã®ã‚’ã¾ã¤ã€‚" -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2084,492 +2098,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "ユーザ定義" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "ADFã®æ›¸é¡žã‚’排出ã™ã‚‹" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "補æ£ã‚’ã—ãªã„" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "ガンマ補æ£ã‚’無効" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "オン" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "オフ" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "ディザー" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "エラー拡散" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "ホワイトレベル" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "黒レベル" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "æ¡ä»¶ä»˜ã" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "æ°´å¹³ã®" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "æ°´å¹³ã®" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "æ°´å¹³ã®" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "åž‚ç›´ã®" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "åž‚ç›´ã®" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "ADF表é¢" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, fuzzy, no-c-format msgid "Back" msgstr "ADFè£é¢" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "網版" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "較æ£ã®å®Ÿè¡Œ" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "ç”»åƒå¼·èª¿" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "彩度" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "ç·šç”»ã®èµ°æŸ»ã§é–¾å€¤ã®è‡ªå‹•åˆ¤å®šã‚’有効ã«ã™ã‚‹" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "é¡åƒç”»åƒ" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "æ°´å¹³ã«é¡åƒã‚’ã¨ã‚‹ã€‚" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "ホワイトレベルã®é’値" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "赤レベルã®åˆ¶å¾¡" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "カラーフィルタ" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "スムージング" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "ガンマ値" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "閾値" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "閾値" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "ノイズ除去" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "補æ£ã‚’ã—ãªã„" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "補æ£ã‚’ã—ãªã„" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "ADFã®ã‚«ãƒãƒ¼ãŒé–‹ã„ã¦ã„ã¾ã™" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "上級オプション" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "補æ£ã‚’ã—ãªã„" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "å–り出ã—å£" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "フィーダーモード" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2577,65 +2611,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "ランプをオフã«ã™ã‚‹æ™‚é–“" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "赤オフセット" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "緑オフセット" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "緑オフセット" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, fuzzy, no-c-format msgid "Low Memory" msgstr "メモリä¸è¶³" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2644,374 +2678,362 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "両é¢ã‚¹ã‚ャン" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "上級オプション" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "ノイズ除去" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "ç´™ã‹ã‚‰" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "ç´™ã‹ã‚‰" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "ç´™ã‹ã‚‰" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "ç´™ã‹ã‚‰" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "スã‚ャナーã®ã‚«ãƒãƒ¼ãŒé–‹ã„ã¦ã„ã¾ã™" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "手動焦点ä½ç½®" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "手動焦点ä½ç½®" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "ãƒãƒ¼ãƒ‰ã‚¦ã‚¨ã‚¢ãƒã‚§ãƒƒã‚¯ã‚¨ãƒ©ãƒ¼" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "ホワイトレベル" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "濃度制御" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "濃度制御" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "両é¢ã‚¹ã‚ャン" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "è¿½åŠ " -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3020,44 +3042,44 @@ msgstr "" "水平解åƒåº¦ãŒåž‚直解åƒåº¦ã‚ˆã‚Šä½Žã„よã†ãªé«˜è§£åƒåº¦ã‚’使ã†ã¨ãã¯ã€æ°´å¹³" "interpolationを無効ã«ã—ã¾ã™ã€‚" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "カラーフィルタ" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "æ ¡æ£" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "較æ£ã‚’「ã™ãã«ã€å®Ÿè¡Œã—ã¾ã™" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "較æ£ãƒ‡ãƒ¼ã‚¿ã®ã‚ャッシュ" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "ランプをオフã«ã™ã‚‹æ™‚é–“" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3066,89 +3088,108 @@ msgstr "" "ランプã¯æŒ‡å®šã•ã‚ŒãŸæ™‚間(分)ãŒçµŒéŽã—ãŸã‚‰ã‚ªãƒ•ã«ã•ã‚Œã¾ã™ã€‚値ãŒï¼ã®ã¨ãã¯ã€" "ã“ã®æ©Ÿèƒ½ã¯åƒãã¾ã›ã‚“。" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "ダーク補æ£æ™‚ã«ãƒ©ãƒ³ãƒ—をオフã«ã™ã‚‹" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, fuzzy, no-c-format msgid "The lamp will be turned off during scan. " msgstr "走査ã—ãŸå¾Œã€ãƒ©ãƒ³ãƒ—ãŒã‚ªãƒ•ã«ãªã‚‹ã¾ã§ã®æ™‚間(分)" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "ファイルボタン" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "OCRボタン" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "é›»æºãƒœã‚¿ãƒ³" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "é›»åメールボタン" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "較æ£ã®ã‚¯ãƒªã‚¢" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "走査å‰ã«ã‚¹ã‚ャナã®æ ¡æ£ã‚’強制ã™ã‚‹" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "ボタン" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "較æ£" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "特殊シートを用ã„ãŸè£œæ£ã‚’開始" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "較æ£ã®ã‚¯ãƒªã‚¢" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "æ ¡æ£ã‚ャッシュを消去ã™ã‚‹" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "ç²—æ ¡æ£" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "緑オフセット" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "é€éŽã‚¢ãƒ€ãƒ—ター" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "é€éŽã‚¢ãƒ€ãƒ—ター" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3246,6 +3287,304 @@ msgstr "ガンマ値" msgid "Sets the gamma value of all channels." msgstr "ã™ã¹ã¦ã®ãƒãƒ£ãƒãƒ«ã®ã‚¬ãƒ³ãƒžå€¤ã‚’è¨å®š" +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "上級オプション" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "ç²—" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "密" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "ãƒã‚¤ã‚¨ãƒ«" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "カスタム" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "自動" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSCæ–¹å¼RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPAæ–¹å¼RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "パススルー" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSCã®ã‚°ãƒ¬ãƒ¼" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPAã®ã‚°ãƒ¬ãƒ¼" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "é…ã„" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "普通" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "速ã„" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "超高速" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2ピクセル" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4ピクセル" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8ピクセル" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "å°åˆ·" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "スライド" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "フィルムã®ä¸€ç‰‡" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "æ¡ä»¶ä»˜ã" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "実験的" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "é®®é‹åŒ–" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "é®®é‹åŒ–値をè¨å®š" + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "自動閾値" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "ç·šç”»ã®èµ°æŸ»ã§é–¾å€¤ã®è‡ªå‹•åˆ¤å®šã‚’有効ã«ã™ã‚‹" + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "スムージングフィルタをé¸æŠž" + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "走査後ã€ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’å–り出ã™" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "走査後ã«ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’å–り出ã™ã€‚" + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "書類をæ›ãˆã‚‹ã€‚" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "書類をå–ã‚Šæ›ãˆã‚‹ã€‚" + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "å–り出ã—" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "書類ã®å–り出ã—" + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "æ ¡æ£ãƒ—ãƒã‚»ã‚¹ã‚’開始。" + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "メディア" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "メディアã®ç¨®é¡žã‚’è¨å®š" + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "露出時間" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "カラーマトリックス" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "スã‚ャナーã®ã‚«ãƒ©ãƒ¼ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ã‚’è¨å®šã™ã‚‹ã€‚" + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "カスタムカラーマトリックス" + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "モノクãƒãƒ»ã‚«ãƒ©ãƒ¼ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "グレースケール走査ã®ã‚«ã‚¹ã‚¿ãƒ ・カラーマトリックス" + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "æ°´å¹³ã®é¡åƒ" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "æ°´å¹³ã«é¡åƒã‚’ã¨ã‚‹ã€‚" + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "åž‚ç›´é¡åƒ" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "åž‚ç›´ã«é¡åƒã‚’ã¨ã‚‹ã€‚" + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "オプションã®æ›´æ–°" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "オプションを更新ã™ã‚‹ã€‚" + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8ビット出力" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "å‰é¢ãƒœã‚¿ãƒ³ã‚’å¾…ã¤" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "ランプã®åœæ¢" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "スã‚ャナーã®ãƒ©ãƒ³ãƒ—ã‚’åœæ¢ã™ã‚‹ã€‚" + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3256,12 +3595,6 @@ msgstr "é…置グループ" msgid "Scan Mode Group" msgstr "スã‚ャンモードグループ" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "スライド" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3269,12 +3602,12 @@ msgstr "スã‚ャナーモデル" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "イメージカラーãŒå転ã•ã‚Œã¾ã™" #: backend/hp3900_sane.c:1436 @@ -3462,11 +3795,6 @@ msgstr "ランプã®ã‚ªãƒ•ï¼ã‚ªãƒ³ã‚’切り替ãˆ" msgid "Calibrates for black and white level." msgstr "白黒レベルを較æ£" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3577,293 +3905,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "上級オプション" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "ç²—" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "密" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "ãƒã‚¤ã‚¨ãƒ«" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "カスタム" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "自動" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSCæ–¹å¼RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPAæ–¹å¼RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "パススルー" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSCã®ã‚°ãƒ¬ãƒ¼" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPAã®ã‚°ãƒ¬ãƒ¼" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "é…ã„" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "普通" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "速ã„" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "超高速" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2ピクセル" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4ピクセル" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8ピクセル" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "å°åˆ·" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "フィルムã®ä¸€ç‰‡" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "æ¡ä»¶ä»˜ã" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "実験的" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "é®®é‹åŒ–" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "é®®é‹åŒ–値をè¨å®š" - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "自動閾値" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "ç·šç”»ã®èµ°æŸ»ã§é–¾å€¤ã®è‡ªå‹•åˆ¤å®šã‚’有効ã«ã™ã‚‹" - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "スムージングフィルタをé¸æŠž" - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "走査後ã€ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’å–り出ã™" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "走査後ã«ãƒ¡ãƒ‡ã‚£ã‚¢ã‚’å–り出ã™ã€‚" - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "書類をæ›ãˆã‚‹ã€‚" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "書類をå–ã‚Šæ›ãˆã‚‹ã€‚" - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "å–り出ã—" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "書類ã®å–り出ã—" - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "æ ¡æ£ãƒ—ãƒã‚»ã‚¹ã‚’開始。" - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "メディア" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "メディアã®ç¨®é¡žã‚’è¨å®š" - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "露出時間" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "カラーマトリックス" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "スã‚ャナーã®ã‚«ãƒ©ãƒ¼ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹ã‚’è¨å®šã™ã‚‹ã€‚" - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "カスタムカラーマトリックス" - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "モノクãƒãƒ»ã‚«ãƒ©ãƒ¼ãƒžãƒˆãƒªãƒƒã‚¯ã‚¹" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "グレースケール走査ã®ã‚«ã‚¹ã‚¿ãƒ ・カラーマトリックス" - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "æ°´å¹³ã®é¡åƒ" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "æ°´å¹³ã«é¡åƒã‚’ã¨ã‚‹ã€‚" - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "åž‚ç›´é¡åƒ" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "åž‚ç›´ã«é¡åƒã‚’ã¨ã‚‹ã€‚" - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "オプションã®æ›´æ–°" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "オプションを更新ã™ã‚‹ã€‚" - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8ビット出力" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "å‰é¢ãƒœã‚¿ãƒ³ã‚’å¾…ã¤" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "ランプã®åœæ¢" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "スã‚ャナーã®ãƒ©ãƒ³ãƒ—ã‚’åœæ¢ã™ã‚‹ã€‚" - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3962,7 +4003,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4130,9 +4171,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "ç·šç”»" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4261,7 +4302,7 @@ msgstr "イメージ強調をè¨å®š" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "ガンマ" @@ -4328,11 +4369,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4364,12 +4405,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "高密度å°åˆ·" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "低密度å°åˆ·" #: backend/kvs40xx_opt.c:243 @@ -4392,6 +4433,13 @@ msgstr "普通" msgid "Enhanced mode" msgstr "増強" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4451,7 +4499,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4486,12 +4534,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4501,13 +4549,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "é¡åƒç”»åƒ" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4544,52 +4592,52 @@ msgstr "8x8 ãƒã‚¤ã‚¨ãƒ«" msgid "8x8 Vertical Line" msgstr "8x8縦ã®ç·š" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "利得" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "カラーãƒãƒ£ãƒãƒ«ã®åˆ©å¾—è¨å®š" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "グレー利得" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "グレーãƒãƒ£ãƒãƒ«åˆ©å¾—ã‚’è¨å®š" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "赤利得" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "赤ãƒãƒ£ãƒãƒ«åˆ©å¾—ã‚’è¨å®š" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "緑利得" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "ç·‘ãƒãƒ£ãƒãƒ«åˆ©å¾—ã‚’è¨å®š" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "é’利得" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "é’ãƒãƒ£ãƒãƒ«åˆ©å¾—ã‚’è¨å®š" @@ -4675,7 +4723,7 @@ msgstr "1ページ" msgid "All pages" msgstr "全ページ" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "シートフィーダスã‚ャナー" @@ -5169,39 +5217,44 @@ msgid "" "40 seconds warm-up time." msgstr "" -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "較æ£ã®ã‚¯ãƒªã‚¢" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "ãƒã‚¬ãƒ•ã‚£ãƒ«ãƒ " -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "ãƒã‚¬" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, fuzzy, no-c-format msgid "48 bits color" msgstr "高精彩" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "ボタン制御走査" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5209,40 +5262,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "ボタン状態ã®æ›´æ–°" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "ボタン1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "ボタン2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5331,7 +5384,7 @@ msgstr "アナãƒã‚°ãƒ•ãƒãƒ³ãƒˆã‚¨ãƒ³ãƒ‰" msgid "Red gain value of the AFE" msgstr "AFEã®èµ¤ã®åˆ©å¾—値" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "赤オフセット" @@ -5598,7 +5651,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "ã“ã®ã‚ªãƒ—ションã¯ã€ã‚¹ã‚ャナーボタンã®çŠ¶æ…‹ã‚’åæ˜ ã—ã¾ã™ã€‚" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "ランプをオン" @@ -5608,12 +5661,12 @@ msgstr "ランプをオン" msgid "Turn on scanner lamp" msgstr "スã‚ャナーã®ãƒ©ãƒ³ãƒ—をオンã«ã™ã‚‹ã€‚" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "ランプオフ" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "スã‚ャナーã®ãƒ©ãƒ³ãƒ—をオフã«ã™ã‚‹ã€‚" @@ -5751,13 +5804,13 @@ msgstr "焦点ä½ç½®" #: backend/snapscan-options.c:930 #, no-c-format -msgid "Colour lines per read" +msgid "Color lines per read" msgstr "" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" -msgstr "" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" +msgstr "グレースケール走査" #: backend/stv680.c:974 #, no-c-format @@ -6352,52 +6405,52 @@ msgstr "" msgid "Define calibration mode" msgstr "" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "" @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.12\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-12-17 23:01+0100\n" "Last-Translator: Sigurd Stordal <polarbear42@phreaker.net>\n" "Language-Team: \n" @@ -25,31 +25,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometri" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Forbedring" @@ -83,7 +83,7 @@ msgid "Bit depth" msgstr "Bit dybde" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "" @@ -124,7 +124,7 @@ msgid "Bottom-right y" msgstr "Bunn-høyre y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Skanoppløsning" @@ -279,7 +279,7 @@ msgstr "Filnavn" msgid "Halftone pattern size" msgstr "" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "" @@ -289,10 +289,10 @@ msgstr "" msgid "Bind X and Y resolution" msgstr "" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativ" @@ -415,7 +415,7 @@ msgstr "Lampen slÃ¥s av ved avslutning" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" @@ -720,8 +720,8 @@ msgid "Analog gamma-correction for blue" msgstr "" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Varm opp lampen før skanning" #: include/sane/saneopts.h:417 @@ -871,7 +871,7 @@ msgstr "" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -965,7 +965,7 @@ msgstr "Bare utfør skygge-korrigering" #, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" @@ -992,80 +992,40 @@ msgstr "Full skan" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" -msgstr "" - -#: backend/canon630u.c:159 -#, fuzzy, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibrering" - -#: backend/canon630u.c:160 -#, fuzzy, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Grov kalibrering kun for første skan" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "GrÃ¥skala scan" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Gjør et grÃ¥skala heller enn farge scan" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" +msgid "Correction according to transparency ratio" msgstr "" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "Gamma korreksjon" - -#: backend/canon630u.c:348 -#, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Velger den gamma korrigerte overførsels kurven" - -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Raw" +msgid "Correction according to film type" msgstr "" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 #: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format msgid "Fine color" msgstr "" -#: backend/canon.c:169 +#: backend/canon-sane.c:776 backend/canon.c:176 #, fuzzy, no-c-format -msgid "No transparency correction" -msgstr "Farge korreksjon" - -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" +msgid "Negatives" +msgstr "Negativ" -#: backend/canon.c:171 backend/canon-sane.c:674 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format -msgid "Correction according to transparency ratio" +msgid "Raw" msgstr "" -#: backend/canon.c:176 backend/canon-sane.c:776 +#: backend/canon.c:169 #, fuzzy, no-c-format -msgid "Negatives" -msgstr "Negativ" +msgid "No transparency correction" +msgstr "Farge korreksjon" #: backend/canon.c:176 #, fuzzy, no-c-format @@ -1201,7 +1161,7 @@ msgstr "" #: backend/canon.c:460 #, no-c-format -msgid "option not connect" +msgid "option not correct" msgstr "" #: backend/canon.c:474 @@ -1489,133 +1449,184 @@ msgstr "Filmtype" msgid "Select the film type" msgstr "" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, fuzzy, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibrering" + +#: backend/canon630u.c:160 +#, fuzzy, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Grov kalibrering kun for første skan" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "GrÃ¥skala scan" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Gjør et grÃ¥skala heller enn farge scan" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gamma korreksjon" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Velger den gamma korrigerte overførsels kurven" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Rød" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Grønn" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "BlÃ¥" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Forbedring" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Forbedring" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Forbedring" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ingen" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "" @@ -1727,7 +1738,7 @@ msgstr "Blekkskrivere" msgid "CRT monitors" msgstr "" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1791,8 +1802,9 @@ msgstr "" msgid "Max" msgstr "Maks" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1964,17 +1976,17 @@ msgstr "" msgid "Quick format" msgstr "" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Tilleggsutstyr" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Utløs" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Utløs arket i ADF" @@ -1989,12 +2001,14 @@ msgstr "Automatisk utløsning" msgid "Eject document after scanning" msgstr "Løs ut dokoment etter skanning" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2041,14 +2055,14 @@ msgstr "" "Etter at kommandoen for skan er sendt, vent til skannerens knapp " "ertrykket før skanings prossesen startes." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2071,492 +2085,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "Brukerdefinert" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Utløs arket i ADF" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Ingen korrigering" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Gamma korreksjon" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "HvitnivÃ¥" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "SvartnivÃ¥" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Grov kalibrering" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Kalibrering" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Speilbilde" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Speilbilde" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "HvitnivÃ¥ for blÃ¥" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Kontrollerer rød-nivÃ¥" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Fargestrektegning" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Gammaverdi" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Støyreduksjon" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Ingen korrigering" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Ingen korrigering" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Spesielle valg" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Ingen korrigering" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Lampe pÃ¥" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2564,65 +2598,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Lampe av" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Lampe av" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, fuzzy, no-c-format msgid "Green offset" msgstr "Lampe av" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Lampe av" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, fuzzy, no-c-format msgid "Blue offset" msgstr "Lampe av" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Kontrast blÃ¥kanal" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2631,507 +2665,514 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Full skan" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Spesielle valg" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Støyreduksjon" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Fra papir" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Manuell førfokus" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Manuell førfokus" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "Skanoppløsning" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "HvitnivÃ¥" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "lav densitets utskrift" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Full skan" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Fargestrektegning" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibrering" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Kvalitets kalibrering" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Kalibrering" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, fuzzy, no-c-format msgid "Lamp off time" msgstr "Lampe av" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " "of 0 means, that the lamp won't be turned off." msgstr "" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Grov kalibrering" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "Vent pÃ¥ knappen" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "Vent pÃ¥ knappen" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Vent pÃ¥ knappen" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Grov kalibrering" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Grov kalibrering kun for første skan" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, fuzzy, no-c-format msgid "Buttons" msgstr "Knappstatus" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, fuzzy, no-c-format msgid "Calibrate" msgstr "Kalibrering" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Grov kalibrering" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Grov kalibrering" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Kalibrering" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Grov kalibrering" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Lampe av" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "" +#: backend/genesys/genesys.h:80 +#, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3222,6 +3263,304 @@ msgstr "Gammaverdi" msgid "Sets the gamma value of all channels." msgstr "" +#: backend/hp-option.c:2987 +#, fuzzy, no-c-format +msgid "Advanced Options" +msgstr "Spesielle valg" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Grov" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fin" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Valgfri" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatisk" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC-grÃ¥" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA-grÃ¥" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Treig" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rask" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "" + +#: backend/hp-option.c:3178 +#, fuzzy, no-c-format +msgid "Film-strip" +msgstr "Filmtype" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "" + +#: backend/hp-option.h:60 +#, fuzzy, no-c-format +msgid "Sharpening" +msgstr "Skarphet" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "" + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "" + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "" + +#: backend/hp-option.h:80 +#, fuzzy, no-c-format +msgid "Unloads the media after a scan." +msgstr "Last bildet som grÃ¥skala" + +#: backend/hp-option.h:85 +#, fuzzy, no-c-format +msgid "Change document" +msgstr "Forbedring" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "" + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "" + +#: backend/hp-option.h:98 +#, fuzzy, no-c-format +msgid "Start calibration process." +msgstr "Grov kalibrering" + +#: backend/hp-option.h:103 +#, fuzzy, no-c-format +msgid "Media" +msgstr "Middels" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "" + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, fuzzy, no-c-format +msgid "Color Matrix" +msgstr "Fargemønster" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Kontrast rødkanal" + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "" + +#: backend/hp-option.h:132 +#, fuzzy, no-c-format +msgid "Mono Color Matrix" +msgstr "Fargemønster" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "" + +#: backend/hp-option.h:138 +#, fuzzy, no-c-format +msgid "Mirror horizontal" +msgstr "Speilbilde" + +#: backend/hp-option.h:139 +#, fuzzy, no-c-format +msgid "Mirror image horizontally." +msgstr "Speilbilde" + +#: backend/hp-option.h:144 +#, fuzzy, no-c-format +msgid "Mirror vertical" +msgstr "Speilbilde" + +#: backend/hp-option.h:145 +#, fuzzy, no-c-format +msgid "Mirror image vertically." +msgstr "Speilbilde" + +#: backend/hp-option.h:150 +#, fuzzy, no-c-format +msgid "Update options" +msgstr "Spesielle valg" + +#: backend/hp-option.h:151 +#, fuzzy, no-c-format +msgid "Update options." +msgstr "Spesielle valg" + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "SlÃ¥ av skanner lampen." + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3232,12 +3571,6 @@ msgstr "Geometri" msgid "Scan Mode Group" msgstr "" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3245,12 +3578,12 @@ msgstr "" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3431,11 +3764,6 @@ msgstr "" msgid "Calibrates for black and white level." msgstr "" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3546,293 +3874,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, fuzzy, no-c-format -msgid "Advanced Options" -msgstr "Spesielle valg" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Grov" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fin" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Valgfri" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatisk" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC-grÃ¥" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA-grÃ¥" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Treig" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rask" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "" - -#: backend/hp-option.c:3178 -#, fuzzy, no-c-format -msgid "Film-strip" -msgstr "Filmtype" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "" - -#: backend/hp-option.h:60 -#, fuzzy, no-c-format -msgid "Sharpening" -msgstr "Skarphet" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "" - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "" - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "" - -#: backend/hp-option.h:80 -#, fuzzy, no-c-format -msgid "Unloads the media after a scan." -msgstr "Last bildet som grÃ¥skala" - -#: backend/hp-option.h:85 -#, fuzzy, no-c-format -msgid "Change document" -msgstr "Forbedring" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "" - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "" - -#: backend/hp-option.h:98 -#, fuzzy, no-c-format -msgid "Start calibration process." -msgstr "Grov kalibrering" - -#: backend/hp-option.h:103 -#, fuzzy, no-c-format -msgid "Media" -msgstr "Middels" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "" - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, fuzzy, no-c-format -msgid "Color Matrix" -msgstr "Fargemønster" - -#: backend/hp-option.h:121 -#, fuzzy, no-c-format -msgid "Set the scanners color matrix." -msgstr "Kontrast rødkanal" - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "" - -#: backend/hp-option.h:132 -#, fuzzy, no-c-format -msgid "Mono Color Matrix" -msgstr "Fargemønster" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "" - -#: backend/hp-option.h:138 -#, fuzzy, no-c-format -msgid "Mirror horizontal" -msgstr "Speilbilde" - -#: backend/hp-option.h:139 -#, fuzzy, no-c-format -msgid "Mirror image horizontally." -msgstr "Speilbilde" - -#: backend/hp-option.h:144 -#, fuzzy, no-c-format -msgid "Mirror vertical" -msgstr "Speilbilde" - -#: backend/hp-option.h:145 -#, fuzzy, no-c-format -msgid "Mirror image vertically." -msgstr "Speilbilde" - -#: backend/hp-option.h:150 -#, fuzzy, no-c-format -msgid "Update options" -msgstr "Spesielle valg" - -#: backend/hp-option.h:151 -#, fuzzy, no-c-format -msgid "Update options." -msgstr "Spesielle valg" - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "SlÃ¥ av skanner lampen." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3931,7 +3972,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4099,9 +4140,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Strektegning" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4228,7 +4269,7 @@ msgstr "" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "" @@ -4295,11 +4336,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4331,12 +4372,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Høy densitets utskrift" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "lav densitets utskrift" #: backend/kvs40xx_opt.c:243 @@ -4359,6 +4400,13 @@ msgstr "Skanhastighet" msgid "Enhanced mode" msgstr "Forbedring" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4418,7 +4466,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4453,12 +4501,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4468,13 +4516,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Speilbilde" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4511,52 +4559,52 @@ msgstr "" msgid "8x8 Vertical Line" msgstr "" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, fuzzy, no-c-format msgid "Gray gain" msgstr "Grønn" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, fuzzy, no-c-format msgid "Sets gray channel gain" msgstr "Kontrast grønnkanal" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, fuzzy, no-c-format msgid "Red gain" msgstr "Rødbalanse" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, fuzzy, no-c-format msgid "Sets red channel gain" msgstr "Kontrast rødkanal" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, fuzzy, no-c-format msgid "Green gain" msgstr "Grønn" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, fuzzy, no-c-format msgid "Sets green channel gain" msgstr "Kontrast grønnkanal" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, fuzzy, no-c-format msgid "Blue gain" msgstr "BlÃ¥" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, fuzzy, no-c-format msgid "Sets blue channel gain" msgstr "Kontrast blÃ¥kanal" @@ -4642,7 +4690,7 @@ msgstr "En side" msgid "All pages" msgstr "Alle sider" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "" @@ -5138,39 +5186,44 @@ msgid "" "40 seconds warm-up time." msgstr "" -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Grov kalibrering" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Negativ Film" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativ" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5178,40 +5231,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, fuzzy, no-c-format msgid "Update button state" msgstr "Knappstatus" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, fuzzy, no-c-format msgid "Button 1" msgstr "Knappstatus" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, fuzzy, no-c-format msgid "Button 2" msgstr "Knappstatus" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5300,7 +5353,7 @@ msgstr "" msgid "Red gain value of the AFE" msgstr "" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, fuzzy, no-c-format msgid "Red offset" msgstr "Lampe av" @@ -5555,7 +5608,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lampe pÃ¥" @@ -5565,12 +5618,12 @@ msgstr "Lampe pÃ¥" msgid "Turn on scanner lamp" msgstr "SlÃ¥ pÃ¥ skanner lampen" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Lampe av" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "SlÃ¥ av skanner lampen" @@ -5705,14 +5758,14 @@ msgid "Focus point" msgstr "Fokuseringposisjon" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" -msgstr "" +#, fuzzy, no-c-format +msgid "Color lines per read" +msgstr "Fargestrektegning" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" -msgstr "" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" +msgstr "GrÃ¥skala scan" #: backend/stv680.c:974 #, no-c-format @@ -6296,52 +6349,52 @@ msgstr "" msgid "Define calibration mode" msgstr "" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, fuzzy, no-c-format msgid "Gray offset" msgstr "Lampe av" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, fuzzy, no-c-format msgid "Sets gray channel offset" msgstr "Kontrast grønnkanal" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, fuzzy, no-c-format msgid "Sets red channel offset" msgstr "Kontrast rødkanal" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, fuzzy, no-c-format msgid "Sets green channel offset" msgstr "Kontrast grønnkanal" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, fuzzy, no-c-format msgid "Sets blue channel offset" msgstr "Kontrast blÃ¥kanal" @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends.nl\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2019-07-26 13:38+0900\n" "Last-Translator: Olaf Meeuwissen <paddy-hack@member.fsf.org>\n" "Language-Team:\n" @@ -30,31 +30,31 @@ msgid "Standard" msgstr "Standaard" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometrie" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Kleurverbetering" @@ -88,7 +88,7 @@ msgid "Bit depth" msgstr "Bitdiepte" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Scanmodus" @@ -129,7 +129,7 @@ msgid "Bottom-right y" msgstr "Rechtsonder y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Scanresolutie" @@ -284,7 +284,7 @@ msgstr "Bestandsnaam" msgid "Halftone pattern size" msgstr "Grootte van het halftoonpatroon" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Halftoonpatroon" @@ -294,10 +294,10 @@ msgstr "Halftoonpatroon" msgid "Bind X and Y resolution" msgstr "Combineer X- en Y-resolutie" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negatief" @@ -418,9 +418,9 @@ msgid "Lamp off at exit" msgstr "Lamp aan het einde uitschakelen" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Alleen-lezen optie, die aangeeft hoeveel opties een apparaat ondersteunt." @@ -762,8 +762,8 @@ msgid "Analog gamma-correction for blue" msgstr "Analoge gammacorrectie voor blauw" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Warm de lamp op alvorens te scannen" #: include/sane/saneopts.h:417 @@ -914,8 +914,8 @@ msgid "Operation not supported" msgstr "Handeling niet ondersteund" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "Handeling was geannuleerd" #: backend/sane_strstatus.c:68 @@ -1009,10 +1009,10 @@ msgid "Only perform shading-correction" msgstr "Voer alleen een schaduwcorrectie uit" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Indien ingeschakeld, wordt tijdens het kalibreren alleen de schaduw-" @@ -1041,83 +1041,43 @@ msgid "Duplex scan" msgstr "Dubbelzijdige scan" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "Dubbelzijdige scan scant beide zijden van een document" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibreer scanner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Dwing te kalibreren voor het scannen" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Grijstrapscan" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Voer een grijstrap-, in plaats van een kleurenscan uit" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analoog bereik" +msgid "Correction according to transparency ratio" +msgstr "Correctie op basis van de transparantieverhouding" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Vergroot of verklein het analoge bereik van de CCD-sensor" +msgid "Correction according to film type" +msgstr "Correctie op basis van filmtype" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Gammacorrectie" +msgid "Fine color" +msgstr "Fraaie kleuren" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Kiest de gamma gecorrigeerde overdrachtscurve" +msgid "Negatives" +msgstr "Negatieven" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Ongecomprimeerd" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Fraaie kleuren" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Ongecorrigeerde transparantie" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Correctie op basis van filmtype" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Correctie op basis van de transparantieverhouding" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negatieven" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1252,8 +1212,8 @@ msgid "invalid bit IDENTIFY message" msgstr "ongeldig onderdeel in IDENTIFY boodschap" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "optie onjuist" #: backend/canon.c:474 @@ -1543,133 +1503,184 @@ msgstr "Selecteert filmtype" msgid "Select the film type" msgstr "Selecteert het filmtype" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibreer scanner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Dwing te kalibreren voor het scannen" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Grijstrapscan" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Voer een grijstrap-, in plaats van een kleurenscan uit" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analoog bereik" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Vergroot of verklein het analoge bereik van de CCD-sensor" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gammacorrectie" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Kiest de gamma gecorrigeerde overdrachtscurve" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Flatbed" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "Automatische documentinvoer voorzijde" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "Automatische documentinvoer achterzijde" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Automatische documentinvoer dubbelzijdig" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "Kaart voorzijde" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "Kaart achterzijde" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "Kaart dubbelzijdig" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Rood" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Groen" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Blauw" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Verbeter rood" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Verbeter groen" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Verbeter blauw" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Geen" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "Softwarematig over te slaan percentage lege pagina's" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "Verzoek het stuurprogramma pagina's met weinig dekking te negeren" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "enkelzijdig" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Dubbelzijdig" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Filmeenheid" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatische documentinvoer" @@ -1781,7 +1792,7 @@ msgstr "Inkjetprinters" msgid "CRT monitors" msgstr "CRT-monitoren" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1845,8 +1856,9 @@ msgstr "A4" msgid "Max" msgstr "Maximaal" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2018,17 +2030,17 @@ msgstr "Definieert de vergrotingsfactor die de scanner zal gebruiken" msgid "Quick format" msgstr "Snelle opmaak" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Optioneel hulpstuk" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Uitwerpen" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Werp het document in de automatische documentinvoer uit" @@ -2043,12 +2055,14 @@ msgstr "Automatische uitworp" msgid "Eject document after scanning" msgstr "Werp het document uit na het scannen" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Automatische documentinvoer Modus" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2100,16 +2114,16 @@ msgstr "" "Begin pas met scannen als eerst het scancommando naar de scanner is " "gestuurd en daarna de knop van de scanner is ingedrukt." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Infrarood" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "TPU8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Infrarood" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2130,243 +2144,263 @@ msgstr "Ingebouwd CCT profiel" msgid "User defined CCT profile" msgstr "Door gebruiker gedefinieerd CCT profiel" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Werp het document in de automatische documentinvoer uit" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Geen correctie" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Schakel gammacorrectie uit" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Aan" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Uit" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Dither" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Verspreiding" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Wit" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Zwart" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Voortzetten" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Stoppen" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Horizontaal" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Horizontaal vet" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Horizontaal smal" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Verticaal" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Verticaal vet" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "Van boven naar beneden" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "Van beneden naar boven" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Voorzijde" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Achterzijde" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "Gammafunctie exponent" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "Verandert de intensiteit van de middentonen" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "GBF" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "Gespiegeld beeld formaat" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "Halftoon type" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "Regeltype van het halftoon filter" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "Regelpatroon van het halftoon filter" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "Contour" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, no-c-format msgid "Perform outline extraction" msgstr "Extract contouren" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "Nadruk" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "Negatief naar geleidelijk of positief naar scherp beeld" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, no-c-format msgid "Separation" msgstr "Scheiding" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "Schakel automatische scheiding tussen beeld en tekst in" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "Spiegelen" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "Spiegel het resulterende beeld horizontaal" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, no-c-format msgid "White level follower" msgstr "Witwaarde volger" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, no-c-format msgid "Control white level follower" msgstr "Regel de witwaarde volger" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, no-c-format msgid "BP filter" msgstr "BP filter" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "Verbeterd de kwaliteit van hoog resolutie bal-punt pen tekst" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Verzachten" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "Schakelt verzachting in om OCR te verbeteren" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, no-c-format msgid "Gamma curve" msgstr "Gammakromme" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" "Gammakromme, van licht naar donker, maar bovenste twee werken misschien " "niet" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Drempel curve" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" @@ -2374,111 +2408,111 @@ msgstr "" "Drempel curve, van licht naar donker, maar bovenste twee zijn misschien " "niet liniair" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "Drempel wit" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "Stelt schermpunten in overeenkomstig de drempel voor wit ipv zwart" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "Ruisverwijdering" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "Matrix 5x5" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "Verwijder ruis met een 5 pixel vierkant" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "Matrix 4x4" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "Verwijder ruis met een 4 pixel vierkant" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "Matrix 3x3" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "Verwijder ruis met een 3 pixel vierkant" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "Matrix 2x2" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "Verwijder 2 beeldpunten in een vierkant ruis" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "Variantie" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "Stelt SDTC variantie rato in (gevoeligheid), 0 is gelijk aan 127" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, no-c-format msgid "Auto width detection" msgstr "Automatische breedte herkenning" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "Scanner herkent paper zijden. Kan de scansnelheid verminderen." -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, no-c-format msgid "Auto length detection" msgstr "Automatische lengte herkenning" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" "Scanner herkent onderzijde van het papier. Kan sommige frontends in de " "war brengen." -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "Compressie" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" "Schakelt gecomprimeerde gegevens in. Kan je front-end programma laten " "crashen." -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "Compressie argument" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " @@ -2487,106 +2521,106 @@ msgstr "" "Niveau van JPEG compressie. 1 is klein bestand, 7 is groot bestand. 0 " "(standaard) is hetzelfde als 4" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "DF actie" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "Actie die volgt op dubbele doorvoer fout" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "DF scheefheid" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "Schakel dubbele doorvoer fout in als gevolg van scheefheid" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "DF dikte" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Stelt dubbele doorvoer fout in als gevolg van papierdikte" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "DF lengte" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "Stelt dubbele doorvoer fout in als gevolg van papierlengte" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "DF lengte verschil" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "Verschil in papier lengte om dubbele doorvoer fout te veroorzaken" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "DF herstel modus" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "Vraag de scanner de doorvoer om te keren bij papier opstopping" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "Papier protectie" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "Vraag de scanner opstoppingen in de ADF te voorspellen " -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, no-c-format msgid "Advanced paper protection" msgstr "Geavanceerde papier protectie" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" "Vraag de scanner opstoppingen in de ADF te voorspellen met behulp van " "verbeterde sensoren" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, no-c-format msgid "Staple detection" msgstr "Nietjes detectie" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" "Vraag de scanner opstoppingen in de ADF te detecteren die worden " "veroorzaakt door nietjes" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "Achtergrond kleur" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" @@ -2594,12 +2628,12 @@ msgstr "" "Stel de achtergrond kleur van scans in. Kan conflicteren met de " "'overscan' optie" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "Uitvalkleur" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " @@ -2608,34 +2642,34 @@ msgstr "" "One-pass scanners gebruiken slechts een kleur bij grijstrap of binair " "scannen, bruikbaar voor gekleurd papier of inkt." -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "Buffermodus" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" "Vraag de scanner pagina's vanuit de ADF zo snel mogelijk in te lezen in " "het interne geheugen" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "Voorkeuze" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "Vraag de scanner de volgende pagina uit de ADF op te halen" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "Overscan" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2647,24 +2681,24 @@ msgstr "" "oppervlak t.o.v. het papierformaat, om de inzameling van de overige " "kanten toe te staan. Kan conflicteren met 'bgcolor' optie" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "Tijdschakelaar - slaapstand" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" "Tijd in minuten voordat de interne voeding overschakelt naar slaap modus" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "Tijdschakelaar - uitstand" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " @@ -2673,42 +2707,42 @@ msgstr "" "Tijd in minuten voordat de interne voeding de scanner uitschakelt. In " "stappen van 15 minuten. Nul betekent nooit uitschakelen" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, no-c-format msgid "Duplex offset" msgstr "Dubbelzijdige compensatie" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "Pas voor-/achtercompensatie aan" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Groen compensatie" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, no-c-format msgid "Adjust green/red offset" msgstr "Pas groen-/roodcompensatie aan" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Blauw compensatie" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "Pas blauw-/roodcompensatie aan" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "Te weinig geheugen beschikbaar" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2722,12 +2756,12 @@ msgstr "" "gebruikt om het juiste beeld vast te stellen. Deze optie dient " "uitsluitend te worden gebruikt door aangepaste front-end software." -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, no-c-format msgid "Duplex side" msgstr "Duplex zijde" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " @@ -2736,56 +2770,56 @@ msgstr "" "Vertelt welke zijde (0=voorkant, 1=achterkant) van een duplex scan bij " "de volgende aanroep van sane_read wordt geretourneerd." -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "Hardware rechtzetten en afknippen" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "Vraag de scanner pagina's digitaal te roteren en af te knippen." -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Softwarematige scheefheid correctie" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" "Vraag het stuurprogramma scheef getrokken pagina's digitaal te roteren." -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Softwarematige ontspikkel omvang" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" "Maximale diameter van verspreid liggende spikkels, die van het gescande " "beeld moeten worden verwijderd." -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "Softwarematig uitsnijden" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" "Vraag het stuurprogramma randen van pagina's digitaal te verwijderen." -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "Stoppen bij annuleren" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." @@ -2793,105 +2827,105 @@ msgstr "" "Vraag het stuurprogramma de papierdoorvoer te stoppen i.p.v. uit te " "werpen tijdens een annulering" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, no-c-format msgid "Endorser Options" msgstr "Endorser-opties" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "Stuurt de Endorser eenheid aan" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "Endorser" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "Schakel Endorser eenheid in" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "Endorser delen" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "Bepaald maximale Endorser teller waarde" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "Endorser waarde" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "Initiële Endorser teller waarde" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "Endorser stap" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" "Wijzig Endorser teller waarde met deze hoeveelheid voor elke pagina" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "Endorser Y" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "Endorser afdruk compensatie vanaf de bovenkant van het papier" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "Endorser lettertype" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "Endorser afdruk lettertype" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, no-c-format msgid "Endorser direction" msgstr "Endorser richting" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "Endorser afdruk richting" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "Endorser zijde" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" "Endorser afdrukzijde, vereist hardware ondersteuning om te worden " "gewijzigd" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "Endorser tekst" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " @@ -2900,214 +2934,200 @@ msgstr "" "Endorser alfanumerieke afdrukformaat. %05ud of %08ud zal aan het eind " "worden vervangen door de teller waarde." -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "Bovenrand" -#: backend/fujitsu.c:4380 -#, no-c-format -msgid "Paper is pulled partly into adf" +#: backend/fujitsu.c:4384 +#, fuzzy, no-c-format +msgid "Paper is pulled partly into ADF" msgstr "Papier is gedeeltelijk in de ADF getrokken" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "A3 papier" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "A3 papier gedetecteerd" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "B4 papier" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "B4 papier gedetecteerd" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "A4 papier" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "A4 papier gedetecteerd" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "B5 papier" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "B5 papier gedetecteerd" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "OMR of DF" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "OMR of dubbele doorvoer gedetecteerd" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "Energiebesparende" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "Scanner in energiebesparende modus" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "Handmatige doorvoer" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "Handmatige doorvoer geselecteerd" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "Functie" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "Functie karakter op het scherm" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "Inkt bijna op" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "Imprinter inkt is bijna op" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "Dubbele doorvoer" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "Dubbele doorvoer gedetecteerd" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "Foutcode" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "Hardware foutcode" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "Scheefheidshoek" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "Vereist zwarte achtergrond voor het scannen" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "Resterende hoeveelheid inkt" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, no-c-format msgid "Imprinter ink level" msgstr "Imprinter inkt niveau" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, no-c-format msgid "Density" msgstr "Dichtheid" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "Dichtheid schaal" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, no-c-format msgid "Duplex switch" msgstr "Duplex schakelaar" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "Vraag backend randen van pagina's digitaal te verwijderen" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" "Vraag het stuurprogramma pagina's met weinig dekking te verwijderen" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "Softwarematige rotatie tegen de klok in" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" "Vraag stuurprogramma een 90 graden gedraaid beeld te herkennen en " "corrigeren" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Extra's" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "Dynamische drempel curve, van licht naar donker, normaal 50-65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Dynamische lijntekening uitschakelen" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"Schakel, om een lijntekening te genereren het gebruik van een software " -"aanpassend algoritme uit en vertrouw in plaats daarvan op de hardware." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Schakel interpolatie uit" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3117,34 +3137,34 @@ msgstr "" "resolutie kleiner is dan de verticale resolutie, wordt de horizontale " "interpolatie uitgeschakeld." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, no-c-format msgid "Color filter" msgstr "Kleurenfilter" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "Wanneer grijs of lijntekening wordt gebruikt, selecteert deze optie de " "huidige actieve kleur." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, no-c-format msgid "Calibration file" msgstr "Kalibratiebestand" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, no-c-format msgid "Specify the calibration file to use" msgstr "Specificeer het te gebruiken kalibratiebestand" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, no-c-format msgid "Calibration cache expiration time" msgstr "Vervaltijd van de kalibratie cache" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " @@ -3154,12 +3174,12 @@ msgstr "" "van 0 betekent dat geen cache wordt gebruikt. Een negatieve waarde " "betekent dat de cache nooit verloopt." -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Lamp-uit tijd" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3168,89 +3188,108 @@ msgstr "" "De lamp wordt uitgeschakeld na de opgegeven tijd (in minuten). Een " "waarde van 0 betekent, dat de lamp niet wordt uitgeschakeld." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "Lamp uit tijdens het scannen" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "De lamp wordt uitgeschakeld tijdens het scannen" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Bestand-knop" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "OCR-knop" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Aan/Uit-knop" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, no-c-format msgid "Extra button" msgstr "Extra-knop" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 -#, no-c-format -msgid "Need calibration" +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 +#, fuzzy, no-c-format +msgid "Needs calibration" msgstr "Kalibratie nodig" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "De scanner moet worden gekalibreerd voor de huidige instellingen" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Knoppen" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibreren" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Begin kalibreerproces met een speciale transparant" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Reset kalibratie" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Reset kalibratiecache" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, no-c-format msgid "Force calibration" msgstr "Dwing kalibratie" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "Dwing kalibratie en negeer alle kalibratie caches" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Groen compensatie" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Transparantenhulpstuk" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Transparantenhulpstuk" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3359,6 +3398,310 @@ msgstr "Gammawaarde" msgid "Sets the gamma value of all channels." msgstr "Stelt de gammawaarde voor alle kanalen in." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Geavanceerde opties" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Grof" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fijn" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Door de gebruiker gedefinieerd" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatisch" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Doorgang" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC Grijs" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA Grijs" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Langzaam" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normaal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Snel" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Extra snel" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-beeldpunt" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-beeldpunt" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-beeldpunt" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Afdruk" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Dia" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Filmstrook" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "Automatische documentinvoer" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Voorwaardelijk" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experiment" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Scherper maken" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Stel scherpte waarde in." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Automatische drempelwaarde" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Maak automatische bepaling mogelijk van de drempelwaarde voor " +"lijntekening scans." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Kies halftoon filter." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Verwijder origineel na de scan" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Verwijdert het origineel na de scan." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Wijzig origineel" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Wijzig Origineel." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Verwijder" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Verwijder Origineel." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Begin het kalibreer proces" + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Origineel" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Stel origineel type in." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Belichtingstijd" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Een langere belichtingstijd laat de scanner meer licht verzamelen. " +"Advies is om 175% voor papieren originelen, 150% voor dia's en \"Negatief" +"\" voor negatieven te gebruiken. Voor donkere (onderbelichte) beelden " +"kun je deze waarde verhogen." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Kleurmatrix" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Stel de kleurmatrix in van de scanner" + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Door de gebruiker gedefinieerde kleurmatrix" + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Mono Kleurmatrix" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Door de gebruiker gedefinieerd kleurmatrix voor grijstint scans" + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Horizontaal spiegelen" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Beeld horizontaal spiegelen" + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Verticaal spiegelen" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Beeld verticaal spiegelen" + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Opties bijwerken" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Opties bijwerken." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8-bit resultaat" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "Gebruik intern meer dan acht bits, maar geef slechts acht bits." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Voorpaneel knop wacht" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Wacht met scannen totdat knop op voorpaneel is ingedrukt." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Schakel de lamp uit" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Schakel de scannerlamp uit." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3369,27 +3712,21 @@ msgstr "Geometrie groep" msgid "Scan Mode Group" msgstr "Scanmodus groep" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Dia" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" msgstr "Scanner model" #: backend/hp3900_sane.c:1408 -#, no-c-format -msgid "Allows one to test device behaviour with other supported models" +#, fuzzy, no-c-format +msgid "Allows one to test device behavior with other supported models" msgstr "" "Biedt men de mogelijkheid de werking van het apparaat te testen met " "andere ondersteunde modellen." #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "Kleuren van het beeld worden geïnverteerd" #: backend/hp3900_sane.c:1436 @@ -3579,11 +3916,6 @@ msgstr "Schakelt de lamp aan of uit." msgid "Calibrates for black and white level." msgstr "Kalibreert voor de zwart-/witwaarde" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "Automatische documentinvoer" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3694,299 +4026,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Geavanceerde opties" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Grof" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fijn" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Door de gebruiker gedefinieerd" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatisch" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Doorgang" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC Grijs" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA Grijs" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Langzaam" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normaal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Snel" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Extra snel" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-beeldpunt" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-beeldpunt" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-beeldpunt" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Afdruk" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Filmstrook" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Voorwaardelijk" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experiment" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Scherper maken" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Stel scherpte waarde in." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Automatische drempelwaarde" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Maak automatische bepaling mogelijk van de drempelwaarde voor " -"lijntekening scans." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Kies halftoon filter." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Verwijder origineel na de scan" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Verwijdert het origineel na de scan." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Wijzig origineel" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Wijzig Origineel." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Verwijder" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Verwijder Origineel." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Begin het kalibreer proces" - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Origineel" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Stel origineel type in." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Belichtingstijd" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Een langere belichtingstijd laat de scanner meer licht verzamelen. " -"Advies is om 175% voor papieren originelen, 150% voor dia's en \"Negatief" -"\" voor negatieven te gebruiken. Voor donkere (onderbelichte) beelden " -"kun je deze waarde verhogen." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Kleurmatrix" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Stel de kleurmatrix in van de scanner" - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Door de gebruiker gedefinieerde kleurmatrix" - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Mono Kleurmatrix" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Door de gebruiker gedefinieerd kleurmatrix voor grijstint scans" - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Horizontaal spiegelen" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Beeld horizontaal spiegelen" - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Verticaal spiegelen" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Beeld verticaal spiegelen" - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Opties bijwerken" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Opties bijwerken." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8-bit resultaat" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "Gebruik intern meer dan acht bits, maar geef slechts acht bits." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Voorpaneel knop wacht" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Wacht met scannen totdat knop op voorpaneel is ingedrukt." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Schakel de lamp uit" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Schakel de scannerlamp uit." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4086,7 +4125,7 @@ msgid "single" msgstr "enkel" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4254,9 +4293,9 @@ msgid "crt" msgstr "crt" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "lineair" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Lijntekening" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4385,7 +4424,7 @@ msgstr "Stelt beeldverbetering in" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4457,11 +4496,11 @@ msgid "Request driver to remove border from pages digitally" msgstr "" "Vraag het stuurprogramma randen van pagina's digitaal te verwijderen " -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 -#, no-c-format +#: backend/kvs20xx_opt.c:233 +#, fuzzy, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" "Formaat Controle Modus is een modus waarbij de scanner leest tot aan de " "kortste lengte van het gebruikte papier of de feitelijke lengte van het " @@ -4495,13 +4534,13 @@ msgid "B4" msgstr "B4" #: backend/kvs40xx_opt.c:231 -#, no-c-format -msgid "High sensivity" +#, fuzzy, no-c-format +msgid "High sensitivity" msgstr "Hoge gevoeligheid" #: backend/kvs40xx_opt.c:232 -#, no-c-format -msgid "Low sensivity" +#, fuzzy, no-c-format +msgid "Low sensitivity" msgstr "Lage gevoeligheid" #: backend/kvs40xx_opt.c:243 @@ -4524,6 +4563,16 @@ msgstr "Normale modus" msgid "Enhanced mode" msgstr "Verbetermodus" +#: backend/kvs40xx_opt.c:396 +#, fuzzy, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"Formaat Controle Modus is een modus waarbij de scanner leest tot aan de " +"kortste lengte van het gebruikte papier of de feitelijke lengte van het " +"document." + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4585,8 +4634,8 @@ msgid "JPEG compression" msgstr "JPEG compressie" #: backend/kvs40xx_opt.c:718 -#, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +#, fuzzy, no-c-format +msgid "JPEG compression (your application must be able to uncompress)" msgstr "JPEG compressie (je programma moet in staat zijn te decomprimeren)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4620,13 +4669,13 @@ msgid "Skew adjustment" msgstr "Scheefheid correctie" #: backend/kvs40xx_opt.c:808 -#, no-c-format -msgid "Stop scanner when a paper have been skewed" +#, fuzzy, no-c-format +msgid "Stop scanner if a sheet is skewed" msgstr "Stop de scanner als het papier is scheefgetrokken" #: backend/kvs40xx_opt.c:809 -#, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +#, fuzzy, no-c-format +msgid "Scanner will stop if a sheet is skewed" msgstr "De scanner wordt gestopt als het papier is scheefgetrokken" #: backend/kvs40xx_opt.c:816 @@ -4635,15 +4684,15 @@ msgid "Crop actual image area" msgstr "Snij het effectieve beeldoppervlak uit" #: backend/kvs40xx_opt.c:817 -#, no-c-format -msgid "Scanner automatically detect image area and crop it" +#, fuzzy, no-c-format +msgid "Scanner will automatically detect image area and crop to it" msgstr "" "De scanner herkent automatisch het beeldoppervlak en snijdt die uit" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "Het is rechts en links omkering" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Spiegel het beeld" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4680,52 +4729,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 Verticale Lijn" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Bereik" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Bereikinstellingen van de kleurkanalen" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Grijsbereik" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Stelt het bereik in van het grijze kanaal" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Roodbereik" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Stelt het bereik in van het rode kanaal" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Groenbereik" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Stelt het bereik in van het groene kanaal" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Blauwbereik" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Stelt het bereik in van het blauwe kanaal" @@ -4811,7 +4860,7 @@ msgstr "Eén pagina" msgid "All pages" msgstr "Alle pagina's" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "Doorvoerscanner" @@ -5326,27 +5375,32 @@ msgstr "" "Warm op totdat de helderheid van de lamp constant is in plaats van de " "'verplichte' 40 seconde opwarmtijd aan te houden." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Kalibratie nodig" + +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "Kleurennegatief" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "Grijsnegatief" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "48 bits kleur" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "16 bits grijs" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " @@ -5356,12 +5410,12 @@ msgstr "" "de modus en resolutie. Zet modus en resolutie terug naar automatische " "waarden." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Knop-gestuurde scan" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5372,40 +5426,40 @@ msgstr "" "gaan, druk op de \"SCAN\" knop (voor MP150) of \"COLOR\" knop (voor " "andere modellen). Om te annuleren, druk op de \"GRAY\" knop." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Werk de status van de knop bij" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Knop 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Knop 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "Soort te scannen origineel" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "Soort bewerking van het resultaat" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "ADF wachttijd" -#: backend/pixma_sane_options.c:349 -#, no-c-format +#: backend/pixma/pixma_sane_options.c:349 +#, fuzzy, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" "Wanneer ingesteld, zoekt de scanner gedurende de wachttijd in seconden " @@ -5497,7 +5551,7 @@ msgstr "Analoge \"frontend\"" msgid "Red gain value of the AFE" msgstr "Roodbereik waarde van de AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Rood compensatie" @@ -5775,7 +5829,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Deze optie geeft de status weer van een scannerknop." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lamp aan" @@ -5785,12 +5839,12 @@ msgstr "Lamp aan" msgid "Turn on scanner lamp" msgstr "Schakel scannerlamp aan" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Lamp uit" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Schakel de scannerlamp uit" @@ -5934,13 +5988,13 @@ msgid "Focus point" msgstr "Scherpstel positie" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Kleurlijnen per leesopdracht" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Grijstraplijnen per leesopdracht" #: backend/stv680.c:974 @@ -6598,52 +6652,69 @@ msgstr "Kalibreermodus" msgid "Define calibration mode" msgstr "Bepaal kalibreermodus" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Schakelt de lamp aan/uit" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA aan" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Schakelt UTA aan/uit" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Compensatie" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Compensatieinstellingen van de kleurkanalen" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Grijscompensatie" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Stelt de compensatie in van het grijze kanaal" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Stelt de compensatie in van het rode kanaal" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Stelt de compensatie in van het groene kanaal" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Stelt de compensatie in van het blauwe kanaal" + +#~ msgid "Disable dynamic lineart" +#~ msgstr "Dynamische lijntekening uitschakelen" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "Schakel, om een lijntekening te genereren het gebruik van een " +#~ "software aanpassend algoritme uit en vertrouw in plaats daarvan op de " +#~ "hardware." + +#~ msgid "linier" +#~ msgstr "lineair" + +#~ msgid "It is right and left reversing" +#~ msgstr "Het is rechts en links omkering" @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.21\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2010-11-06 19:33+0100\n" "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n" "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n" @@ -26,31 +26,31 @@ msgid "Standard" msgstr "Standardowe" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "KrawÄ™dzie obszaru skanowania" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Ulepszanie" @@ -84,7 +84,7 @@ msgid "Bit depth" msgstr "GÅ‚Ä™bokość bitowa" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Tryb skanowania" @@ -125,7 +125,7 @@ msgid "Bottom-right y" msgstr "Dolna" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Rozdzielczość skanowania" @@ -280,7 +280,7 @@ msgstr "Nazwa pliku" msgid "Halftone pattern size" msgstr "Rozmiar wzoru półcienia" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Wzór półcienia" @@ -290,10 +290,10 @@ msgstr "Wzór półcienia" msgid "Bind X and Y resolution" msgstr "Zrównaj rozdzielczość w osi X i Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negatyw" @@ -414,9 +414,9 @@ msgid "Lamp off at exit" msgstr "WyÅ‚Ä…cz lampÄ™ przy wyjÅ›ciu" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "Opcja tylko do odczytu, mówiÄ…ca ile opcji wspiera dane urzÄ…dzenie." @@ -759,8 +759,8 @@ msgid "Analog gamma-correction for blue" msgstr "Analogowa korekcja gamma dla niebieskiego" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Rozgrzej lampÄ™ przed skanowaniem" #: include/sane/saneopts.h:417 @@ -909,8 +909,8 @@ msgid "Operation not supported" msgstr "Operacja nieobsÅ‚ugiwana" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "Operacja anulowana" #: backend/sane_strstatus.c:68 @@ -1004,10 +1004,10 @@ msgid "Only perform shading-correction" msgstr "Przeprowadź tylko korektÄ™ cieniowania" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Jeżeli wÅ‚Ä…czone, tylko korekcja cieniowania jest przeprowadzana w czasie " @@ -1035,85 +1035,45 @@ msgid "Duplex scan" msgstr "Skanowanie dwustronne" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "Skanowanie dwustronne pozwala na skanowanie przedniej i tylnej strony " "dokumentu" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibruj Skaner" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "WymuÅ› kalibracjÄ™ przed skanowaniem" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Skanowanie w odcieniach szaroÅ›ci" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Skanuj raczej w odcieniach szaroÅ›ci niż w kolorze" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Wzmocnienie analogowe" +msgid "Correction according to transparency ratio" +msgstr "Korekcja zgodna ze współczynnikiem przezroczystoÅ›ci" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "ZwiÄ™ksz lub zmniejsz wzmocnienie analogowe matrycy CCD" +msgid "Correction according to film type" +msgstr "Korekcja zgodna z rodzajem filmu" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Korekcja Gamma" +msgid "Fine color" +msgstr "Dobry kolor" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Wybiera poprawionÄ… krzywÄ… przejÅ›cia" +msgid "Negatives" +msgstr "Negatywy" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Surowy" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Dobry kolor" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Brak korekcji dla klisz" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Korekcja zgodna z rodzajem filmu" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Korekcja zgodna ze współczynnikiem przezroczystoÅ›ci" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negatywy" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1247,8 +1207,8 @@ msgid "invalid bit IDENTIFY message" msgstr "bÅ‚Ä™dny komunikat bitowy IDENTIFY" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "opcja nie podÅ‚Ä…czona" #: backend/canon.c:474 @@ -1538,133 +1498,184 @@ msgstr "Rodzaj filmu" msgid "Select the film type" msgstr "Wybór rodzaju filmu" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibruj Skaner" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "WymuÅ› kalibracjÄ™ przed skanowaniem" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Skanowanie w odcieniach szaroÅ›ci" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Skanuj raczej w odcieniach szaroÅ›ci niż w kolorze" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Wzmocnienie analogowe" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "ZwiÄ™ksz lub zmniejsz wzmocnienie analogowe matrycy CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Korekcja Gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Wybiera poprawionÄ… krzywÄ… przejÅ›cia" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "PÅ‚yta" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "ADF przód" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "ADF tyÅ‚" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "ADF dwustronny" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Przód" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, fuzzy, no-c-format msgid "Card Back" msgstr "TyÅ‚" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Dwustronny" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Czerwony" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Zielony" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Niebieski" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Rozszerzenie czerwieni" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Rozszerzenie zieleni" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Rozszerzenie bÅ‚Ä™kitu" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Brak" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Jednostronny" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Dwustronny" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "ModuÅ‚ do skanowania przezroczy" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatyczny podajnik dokumentów" @@ -1776,7 +1787,7 @@ msgstr "Drukarki atramentowe" msgid "CRT monitors" msgstr "Monitory CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1840,8 +1851,9 @@ msgstr "A4" msgid "Max" msgstr "Maksimum" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2014,17 +2026,17 @@ msgstr "Definiuje współczynnik powiÄ™kszenia dla skanera" msgid "Quick format" msgstr "Szybkie formatowanie" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Wyposażenie opcjonalne" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "WysuÅ„" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "WysuÅ„ arkusz z ADF" @@ -2039,12 +2051,14 @@ msgstr "Wysuwanie automatyczne" msgid "Eject document after scanning" msgstr "WysuÅ„ dokument po zeskanowaniu" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Tryb ADF" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Wybiera tryb ADF (jedno/dwustronny)" @@ -2093,16 +2107,16 @@ msgstr "" "Po wysÅ‚aniu komendy skanowania, czekaj aż przycisk na skanerze jest " "naciÅ›niÄ™ty, aby naprawdÄ™ rozpocząć skanowanie" -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "PodczerwieÅ„" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "PodczerwieÅ„" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2123,492 +2137,512 @@ msgstr "Wbudowany profil CCT" msgid "User defined CCT profile" msgstr "Profil CCT zdefiniowany przez użytkownika" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "WysuÅ„ arkusz z ADF" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Brak korekcji" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "WyÅ‚Ä…cz korekcjÄ™ gamma" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "WÅ‚Ä…czony" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "WyÅ‚Ä…cz" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Ditheruj" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Dyfuzja" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Biel" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "CzerÅ„" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Kontynuacja" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Stop" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Poziomy" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Poziomy pogrubiony" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Poziomy cienki" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Pionowy" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Pionowy pogrubiony" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "Od góry do doÅ‚u" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "Od doÅ‚u do góry" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Przód" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "TyÅ‚" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Półtony" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Wykonuje kalibracjÄ™" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Emfaza obrazka" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Nasycenie" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "WÅ‚Ä…cz automatyczne rozpoznawanie progu dla skanów w trybie kreski." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Odbicie lustrzane obrazka" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Poziome, lustrzane odbicie obrazka." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Poziom bieli dla niebieskiego" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Nadzoruje poziom czerwieni" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Filtr kolorów" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "WygÅ‚adzanie" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Wartość gamma" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Krzywa progowa" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, fuzzy, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "Dynamiczna krzywa progowa, od ciemnego do jasnego, zwykle 50-65" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Próg" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Redukcja szumów" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Brak korekcji" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Brak korekcji" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "pokrywa ADF otwarta" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Opcje zaawansowane" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Brak korekcji" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Dropout" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "tryb podajnika" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2616,65 +2650,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Czas wyÅ‚Ä…czania lampy" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Offset bÅ‚Ä™kitu" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Offset zieleni" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Offset zieleni" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Offset bÅ‚Ä™kitu" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Ustawienie offsetu kanaÅ‚u bÅ‚Ä™kitu" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, fuzzy, no-c-format msgid "Low Memory" msgstr "Brak pamiÄ™ci" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2683,376 +2717,362 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Skanowanie dwustronne" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Opcje zaawansowane" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Redukcja szumów" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "Od papieru" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "Od papieru" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "Od papieru" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "Od papieru" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "Pokrywa skanera jest otwarta" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "RÄ™czne wstÄ™pne ustawianie ostroÅ›ci" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "RÄ™czne wstÄ™pne ustawianie ostroÅ›ci" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "bÅ‚Ä…d kontroli sprzÄ™tu" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Poziom bieli" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Kontrola gÄ™stoÅ›ci" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "Kontrola gÄ™stoÅ›ci" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Skanowanie dwustronne" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Dodatki" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "Dynamiczna krzywa progowa, od ciemnego do jasnego, zwykle 50-65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "WyÅ‚Ä…czenie dynamicznego trybu kreski" - -#: backend/genesys.cc:5517 -#, fuzzy, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"WyÅ‚Ä…czenie użycia algorytmu adaptacyjnego do generowania linii zamiast " -"polegania na trybie sprzÄ™towym" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "WyÅ‚Ä…cz interpolacjÄ™" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3062,44 +3082,44 @@ msgstr "" "mniejsza niż rozdzielczość pionowa, ta opcja wyÅ‚Ä…cza interpolacjÄ™ " "poziomÄ…." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Filtr kolorów" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "W trybie szaroÅ›ci lub kreski ta opcja wybiera używany kolor." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibracja" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Zdefiniuj tryb kalibracji" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Pamięć podrÄ™czna danych kalibracji" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Czas wyÅ‚Ä…czania lampy" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3108,89 +3128,108 @@ msgstr "" "Lampa zostanie wyÅ‚Ä…czona po podanym czasie (w minutach). Wartość 0 " "oznacza, że lampa nie bÄ™dzie wyÅ‚Ä…czana." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "WyÅ‚Ä…cz lampÄ™ podczas kalibracji ciemnoÅ›ci" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, fuzzy, no-c-format msgid "The lamp will be turned off during scan. " msgstr "Liczba minut do wyÅ‚Ä…czenia lampy po skanowaniu" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Przycisk pliku" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Przycisk OCR" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Przycisk zasilania" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Przycisk E-maila" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 -#, no-c-format -msgid "Need calibration" +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 +#, fuzzy, no-c-format +msgid "Needs calibration" msgstr "Wymaga kalibracji" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Skaner wymaga kalibracji dla obecnych ustawieÅ„" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Przyciski" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibracja" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Rozpocznij kalibracjÄ™ przy użyciu specjalnej kartki" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Wyczyść kalibracjÄ™" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Wyczyść pamięć podrÄ™cznÄ… kalibracji" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Kalibracja ziarnistoÅ›ci" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Offset zieleni" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "ModuÅ‚ do skanowania negatywów" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "ModuÅ‚ do skanowania negatywów" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3299,6 +3338,310 @@ msgstr "Wartość gamma" msgid "Sets the gamma value of all channels." msgstr "Ustawia wartość gamma dla wszystkich kanałów" +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Opcje zaawansowane" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Ziarnistość" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "DokÅ‚adny" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayera" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Użytkownika" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatyczny" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Åšrodkowoprzepustowy" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "Skala szaroÅ›ci NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Skala szaroÅ›ci XPA" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Powolny" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "ZwykÅ‚y" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Szybki" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Bardzo szybki" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2-pikselowy" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4-pikselowy" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8-pikselowy" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Drukuj" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Slajd" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Pasek filmu" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ADF" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Warunkowy" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Eksperyment" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Wyostrzanie" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Ustaw wartość wyostrzania." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Automatyczne progowanie" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "WÅ‚Ä…cz automatyczne rozpoznawanie progu dla skanów w trybie kreski." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Wybierz filtr wygÅ‚adzajÄ…cy." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "WysuÅ„ noÅ›nik po skanowaniu" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Wysuwa noÅ›nik po skanowaniu." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "ZmieÅ„ dokument" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "ZmieÅ„ Dokument." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "WysuÅ„" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "WysuÅ„ Dokument." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Rozpocznij proces kalibracji." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "NoÅ›nik" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Ustaw rodzaj noÅ›nika." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Czas ekspozycji" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"DÅ‚uższy czas ekspozycji pozwala gÅ‚owicy odebrać wiÄ™cej Å›wiatÅ‚a. " +"Sugerowane jest 175% dla wydruków, 150% dla zwykÅ‚ych slajdów i \"Negatyw" +"\" dla filmu negatywowego. Dla ciemnych (nie doÅ›wietlonych) obrazków " +"możesz zwiÄ™kszyć tÄ™ wartość." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Matryca kolorów" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Ustaw matrycÄ™ kolorów skanera." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Matryca kolorów użytkownika" + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Monochromatyczna matryca kolorów" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Matryca kolorów użytkownika dla skanów w skali szaroÅ›ci." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Odbicie poziome" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Poziome, lustrzane odbicie obrazka." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Odbij pionowo." + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Pionowe, lustrzane odbicie obrazka." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Aktualizuj opcje" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Aktualizuj opcje." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8-bitowe wyjÅ›cie" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Użyj wewnÄ™trznie gÅ‚Ä™bi wiÄ™kszej niż osiem bitów, lecz na wyjÅ›ciu daj " +"równe osiem." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Oczekiwanie na przycisk panelu" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Czekaj ze skanowaniem na naciÅ›niÄ™cie przycisku na przednim panelu." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "WyÅ‚Ä…cz lampÄ™" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "WyÅ‚Ä…cz lampÄ™ skanera." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3309,12 +3652,6 @@ msgstr "Grupa geometrii" msgid "Scan Mode Group" msgstr "Grupa trybu skanowania" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Slajd" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3322,14 +3659,14 @@ msgstr "Model skanera" #: backend/hp3900_sane.c:1408 #, fuzzy, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" "Umożliwia sprawdzenie zachowania urzÄ…dzenia z innymi obsÅ‚ugiwanymi " "modelami" #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "Kolory obrazu bÄ™dÄ… odwrócone" #: backend/hp3900_sane.c:1436 @@ -3518,11 +3855,6 @@ msgstr "WÅ‚Ä…cza lub wyÅ‚Ä…cza lampÄ™." msgid "Calibrates for black and white level." msgstr "Kalibruje poziom dla czerni i bieli." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ADF" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3633,299 +3965,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Opcje zaawansowane" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Ziarnistość" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "DokÅ‚adny" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayera" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Użytkownika" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatyczny" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Åšrodkowoprzepustowy" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "Skala szaroÅ›ci NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Skala szaroÅ›ci XPA" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Powolny" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "ZwykÅ‚y" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Szybki" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Bardzo szybki" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2-pikselowy" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4-pikselowy" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8-pikselowy" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Drukuj" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Pasek filmu" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Warunkowy" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Eksperyment" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Wyostrzanie" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Ustaw wartość wyostrzania." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Automatyczne progowanie" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "WÅ‚Ä…cz automatyczne rozpoznawanie progu dla skanów w trybie kreski." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Wybierz filtr wygÅ‚adzajÄ…cy." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "WysuÅ„ noÅ›nik po skanowaniu" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Wysuwa noÅ›nik po skanowaniu." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "ZmieÅ„ dokument" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "ZmieÅ„ Dokument." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "WysuÅ„" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "WysuÅ„ Dokument." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Rozpocznij proces kalibracji." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "NoÅ›nik" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Ustaw rodzaj noÅ›nika." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Czas ekspozycji" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"DÅ‚uższy czas ekspozycji pozwala gÅ‚owicy odebrać wiÄ™cej Å›wiatÅ‚a. " -"Sugerowane jest 175% dla wydruków, 150% dla zwykÅ‚ych slajdów i \"Negatyw" -"\" dla filmu negatywowego. Dla ciemnych (nie doÅ›wietlonych) obrazków " -"możesz zwiÄ™kszyć tÄ™ wartość." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Matryca kolorów" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Ustaw matrycÄ™ kolorów skanera." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Matryca kolorów użytkownika" - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Monochromatyczna matryca kolorów" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Matryca kolorów użytkownika dla skanów w skali szaroÅ›ci." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Odbicie poziome" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Poziome, lustrzane odbicie obrazka." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Odbij pionowo." - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Pionowe, lustrzane odbicie obrazka." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Aktualizuj opcje" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Aktualizuj opcje." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8-bitowe wyjÅ›cie" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Użyj wewnÄ™trznie gÅ‚Ä™bi wiÄ™kszej niż osiem bitów, lecz na wyjÅ›ciu daj " -"równe osiem." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Oczekiwanie na przycisk panelu" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Czekaj ze skanowaniem na naciÅ›niÄ™cie przycisku na przednim panelu." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "WyÅ‚Ä…cz lampÄ™" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "WyÅ‚Ä…cz lampÄ™ skanera." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4024,7 +4063,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4192,9 +4231,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Tryb kreski" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4323,7 +4362,7 @@ msgstr "Ustawia emfazÄ™ obrazka" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4390,11 +4429,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4426,12 +4465,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Druk wysokiej gÄ™stoÅ›ci" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Druk niskiej gÄ™stoÅ›ci" #: backend/kvs40xx_opt.c:243 @@ -4454,6 +4493,13 @@ msgstr "ZwykÅ‚y" msgid "Enhanced mode" msgstr "Ulepszanie" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4513,7 +4559,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4548,12 +4594,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4563,13 +4609,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Odbicie lustrzane obrazka" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4606,52 +4652,52 @@ msgstr "Pogrubianie Bayera 8x8" msgid "8x8 Vertical Line" msgstr "Linie pionowe 8x8" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Wzmocnienie" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Ustawienia wzmocnienia kanałów kolorów" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Wzmocnienie szaroÅ›ci" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Ustawia wzmocnienie kanaÅ‚u szaroÅ›ci" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Wzmocnienie czerwieni" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Ustawia wzmocnienie kanaÅ‚u czerwieni" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Wzmocnienie zieleni" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Ustawia wzmocnienie kanaÅ‚u zieleni" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Wzmocnienie bÅ‚Ä™kitu" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Ustawia wzmocnienie kanaÅ‚u bÅ‚Ä™kitu" @@ -4737,7 +4783,7 @@ msgstr "Jedna strona" msgid "All pages" msgstr "Wszystkie strony" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "skaner arkuszy" @@ -5250,39 +5296,44 @@ msgstr "" "Rozgrzewaj dopóki jasność lampy bÄ™dzie staÅ‚a, zamiast przyjmować staÅ‚y " "czas 40 sekund." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Wymaga kalibracji" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Negatyw" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negatyw" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, fuzzy, no-c-format msgid "48 bits color" msgstr "Dobry kolor" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Skanowanie sterowane przyciskiem" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5294,40 +5345,40 @@ msgstr "" "\"COLOR\" (dla innych modeli). Aby anulować, należy nacisnąć przycisk " "\"GRAY\"." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Uaktualnij stan przycisku" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Przycisk 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Przycisk 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5416,7 +5467,7 @@ msgstr "Frontend analogowy" msgid "Red gain value of the AFE" msgstr "Wartość AFE wzmocnienia czerwieni" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Offset czerwieni" @@ -5692,7 +5743,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Opcja ta odzwierciedla stan przycisku skanera." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "WÅ‚Ä…cz lampÄ™" @@ -5702,12 +5753,12 @@ msgstr "WÅ‚Ä…cz lampÄ™" msgid "Turn on scanner lamp" msgstr "WÅ‚Ä…cza lampÄ™ skanera" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "WyÅ‚Ä…cz lampÄ™" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "WyÅ‚Ä…cza lampÄ™ skanera" @@ -5851,13 +5902,13 @@ msgid "Focus point" msgstr "Pozycja skupienia (ostroÅ›ci)" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Liczba kolorów na odczyt" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Liczba linii w skali szaroÅ›ci na odczyt" #: backend/stv680.c:974 @@ -6512,56 +6563,67 @@ msgstr "Tryb kalibracji" msgid "Define calibration mode" msgstr "Zdefiniuj tryb kalibracji" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Ustawia lapÄ™ jako wÅ‚Ä…czonÄ… lub wyÅ‚Ä…czonÄ…" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "WÅ‚Ä…cz UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Ustawia UTA jako wÅ‚Ä…czone lub wyÅ‚Ä…czone" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Offset" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Ustawienia offsetu kanałów koloru" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "PrzesuniÄ™cie (offset) skali szaroÅ›ci" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Ustawienie offsetu kanaÅ‚u szaroÅ›ci" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Ustawienie offsetu kanaÅ‚u czerwieni" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Ustawienie offsetu kanaÅ‚u zieleni" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Ustawienie offsetu kanaÅ‚u bÅ‚Ä™kitu" +#~ msgid "Disable dynamic lineart" +#~ msgstr "WyÅ‚Ä…czenie dynamicznego trybu kreski" + +#, fuzzy +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "WyÅ‚Ä…czenie użycia algorytmu adaptacyjnego do generowania linii " +#~ "zamiast polegania na trybie sprzÄ™towym" + #, fuzzy #~ msgid "IPC mode" #~ msgstr "Tryb podglÄ…du" @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.10\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-05-08 13:31+0200\n" "Last-Translator: Pedro Morais <morais@inocam.com>\n" "Language-Team: pt <morais@inocam.com>\n" @@ -25,31 +25,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometria" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Melhorias" @@ -83,7 +83,7 @@ msgid "Bit depth" msgstr "" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Modo de digitalização" @@ -124,7 +124,7 @@ msgid "Bottom-right y" msgstr "Inferior-direita y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Resolução digitalização" @@ -279,7 +279,7 @@ msgstr "Nome do ficheiro" msgid "Halftone pattern size" msgstr "Tamanho padrão ponto - simulação cinza" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Simulação cinza padrão" @@ -289,10 +289,10 @@ msgstr "Simulação cinza padrão" msgid "Bind X and Y resolution" msgstr "Vincular resoluções X e Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativo" @@ -415,7 +415,7 @@ msgstr "Desligar lâmpada na saÃda" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" @@ -723,8 +723,8 @@ msgid "Analog gamma-correction for blue" msgstr "Correção analógica gama para Azul" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Aquecer lâmpada antes de digitalizar" #: include/sane/saneopts.h:417 @@ -874,7 +874,7 @@ msgstr "" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -968,7 +968,7 @@ msgstr "" #, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" @@ -995,81 +995,41 @@ msgstr "Digitalização completa" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" -#: backend/canon630u.c:159 -#, fuzzy, no-c-format -msgid "Calibrate Scanner" -msgstr "Calibração" - -#: backend/canon630u.c:160 -#, fuzzy, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Calibração rudimentar apenas na primeira digitalização" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Grayscale scan" +msgid "Correction according to transparency ratio" msgstr "" -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Do a grayscale rather than color scan" +msgid "Correction according to film type" msgstr "" -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Ganho analógico" - -#: backend/canon630u.c:307 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" +msgid "Fine color" msgstr "" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "Correcção do gamma" - -#: backend/canon630u.c:348 -#, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "" +#: backend/canon-sane.c:776 backend/canon.c:176 +#, fuzzy, no-c-format +msgid "Negatives" +msgstr "Negativo" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "" - #: backend/canon.c:169 #, fuzzy, no-c-format msgid "No transparency correction" msgstr "Correcção do gamma" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, fuzzy, no-c-format -msgid "Negatives" -msgstr "Negativo" - #: backend/canon.c:176 #, fuzzy, no-c-format msgid "Slides" @@ -1204,7 +1164,7 @@ msgstr "" #: backend/canon.c:460 #, no-c-format -msgid "option not connect" +msgid "option not correct" msgstr "" #: backend/canon.c:474 @@ -1492,135 +1452,186 @@ msgstr "" msgid "Select the film type" msgstr "" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, fuzzy, no-c-format +msgid "Calibrate Scanner" +msgstr "Calibração" + +#: backend/canon630u.c:160 +#, fuzzy, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Calibração rudimentar apenas na primeira digitalização" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Ganho analógico" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Correcção do gamma" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Flachbett" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Vermelho" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Verde" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Azul" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Melhorias" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Melhorias" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Melhorias" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "Desconsiderar porcentagem branco" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, fuzzy, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" "Solicita ao driver para eliminar páginas com baixo número de pixels " "escuros" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Unidade de Transparências" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "" @@ -1732,7 +1743,7 @@ msgstr "Impressoras de jacto de tinta" msgid "CRT monitors" msgstr "Monitores CRT" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1796,8 +1807,9 @@ msgstr "A4" msgid "Max" msgstr "Máximo" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -1969,17 +1981,17 @@ msgstr "" msgid "Quick format" msgstr "" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "" @@ -1994,12 +2006,14 @@ msgstr "" msgid "Eject document after scanning" msgstr "" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2044,14 +2058,14 @@ msgid "" "pressed to actually start the scan process." msgstr "" -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2074,492 +2088,512 @@ msgstr "" msgid "User defined CCT profile" msgstr "Definido pelo utilizador" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, no-c-format +msgid "Load a sheet in the ADF" +msgstr "" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Sem Correcção" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Correcção do gamma" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "NÃvel de branco" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "NÃvel de preto" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, fuzzy, no-c-format msgid "Reverse image format" msgstr "Inverte imagem" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Simulação cinza padrão" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Calibração rudimentar" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Saturação" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "NÃvel de branco para azul" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Contraste do canal azul" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Linhas em cor" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Valor de 'gamma'" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Limiar de aquecimento" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Valor do pixel-Threshold" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Sem Correcção" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Sem Correcção" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, fuzzy, no-c-format msgid "Compression" msgstr "Compressão JPEG" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, fuzzy, no-c-format msgid "Enable double feed error due to skew" msgstr "Liga / Desliga Modo de detecção de alimentação" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, fuzzy, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Liga / Desliga Modo de detecção de alimentação" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, fuzzy, no-c-format msgid "Enable double feed error due to paper length" msgstr "Liga / Desliga Modo de detecção de alimentação" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, fuzzy, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "Solicita ao driver para remover digitalmente bordas das páginas" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Imprimir opções" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Sem Correcção" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Cor da lâmpada" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2567,65 +2601,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Lâmpada acesa" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Deslocamento do azul" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Deslocamento do verde" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Deslocamento do verde" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Deslocamento do azul" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Deslocamento do canal azul" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2634,510 +2668,517 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Digitalização completa" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, fuzzy, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "Solicita ao driver para rotacionar digitalmente páginas inclinadas" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Alinhamento - Deskew" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, fuzzy, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "Solicita ao driver para rotacionar digitalmente páginas inclinadas" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Diâmetro despeckle" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, fuzzy, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" "Diâmetro máximo de pontos isolados a serem removidos da digitalização" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, fuzzy, no-c-format msgid "Software crop" msgstr "Crop automático" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, fuzzy, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "Solicita ao driver para remover digitalmente bordas das páginas" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Imprimir opções" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Calibração rudimentar" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, fuzzy, no-c-format msgid "OMR or double feed detected" msgstr "Detecção de dupla alimentação" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Modo de Alimentação manual" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Modo de Alimentação manual" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, fuzzy, no-c-format msgid "Double feed" msgstr "Detecção de dupla alimentação" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, fuzzy, no-c-format msgid "Double feed detected" msgstr "Detecção de dupla alimentação" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "NÃvel de branco" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Intensidade do vermelho" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Digitalização completa" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, fuzzy, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "Solicita ao driver para remover digitalmente bordas das páginas" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" "Solicita ao driver para eliminar páginas com baixo número de pixels " "escuros" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, fuzzy, no-c-format msgid "Software derotate" msgstr "Alinhamento - Deskew" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, fuzzy, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "Solicita ao driver para remover digitalmente bordas das páginas" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Linhas em cor" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Calibração" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Definine o modo de calibração" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Modo de calibração" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, fuzzy, no-c-format msgid "Lamp off time" msgstr "Lâmpada acesa" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " "of 0 means, that the lamp won't be turned off." msgstr "" -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Calibração rudimentar" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Origem da digitalização" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Calibração rudimentar" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Calibração rudimentar apenas na primeira digitalização" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, fuzzy, no-c-format msgid "Buttons" msgstr "Estado do botão" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, fuzzy, no-c-format msgid "Calibrate" msgstr "Calibração" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Calibração rudimentar" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Calibração rudimentar" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "Modo de calibração" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Calibração rudimentar" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Deslocamento do verde" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Adaptador de Transparências" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Adaptador de Transparências" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3239,6 +3280,304 @@ msgstr "Valor de 'gamma'" msgid "Sets the gamma value of all channels." msgstr "Define o valor de 'gamma' em todos os canais." +#: backend/hp-option.c:2987 +#, fuzzy, no-c-format +msgid "Advanced Options" +msgstr "Imprimir opções" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "" + +#: backend/hp-option.c:3045 +#, fuzzy, no-c-format +msgid "Fine" +msgstr "Nome do ficheiro" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automático" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC cinzento" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA cinzento" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Lento" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Rápido" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "" + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Limiar de aquecimento" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "" + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "" + +#: backend/hp-option.h:85 +#, fuzzy, no-c-format +msgid "Change document" +msgstr "Melhorias" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "" + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "" + +#: backend/hp-option.h:98 +#, fuzzy, no-c-format +msgid "Start calibration process." +msgstr "Calibração rudimentar" + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "" + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, fuzzy, no-c-format +msgid "Color Matrix" +msgstr "Linhas em cor" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Contraste do canal vermelho." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "" + +#: backend/hp-option.h:132 +#, fuzzy, no-c-format +msgid "Mono Color Matrix" +msgstr "Linhas em cor" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "" + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "" + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "" + +#: backend/hp-option.h:150 +#, fuzzy, no-c-format +msgid "Update options" +msgstr "Imprimir opções" + +#: backend/hp-option.h:151 +#, fuzzy, no-c-format +msgid "Update options." +msgstr "Imprimir opções" + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "" + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3249,12 +3588,6 @@ msgstr "Geometria" msgid "Scan Mode Group" msgstr "Modo de Digitalização" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3262,12 +3595,12 @@ msgstr "Modo de digitalização" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3448,11 +3781,6 @@ msgstr "" msgid "Calibrates for black and white level." msgstr "" -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3563,293 +3891,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, fuzzy, no-c-format -msgid "Advanced Options" -msgstr "Imprimir opções" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "" - -#: backend/hp-option.c:3045 -#, fuzzy, no-c-format -msgid "Fine" -msgstr "Nome do ficheiro" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automático" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC cinzento" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA cinzento" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Lento" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Rápido" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "" - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Limiar de aquecimento" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "" - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "" - -#: backend/hp-option.h:85 -#, fuzzy, no-c-format -msgid "Change document" -msgstr "Melhorias" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "" - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "" - -#: backend/hp-option.h:98 -#, fuzzy, no-c-format -msgid "Start calibration process." -msgstr "Calibração rudimentar" - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "" - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, fuzzy, no-c-format -msgid "Color Matrix" -msgstr "Linhas em cor" - -#: backend/hp-option.h:121 -#, fuzzy, no-c-format -msgid "Set the scanners color matrix." -msgstr "Contraste do canal vermelho." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "" - -#: backend/hp-option.h:132 -#, fuzzy, no-c-format -msgid "Mono Color Matrix" -msgstr "Linhas em cor" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "" - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "" - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "" - -#: backend/hp-option.h:150 -#, fuzzy, no-c-format -msgid "Update options" -msgstr "Imprimir opções" - -#: backend/hp-option.h:151 -#, fuzzy, no-c-format -msgid "Update options." -msgstr "Imprimir opções" - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "" - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -3948,7 +3989,7 @@ msgid "single" msgstr "simples" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4117,7 +4158,7 @@ msgstr "" #: backend/kvs1025_opt.c:229 #, fuzzy, no-c-format -msgid "linier" +msgid "linear" msgstr "Linhas" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 @@ -4246,7 +4287,7 @@ msgstr "" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "" @@ -4314,11 +4355,11 @@ msgstr "Crop automático" msgid "Request driver to remove border from pages digitally" msgstr "Solicita ao driver para remover digitalmente bordas das páginas" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4350,12 +4391,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "" #: backend/kvs40xx_opt.c:232 #, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "" #: backend/kvs40xx_opt.c:243 @@ -4378,6 +4419,13 @@ msgstr "Normal" msgid "Enhanced mode" msgstr "Melhorias" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4437,7 +4485,7 @@ msgstr "Compressão JPEG" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4472,12 +4520,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4487,12 +4535,12 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 #, no-c-format -msgid "It is right and left reversing" +msgid "Left/right mirror image" msgstr "" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 @@ -4530,52 +4578,52 @@ msgstr "" msgid "8x8 Vertical Line" msgstr "" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Ganho" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "Ganho do cinzento" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Ganho do canal cinzento" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Ganho do vermelho" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Ganho do canal vermelho" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Ganho do verde" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Ganho do canal verde" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "Ganho do azul" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Ganho do canal azul" @@ -4661,7 +4709,7 @@ msgstr "Uma página" msgid "All pages" msgstr "Todas as páginas" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "" @@ -5156,39 +5204,44 @@ msgstr "" "Aquecer até o brilho da lâmpada ser constante em ver de insistir em 40 " "segundos de tempo de aquecimento." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Calibração rudimentar" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Filme Negativo" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Negativo" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5196,40 +5249,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, fuzzy, no-c-format msgid "Update button state" msgstr "Estado do botão" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, fuzzy, no-c-format msgid "Button 1" msgstr "Estado do botão" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, fuzzy, no-c-format msgid "Button 2" msgstr "Estado do botão" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5318,7 +5371,7 @@ msgstr "Ganho analógico" msgid "Red gain value of the AFE" msgstr "" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Deslocamento do vermelho" @@ -5573,7 +5626,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "" -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lâmpada acesa" @@ -5583,12 +5636,12 @@ msgstr "Lâmpada acesa" msgid "Turn on scanner lamp" msgstr "" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "" @@ -5723,13 +5776,13 @@ msgid "Focus point" msgstr "" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" -msgstr "" +#, fuzzy, no-c-format +msgid "Color lines per read" +msgstr "Linhas em cor" #: backend/snapscan-options.c:942 #, no-c-format -msgid "Greyscale lines per read" +msgid "Grayscale lines per read" msgstr "" #: backend/stv680.c:974 @@ -6314,57 +6367,61 @@ msgstr "Modo de calibração" msgid "Define calibration mode" msgstr "Definine o modo de calibração" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Deslocamento" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Deslocamento do cinzento" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Deslocamento do canal cinzento" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Deslocamento do canal vermelho" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Deslocamento do canal verde" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Deslocamento do canal azul" #, fuzzy +#~ msgid "linier" +#~ msgstr "Linhas" + +#, fuzzy #~ msgid "Request backend to rotate skewed pages digitally" #~ msgstr "" #~ "Solicita ao driver para rotacionar digitalmente páginas inclinadas" @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2007-12-17 23:05+0100\n" "Last-Translator: \n" "Language-Team: <ru@li.org>\n" @@ -31,31 +31,31 @@ msgid "Standard" msgstr "" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "РаÑположение" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Повышение" @@ -89,7 +89,7 @@ msgid "Bit depth" msgstr "Бит на цвет" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Режим ÑканированиÑ" @@ -130,7 +130,7 @@ msgid "Bottom-right y" msgstr "ÐŸÑ€Ð°Ð²Ð°Ñ Ð½Ð¸Ð¶Ð½ÑÑ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚Ð° Y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Разрешение ÑканированиÑ" @@ -285,7 +285,7 @@ msgstr "Ðазвание файла" msgid "Halftone pattern size" msgstr "Размер чёрно-белого шаблона" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Чёрно-белый шаблон" @@ -295,10 +295,10 @@ msgstr "Чёрно-белый шаблон" msgid "Bind X and Y resolution" msgstr "СоглаÑовывать разрешение по X и по Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Ðегатив" @@ -419,9 +419,9 @@ msgid "Lamp off at exit" msgstr "Выключить лампу при выходе" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Параметр только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ, указывающий как много параметров указанное " @@ -775,8 +775,8 @@ msgid "Analog gamma-correction for blue" msgstr "ÐÐ½Ð°Ð»Ð¾Ð³Ð¾Ð²Ð°Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð³Ð°Ð¼Ð¼Ñ‹ Ð´Ð»Ñ Ñинего" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Прогревать лампу перед Ñканированием" #: include/sane/saneopts.h:417 @@ -926,7 +926,7 @@ msgstr "Полутоновое Ñканирование не поддерживР#: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "" #: backend/sane_strstatus.c:68 @@ -1020,10 +1020,10 @@ msgid "Only perform shading-correction" msgstr "ВыполнÑÑ‚ÑŒ только коррекцию оттенка" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "ЕÑли отмечено, во Ð²Ñ€ÐµÐ¼Ñ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ¸ выполнÑетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ " @@ -1051,84 +1051,44 @@ msgid "Duplex scan" msgstr "ДвухÑтороннее Ñканирование" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "ДвухÑтороннее Ñканирование позволÑет получить изображение лицевой и " "обратной Ñтороны документа" -#: backend/canon630u.c:159 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Calibrate Scanner" -msgstr "Калибровать Ñканер" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "ВыполнÑÑ‚ÑŒ калибровку Ñканера перед Ñканированием" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "Чёрно-белое Ñканирование" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "ВыполнÑÑ‚ÑŒ чёрно-белое Ñканирование вмеÑто цветного" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Ðналоговое уÑиление" - -#: backend/canon630u.c:307 -#, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Увеличить или уменьшить аналоговое уÑиление матрицы CCD" - -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 -#, no-c-format -msgid "Gamma Correction" -msgstr "ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð³Ð°Ð¼Ð¼Ñ‹" - -#: backend/canon630u.c:348 -#, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Выберите кривую гамма-коррекции" +msgid "Correction according to transparency ratio" +msgstr "" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Raw" +msgid "Correction according to film type" msgstr "" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 #: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format msgid "Fine color" msgstr "" -#: backend/canon.c:169 +#: backend/canon-sane.c:776 backend/canon.c:176 #, fuzzy, no-c-format -msgid "No transparency correction" -msgstr "ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²" - -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "" +msgid "Negatives" +msgstr "Ðегатив" -#: backend/canon.c:171 backend/canon-sane.c:674 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format -msgid "Correction according to transparency ratio" +msgid "Raw" msgstr "" -#: backend/canon.c:176 backend/canon-sane.c:776 +#: backend/canon.c:169 #, fuzzy, no-c-format -msgid "Negatives" -msgstr "Ðегатив" +msgid "No transparency correction" +msgstr "ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²" #: backend/canon.c:176 #, fuzzy, no-c-format @@ -1263,9 +1223,9 @@ msgid "invalid bit IDENTIFY message" msgstr "" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" -msgstr "" +#, fuzzy, no-c-format +msgid "option not correct" +msgstr "Полутоновое Ñканирование не поддерживаетÑÑ" #: backend/canon.c:474 #, no-c-format @@ -1552,133 +1512,184 @@ msgstr "Тип плёнки" msgid "Select the film type" msgstr "Выбирает полутона." -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Калибровать Ñканер" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "ВыполнÑÑ‚ÑŒ калибровку Ñканера перед Ñканированием" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Чёрно-белое Ñканирование" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "ВыполнÑÑ‚ÑŒ чёрно-белое Ñканирование вмеÑто цветного" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Ðналоговое уÑиление" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Увеличить или уменьшить аналоговое уÑиление матрицы CCD" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð³Ð°Ð¼Ð¼Ñ‹" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Выберите кривую гамма-коррекции" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Планшетный" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, fuzzy, no-c-format msgid "ADF Back" msgstr "ÐПД" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, fuzzy, no-c-format msgid "ADF Duplex" msgstr "ДвухÑторонний" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "РаÑпечатка" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "ДвухÑторонний" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "КраÑный" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Зелёный" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Синий" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, fuzzy, no-c-format msgid "Enhance Red" msgstr "Повышение" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, fuzzy, no-c-format msgid "Enhance Green" msgstr "Повышение" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, fuzzy, no-c-format msgid "Enhance Blue" msgstr "Повышение" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ðичего" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "ОдноÑторонний" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "ДвухÑторонний" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Модуль Ð´Ð»Ñ Ñлайдов" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "ÐвтоматичеÑкий податчик документов" @@ -1790,7 +1801,7 @@ msgstr "Струйные принтеры" msgid "CRT monitors" msgstr "Мониторы Ñ ÐЛТ" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1854,8 +1865,9 @@ msgstr "A4" msgid "Max" msgstr "МакÑ" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2031,17 +2043,17 @@ msgstr "" msgid "Quick format" msgstr "БыÑтрый формат" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Дополнительное оборудование" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Извлечь" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Ð’Ñтавить бумагу в уÑтройÑтво подачи документов" @@ -2056,12 +2068,14 @@ msgstr "Ðвтоизвлечение" msgid "Eject document after scanning" msgstr "Извлечь документ поÑле ÑканированиÑ" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Режим автоподачи" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Выбирает режим автоподачи (одноÑторонний/двухÑторонний)" @@ -2112,14 +2126,14 @@ msgstr "" "ПоÑле подачи команды \"Ñканировать\", будет ожидать пока не будет нажата " "кнопка на Ñканере, чтобы дейÑтвительно начать процеÑÑ ÑканированиÑ." -#: backend/epson2.c:102 backend/pixma.c:409 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format -msgid "Infrared" +msgid "TPU8x10" msgstr "" -#: backend/epson2.c:117 +#: backend/epson2.c:102 backend/pixma/pixma.c:409 #, no-c-format -msgid "TPU8x10" +msgid "Infrared" msgstr "" #: backend/epson2.c:136 @@ -2142,494 +2156,514 @@ msgstr "" msgid "User defined CCT profile" msgstr "ОпределÑемое пользователем" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Ð’Ñтавить бумагу в уÑтройÑтво подачи документов" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Без коррекции" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "ÐÐ½Ð°Ð»Ð¾Ð³Ð¾Ð²Ð°Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð³Ð°Ð¼Ð¼Ñ‹" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Вкл" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Выкл" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Размытие" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, fuzzy, no-c-format msgid "Diffusion" msgstr "Ð”Ð¸Ñ„Ñ„ÑƒÐ·Ð¸Ñ Ð¾ÑˆÐ¸Ð±Ð¾Ðº" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, fuzzy, no-c-format msgid "White" msgstr "Уровень белого" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, fuzzy, no-c-format msgid "Black" msgstr "Уровень чёрного" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, fuzzy, no-c-format msgid "Continue" msgstr "УÑловно" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "Горизонтально" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, fuzzy, no-c-format msgid "Horizontal bold" msgstr "Горизонтально" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, fuzzy, no-c-format msgid "Horizontal narrow" msgstr "Горизонтально" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Вертикальное" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, fuzzy, no-c-format msgid "Vertical bold" msgstr "Вертикальное" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, fuzzy, no-c-format msgid "Front" msgstr "РаÑпечатка" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Полутоновый (раÑÑ‚Ñ€)" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Ð“Ñ€ÑƒÐ±Ð°Ñ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ°" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "ВыразительноÑÑ‚ÑŒ изображениÑ" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "ÐаÑыщенноÑÑ‚ÑŒ" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "" "Включает автоматичеÑкое определение порога при Ñканировании штриховых " "изображений." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Зеркальное изображение" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Отображает изображение по горизонтали." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "Уровень белого Ð´Ð»Ñ Ñинего" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "УправлÑет уровнем краÑного" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Цветное штриховое" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Сглаживание" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Значение гаммы" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, fuzzy, no-c-format msgid "Threshold curve" msgstr "Порог" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Порог" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Уменьшение шумов" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Без коррекции" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Без коррекции" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" msgstr "" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "Режим подачи" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Дополнительные параметры" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Без коррекции" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Включить лампу" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Режим подачи" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2637,65 +2671,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð»Ð°Ð¼Ð¿Ñ‹" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "Смещение Ñинего" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Смещение зелёного" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Смещение зелёного" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Смещение Ñинего" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "УÑтанавливает Ñмещение канала Ñинего" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2704,418 +2738,406 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "ДвухÑтороннее Ñканирование" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Дополнительные параметры" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Уменьшение шумов" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "От бумаги" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "От бумаги" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "От бумаги" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "От бумаги" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Ð ÑƒÑ‡Ð½Ð°Ñ Ð¿Ñ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ„Ð¾ÐºÑƒÑировка" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Ð ÑƒÑ‡Ð½Ð°Ñ Ð¿Ñ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ„Ð¾ÐºÑƒÑировка" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "Разрешение ÑканированиÑ" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "Уровень белого" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "ИнтенÑивноÑÑ‚ÑŒ краÑного" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "ДвухÑтороннее Ñканирование" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Дополнительно" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, fuzzy, no-c-format msgid "Disable interpolation" msgstr "Выключить отÑлеживание" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " "than the vertical resolution this disables horizontal interpolation." msgstr "" -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Цветное штриховое" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Калибровка" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Задать режим калибровки" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "КÑширование калибровочных данных" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð»Ð°Ð¼Ð¿Ñ‹" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3124,89 +3146,108 @@ msgstr "" "Лампа будет выключена через указанное Ð²Ñ€ÐµÐ¼Ñ (в минутах). Значение 0 " "означает, что лампа выключатьÑÑ Ð½Ðµ будет." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, fuzzy, no-c-format msgid "Lamp off during scan" msgstr "Ð“Ñ€ÑƒÐ±Ð°Ñ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ°" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "" -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, fuzzy, no-c-format msgid "File button" msgstr "Ожидать Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, fuzzy, no-c-format msgid "Power button" msgstr "Ожидать Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "Ожидать Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, fuzzy, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Ð“Ñ€ÑƒÐ±Ð°Ñ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ°" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, fuzzy, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "ВыполнÑÑ‚ÑŒ калибровку Ñканера перед Ñканированием" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Кнопки" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Калибровка" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, fuzzy, no-c-format msgid "Start calibration using special sheet" msgstr "Ðачать процеÑÑ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ¸." -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, fuzzy, no-c-format msgid "Clear calibration" msgstr "Ð“Ñ€ÑƒÐ±Ð°Ñ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ°" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, fuzzy, no-c-format msgid "Clear calibration cache" msgstr "КÑширование калибровочных данных" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Ð“Ñ€ÑƒÐ±Ð°Ñ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ°" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Смещение зелёного" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Слайд-модуль" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Слайд-модуль" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3316,6 +3357,311 @@ msgstr "Значение гаммы" msgid "Sets the gamma value of all channels." msgstr "УÑтанавливает значение гаммы вÑех каналов." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Дополнительные параметры" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Грубое" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Точное" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "ПользовательÑкое" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "ÐвтоматичеÑки" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "ПропуÑкать Ñквозь" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "Чёрно-белое NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Чёрно-белое XPA" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Медленно" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Ðормально" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "БыÑтро" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Очень быÑтро" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "Двухточечное" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "Четырёхточечное" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "ВоÑьмиточечное" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "РаÑпечатка" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Слайд" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Плёнка" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ÐПД" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "УÑловно" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "ÐкÑперимент" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "ЗаоÑтрениÑ" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "УÑтанавливает величину заоÑтрениÑ." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "ÐвтоматичеÑкий порог" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Включает автоматичеÑкое определение порога при Ñканировании штриховых " +"изображений." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Выберите фильтр Ð´Ð»Ñ ÑглаживаниÑ." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Выгружать ноÑитель поÑле ÑканированиÑ" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Выгружает ноÑитель поÑле ÑканированиÑ." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Сменить документ" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Изменить документ." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Выгрузить" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Выгрузить документ." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Ðачать процеÑÑ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ¸." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "ÐоÑитель" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "УÑтановить тип ноÑителÑ." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð´ÐµÑ€Ð¶ÐºÐ¸" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Длительное Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð´ÐµÑ€Ð¶ÐºÐ¸ позволÑет Ñканеру Ñобрать больше Ñвета. " +"РекомендуетÑÑ Ð¸Ñпользовать 175% Ð´Ð»Ñ Ñ€Ð°Ñпечаток, 150% Ð´Ð»Ñ Ð½Ð¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ñ… " +"Ñлайдов и \"Ðегатив\" Ð´Ð»Ñ Ð½ÐµÐ³Ð°Ñ‚Ð¸Ð²Ð¾Ð². Ð”Ð»Ñ Ñ‚Ñ‘Ð¼Ð½Ñ‹Ñ… (недоÑкÑпонированных) " +"изображений вы можете увеличить Ñто значение." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "УÑтанавливает цветовую матрицу Ñканера." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "ПользовательÑÐºÐ°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°" + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "ÐžÐ´Ð½Ð¾Ñ‚Ð¾Ð½Ð½Ð°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "ПользовательÑÐºÐ°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° Ð´Ð»Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾-белых изображений." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Отобразить горизонтально" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Отображает изображение по горизонтали." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Отобразить вертикально" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Отображает изображение по вертикали." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Обновить параметры" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "ОбновлÑет параметры." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "ВоÑьмибитный вывод" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Внутри иÑпользовать разрÑдноÑÑ‚ÑŒ более 8 бит, но выводить только 8 бит." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Ожидать кнопки на лицевой панели" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "Ждать Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ на передней панели Ð´Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° ÑканированиÑ." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Выключить лампу" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Выключает лампу Ñканера." + #: backend/hp3500.c:1020 #, fuzzy, no-c-format msgid "Geometry Group" @@ -3326,12 +3672,6 @@ msgstr "РаÑположение" msgid "Scan Mode Group" msgstr "Режим ÑканированиÑ" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Слайд" - #: backend/hp3900_sane.c:1405 #, fuzzy, no-c-format msgid "Scanner model" @@ -3339,12 +3679,12 @@ msgstr "Режим ÑканированиÑ" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "" #: backend/hp3900_sane.c:1436 @@ -3525,11 +3865,6 @@ msgstr "Включить/выключить лампу." msgid "Calibrates for black and white level." msgstr "Калибрует Ð´Ð»Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾Ð³Ð¾ и белого уровнÑ." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ÐПД" - #: backend/hp5590.c:95 #, fuzzy, no-c-format msgid "TMA Slides" @@ -3640,300 +3975,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Дополнительные параметры" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Грубое" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Точное" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "ПользовательÑкое" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "ÐвтоматичеÑки" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "ПропуÑкать Ñквозь" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "Чёрно-белое NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Чёрно-белое XPA" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Медленно" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Ðормально" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "БыÑтро" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Очень быÑтро" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "Двухточечное" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "Четырёхточечное" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "ВоÑьмиточечное" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "РаÑпечатка" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Плёнка" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "УÑловно" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "ÐкÑперимент" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "ЗаоÑтрениÑ" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "УÑтанавливает величину заоÑтрениÑ." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "ÐвтоматичеÑкий порог" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Включает автоматичеÑкое определение порога при Ñканировании штриховых " -"изображений." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Выберите фильтр Ð´Ð»Ñ ÑглаживаниÑ." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Выгружать ноÑитель поÑле ÑканированиÑ" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Выгружает ноÑитель поÑле ÑканированиÑ." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Сменить документ" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Изменить документ." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Выгрузить" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Выгрузить документ." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Ðачать процеÑÑ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ¸." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "ÐоÑитель" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "УÑтановить тип ноÑителÑ." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð´ÐµÑ€Ð¶ÐºÐ¸" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Длительное Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð´ÐµÑ€Ð¶ÐºÐ¸ позволÑет Ñканеру Ñобрать больше Ñвета. " -"РекомендуетÑÑ Ð¸Ñпользовать 175% Ð´Ð»Ñ Ñ€Ð°Ñпечаток, 150% Ð´Ð»Ñ Ð½Ð¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ñ… " -"Ñлайдов и \"Ðегатив\" Ð´Ð»Ñ Ð½ÐµÐ³Ð°Ñ‚Ð¸Ð²Ð¾Ð². Ð”Ð»Ñ Ñ‚Ñ‘Ð¼Ð½Ñ‹Ñ… (недоÑкÑпонированных) " -"изображений вы можете увеличить Ñто значение." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "УÑтанавливает цветовую матрицу Ñканера." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "ПользовательÑÐºÐ°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°" - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "ÐžÐ´Ð½Ð¾Ñ‚Ð¾Ð½Ð½Ð°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "ПользовательÑÐºÐ°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° Ð´Ð»Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾-белых изображений." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Отобразить горизонтально" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Отображает изображение по горизонтали." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Отобразить вертикально" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Отображает изображение по вертикали." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Обновить параметры" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "ОбновлÑет параметры." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "ВоÑьмибитный вывод" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Внутри иÑпользовать разрÑдноÑÑ‚ÑŒ более 8 бит, но выводить только 8 бит." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Ожидать кнопки на лицевой панели" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "Ждать Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ на передней панели Ð´Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° ÑканированиÑ." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Выключить лампу" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Выключает лампу Ñканера." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4032,7 +4073,7 @@ msgid "single" msgstr "" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, fuzzy, no-c-format msgid "continuous" @@ -4200,9 +4241,9 @@ msgid "crt" msgstr "" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Штриховой" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4331,7 +4372,7 @@ msgstr "УÑтанавливает выразительноÑÑ‚ÑŒ изображ #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Гамма" @@ -4398,11 +4439,11 @@ msgstr "" msgid "Request driver to remove border from pages digitally" msgstr "" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" #: backend/kvs20xx_opt.c:424 backend/kvs20xx_opt.c:425 @@ -4434,12 +4475,12 @@ msgstr "" #: backend/kvs40xx_opt.c:231 #, fuzzy, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "Печать выÑокой плотноÑти" #: backend/kvs40xx_opt.c:232 #, fuzzy, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Печать выÑокой плотноÑти" #: backend/kvs40xx_opt.c:243 @@ -4462,6 +4503,13 @@ msgstr "Ðормально" msgid "Enhanced mode" msgstr "Повышение" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4521,7 +4569,7 @@ msgstr "" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +msgid "JPEG compression (your application must be able to uncompress)" msgstr "" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4556,12 +4604,12 @@ msgstr "" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "" #: backend/kvs40xx_opt.c:816 @@ -4571,13 +4619,13 @@ msgstr "" #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Зеркальное изображение" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4614,52 +4662,52 @@ msgstr "" msgid "8x8 Vertical Line" msgstr "8x8 Ð²ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "УÑиление" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "ÐаÑтройки уÑÐ¸Ð»ÐµÐ½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ñ‹Ñ… каналов" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "УÑиление Ñерого" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "УÑтанавливает уÑиление Ñерого канала" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "УÑиление краÑного" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "УÑтанавливает уÑиление краÑного канала" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "УÑиление зелёного" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "УÑтанавливает уÑиление зелёного канала" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "УÑиление Ñинего" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "УÑтанавливает уÑиление Ñинего канала" @@ -4745,7 +4793,7 @@ msgstr "Одна Ñтраница" msgid "All pages" msgstr "Ð’Ñе Ñтраницы" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "лиÑтовой Ñканер" @@ -5265,39 +5313,44 @@ msgstr "" "Разогревать пока ÑркоÑÑ‚ÑŒ лампы не Ñтанет поÑтоÑнной, вмеÑто проÑтого 40-" "тиÑекундного Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ñ€Ð°Ð·Ð¾Ð³Ñ€ÐµÐ²Ð°." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Ð“Ñ€ÑƒÐ±Ð°Ñ ÐºÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²ÐºÐ°" + +#: backend/pixma/pixma.c:397 #, fuzzy, no-c-format msgid "Negative color" msgstr "Ðегатив" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, fuzzy, no-c-format msgid "Negative gray" msgstr "Ðегатив" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " "mode and resolution. Resets mode and resolution to auto values." msgstr "" -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5305,40 +5358,40 @@ msgid "" "cancel, press \"GRAY\" button." msgstr "" -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, fuzzy, no-c-format msgid "Update button state" msgstr "СоÑтоÑние кнопки" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, fuzzy, no-c-format msgid "Button 1" msgstr "Кнопки" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, fuzzy, no-c-format msgid "Button 2" msgstr "Кнопки" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5427,7 +5480,7 @@ msgstr "" msgid "Red gain value of the AFE" msgstr "" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Смещение краÑного" @@ -5690,7 +5743,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Ðтот параметр отражает ÑоÑтоÑние кнопок Ñканера." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Включить лампу" @@ -5700,12 +5753,12 @@ msgstr "Включить лампу" msgid "Turn on scanner lamp" msgstr "Включить лампу Ñканера" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Выключить лампу" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Выключить лампу Ñканера" @@ -5852,13 +5905,13 @@ msgid "Focus point" msgstr "РаÑположение фокуÑа" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Цветных Ñтрок за Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° чтение" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "Чёрно-белых Ñтрок за Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° чтение" #: backend/stv680.c:974 @@ -6466,52 +6519,52 @@ msgstr "Режим калибровки" msgid "Define calibration mode" msgstr "Задать режим калибровки" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Включить/выключить лампу" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "включить UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Включить/выключить UTA" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Смещение" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "ÐаÑтройки ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ñ‹Ñ… каналов" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "Смещение Ñерого" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "УÑтанавливает Ñмещение канала Ñерого" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "УÑтанавливает Ñмещение канала краÑного" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "УÑтанавливает Ñмещение канала зелёного" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "УÑтанавливает Ñмещение канала Ñинего" @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: sane-backends 1.0.18\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" "PO-Revision-Date: 2012-10-22 11:17+0200\n" "Last-Translator: Mattias Ellert <mattias.ellert@fysast.uu.se>\n" "Language-Team: Swedish <sv@li.org>\n" @@ -31,31 +31,31 @@ msgid "Standard" msgstr "Standard" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "Geometri" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "Förbättring" @@ -89,7 +89,7 @@ msgid "Bit depth" msgstr "Bitdjup" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Bildläsarläge" @@ -130,7 +130,7 @@ msgid "Bottom-right y" msgstr "Nedre" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Upplösning" @@ -285,7 +285,7 @@ msgstr "Filnamn" msgid "Halftone pattern size" msgstr "Rastermönstersstorlek" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Rastermönster" @@ -295,10 +295,10 @@ msgstr "Rastermönster" msgid "Bind X and Y resolution" msgstr "Koppla X- och Y-upplösning" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Negativ" @@ -419,9 +419,9 @@ msgid "Lamp off at exit" msgstr "Lampa av vid avslut" #: include/sane/saneopts.h:245 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Skrivskyddat värde som anger hur mÃ¥nga parametrar en specifik enhet " @@ -749,8 +749,8 @@ msgid "Analog gamma-correction for blue" msgstr "Analog gammakorrigering för blÃ¥tt" #: include/sane/saneopts.h:415 -#, no-c-format -msgid "Warmup lamp before scanning" +#, fuzzy, no-c-format +msgid "Warm up lamp before scanning" msgstr "Värm upp lampan innan inläsning" #: include/sane/saneopts.h:417 @@ -899,8 +899,8 @@ msgid "Operation not supported" msgstr "Kommandot ej understött" #: backend/sane_strstatus.c:65 -#, no-c-format -msgid "Operation was cancelled" +#, fuzzy, no-c-format +msgid "Operation was canceled" msgstr "Kommandot avbröts" #: backend/sane_strstatus.c:68 @@ -993,10 +993,10 @@ msgid "Only perform shading-correction" msgstr "Utför endast skuggkorrigering" #: backend/artec_eplus48u.c:2956 -#, no-c-format +#, fuzzy, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Om denna inställning är vald utförs endast skuggkorrigering vid " @@ -1024,83 +1024,43 @@ msgid "Duplex scan" msgstr "Dubbelsidig inläsning" #: backend/avision.h:783 -#, no-c-format +#, fuzzy, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "Dubbelsidig inläsning läser in dokumentets framsida och baksida" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Kalibrera bildläsaren" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Utför bildläsarkalibrering före inläsning" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 -#, no-c-format -msgid "Grayscale scan" -msgstr "GrÃ¥skaleinläsning" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Gör en grÃ¥skaleinläsning i stället för en färginläsning" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Analog förstärkning" +msgid "Correction according to transparency ratio" +msgstr "Korrigering beroende pÃ¥ genomlysningskvot" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Öka eller minska CCD-sensorns analoga förstärkning" +msgid "Correction according to film type" +msgstr "Korrigering beroende pÃ¥ filmtyp" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Gammakorrigering" +msgid "Fine color" +msgstr "Fin färg" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Väljer gammakorrigerad överföringskurva" +msgid "Negatives" +msgstr "Negativ" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "RÃ¥" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "Fin färg" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Ingen genomlysningskorrigering" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Korrigering beroende pÃ¥ filmtyp" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Korrigering beroende pÃ¥ genomlysningskvot" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Negativ" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1234,8 +1194,8 @@ msgid "invalid bit IDENTIFY message" msgstr "ogiltigt bit-IDENTIFY-meddelande" #: backend/canon.c:460 -#, no-c-format -msgid "option not connect" +#, fuzzy, no-c-format +msgid "option not correct" msgstr "inställning inte anslut" #: backend/canon.c:474 @@ -1525,133 +1485,184 @@ msgstr "Välj filmtyp" msgid "Select the film type" msgstr "Välj filmtyp" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Kalibrera bildläsaren" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Utför bildläsarkalibrering före inläsning" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "GrÃ¥skaleinläsning" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Gör en grÃ¥skaleinläsning i stället för en färginläsning" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Analog förstärkning" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Öka eller minska CCD-sensorns analoga förstärkning" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Gammakorrigering" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Väljer gammakorrigerad överföringskurva" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Flatbädd" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "Automatisk dokumentmatare framsida" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "Automatisk dokumentmatare baksida" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Automatisk dokumentmatare dubbelsidigt" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, fuzzy, no-c-format msgid "Card Front" msgstr "Framsida" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, fuzzy, no-c-format msgid "Card Back" msgstr "Baksida" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, fuzzy, no-c-format msgid "Card Duplex" msgstr "Dubbelsidigt" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Röd" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Grön" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "BlÃ¥" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Framhäv rött" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Framhäv grönt" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Framhäv blÃ¥tt" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Inget" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "Procentsats för hoppa över blanka sidor" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, fuzzy, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "Begär att drivrutinen hoppar över sidor med fÃ¥ mörka pixlar" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Enkelsidigt" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Dubbelsidigt" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Genomlysningsenhet" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Automatisk dokumentmatare" @@ -1763,7 +1774,7 @@ msgstr "BläckstrÃ¥leskrivare" msgid "CRT monitors" msgstr "Bildskärmar (CRT)" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1827,8 +1838,9 @@ msgstr "A4" msgid "Max" msgstr "Max" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2000,17 +2012,17 @@ msgstr "Anger zoom-faktorn som bildläsaren kommer att använda" msgid "Quick format" msgstr "Snabbformatera" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Tillvalsutrustning" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Mata ut" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Mata ut bladet i dokumentmataren" @@ -2025,12 +2037,14 @@ msgstr "Mata ut automatiskt" msgid "Eject document after scanning" msgstr "Mata ut dokument efter inläsning" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Dokumentmatarläge" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "" @@ -2083,16 +2097,16 @@ msgstr "" "Efter att ha skickat inläsningskommandot, vänta tills knappen pÃ¥ läsaren " "trycks in för att starta inläsningen." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Infraröd" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "TPU 8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Infraröd" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2113,494 +2127,514 @@ msgstr "Inbyggd CCT-profil" msgid "User defined CCT profile" msgstr "Användardefinierad CCT-profil" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "" + +#: backend/epsonds.c:751 +#, fuzzy, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Mata ut bladet i dokumentmataren" + +#: backend/epsonds.c:771 +#, fuzzy, no-c-format +msgid "ADF Skew Correction" +msgstr "Ingen korrigering" + +#: backend/epsonds.c:773 +#, fuzzy, no-c-format +msgid "Enables ADF skew correction" +msgstr "Stäng av gammakorrigering" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "PÃ¥" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Av" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Gitter" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "Diffusion" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Vit" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Svart" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Fortsätt" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Avsluta" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10 mm" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15 mm" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20 mm" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "VÃ¥grätt" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "VÃ¥grätt fetstil" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "VÃ¥grätt smal" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "Lodrätt" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Lodrätt fetstil" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "UppifrÃ¥n och ner" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "NerifrÃ¥n och upp" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Framsida" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Baksida" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "Gammafunktionsexponent" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "Ändrar intensitet hos mellantoner" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, fuzzy, no-c-format msgid "Reverse image format" msgstr "Inverterad bild" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, fuzzy, no-c-format msgid "Halftone type" msgstr "Raster" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, fuzzy, no-c-format msgid "Perform outline extraction" msgstr "Utför kalibrering" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, fuzzy, no-c-format msgid "Emphasis" msgstr "Bildton" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, fuzzy, no-c-format msgid "Separation" msgstr "Mättnad" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, fuzzy, no-c-format msgid "Enable automatic separation of image and text" msgstr "" "Möjliggör automatisk bestämning av tröskelvärde för " "streckteckningsinläsningar." -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, fuzzy, no-c-format msgid "Mirroring" msgstr "Spegla bild" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, fuzzy, no-c-format msgid "Reflect output image horizontally" msgstr "Spegla bilden vÃ¥grätt." -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, fuzzy, no-c-format msgid "White level follower" msgstr "VitnivÃ¥ för blÃ¥tt" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, fuzzy, no-c-format msgid "Control white level follower" msgstr "Bestämmer rödnivÃ¥n" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, fuzzy, no-c-format msgid "BP filter" msgstr "Färgfilter" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "Utjämning" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, fuzzy, no-c-format msgid "Gamma curve" msgstr "Gammavärde" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Tröskelkurva" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, fuzzy, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" msgstr "Dynamisk tröskelkurva, frÃ¥n ljust till mörkt, vanligen 50-65" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, fuzzy, no-c-format msgid "Threshold white" msgstr "Tröskelvärde" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, fuzzy, no-c-format msgid "Noise removal" msgstr "Brusreducering" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, fuzzy, no-c-format msgid "Auto width detection" msgstr "Ingen detektering" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "" -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, fuzzy, no-c-format msgid "Auto length detection" msgstr "Ingen detektering" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, fuzzy, no-c-format msgid "Compression" msgstr "jpeg-komprimmering" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " "is same as 4" msgstr "" -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, fuzzy, no-c-format msgid "Action following double feed error" msgstr "Ignorera högra dubbelmatningssensorn" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, fuzzy, no-c-format msgid "Enable double feed error due to skew" msgstr "Aktivera/avaktivera dubbelmatningsdetekteing" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, fuzzy, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Aktivera/avaktivera dubbelmatningsdetekteing" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, fuzzy, no-c-format msgid "Enable double feed error due to paper length" msgstr "Aktivera/avaktivera dubbelmatningsdetekteing" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, fuzzy, no-c-format msgid "DF recovery mode" msgstr "automatiska dokumentmatarens lock är öppet" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, fuzzy, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "Begär att drivrutinen tar bort ramar frÃ¥n sidor auomatiskt" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, fuzzy, no-c-format msgid "Advanced paper protection" msgstr "Avancerade inställningar" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, fuzzy, no-c-format msgid "Staple detection" msgstr "Ingen detektering" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" msgstr "" -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, fuzzy, no-c-format msgid "Dropout color" msgstr "Blindfärg" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " "useful for colored paper or ink" msgstr "" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, fuzzy, no-c-format msgid "Buffer mode" msgstr "Dokumentmatarläge" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format msgid "Request scanner to read pages quickly from ADF into internal memory" msgstr "" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" msgstr "" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2608,65 +2642,65 @@ msgid "" "collection on remaining sides. May conflict with bgcolor option" msgstr "" -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" msgstr "" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, fuzzy, no-c-format msgid "Off timer" msgstr "Lampavstängningstid" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " "off. Will be rounded to nearest 15 minutes. Zero means never power off." msgstr "" -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, fuzzy, no-c-format msgid "Duplex offset" msgstr "BlÃ¥ offset" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Grön offset" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, fuzzy, no-c-format msgid "Adjust green/red offset" msgstr "Grön offset" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "BlÃ¥ offset" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, fuzzy, no-c-format msgid "Adjust blue/red offset" msgstr "Ställer in den blÃ¥ kanalens offset" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, fuzzy, no-c-format msgid "Low Memory" msgstr "Slut pÃ¥ minne" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2675,379 +2709,364 @@ msgid "" "only be used with custom front-end software." msgstr "" -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, fuzzy, no-c-format msgid "Duplex side" msgstr "Dubbelsidig inläsning" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " "sane_read will return." msgstr "" -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, fuzzy, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "Begär att drivrutinen linjerar upp sneda sidor digitalt" -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Mjukvaruupplinjering" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, fuzzy, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "Begär att drivrutinen linjerar upp sneda sidor digitalt" -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Mjukvarufläckborttagningsdiameter" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, fuzzy, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" "Maximal diameter för ensamma prickar som tas bort frÃ¥n den inlästa bilden" -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "Mjukvarubeskärning" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, fuzzy, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "Begär att drivrutinen tar bort ramar frÃ¥n sidor auomatiskt" -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." msgstr "" -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, fuzzy, no-c-format msgid "Endorser Options" msgstr "Avancerade inställningar" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "" -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "" -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "" -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "" -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, fuzzy, no-c-format msgid "Endorser direction" msgstr "Brusreducering" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "" -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " "replaced by counter value." msgstr "" -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, fuzzy, no-c-format msgid "A3 paper" msgstr "FrÃ¥n papper" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, fuzzy, no-c-format msgid "B4 paper" msgstr "FrÃ¥n papper" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, fuzzy, no-c-format msgid "A4 paper" msgstr "FrÃ¥n papper" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, fuzzy, no-c-format msgid "B5 paper" msgstr "FrÃ¥n papper" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, fuzzy, no-c-format msgid "OMR or double feed detected" msgstr "Dubbelmatningsdetektering" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, fuzzy, no-c-format msgid "Scanner in power saving mode" msgstr "Bildläsarens lock är öppet" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, fuzzy, no-c-format msgid "Manual feed" msgstr "Manuell matning" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, fuzzy, no-c-format msgid "Manual feed selected" msgstr "Manuell matning" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, fuzzy, no-c-format msgid "Double feed" msgstr "Dubbelmatningsdetektering" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, fuzzy, no-c-format msgid "Double feed detected" msgstr "Dubbelmatningsdetektering" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, fuzzy, no-c-format msgid "Hardware error code" msgstr "hÃ¥rdvarukontrollfel" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, fuzzy, no-c-format msgid "Imprinter ink level" msgstr "VitnivÃ¥" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, fuzzy, no-c-format msgid "Density" msgstr "Densitetsinställning" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, fuzzy, no-c-format msgid "Density dial" msgstr "Densitetsinställning" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, fuzzy, no-c-format msgid "Duplex switch" msgstr "Dubbelsidig inläsning" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "Begär att drivrutinen tar bort ram frÃ¥n sidor automatiskt" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "Begär att drivrutinen hoppar över sidor med fÃ¥ mörka pixlar" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "Mjukvaruavrotera" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" "Begär att drivrutinen detekterar och korrigerar 90 graders bildrotation" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Övrigt" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "Dynamisk tröskelkurva, frÃ¥n ljust till mörkt, vanligen 50-65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Avaktivera dynamisk streckteckning" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"Stäng av användandet av en adaptiv algoritm i mjukvaran för att generera " -"streckteckningsinläsningar för att i stället använda hÃ¥rdvarans " -"streckteckningsinläsningsläge." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Stäng av interpolering" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3057,46 +3076,46 @@ msgstr "" "mindre än den vertikala upplösningen stänger detta av den horisontella " "interpoleringen." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, fuzzy, no-c-format msgid "Color filter" msgstr "Färgfilter" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "När grÃ¥skala eller streckteckning används väljer denna inställning den " "använda färgen." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, fuzzy, no-c-format msgid "Calibration file" msgstr "Kalibrering" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, fuzzy, no-c-format msgid "Specify the calibration file to use" msgstr "Definiera kalibreringsläge" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, fuzzy, no-c-format msgid "Calibration cache expiration time" msgstr "Kalibreringsdatacache" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " "means cache is not used. A negative value means cache never expires." msgstr "" -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Lampavstängningstid" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3105,89 +3124,108 @@ msgstr "" "Lampan kommer att stängas av efter den angivna tiden (i minuter). Värdet " "0 betyder att lampan inte kommer att stängas av." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "Stäng av lampan under inläsning" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "Lampan kommer att stängas av under inläsningen." -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Filknapp" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Optisk teckenigenkännings-knapp" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "PÃ¥slagningsknapp" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, fuzzy, no-c-format msgid "Extra button" msgstr "E-postknapp" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 -#, no-c-format -msgid "Need calibration" +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 +#, fuzzy, no-c-format +msgid "Needs calibration" msgstr "Behöver kalibrering" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Bildläsaren behöver kalibrering för nuvarande inställningar" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Knappar" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Kalibrera" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "PÃ¥börja kalibrering med specialark" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Rensa kalibrering" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Rensa kalibreringsdatacache" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, fuzzy, no-c-format msgid "Force calibration" msgstr "Grovkalibrering" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, fuzzy, no-c-format +msgid "Ignore internal offsets" +msgstr "Grön offset" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Genomlysningsadapter" +#: backend/genesys/genesys.h:80 +#, fuzzy, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Genomlysningsadapter" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3293,6 +3331,312 @@ msgstr "Gammavärde" msgid "Sets the gamma value of all channels." msgstr "Ställer in gammavärdet för alla kanaler." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Avancerade inställningar" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Grovt" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "Fint" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "Bayer" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Användardefinierat" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Automatiskt" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC-RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA-RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "Oförändrat" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "NTSC-grÃ¥" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "XPA-grÃ¥" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "LÃ¥ngsam" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Normal" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Snabb" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Extra snabb" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "2 pixlar" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "4 pixlar" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "8 pixlar" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Fotografi" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Diapositiv" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Filmremsa" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "Automatisk dokumentmatare" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Villkorlig" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "Experiment" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Skärpa" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Ställer in skärpevärdet." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Automatiskt tröskelvärde" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Möjliggör automatisk bestämning av tröskelvärde för " +"streckteckningsinläsningar." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Välj utjämningsfilter." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Mata ut media efter inläsning" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Matar ut media efter en inläsning." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Byt dokument" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Byt dokument." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Mata ut" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Mata ut dokument." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "PÃ¥börja kalibreringsprocessen." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "Media" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Välj mediatyp." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Exponeringstid" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"En längre exponeringstid lÃ¥ter bildläsaren samla in mer ljus. Föreslagen " +"användning är 175% för fotografier, 150% för diapositiv och \"Negativ\" " +"för negativ film. För mörka (underexponerade) bilder kan du öka detta " +"värde." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "Färgmatris" + +#: backend/hp-option.h:121 +#, fuzzy, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Ställer in bildläsarens färgmatris." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Användardefinierad färgmatris." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Enfärgsmatris" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Användardefinierad färgmatris för grÃ¥skaleinläsningar." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Spegla vÃ¥grätt" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Spegla bilden vÃ¥grätt." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Spegla lodrätt" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Spegla bilden lodrätt." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Uppdatera inställningsvärden" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Uppdatera inställningsvärden." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8 bitars utdata" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Använd ett bitdjup större än 8 internt, men ge endast 8 bitars utdata." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Invänta knapptryck" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" +"Vänta med inläsningen tills dess att knappen pÃ¥ frontpanelen trycks in." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "SlÃ¥ av lampan" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "SlÃ¥ av bildläsarlampan." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3303,12 +3647,6 @@ msgstr "Geometrigrupp" msgid "Scan Mode Group" msgstr "Bildläsarlägesgrupp" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Diapositiv" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3316,12 +3654,12 @@ msgstr "Bildläsarmodel" #: backend/hp3900_sane.c:1408 #, fuzzy, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "TillÃ¥ter att testa enhetsbeteende med andra understötta modeller" #: backend/hp3900_sane.c:1422 -#, no-c-format -msgid "Image colours will be inverted" +#, fuzzy, no-c-format +msgid "Image colors will be inverted" msgstr "Bildens färger kommer att inverteras" #: backend/hp3900_sane.c:1436 @@ -3510,11 +3848,6 @@ msgstr "Sätter pÃ¥ eller av lampan." msgid "Calibrates for black and white level." msgstr "Kalibrerar för svart- och vitnivÃ¥." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "Automatisk dokumentmatare" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3625,301 +3958,6 @@ msgid "" "r*65536+256*g+b or gray value (default=violet or gray)" msgstr "" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Avancerade inställningar" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Grovt" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "Fint" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "Bayer" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Användardefinierat" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Automatiskt" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC-RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA-RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "Oförändrat" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "NTSC-grÃ¥" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "XPA-grÃ¥" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "LÃ¥ngsam" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Normal" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Snabb" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Extra snabb" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "2 pixlar" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "4 pixlar" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "8 pixlar" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Fotografi" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Filmremsa" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Villkorlig" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "Experiment" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Skärpa" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Ställer in skärpevärdet." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Automatiskt tröskelvärde" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Möjliggör automatisk bestämning av tröskelvärde för " -"streckteckningsinläsningar." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Välj utjämningsfilter." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Mata ut media efter inläsning" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Matar ut media efter en inläsning." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Byt dokument" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Byt dokument." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Mata ut" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Mata ut dokument." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "PÃ¥börja kalibreringsprocessen." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "Media" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Välj mediatyp." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Exponeringstid" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"En längre exponeringstid lÃ¥ter bildläsaren samla in mer ljus. Föreslagen " -"användning är 175% för fotografier, 150% för diapositiv och \"Negativ\" " -"för negativ film. För mörka (underexponerade) bilder kan du öka detta " -"värde." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "Färgmatris" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Ställer in bildläsarens färgmatris." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Användardefinierad färgmatris." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Enfärgsmatris" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Användardefinierad färgmatris för grÃ¥skaleinläsningar." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Spegla vÃ¥grätt" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Spegla bilden vÃ¥grätt." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Spegla lodrätt" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Spegla bilden lodrätt." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Uppdatera inställningsvärden" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Uppdatera inställningsvärden." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8 bitars utdata" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Använd ett bitdjup större än 8 internt, men ge endast 8 bitars utdata." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Invänta knapptryck" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" -"Vänta med inläsningen tills dess att knappen pÃ¥ frontpanelen trycks in." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "SlÃ¥ av lampan" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "SlÃ¥ av bildläsarlampan." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4018,7 +4056,7 @@ msgid "single" msgstr "ensidigt" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4186,9 +4224,9 @@ msgid "crt" msgstr "bildskärm" #: backend/kvs1025_opt.c:229 -#, no-c-format -msgid "linier" -msgstr "linjär" +#, fuzzy, no-c-format +msgid "linear" +msgstr "Streckteckning" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4317,7 +4355,7 @@ msgstr "Ställer in bildton" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Gamma" @@ -4385,11 +4423,11 @@ msgstr "Automatisk beskärning i mjukvara" msgid "Request driver to remove border from pages digitally" msgstr "Begär att drivrutinen tar bort ramar frÃ¥n sidor auomatiskt" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 -#, no-c-format +#: backend/kvs20xx_opt.c:233 +#, fuzzy, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" "I längdkontrolläge läser bildläsaren upp till den kortare av verklig " "papperslängd och logisk dokumentlängd." @@ -4422,13 +4460,13 @@ msgid "B4" msgstr "B4" #: backend/kvs40xx_opt.c:231 -#, no-c-format -msgid "High sensivity" +#, fuzzy, no-c-format +msgid "High sensitivity" msgstr "Hög känsighet" #: backend/kvs40xx_opt.c:232 -#, no-c-format -msgid "Low sensivity" +#, fuzzy, no-c-format +msgid "Low sensitivity" msgstr "LÃ¥g känsighet" #: backend/kvs40xx_opt.c:243 @@ -4451,6 +4489,15 @@ msgstr "Normalläge" msgid "Enhanced mode" msgstr "Förbättringsläge" +#: backend/kvs40xx_opt.c:396 +#, fuzzy, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"I längdkontrolläge läser bildläsaren upp till den kortare av verklig " +"papperslängd och logisk dokumentlängd." + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4512,8 +4559,8 @@ msgid "JPEG compression" msgstr "JPEG-komprimmering" #: backend/kvs40xx_opt.c:718 -#, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" +#, fuzzy, no-c-format +msgid "JPEG compression (your application must be able to uncompress)" msgstr "JPEG-komprimmering (din applikation mÃ¥ste kunna dekomprimmera)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 @@ -4547,13 +4594,13 @@ msgid "Skew adjustment" msgstr "Justering för sned inmatning" #: backend/kvs40xx_opt.c:808 -#, no-c-format -msgid "Stop scanner when a paper have been skewed" +#, fuzzy, no-c-format +msgid "Stop scanner if a sheet is skewed" msgstr "Stoppa bildläsaren när ett papper har inmatats snett" #: backend/kvs40xx_opt.c:809 -#, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +#, fuzzy, no-c-format +msgid "Scanner will stop if a sheet is skewed" msgstr "Stoppa bildläsaren när ett papper har inmatats snett" #: backend/kvs40xx_opt.c:816 @@ -4562,14 +4609,14 @@ msgid "Crop actual image area" msgstr "Beskär verklig bildarea" #: backend/kvs40xx_opt.c:817 -#, no-c-format -msgid "Scanner automatically detect image area and crop it" +#, fuzzy, no-c-format +msgid "Scanner will automatically detect image area and crop to it" msgstr "Bildläsaren detecterar automatiskt verklig bildarea och beskär den" #: backend/kvs40xx_opt.c:827 -#, no-c-format -msgid "It is right and left reversing" -msgstr "Den kastar om höger och vänster" +#, fuzzy, no-c-format +msgid "Left/right mirror image" +msgstr "Spegla bild" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4606,52 +4653,52 @@ msgstr "8x8 Bayer" msgid "8x8 Vertical Line" msgstr "8x8 lodrät linje" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "Förstärking" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Inställningar för färgkanalernas förstärkning" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "GrÃ¥ förstärkning" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Ställer in den grÃ¥ kanalens förstärkning" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "Röd förstärkning" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Ställer in den röda kanalens förstärkning" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "Grön förstärkning" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Ställer in den gröna kanalens förstärkning" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "BlÃ¥ förstärkning" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Ställer in den blÃ¥ kanalens förstärkning" @@ -4737,7 +4784,7 @@ msgstr "En sida" msgid "All pages" msgstr "Alla sidor" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "arkmatad bildläsare" @@ -5244,27 +5291,32 @@ msgstr "" "Värm upp tills lampans ljusstyrka är konstant i stället för att " "insistera pÃ¥ 40 sekunders uppvärmningstid." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, fuzzy, no-c-format +msgid "Need calibration" +msgstr "Behöver kalibrering" + +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "Negativ färg" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "Negativ grÃ¥skala" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "48 bitars färg" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "16 bitars grÃ¥skala" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " @@ -5273,12 +5325,12 @@ msgstr "" "Väljer inläsningskälla (som t.ex. dokumentmatare). Välj källa före läge " "och upplösning. Ã…terställer läge och upplösning till förvalsvärden." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Knappkontrollerad inläsning" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5289,40 +5341,40 @@ msgstr "" "omedelbart. För att forsätta, tryck SCAN-knappen (för MP150) eller COLOR-" "knappen (för andra modeller). För att avbryta, tryck GRAY-knappen." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Uppdatera knappläge" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Knapp 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Knapp 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" @@ -5411,7 +5463,7 @@ msgstr "Analogt framplan" msgid "Red gain value of the AFE" msgstr "Det analoga framplanets rödförstärkningsvärde" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Röd offset" @@ -5687,7 +5739,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Denna inställing avspeglar status pÃ¥ en av bildläsarens knappar." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Lampa pÃ¥" @@ -5697,12 +5749,12 @@ msgstr "Lampa pÃ¥" msgid "Turn on scanner lamp" msgstr "SlÃ¥ pÃ¥ bildläsarlampan" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Lampa av" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "SlÃ¥ av bildläsarlampan" @@ -5846,13 +5898,13 @@ msgid "Focus point" msgstr "Fokuseringspunkt" #: backend/snapscan-options.c:930 -#, no-c-format -msgid "Colour lines per read" +#, fuzzy, no-c-format +msgid "Color lines per read" msgstr "Färglinjer per inläsning" #: backend/snapscan-options.c:942 -#, no-c-format -msgid "Greyscale lines per read" +#, fuzzy, no-c-format +msgid "Grayscale lines per read" msgstr "GrÃ¥skalelinjer per inläsning" #: backend/stv680.c:974 @@ -6494,56 +6546,73 @@ msgstr "Kalibreringsläge" msgid "Define calibration mode" msgstr "Definiera kalibreringsläge" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Sätt pÃ¥/av lampan" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "UTA pÃ¥" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Sätter pÃ¥/av UTA" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "Offset" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Inställningar för färgkanalernas offset" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "GrÃ¥ offset" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Ställer in den grÃ¥ kanalens offset" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Ställer in den röda kanalens offset" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Ställer in den gröna kanalens offset" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Ställer in den blÃ¥ kanalens offset" +#~ msgid "Disable dynamic lineart" +#~ msgstr "Avaktivera dynamisk streckteckning" + +#~ msgid "" +#~ "Disable use of a software adaptive algorithm to generate lineart " +#~ "relying instead on hardware lineart." +#~ msgstr "" +#~ "Stäng av användandet av en adaptiv algoritm i mjukvaran för att " +#~ "generera streckteckningsinläsningar för att i stället använda " +#~ "hÃ¥rdvarans streckteckningsinläsningsläge." + +#~ msgid "linier" +#~ msgstr "linjär" + +#~ msgid "It is right and left reversing" +#~ msgstr "Den kastar om höger och vänster" + #, fuzzy #~ msgid "IPC mode" #~ msgstr "Förhandsgranskningsläge" @@ -1,22 +1,22 @@ # Copyright (C) 2009 # This file is distributed under the same license as the sane-backends package. # -# Yuri Chornoivan <yurchor@ukr.net>, 2009, 2010, 2011, 2012, 2013, 2015, 2017, 2018, 2019. +# Yuri Chornoivan <yurchor@ukr.net>, 2009, 2010, 2011, 2012, 2013, 2015, 2017, 2018, 2019, 2020. msgid "" msgstr "" -"Project-Id-Version: sane-backends\n" +"Project-Id-Version: sane-backends 1.0.29\n" "Report-Msgid-Bugs-To: sane-devel@alioth-lists.debian.net\n" -"POT-Creation-Date: 2019-07-23 12:14+0000\n" -"PO-Revision-Date: 2019-06-26 18:14+0300\n" +"POT-Creation-Date: 2020-01-12 07:09+0000\n" +"PO-Revision-Date: 2020-01-26 16:30+0900\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <translation@linux.org.ua>\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Lokalize 19.07.70\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " -"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 20.03.70\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 &&" +" n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: include/sane/saneopts.h:154 #, no-c-format @@ -29,31 +29,31 @@ msgid "Standard" msgstr "Типово" #: include/sane/saneopts.h:157 backend/artec_eplus48u.c:2884 -#: backend/epson.c:3298 backend/epson2.c:1290 backend/genesys.cc:5294 -#: backend/gt68xx.c:696 backend/hp3500.c:1019 backend/hp-option.c:3300 -#: backend/kvs1025_opt.c:639 backend/kvs20xx_opt.c:285 -#: backend/kvs40xx_opt.c:506 backend/leo.c:823 backend/lexmark.c:199 -#: backend/ma1509.c:551 backend/matsushita.c:1135 backend/microtek2.h:599 -#: backend/mustek.c:4373 backend/mustek_usb.c:301 backend/mustek_usb2.c:465 -#: backend/pixma_sane_options.c:160 backend/plustek.c:808 -#: backend/plustek_pp.c:747 backend/sceptre.c:702 +#: backend/epson.c:3298 backend/epson2.c:1290 backend/epsonds.c:677 +#: backend/genesys/genesys.cpp:4034 backend/gt68xx.c:696 +#: backend/hp-option.c:3300 backend/hp3500.c:1019 backend/kvs1025_opt.c:639 +#: backend/kvs20xx_opt.c:285 backend/kvs40xx_opt.c:506 backend/leo.c:823 +#: backend/lexmark.c:199 backend/ma1509.c:551 backend/matsushita.c:1135 +#: backend/microtek2.h:599 backend/mustek.c:4373 backend/mustek_usb.c:301 +#: backend/mustek_usb2.c:465 backend/pixma/pixma_sane_options.c:160 +#: backend/plustek.c:808 backend/plustek_pp.c:747 backend/sceptre.c:702 #: backend/snapscan-options.c:550 backend/teco1.c:1095 backend/teco2.c:1910 #: backend/teco3.c:920 backend/test.c:647 backend/u12.c:546 -#: backend/umax.c:5176 backend/umax_pp.c:580 +#: backend/umax.c:5176 backend/umax_pp.c:570 #, no-c-format msgid "Geometry" msgstr "ÐŸÐ¾Ð·Ð¸Ñ†Ñ–Ñ Ñ– розміри" #: include/sane/saneopts.h:158 backend/artec_eplus48u.c:2805 -#: backend/canon.c:1493 backend/genesys.cc:5354 backend/gt68xx.c:665 -#: backend/hp-option.c:2956 backend/kvs1025_opt.c:703 backend/leo.c:871 -#: backend/ma1509.c:599 backend/matsushita.c:1189 backend/microtek2.h:600 -#: backend/mustek.c:4421 backend/mustek_usb.c:349 backend/mustek_usb2.c:431 -#: backend/niash.c:754 backend/plustek.c:854 backend/plustek_pp.c:793 -#: backend/sceptre.c:750 backend/snapscan-options.c:617 -#: backend/stv680.c:1067 backend/teco1.c:1143 backend/teco2.c:1958 -#: backend/teco3.c:968 backend/u12.c:592 backend/umax.c:5226 -#: backend/umax_pp.c:629 +#: backend/canon.c:1493 backend/genesys/genesys.cpp:4077 +#: backend/gt68xx.c:665 backend/hp-option.c:2956 backend/kvs1025_opt.c:703 +#: backend/leo.c:871 backend/ma1509.c:599 backend/matsushita.c:1189 +#: backend/microtek2.h:600 backend/mustek.c:4421 backend/mustek_usb.c:349 +#: backend/mustek_usb2.c:431 backend/niash.c:754 backend/plustek.c:854 +#: backend/plustek_pp.c:793 backend/sceptre.c:750 +#: backend/snapscan-options.c:617 backend/stv680.c:1067 +#: backend/teco1.c:1143 backend/teco2.c:1958 backend/teco3.c:968 +#: backend/u12.c:592 backend/umax.c:5226 backend/umax_pp.c:619 #, no-c-format msgid "Enhancement" msgstr "ПокращеннÑ" @@ -87,7 +87,7 @@ msgid "Bit depth" msgstr "КількіÑÑ‚ÑŒ бітів на колір" #: include/sane/saneopts.h:165 backend/canon.c:1140 backend/leo.c:781 -#: backend/pixma_sane_options.c:47 +#: backend/pixma/pixma_sane_options.c:47 #, no-c-format msgid "Scan mode" msgstr "Режим ÑкануваннÑ" @@ -128,7 +128,7 @@ msgid "Bottom-right y" msgstr "ÐÐ¸Ð¶Ð½Ñ Ð¿Ñ€Ð°Ð²Ð° координата за Y" #: include/sane/saneopts.h:173 backend/canon.c:1216 -#: backend/pixma_sane_options.c:300 +#: backend/pixma/pixma_sane_options.c:300 #, no-c-format msgid "Scan resolution" msgstr "Роздільна здатніÑÑ‚ÑŒ ÑкануваннÑ" @@ -283,7 +283,7 @@ msgstr "Ðазва файла" msgid "Halftone pattern size" msgstr "Розмір шаблону напівтонів" -#: include/sane/saneopts.h:204 backend/fujitsu.c:3233 +#: include/sane/saneopts.h:204 backend/fujitsu.c:3237 #, no-c-format msgid "Halftone pattern" msgstr "Шаблон напівтонів" @@ -293,10 +293,10 @@ msgstr "Шаблон напівтонів" msgid "Bind X and Y resolution" msgstr "Пов’Ñзати роздільні здатноÑÑ‚Ñ– за X Ñ– Y" -#: include/sane/saneopts.h:206 backend/hp3900_sane.c:428 -#: backend/hp3900_sane.c:1021 backend/hp3900_sane.c:1421 -#: backend/hp-option.c:3238 backend/mustek_usb2.c:121 backend/plustek.c:236 -#: backend/plustek_pp.c:205 backend/u12.c:157 +#: include/sane/saneopts.h:206 backend/hp-option.c:3238 +#: backend/hp3900_sane.c:428 backend/hp3900_sane.c:1021 +#: backend/hp3900_sane.c:1421 backend/mustek_usb2.c:121 +#: backend/plustek.c:236 backend/plustek_pp.c:205 backend/u12.c:157 #, no-c-format msgid "Negative" msgstr "Ðегатив" @@ -419,11 +419,11 @@ msgstr "Вимикати лампу при виході" #: include/sane/saneopts.h:245 #, no-c-format msgid "" -"Read-only option that specifies how many options a specific devices " +"Read-only option that specifies how many options a specific device " "supports." msgstr "" "Параметр лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ, Ñкий визначає кількіÑÑ‚ÑŒ параметрів, Ñкі " -"підтримують певні приÑтрої." +"підтримує певний приÑтрій." #: include/sane/saneopts.h:248 #, no-c-format @@ -532,7 +532,8 @@ msgstr "" #: include/sane/saneopts.h:298 #, no-c-format msgid "Sets the vertical resolution of the scanned image." -msgstr "Визначає вертикальну роздільну здатніÑÑ‚ÑŒ заÑканованого зображеннÑ." +msgstr "" +"Визначає вертикальну роздільну здатніÑÑ‚ÑŒ заÑканованого зображеннÑ." #: include/sane/saneopts.h:301 #, no-c-format @@ -726,7 +727,8 @@ msgstr "ВикориÑтовувати лінзу, Ñка подвоює оптР#: include/sane/saneopts.h:401 include/sane/saneopts.h:413 #, no-c-format msgid "In RGB-mode use same values for each color" -msgstr "У режимі RGB викориÑтовувати однакові Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ кольору" +msgstr "" +"У режимі RGB викориÑтовувати однакові Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ кольору" #: include/sane/saneopts.h:403 #, no-c-format @@ -755,7 +757,7 @@ msgstr "Ðналогове Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð³Ð°Ð¼Ð¸ Ð´Ð»Ñ Ñинього #: include/sane/saneopts.h:415 #, no-c-format -msgid "Warmup lamp before scanning" +msgid "Warm up lamp before scanning" msgstr "Розігрівати лампу перед ÑкануваннÑм" #: include/sane/saneopts.h:417 @@ -905,7 +907,7 @@ msgstr "Ð”Ñ–Ñ Ð½Ðµ підтримуєтьÑÑ" #: backend/sane_strstatus.c:65 #, no-c-format -msgid "Operation was cancelled" +msgid "Operation was canceled" msgstr "Дію було ÑкаÑовано" #: backend/sane_strstatus.c:68 @@ -1002,7 +1004,7 @@ msgstr "Виконати лише ÐºÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€Ð°Ð´Ð°Ñ†Ñ–Ñ—" #, no-c-format msgid "" "If enabled, only the shading correction is performed during calibration. " -"The default values for gain, offset and exposure time, either build-in " +"The default values for gain, offset and exposure time, either built-in " "or from the configuration file, are used." msgstr "" "Якщо позначено цей пункт, під Ñ‡Ð°Ñ ÐºÐ°Ð»Ñ–Ð±Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ виконано лише " @@ -1033,83 +1035,43 @@ msgstr "Двобічне ÑкануваннÑ" #: backend/avision.h:783 #, no-c-format msgid "" -"Duplex scan provide a scan of the front and back side of the document" +"Duplex scan provides a scan of the front and back side of the document" msgstr "" "За викориÑÑ‚Ð°Ð½Ð½Ñ Ð´Ð²Ð¾Ð±Ñ–Ñ‡Ð½Ð¾Ð³Ð¾ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸ отримаєте одразу Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ " "лицьового та зворотного боків документа" -#: backend/canon630u.c:159 -#, no-c-format -msgid "Calibrate Scanner" -msgstr "Калібрувати Ñканер" - -#: backend/canon630u.c:160 -#, no-c-format -msgid "Force scanner calibration before scan" -msgstr "Виконувати примуÑове ÐºÐ°Ð»Ñ–Ð±Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ´ ÑкануваннÑм" - -#: backend/canon630u.c:259 backend/umax1220u.c:208 +#: backend/canon-sane.c:674 backend/canon.c:171 #, no-c-format -msgid "Grayscale scan" -msgstr "Сканувати у відтінках Ñірого" - -#: backend/canon630u.c:260 backend/umax1220u.c:209 -#, no-c-format -msgid "Do a grayscale rather than color scan" -msgstr "Виконувати чорно-біле ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¼Ñ–ÑÑ‚ÑŒ кольорового" - -#: backend/canon630u.c:306 -#, no-c-format -msgid "Analog Gain" -msgstr "Ðналогове підÑиленнÑ" +msgid "Correction according to transparency ratio" +msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾ до ÑÐ¿Ñ–Ð²Ð²Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€Ð¾ÑÑ‚Ñ–" -#: backend/canon630u.c:307 +#: backend/canon-sane.c:680 backend/canon.c:170 #, no-c-format -msgid "Increase or decrease the analog gain of the CCD array" -msgstr "Збільшити або зменшити аналогове підÑÐ¸Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ– ПЗЗ" +msgid "Correction according to film type" +msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾ до типу плівки" -#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#: backend/canon-sane.c:732 backend/canon-sane.c:940 +#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 +#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 backend/canon.c:157 #, no-c-format -msgid "Gamma Correction" -msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð³Ð°Ð¼Ð¸" +msgid "Fine color" +msgstr "ЧиÑтий колір" -#: backend/canon630u.c:348 +#: backend/canon-sane.c:776 backend/canon.c:176 #, no-c-format -msgid "Selects the gamma corrected transfer curve" -msgstr "Визначити криву Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð³Ð°Ð¼Ð¸" +msgid "Negatives" +msgstr "Ðегативи" -#: backend/canon.c:149 backend/canon-sane.c:1318 +#: backend/canon-sane.c:1318 backend/canon.c:149 #, no-c-format msgid "Raw" msgstr "Без обробки" -#: backend/canon.c:157 backend/canon-sane.c:732 backend/canon-sane.c:940 -#: backend/canon-sane.c:1076 backend/canon-sane.c:1314 -#: backend/canon-sane.c:1494 backend/canon-sane.c:1643 -#, no-c-format -msgid "Fine color" -msgstr "ЧиÑтий колір" - #: backend/canon.c:169 #, no-c-format msgid "No transparency correction" msgstr "Без Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€Ð¾ÑÑ‚Ñ–" -#: backend/canon.c:170 backend/canon-sane.c:680 -#, no-c-format -msgid "Correction according to film type" -msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾ до типу плівки" - -#: backend/canon.c:171 backend/canon-sane.c:674 -#, no-c-format -msgid "Correction according to transparency ratio" -msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾ до ÑÐ¿Ñ–Ð²Ð²Ñ–Ð´Ð½Ð¾ÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð·Ð¾Ñ€Ð¾ÑÑ‚Ñ–" - -#: backend/canon.c:176 backend/canon-sane.c:776 -#, no-c-format -msgid "Negatives" -msgstr "Ðегативи" - #: backend/canon.c:176 #, no-c-format msgid "Slides" @@ -1244,8 +1206,8 @@ msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ некоректний біт IDENTIFY" #: backend/canon.c:460 #, no-c-format -msgid "option not connect" -msgstr "Додаткову функціональніÑÑ‚ÑŒ не з’єднано" +msgid "option not correct" +msgstr "параметр не Ñ” коректним" #: backend/canon.c:474 #, no-c-format @@ -1539,135 +1501,186 @@ msgstr "Оберіть тип плівки" msgid "Select the film type" msgstr "Визначає тип плівки" -#: backend/canon_dr.c:411 backend/epjitsu.c:233 backend/epson.c:501 -#: backend/epson2.c:115 backend/fujitsu.c:675 backend/gt68xx.c:148 +#: backend/canon630u.c:159 +#, no-c-format +msgid "Calibrate Scanner" +msgstr "Калібрувати Ñканер" + +#: backend/canon630u.c:160 +#, no-c-format +msgid "Force scanner calibration before scan" +msgstr "Виконувати примуÑове ÐºÐ°Ð»Ñ–Ð±Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ´ ÑкануваннÑм" + +#: backend/canon630u.c:259 backend/umax1220u.c:208 +#, no-c-format +msgid "Grayscale scan" +msgstr "Сканувати у відтінках Ñірого" + +#: backend/canon630u.c:260 backend/umax1220u.c:209 +#, no-c-format +msgid "Do a grayscale rather than color scan" +msgstr "Виконувати чорно-біле ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¼Ñ–ÑÑ‚ÑŒ кольорового" + +#: backend/canon630u.c:306 +#, no-c-format +msgid "Analog Gain" +msgstr "Ðналогове підÑиленнÑ" + +#: backend/canon630u.c:307 +#, no-c-format +msgid "Increase or decrease the analog gain of the CCD array" +msgstr "Збільшити або зменшити аналогове підÑÐ¸Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ– ПЗЗ" + +#: backend/canon630u.c:347 backend/epson.h:68 backend/epson2.h:67 +#, no-c-format +msgid "Gamma Correction" +msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð³Ð°Ð¼Ð¸" + +#: backend/canon630u.c:348 +#, no-c-format +msgid "Selects the gamma corrected transfer curve" +msgstr "Визначити криву Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð³Ð°Ð¼Ð¸" + +#: backend/canon_dr.c:413 backend/epjitsu.c:233 backend/epson.c:501 +#: backend/epson2-ops.c:101 backend/epson2.c:115 backend/epsonds-ops.c:32 +#: backend/epsonds.c:95 backend/epsonds.h:62 backend/fujitsu.c:677 +#: backend/genesys/genesys.h:78 backend/gt68xx.c:148 #: backend/hp3900_sane.c:418 backend/hp3900_sane.c:427 -#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/ma1509.c:108 -#: backend/magicolor.c:181 backend/mustek.c:156 backend/mustek.c:160 -#: backend/mustek.c:164 backend/pixma.c:920 backend/pixma_sane_options.c:92 -#: backend/snapscan-options.c:86 backend/test.c:192 backend/umax.c:181 +#: backend/hp3900_sane.c:1017 backend/hp5590.c:92 backend/kodakaio.c:617 +#: backend/ma1509.c:108 backend/magicolor.c:181 backend/mustek.c:156 +#: backend/mustek.c:160 backend/mustek.c:164 backend/pixma/pixma.c:920 +#: backend/pixma/pixma_sane_options.c:92 backend/snapscan-options.c:86 +#: backend/test.c:192 backend/umax.c:181 #, no-c-format msgid "Flatbed" msgstr "Планшет" -#: backend/canon_dr.c:412 backend/epjitsu.c:234 backend/fujitsu.c:676 +#: backend/canon_dr.c:414 backend/epjitsu.c:234 backend/fujitsu.c:678 #: backend/kodak.c:140 #, no-c-format msgid "ADF Front" msgstr "Перед протÑжного механізму" -#: backend/canon_dr.c:413 backend/epjitsu.c:235 backend/fujitsu.c:677 +#: backend/canon_dr.c:415 backend/epjitsu.c:235 backend/fujitsu.c:679 #: backend/kodak.c:141 #, no-c-format msgid "ADF Back" msgstr "Зворот протÑжного механізму" -#: backend/canon_dr.c:414 backend/epjitsu.c:236 backend/fujitsu.c:678 -#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma.c:931 +#: backend/canon_dr.c:416 backend/epjitsu.c:236 backend/fujitsu.c:680 +#: backend/hp5590.c:94 backend/kodak.c:142 backend/pixma/pixma.c:931 #, no-c-format msgid "ADF Duplex" msgstr "Двобічна ÐПД" -#: backend/canon_dr.c:415 +#: backend/canon_dr.c:417 #, no-c-format msgid "Card Front" msgstr "Картка (профіль)" -#: backend/canon_dr.c:416 +#: backend/canon_dr.c:418 #, no-c-format msgid "Card Back" msgstr "Картка (зворот)" -#: backend/canon_dr.c:417 +#: backend/canon_dr.c:419 #, no-c-format msgid "Card Duplex" msgstr "Картка (обидва боки)" -#: backend/canon_dr.c:424 backend/epson.c:599 backend/epson.c:3096 -#: backend/epson2.c:201 backend/fujitsu.c:695 backend/genesys.cc:89 -#: backend/genesys.cc:96 backend/gt68xx_low.h:136 backend/hp-option.c:3096 +#: backend/canon_dr.c:426 backend/epson.c:599 backend/epson.c:3096 +#: backend/epson2.c:201 backend/fujitsu.c:697 +#: backend/genesys/genesys.cpp:120 backend/genesys/genesys.cpp:127 +#: backend/gt68xx_low.h:136 backend/hp-option.c:3096 #, no-c-format msgid "Red" msgstr "Червоний" -#: backend/canon_dr.c:425 backend/epson.c:600 backend/epson.c:3092 -#: backend/epson2.c:202 backend/fujitsu.c:696 backend/genesys.cc:90 -#: backend/genesys.cc:97 backend/gt68xx_low.h:137 backend/hp-option.c:3097 +#: backend/canon_dr.c:427 backend/epson.c:600 backend/epson.c:3092 +#: backend/epson2.c:202 backend/fujitsu.c:698 +#: backend/genesys/genesys.cpp:121 backend/genesys/genesys.cpp:128 +#: backend/gt68xx_low.h:137 backend/hp-option.c:3097 #, no-c-format msgid "Green" msgstr "Зелений" -#: backend/canon_dr.c:426 backend/epson.c:601 backend/epson.c:3100 -#: backend/epson2.c:203 backend/fujitsu.c:697 backend/genesys.cc:91 -#: backend/genesys.cc:98 backend/gt68xx_low.h:138 backend/hp-option.c:3098 +#: backend/canon_dr.c:428 backend/epson.c:601 backend/epson.c:3100 +#: backend/epson2.c:203 backend/fujitsu.c:699 +#: backend/genesys/genesys.cpp:122 backend/genesys/genesys.cpp:129 +#: backend/gt68xx_low.h:138 backend/hp-option.c:3098 #, no-c-format msgid "Blue" msgstr "Синій" -#: backend/canon_dr.c:427 +#: backend/canon_dr.c:429 #, no-c-format msgid "Enhance Red" msgstr "Покращити червоний" -#: backend/canon_dr.c:428 +#: backend/canon_dr.c:430 #, no-c-format msgid "Enhance Green" msgstr "Покращити зелений" -#: backend/canon_dr.c:429 +#: backend/canon_dr.c:431 #, no-c-format msgid "Enhance Blue" msgstr "Покращити Ñиній" -#: backend/canon_dr.c:431 backend/epson.c:556 backend/epson.c:564 +#: backend/canon_dr.c:433 backend/epson.c:556 backend/epson.c:564 #: backend/epson.c:576 backend/epson.c:598 backend/epson2.c:165 #: backend/epson2.c:173 backend/epson2.c:185 backend/epson2.c:200 -#: backend/epson2.c:214 backend/fujitsu.c:701 backend/genesys.cc:99 -#: backend/leo.c:109 backend/matsushita.c:138 backend/matsushita.c:159 +#: backend/epson2.c:214 backend/fujitsu.c:703 +#: backend/genesys/genesys.cpp:130 backend/leo.c:109 +#: backend/matsushita.c:138 backend/matsushita.c:159 #: backend/matsushita.c:191 backend/matsushita.c:213 #: backend/snapscan-options.c:91 #, no-c-format msgid "None" msgstr "Ðемає" -#: backend/canon_dr.c:432 backend/fujitsu.c:702 +#: backend/canon_dr.c:434 backend/fujitsu.c:704 #, no-c-format msgid "JPEG" msgstr "JPEG" -#: backend/canon_dr.c:2477 backend/fujitsu.c:4113 backend/genesys.cc:5445 -#: backend/kvs1025_opt.c:910 +#: backend/canon_dr.c:2479 backend/fujitsu.c:4117 +#: backend/genesys/genesys.cpp:4168 backend/kvs1025_opt.c:910 #, no-c-format msgid "Software blank skip percentage" msgstr "Порогове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ–Ñ… Ñторінок Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð½Ð¾Ð³Ð¾ відкиданнÑ" -#: backend/canon_dr.c:2478 backend/fujitsu.c:4114 +#: backend/canon_dr.c:2480 backend/fujitsu.c:4118 #, no-c-format msgid "Request driver to discard pages with low percentage of dark pixels" msgstr "" "Вимагати від драйвера Ð²Ñ–Ð´ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ñторінок з надто низькою питомою " "кількіÑÑ‚ÑŽ темних пікÑелів" -#: backend/epson.c:491 backend/epson2.c:108 backend/magicolor.c:174 +#: backend/epson.c:491 backend/epson2.c:108 backend/epsonds.c:88 +#: backend/kodakaio.c:611 backend/magicolor.c:174 #, no-c-format msgid "Simplex" msgstr "Однобічна" -#: backend/epson.c:492 backend/epson2.c:109 backend/kvs1025.h:50 -#: backend/kvs20xx_opt.c:204 backend/kvs40xx_opt.c:353 -#: backend/magicolor.c:175 backend/matsushita.h:218 +#: backend/epson.c:492 backend/epson2.c:109 backend/epsonds.c:89 +#: backend/kodakaio.c:612 backend/kvs1025.h:50 backend/kvs20xx_opt.c:204 +#: backend/kvs40xx_opt.c:353 backend/magicolor.c:175 +#: backend/matsushita.h:218 #, no-c-format msgid "Duplex" msgstr "Двобічна" -#: backend/epson.c:502 backend/epson2.c:116 backend/pixma.c:937 +#: backend/epson.c:502 backend/epson2-ops.c:102 backend/epson2.c:116 +#: backend/epsonds-ops.c:33 backend/epsonds.h:63 backend/pixma/pixma.c:937 #, no-c-format msgid "Transparency Unit" msgstr "Модуль Ð´Ð»Ñ Ñлайдів" -#: backend/epson.c:503 backend/epson2.c:118 backend/magicolor.c:182 -#: backend/mustek.c:160 backend/pixma.c:925 backend/test.c:192 -#: backend/umax.c:183 +#: backend/epson.c:503 backend/epson2-ops.c:104 backend/epson2.c:118 +#: backend/epsonds-ops.c:34 backend/epsonds.c:96 backend/epsonds.h:64 +#: backend/kodakaio.c:618 backend/magicolor.c:182 backend/mustek.c:160 +#: backend/pixma/pixma.c:925 backend/test.c:192 backend/umax.c:183 #, no-c-format msgid "Automatic Document Feeder" msgstr "Ðвтоматична подача документів" @@ -1779,7 +1792,7 @@ msgstr "Струминні принтери" msgid "CRT monitors" msgstr "Монітори з ЕПТ" -#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:685 +#: backend/epson.c:656 backend/epson2.c:254 backend/fujitsu.c:687 #: backend/hp-option.c:3229 backend/test.c:143 #, no-c-format msgid "Default" @@ -1843,8 +1856,9 @@ msgstr "A4" msgid "Max" msgstr "МакÑ" -#: backend/epson.c:2813 backend/epson2.c:976 backend/genesys.cc:5207 -#: backend/gt68xx.c:451 backend/hp-option.c:2917 backend/kvs1025_opt.c:521 +#: backend/epson.c:2813 backend/epson2.c:976 backend/epsonds.c:629 +#: backend/genesys/genesys.cpp:3965 backend/gt68xx.c:451 +#: backend/hp-option.c:2917 backend/kvs1025_opt.c:521 #: backend/kvs20xx_opt.c:171 backend/kvs40xx_opt.c:320 backend/ma1509.c:501 #: backend/matsushita.c:1084 backend/microtek2.h:598 backend/mustek.c:4215 #: backend/mustek_usb.c:256 backend/mustek_usb2.c:344 backend/niash.c:734 @@ -2018,17 +2032,17 @@ msgstr "Визначає маÑштаб, Ñкий буде викориÑтанРmsgid "Quick format" msgstr "Швидке форматуваннÑ" -#: backend/epson.c:3360 backend/epson2.c:1340 +#: backend/epson.c:3360 backend/epson2.c:1340 backend/epsonds.c:726 #, no-c-format msgid "Optional equipment" msgstr "Додаткове уÑтаткуваннÑ" -#: backend/epson.c:3431 backend/epson2.c:1393 +#: backend/epson.c:3431 backend/epson2.c:1393 backend/epsonds.c:742 #, no-c-format msgid "Eject" msgstr "Виштовхнути" -#: backend/epson.c:3432 backend/epson2.c:1394 +#: backend/epson.c:3432 backend/epson2.c:1394 backend/epsonds.c:743 #, no-c-format msgid "Eject the sheet in the ADF" msgstr "Виштовхнути аркуш з протÑжного приÑтрою" @@ -2043,12 +2057,14 @@ msgstr "ÐвтовиштовхуваннÑ" msgid "Eject document after scanning" msgstr "Виштовхнути документ піÑÐ»Ñ ÑкануваннÑ" -#: backend/epson.c:3457 backend/epson2.c:1416 backend/magicolor.c:2420 +#: backend/epson.c:3457 backend/epson2.c:1416 backend/epsonds.c:758 +#: backend/kodakaio.c:2855 backend/magicolor.c:2420 #, no-c-format msgid "ADF Mode" msgstr "Режим протÑжного приÑтрою" -#: backend/epson.c:3459 backend/epson2.c:1418 backend/magicolor.c:2422 +#: backend/epson.c:3459 backend/epson2.c:1418 backend/epsonds.c:760 +#: backend/kodakaio.c:2857 backend/magicolor.c:2422 #, no-c-format msgid "Selects the ADF mode (simplex/duplex)" msgstr "Визначає режим протÑжного приÑтрою (однобічний/двобічний)" @@ -2100,16 +2116,16 @@ msgstr "" "ПіÑÐ»Ñ Ð½Ð°Ð´ÑÐ¸Ð»Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ðµ розпочинати ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ " "натиÑÐºÐ°Ð½Ð½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ на Ñканері." -#: backend/epson2.c:102 backend/pixma.c:409 -#, no-c-format -msgid "Infrared" -msgstr "Інфрачервоне" - -#: backend/epson2.c:117 +#: backend/epson2-ops.c:103 backend/epson2.c:117 #, no-c-format msgid "TPU8x10" msgstr "TPU8x10" +#: backend/epson2.c:102 backend/pixma/pixma.c:409 +#, no-c-format +msgid "Infrared" +msgstr "Інфрачервоне" + #: backend/epson2.c:136 #, no-c-format msgid "Positive Slide" @@ -2130,243 +2146,263 @@ msgstr "Вбудований профіль CCT" msgid "User defined CCT profile" msgstr "Визначений кориÑтувачем профіль CCT" -#: backend/fujitsu.c:686 backend/hp-option.c:3330 backend/hp-option.c:3343 +#: backend/epsonds.c:750 +#, no-c-format +msgid "Load" +msgstr "Завантажити" + +#: backend/epsonds.c:751 +#, no-c-format +msgid "Load a sheet in the ADF" +msgstr "Завантажити аркуш до протÑжного приÑтрою" + +#: backend/epsonds.c:771 +#, no-c-format +msgid "ADF Skew Correction" +msgstr "Ð’Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð°Ñ…Ð¸Ð»Ñƒ у протÑжному приÑтрої" + +#: backend/epsonds.c:773 +#, no-c-format +msgid "Enables ADF skew correction" +msgstr "Вмикає Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð°Ñ…Ð¸Ð»Ñƒ у протÑжному приÑтрої" + +#: backend/fujitsu.c:688 backend/hp-option.c:3330 backend/hp-option.c:3343 #, no-c-format msgid "On" msgstr "Увімкнути" -#: backend/fujitsu.c:687 backend/hp-option.c:3162 backend/hp-option.c:3329 +#: backend/fujitsu.c:689 backend/hp-option.c:3162 backend/hp-option.c:3329 #: backend/hp-option.c:3342 #, no-c-format msgid "Off" msgstr "Вимкнути" -#: backend/fujitsu.c:689 +#: backend/fujitsu.c:691 #, no-c-format msgid "DTC" msgstr "DTC" -#: backend/fujitsu.c:690 +#: backend/fujitsu.c:692 #, no-c-format msgid "SDTC" msgstr "SDTC" -#: backend/fujitsu.c:692 backend/teco1.c:1152 backend/teco1.c:1153 +#: backend/fujitsu.c:694 backend/teco1.c:1152 backend/teco1.c:1153 #: backend/teco2.c:1967 backend/teco2.c:1968 backend/teco3.c:977 #: backend/teco3.c:978 #, no-c-format msgid "Dither" msgstr "Дизеринг" -#: backend/fujitsu.c:693 +#: backend/fujitsu.c:695 #, no-c-format msgid "Diffusion" msgstr "ДифузіÑ" -#: backend/fujitsu.c:698 +#: backend/fujitsu.c:700 #, no-c-format msgid "White" msgstr "Білий" -#: backend/fujitsu.c:699 +#: backend/fujitsu.c:701 #, no-c-format msgid "Black" msgstr "Чорний" -#: backend/fujitsu.c:704 +#: backend/fujitsu.c:706 #, no-c-format msgid "Continue" msgstr "Продовжити" -#: backend/fujitsu.c:705 +#: backend/fujitsu.c:707 #, no-c-format msgid "Stop" msgstr "Зупинити" -#: backend/fujitsu.c:707 +#: backend/fujitsu.c:709 #, no-c-format msgid "10mm" msgstr "10мм" -#: backend/fujitsu.c:708 +#: backend/fujitsu.c:710 #, no-c-format msgid "15mm" msgstr "15мм" -#: backend/fujitsu.c:709 +#: backend/fujitsu.c:711 #, no-c-format msgid "20mm" msgstr "20мм" -#: backend/fujitsu.c:711 backend/hp-option.c:3048 +#: backend/fujitsu.c:713 backend/hp-option.c:3048 #, no-c-format msgid "Horizontal" msgstr "По горизонталі" -#: backend/fujitsu.c:712 +#: backend/fujitsu.c:714 #, no-c-format msgid "Horizontal bold" msgstr "Жирний по горизонталі" -#: backend/fujitsu.c:713 +#: backend/fujitsu.c:715 #, no-c-format msgid "Horizontal narrow" msgstr "Вузький по горизонталі" -#: backend/fujitsu.c:714 backend/hp-option.c:3047 +#: backend/fujitsu.c:716 backend/hp-option.c:3047 #, no-c-format msgid "Vertical" msgstr "По вертикалі" -#: backend/fujitsu.c:715 +#: backend/fujitsu.c:717 #, no-c-format msgid "Vertical bold" msgstr "Жирний по вертикалі" -#: backend/fujitsu.c:717 +#: backend/fujitsu.c:719 #, no-c-format msgid "Top to bottom" msgstr "Згори вниз" -#: backend/fujitsu.c:718 +#: backend/fujitsu.c:720 #, no-c-format msgid "Bottom to top" msgstr "Знизу догори" -#: backend/fujitsu.c:720 +#: backend/fujitsu.c:722 #, no-c-format msgid "Front" msgstr "Перед" -#: backend/fujitsu.c:721 +#: backend/fujitsu.c:723 #, no-c-format msgid "Back" msgstr "Зворот" -#: backend/fujitsu.c:3144 backend/pixma_sane_options.c:145 +#: backend/fujitsu.c:3148 backend/pixma/pixma_sane_options.c:145 #, no-c-format msgid "Gamma function exponent" msgstr "Показник функції гами" -#: backend/fujitsu.c:3145 backend/pixma_sane_options.c:146 +#: backend/fujitsu.c:3149 backend/pixma/pixma_sane_options.c:146 #, no-c-format msgid "Changes intensity of midtones" msgstr "Змінює інтенÑивніÑÑ‚ÑŒ напівтонів" -#: backend/fujitsu.c:3194 +#: backend/fujitsu.c:3198 #, no-c-format msgid "RIF" msgstr "RIF" -#: backend/fujitsu.c:3195 +#: backend/fujitsu.c:3199 #, no-c-format msgid "Reverse image format" msgstr "ІнверÑивний формат зображеннÑ" -#: backend/fujitsu.c:3212 +#: backend/fujitsu.c:3216 #, no-c-format msgid "Halftone type" msgstr "Тип півтонів" -#: backend/fujitsu.c:3213 +#: backend/fujitsu.c:3217 #, no-c-format msgid "Control type of halftone filter" msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ фільтра півтонів" -#: backend/fujitsu.c:3234 +#: backend/fujitsu.c:3238 #, no-c-format msgid "Control pattern of halftone filter" msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð·Ñ–Ñ€Ñ†ÐµÐ¼ фільтра півтонів" -#: backend/fujitsu.c:3256 +#: backend/fujitsu.c:3260 #, no-c-format msgid "Outline" msgstr "Контур" -#: backend/fujitsu.c:3257 +#: backend/fujitsu.c:3261 #, no-c-format msgid "Perform outline extraction" msgstr "Виконати Ð²Ð¸Ð´Ð¾Ð±ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚ÑƒÑ€Ñƒ" -#: backend/fujitsu.c:3268 +#: backend/fujitsu.c:3272 #, no-c-format msgid "Emphasis" msgstr "ВиокремленнÑ" -#: backend/fujitsu.c:3269 +#: backend/fujitsu.c:3273 #, no-c-format msgid "Negative to smooth or positive to sharpen image" msgstr "" "Ðегатив Ð´Ð»Ñ Ð·Ð³Ð»Ð°Ð´Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ позитив Ð´Ð»Ñ Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ñ€Ñ–Ð·ÐºÐ¾ÑÑ‚Ñ– зображеннÑ" -#: backend/fujitsu.c:3287 +#: backend/fujitsu.c:3291 #, no-c-format msgid "Separation" msgstr "РозділеннÑ" -#: backend/fujitsu.c:3288 +#: backend/fujitsu.c:3292 #, no-c-format msgid "Enable automatic separation of image and text" msgstr "Увімкнути автоматичне Ð²Ñ–Ð´Ð¾ÐºÑ€ÐµÐ¼Ð»ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½ÑŒ Ñ– текÑту" -#: backend/fujitsu.c:3299 +#: backend/fujitsu.c:3303 #, no-c-format msgid "Mirroring" msgstr "ВіддзеркаленнÑ" -#: backend/fujitsu.c:3300 +#: backend/fujitsu.c:3304 #, no-c-format msgid "Reflect output image horizontally" msgstr "Віддзеркалити отримане Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ горизонталі" -#: backend/fujitsu.c:3317 +#: backend/fujitsu.c:3321 #, no-c-format msgid "White level follower" msgstr "Відповідник Ñ€Ñ–Ð²Ð½Ñ Ð±Ñ–Ð»Ð¾Ð³Ð¾" -#: backend/fujitsu.c:3318 +#: backend/fujitsu.c:3322 #, no-c-format msgid "Control white level follower" msgstr "Керує відповідником Ñ€Ñ–Ð²Ð½Ñ Ð±Ñ–Ð»Ð¾Ð³Ð¾" -#: backend/fujitsu.c:3336 +#: backend/fujitsu.c:3340 #, no-c-format msgid "BP filter" msgstr "Фільтр СП" -#: backend/fujitsu.c:3337 +#: backend/fujitsu.c:3341 #, no-c-format msgid "Improves quality of high resolution ball-point pen text" msgstr "Поліпшує ÑкіÑÑ‚ÑŒ текÑту, напиÑаного кульковою ручкою" -#: backend/fujitsu.c:3353 backend/hp-option.h:73 +#: backend/fujitsu.c:3357 backend/hp-option.h:73 #, no-c-format msgid "Smoothing" msgstr "ЗгладжуваннÑ" -#: backend/fujitsu.c:3354 +#: backend/fujitsu.c:3358 #, no-c-format msgid "Enable smoothing for improved OCR" msgstr "Увімкнути Ð·Ð³Ð»Ð°Ð´Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»Ñ–Ð¿ÑˆÐµÐ½Ð½Ñ ÐžÐ Ð¢" -#: backend/fujitsu.c:3370 +#: backend/fujitsu.c:3374 #, no-c-format msgid "Gamma curve" msgstr "Крива гами" -#: backend/fujitsu.c:3371 +#: backend/fujitsu.c:3375 #, no-c-format msgid "Gamma curve, from light to dark, but upper two may not work" msgstr "" "Крива гами, від Ñвітлого до темного, але верхні дві можуть не працювати" -#: backend/fujitsu.c:3393 backend/genesys.cc:5505 -#: backend/pixma_sane_options.c:335 +#: backend/fujitsu.c:3397 backend/genesys/genesys.cpp:4229 +#: backend/pixma/pixma_sane_options.c:335 #, no-c-format msgid "Threshold curve" msgstr "Порогова крива" -#: backend/fujitsu.c:3394 +#: backend/fujitsu.c:3398 #, no-c-format msgid "" "Threshold curve, from light to dark, but upper two may not be linear" @@ -2374,111 +2410,111 @@ msgstr "" "Порогова крива, від Ñвітлого до темного, але верхні дві не можуть бути " "лінійними" -#: backend/fujitsu.c:3416 +#: backend/fujitsu.c:3420 #, no-c-format msgid "Threshold white" msgstr "Білий поріг" -#: backend/fujitsu.c:3417 +#: backend/fujitsu.c:3421 #, no-c-format msgid "Set pixels equal to threshold to white instead of black" msgstr "Ð’Ñтановити Ð´Ð»Ñ Ð¿Ð¾Ñ€Ð¾Ð³Ð¾Ð²Ð¸Ñ… пікÑелів білий колір, а не чорний" -#: backend/fujitsu.c:3433 backend/fujitsu.c:3434 +#: backend/fujitsu.c:3437 backend/fujitsu.c:3438 #, no-c-format msgid "Noise removal" msgstr "Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ ÑˆÑƒÐ¼Ñƒ" -#: backend/fujitsu.c:3450 +#: backend/fujitsu.c:3454 #, no-c-format msgid "Matrix 5x5" msgstr "ÐœÐ°Ñ‚Ñ€Ð¸Ñ†Ñ 5x5" -#: backend/fujitsu.c:3451 +#: backend/fujitsu.c:3455 #, no-c-format msgid "Remove 5 pixel square noise" msgstr "Вилучати пікÑельний шум розміром до 5 пікÑелів" -#: backend/fujitsu.c:3467 +#: backend/fujitsu.c:3471 #, no-c-format msgid "Matrix 4x4" msgstr "ÐœÐ°Ñ‚Ñ€Ð¸Ñ†Ñ 4x4" -#: backend/fujitsu.c:3468 +#: backend/fujitsu.c:3472 #, no-c-format msgid "Remove 4 pixel square noise" msgstr "Вилучати пікÑельний шум розміром до 4 пікÑелів" -#: backend/fujitsu.c:3484 +#: backend/fujitsu.c:3488 #, no-c-format msgid "Matrix 3x3" msgstr "ÐœÐ°Ñ‚Ñ€Ð¸Ñ†Ñ 3x3" -#: backend/fujitsu.c:3485 +#: backend/fujitsu.c:3489 #, no-c-format msgid "Remove 3 pixel square noise" msgstr "Вилучати пікÑельний шум розміром до 3 пікÑелів" -#: backend/fujitsu.c:3501 +#: backend/fujitsu.c:3505 #, no-c-format msgid "Matrix 2x2" msgstr "ÐœÐ°Ñ‚Ñ€Ð¸Ñ†Ñ 2x2" -#: backend/fujitsu.c:3502 +#: backend/fujitsu.c:3506 #, no-c-format msgid "Remove 2 pixel square noise" msgstr "Вилучати пікÑельний шум розміром до 2 пікÑелів" -#: backend/fujitsu.c:3521 +#: backend/fujitsu.c:3525 #, no-c-format msgid "Variance" msgstr "ДиÑперÑÑ–Ñ" -#: backend/fujitsu.c:3522 +#: backend/fujitsu.c:3526 #, no-c-format msgid "Set SDTC variance rate (sensitivity), 0 equals 127" msgstr "Ð’Ñтановити величину диÑперÑÑ–Ñ— SDTC (чутливіÑÑ‚ÑŒ), 0 відповідає 127" -#: backend/fujitsu.c:3555 +#: backend/fujitsu.c:3559 #, no-c-format msgid "Auto width detection" msgstr "ÐвтовиÑÐ²Ð»ÐµÐ½Ð½Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð¸" -#: backend/fujitsu.c:3556 +#: backend/fujitsu.c:3560 #, no-c-format msgid "Scanner detects paper sides. May reduce scanning speed." msgstr "Сканер визначає краї паперу. Може уповільнити ÑкануваннÑ." -#: backend/fujitsu.c:3573 +#: backend/fujitsu.c:3577 #, no-c-format msgid "Auto length detection" msgstr "ÐвтовиÑÐ²Ð»ÐµÐ½Ð½Ñ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð¸" -#: backend/fujitsu.c:3574 +#: backend/fujitsu.c:3578 #, no-c-format msgid "Scanner detects paper lower edge. May confuse some frontends." msgstr "" "Сканер виÑвлÑÑ” нижній край паперу. Може призвеÑти до помилкової роботи " "деÑких програмних оболонок." -#: backend/fujitsu.c:3600 +#: backend/fujitsu.c:3604 #, no-c-format msgid "Compression" msgstr "СтиÑненнÑ" -#: backend/fujitsu.c:3601 +#: backend/fujitsu.c:3605 #, no-c-format msgid "Enable compressed data. May crash your front-end program" msgstr "" "Увімкнути ÑтиÑÐºÐ°Ð½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ…. Може призвеÑти до аварійного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ " "роботи програмних оболонок." -#: backend/fujitsu.c:3621 +#: backend/fujitsu.c:3625 #, no-c-format msgid "Compression argument" msgstr "Ðргумент ÑтиÑканнÑ" -#: backend/fujitsu.c:3622 +#: backend/fujitsu.c:3626 #, no-c-format msgid "" "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) " @@ -2487,107 +2523,108 @@ msgstr "" "Рівень ÑтиÑÐºÐ°Ð½Ð½Ñ JPEG. 1 — малий файл, 7 — великий файл. 0 (типовий) — " "те Ñаме, що Ñ– 4." -#: backend/fujitsu.c:3652 +#: backend/fujitsu.c:3656 #, no-c-format msgid "DF action" msgstr "Ð”Ñ–Ñ ÐŸÐŸ" -#: backend/fujitsu.c:3653 +#: backend/fujitsu.c:3657 #, no-c-format msgid "Action following double feed error" -msgstr "ДіÑ, Ñку буде виконано у відповідь на помилку подвійного подаваннÑ" +msgstr "" +"ДіÑ, Ñку буде виконано у відповідь на помилку подвійного подаваннÑ" -#: backend/fujitsu.c:3669 +#: backend/fujitsu.c:3673 #, no-c-format msgid "DF skew" msgstr "ПП Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐºÐ¾ÑˆÑƒÐ²Ð°Ð½Ð½Ñ" -#: backend/fujitsu.c:3670 +#: backend/fujitsu.c:3674 #, no-c-format msgid "Enable double feed error due to skew" msgstr "Увімкнути помилку подвійного Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· перекошуваннÑ" -#: backend/fujitsu.c:3688 +#: backend/fujitsu.c:3692 #, no-c-format msgid "DF thickness" msgstr "ПП Ð´Ð»Ñ Ñ‚Ð¾Ð²Ñ‰Ð¸Ð½Ð¸" -#: backend/fujitsu.c:3689 +#: backend/fujitsu.c:3693 #, no-c-format msgid "Enable double feed error due to paper thickness" msgstr "Увімкнути помилку подвійного Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· товщину паперу" -#: backend/fujitsu.c:3707 +#: backend/fujitsu.c:3711 #, no-c-format msgid "DF length" msgstr "ПП Ð´Ð»Ñ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð¸" -#: backend/fujitsu.c:3708 +#: backend/fujitsu.c:3712 #, no-c-format msgid "Enable double feed error due to paper length" msgstr "Увімкнути помилку подвійного Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· довжину паперу" -#: backend/fujitsu.c:3731 +#: backend/fujitsu.c:3735 #, no-c-format msgid "DF length difference" msgstr "Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð¸ Ð´Ð»Ñ ÐŸÐŸ" -#: backend/fujitsu.c:3732 +#: backend/fujitsu.c:3736 #, no-c-format msgid "Difference in page length to trigger double feed error" msgstr "" "Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ñƒ довжинах аркушів паперу, Ñка призводитиме до помилки " "подвійного подаваннÑ" -#: backend/fujitsu.c:3755 +#: backend/fujitsu.c:3759 #, no-c-format msgid "DF recovery mode" msgstr "Режим Ð²Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐŸÐŸ" -#: backend/fujitsu.c:3756 +#: backend/fujitsu.c:3760 #, no-c-format msgid "Request scanner to reverse feed on paper jam" msgstr "Вимагати від Ñканера зворотного подаваннÑ, Ñкщо папір зам’Ñто" -#: backend/fujitsu.c:3775 +#: backend/fujitsu.c:3779 #, no-c-format msgid "Paper protection" msgstr "ЗахиÑÑ‚ паперу" -#: backend/fujitsu.c:3776 +#: backend/fujitsu.c:3780 #, no-c-format msgid "Request scanner to predict jams in the ADF" msgstr "Вимагати від Ñканера передбачати зам’ÑÑ‚Ñ‚Ñ Ñƒ протÑжному приÑтрої" -#: backend/fujitsu.c:3795 +#: backend/fujitsu.c:3799 #, no-c-format msgid "Advanced paper protection" msgstr "Додатковий захиÑÑ‚ паперу" -#: backend/fujitsu.c:3796 +#: backend/fujitsu.c:3800 #, no-c-format msgid "Request scanner to predict jams in the ADF using improved sensors" msgstr "" "Вимагати від Ñканера передбачати зам’ÑÑ‚Ñ‚Ñ Ñƒ протÑжному приÑтрої за " "допомогою поліпшених датчиків" -#: backend/fujitsu.c:3815 +#: backend/fujitsu.c:3819 #, no-c-format msgid "Staple detection" msgstr "ВиÑÐ²Ð»ÐµÐ½Ð½Ñ Ñкоб" -#: backend/fujitsu.c:3816 +#: backend/fujitsu.c:3820 #, no-c-format msgid "Request scanner to detect jams in the ADF caused by staples" msgstr "" "Вимагати від Ñканера виÑвлÑти зам’ÑÑ‚Ñ‚Ñ Ñƒ протÑжному приÑтрої через Ñкоби" -#: backend/fujitsu.c:3835 +#: backend/fujitsu.c:3839 #, no-c-format msgid "Background color" msgstr "Колір тла" -#: backend/fujitsu.c:3836 +#: backend/fujitsu.c:3840 #, no-c-format msgid "" "Set color of background for scans. May conflict with overscan option" @@ -2595,12 +2632,12 @@ msgstr "" "Ð’Ñтановити колір Ð´Ð»Ñ Ñ‚Ð»Ð° Ñканованих зображень. Може конфліктувати із " "параметром полів." -#: backend/fujitsu.c:3856 +#: backend/fujitsu.c:3860 #, no-c-format msgid "Dropout color" msgstr "Колір Ð´Ð»Ñ Ð²Ð¸ÐºÐ¸Ð´Ð°Ð½Ð½Ñ" -#: backend/fujitsu.c:3857 +#: backend/fujitsu.c:3861 #, no-c-format msgid "" "One-pass scanners use only one color during gray or binary scanning, " @@ -2610,34 +2647,36 @@ msgstr "" "відтінках Ñірого або чорно-білого ÑкануваннÑ, кориÑно Ð´Ð»Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ð¾Ð²Ð¾Ð³Ð¾ " "паперу або чорнильних запиÑів" -#: backend/fujitsu.c:3880 +#: backend/fujitsu.c:3884 #, no-c-format msgid "Buffer mode" msgstr "Режим буферизації" -#: backend/fujitsu.c:3881 +#: backend/fujitsu.c:3885 #, no-c-format -msgid "Request scanner to read pages quickly from ADF into internal memory" +msgid "" +"Request scanner to read pages quickly from ADF into internal memory" msgstr "" "Ðаказати Ñканеру швидко читати Ñторінки з протÑжного приÑтрою до " "внутрішньої пам’ÑÑ‚Ñ–" -#: backend/fujitsu.c:3900 +#: backend/fujitsu.c:3904 #, no-c-format msgid "Prepick" msgstr "Попереднє захопленнÑ" -#: backend/fujitsu.c:3901 +#: backend/fujitsu.c:3905 #, no-c-format msgid "Request scanner to grab next page from ADF" -msgstr "Ðаказати Ñканеру захопити наÑтупну Ñторінку із протÑжного приÑтрою" +msgstr "" +"Ðаказати Ñканеру захопити наÑтупну Ñторінку із протÑжного приÑтрою" -#: backend/fujitsu.c:3920 +#: backend/fujitsu.c:3924 #, no-c-format msgid "Overscan" msgstr "ПолÑ" -#: backend/fujitsu.c:3921 +#: backend/fujitsu.c:3925 #, no-c-format msgid "" "Collect a few mm of background on top side of scan, before paper enters " @@ -2650,12 +2689,12 @@ msgstr "" "також дозволити Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ñ€ÐµÑˆÑ‚Ð¸ даних з бічних полів. Може конфліктувати " "з параметром кольору тла." -#: backend/fujitsu.c:3939 +#: backend/fujitsu.c:3943 #, no-c-format msgid "Sleep timer" msgstr "Таймер приÑиплÑннÑ" -#: backend/fujitsu.c:3940 +#: backend/fujitsu.c:3944 #, no-c-format msgid "" "Time in minutes until the internal power supply switches to sleep mode" @@ -2663,12 +2702,12 @@ msgstr "" "Ð§Ð°Ñ Ñƒ хвилинах, по завершенню Ñкого внутрішнє Ð¶Ð¸Ð²Ð»ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ переведено у " "режим Ñну" -#: backend/fujitsu.c:3958 +#: backend/fujitsu.c:3962 #, no-c-format msgid "Off timer" msgstr "Таймер вимиканнÑ" -#: backend/fujitsu.c:3959 +#: backend/fujitsu.c:3963 #, no-c-format msgid "" "Time in minutes until the internal power supply switches the scanner " @@ -2678,42 +2717,42 @@ msgstr "" "Буде округлено до найближчого кратного до 15 хвилин. Ðульове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ " "означає, що Ð¶Ð¸Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ðµ вимикатиметьÑÑ." -#: backend/fujitsu.c:3977 +#: backend/fujitsu.c:3981 #, no-c-format msgid "Duplex offset" msgstr "Ð—Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð´Ð²Ð¾Ð±Ñ–Ñ‡Ð½Ð¾Ð³Ð¾" -#: backend/fujitsu.c:3978 +#: backend/fujitsu.c:3982 #, no-c-format msgid "Adjust front/back offset" msgstr "ÐšÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¼Ñ–Ð¶ переднім Ñ– зворотним боком" -#: backend/fujitsu.c:3995 backend/plustek.c:1025 backend/umax_pp.c:804 +#: backend/fujitsu.c:3999 backend/plustek.c:1025 backend/umax_pp.c:794 #, no-c-format msgid "Green offset" msgstr "Ð—Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð·ÐµÐ»ÐµÐ½Ð¾Ð³Ð¾" -#: backend/fujitsu.c:3996 +#: backend/fujitsu.c:4000 #, no-c-format msgid "Adjust green/red offset" msgstr "ÐšÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¼Ñ–Ð¶ зеленим Ñ– червоним каналами" -#: backend/fujitsu.c:4013 backend/plustek.c:1041 backend/umax_pp.c:816 +#: backend/fujitsu.c:4017 backend/plustek.c:1041 backend/umax_pp.c:806 #, no-c-format msgid "Blue offset" msgstr "Ð—Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñинього" -#: backend/fujitsu.c:4014 +#: backend/fujitsu.c:4018 #, no-c-format msgid "Adjust blue/red offset" msgstr "ÐšÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¼Ñ–Ð¶ Ñинім Ñ– червоним каналами" -#: backend/fujitsu.c:4027 +#: backend/fujitsu.c:4031 #, no-c-format msgid "Low Memory" msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð°Ð¼â€™ÑÑ‚Ñ–" -#: backend/fujitsu.c:4028 +#: backend/fujitsu.c:4032 #, no-c-format msgid "" "Limit driver memory usage for use in embedded systems. Causes some " @@ -2727,12 +2766,12 @@ msgstr "" "«side». Цим параметром Ñлід кориÑтуватиÑÑ Ð»Ð¸ÑˆÐµ Ð´Ð»Ñ Ð½ÐµÑ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ " "зовнішнього інтерфейÑу програмного забезпеченнÑ." -#: backend/fujitsu.c:4043 +#: backend/fujitsu.c:4047 #, no-c-format msgid "Duplex side" msgstr "Бік Ð´Ð»Ñ Ð´Ð²Ð¾Ð±Ñ–Ñ‡Ð½Ð¾Ð³Ð¾" -#: backend/fujitsu.c:4044 +#: backend/fujitsu.c:4048 #, no-c-format msgid "" "Tells which side (0=front, 1=back) of a duplex scan the next call to " @@ -2741,58 +2780,58 @@ msgstr "" "Визначає, Ñкий бік (0=передній, 1=зворотний) двобічного Ñканованого " "Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ повернуто під Ñ‡Ð°Ñ Ð½Ð°Ñтупного виклику sane_read." -#: backend/fujitsu.c:4055 +#: backend/fujitsu.c:4059 #, no-c-format msgid "Hardware deskew and crop" msgstr "Ðпаратне Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð°Ñ…Ð¸Ð»Ñƒ Ñ– обрізаннÑ" -#: backend/fujitsu.c:4056 +#: backend/fujitsu.c:4060 #, no-c-format msgid "Request scanner to rotate and crop pages digitally." msgstr "" "Вимагати від Ñканера Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð° Ð¾Ð±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ñторінок у цифровому режимі." -#: backend/fujitsu.c:4067 backend/kvs1025_opt.c:871 +#: backend/fujitsu.c:4071 backend/kvs1025_opt.c:871 #, no-c-format msgid "Software deskew" msgstr "Програмне уÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ" -#: backend/fujitsu.c:4068 +#: backend/fujitsu.c:4072 #, no-c-format msgid "Request driver to rotate skewed pages digitally." msgstr "" "Вимагати від драйвера уÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ñторінок у автоматичному режимі." -#: backend/fujitsu.c:4080 backend/kvs1025_opt.c:880 +#: backend/fujitsu.c:4084 backend/kvs1025_opt.c:880 #, no-c-format msgid "Software despeckle diameter" msgstr "Діаметр плÑм Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð½Ð¾Ð³Ð¾ уÑуваннÑ" -#: backend/fujitsu.c:4081 +#: backend/fujitsu.c:4085 #, no-c-format msgid "Maximum diameter of lone dots to remove from scan." msgstr "" "Мінімальний діаметр окремих плÑм, Ñкі Ñлід уÑунути зі Ñканованого " "зображеннÑ." -#: backend/fujitsu.c:4100 backend/genesys.cc:5436 +#: backend/fujitsu.c:4104 backend/genesys/genesys.cpp:4159 #, no-c-format msgid "Software crop" msgstr "Програмне обрізаннÑ" -#: backend/fujitsu.c:4101 +#: backend/fujitsu.c:4105 #, no-c-format msgid "Request driver to remove border from pages digitally." msgstr "" "Вимагати від драйвера Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ñ– зі Ñторінок у автоматичному " "режимі." -#: backend/fujitsu.c:4130 +#: backend/fujitsu.c:4134 #, no-c-format msgid "Halt on Cancel" msgstr "Перервати при ÑкаÑуванні" -#: backend/fujitsu.c:4131 +#: backend/fujitsu.c:4135 #, no-c-format msgid "" "Request driver to halt the paper feed instead of eject during a cancel." @@ -2800,106 +2839,106 @@ msgstr "" "Ðаказати драйверу перервати Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð¿Ð°Ð¿ÐµÑ€Ñƒ, заміÑÑ‚ÑŒ його " "виштовхуваннÑ, Ñкщо ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ ÑкаÑовано." -#: backend/fujitsu.c:4142 +#: backend/fujitsu.c:4146 #, no-c-format msgid "Endorser Options" msgstr "Параметри наддруку" -#: backend/fujitsu.c:4143 +#: backend/fujitsu.c:4147 #, no-c-format msgid "Controls for endorser unit" msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»ÐµÐ¼ наддруку" -#: backend/fujitsu.c:4154 +#: backend/fujitsu.c:4158 #, no-c-format msgid "Endorser" msgstr "Ðаддрук" -#: backend/fujitsu.c:4155 +#: backend/fujitsu.c:4159 #, no-c-format msgid "Enable endorser unit" msgstr "Увімкнути модуль наддруку" -#: backend/fujitsu.c:4170 +#: backend/fujitsu.c:4174 #, no-c-format msgid "Endorser bits" msgstr "Біти наддруку" -#: backend/fujitsu.c:4171 +#: backend/fujitsu.c:4175 #, no-c-format msgid "Determines maximum endorser counter value." msgstr "Визначає макÑимальне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ° наддруку." -#: backend/fujitsu.c:4196 +#: backend/fujitsu.c:4200 #, no-c-format msgid "Endorser value" msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ð°Ð´Ð´Ñ€ÑƒÐºÑƒ" -#: backend/fujitsu.c:4197 +#: backend/fujitsu.c:4201 #, no-c-format msgid "Initial endorser counter value." msgstr "Початкове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ° наддруку." -#: backend/fujitsu.c:4220 +#: backend/fujitsu.c:4224 #, no-c-format msgid "Endorser step" msgstr "Крок наддруку" -#: backend/fujitsu.c:4221 +#: backend/fujitsu.c:4225 #, no-c-format msgid "Change endorser counter value by this much for each page." msgstr "" "Змінювати Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ° наддруку на вказане чиÑло Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ñ— " "наÑтупної Ñторінки." -#: backend/fujitsu.c:4244 +#: backend/fujitsu.c:4248 #, no-c-format msgid "Endorser Y" msgstr "Y наддруку" -#: backend/fujitsu.c:4245 +#: backend/fujitsu.c:4249 #, no-c-format msgid "Endorser print offset from top of paper." msgstr "ЗÑув мітки наддруку від верхнього краю паперу." -#: backend/fujitsu.c:4270 +#: backend/fujitsu.c:4274 #, no-c-format msgid "Endorser font" msgstr "Шрифт наддруку" -#: backend/fujitsu.c:4271 +#: backend/fujitsu.c:4275 #, no-c-format msgid "Endorser printing font." msgstr "Шрифт наддруку." -#: backend/fujitsu.c:4300 +#: backend/fujitsu.c:4304 #, no-c-format msgid "Endorser direction" msgstr "ÐапрÑмок наддруку" -#: backend/fujitsu.c:4301 +#: backend/fujitsu.c:4305 #, no-c-format msgid "Endorser printing direction." msgstr "ÐапрÑмок друку." -#: backend/fujitsu.c:4325 +#: backend/fujitsu.c:4329 #, no-c-format msgid "Endorser side" msgstr "Бік наддруку" -#: backend/fujitsu.c:4326 +#: backend/fujitsu.c:4330 #, no-c-format msgid "Endorser printing side, requires hardware support to change" msgstr "" "Бік, з Ñкого буде друкуватиÑÑ Ð¼Ñ–Ñ‚ÐºÐ°. Потребує апаратної підтримки Ð´Ð»Ñ " "зміни." -#: backend/fujitsu.c:4351 +#: backend/fujitsu.c:4355 #, no-c-format msgid "Endorser string" msgstr "Ð Ñдок наддруку" -#: backend/fujitsu.c:4352 +#: backend/fujitsu.c:4356 #, no-c-format msgid "" "Endorser alphanumeric print format. %05ud or %08ud at the end will be " @@ -2908,219 +2947,205 @@ msgstr "" "Буквенно-цифровий формат наддруку. %05ud або %08ud наприкінці буде " "замінено на Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°." -#: backend/fujitsu.c:4379 +#: backend/fujitsu.c:4383 #, no-c-format msgid "Top edge" msgstr "Верхній край" -#: backend/fujitsu.c:4380 +#: backend/fujitsu.c:4384 #, no-c-format -msgid "Paper is pulled partly into adf" +msgid "Paper is pulled partly into ADF" msgstr "Папір чаÑтково втÑгнуто до протÑжного приÑтрою" -#: backend/fujitsu.c:4391 +#: backend/fujitsu.c:4395 #, no-c-format msgid "A3 paper" msgstr "Папір A3" -#: backend/fujitsu.c:4392 +#: backend/fujitsu.c:4396 #, no-c-format msgid "A3 paper detected" msgstr "ВиÑвлено папір A3" -#: backend/fujitsu.c:4403 +#: backend/fujitsu.c:4407 #, no-c-format msgid "B4 paper" msgstr "Папір B4" -#: backend/fujitsu.c:4404 +#: backend/fujitsu.c:4408 #, no-c-format msgid "B4 paper detected" msgstr "ВиÑвлено папір B4" -#: backend/fujitsu.c:4415 +#: backend/fujitsu.c:4419 #, no-c-format msgid "A4 paper" msgstr "Папір A4" -#: backend/fujitsu.c:4416 +#: backend/fujitsu.c:4420 #, no-c-format msgid "A4 paper detected" msgstr "ВиÑвлено папір A4" -#: backend/fujitsu.c:4427 +#: backend/fujitsu.c:4431 #, no-c-format msgid "B5 paper" msgstr "Папір B5" -#: backend/fujitsu.c:4428 +#: backend/fujitsu.c:4432 #, no-c-format msgid "B5 paper detected" msgstr "ВиÑвлено папір B5" -#: backend/fujitsu.c:4451 +#: backend/fujitsu.c:4455 #, no-c-format msgid "OMR or DF" msgstr "OMR або ПП" -#: backend/fujitsu.c:4452 +#: backend/fujitsu.c:4456 #, no-c-format msgid "OMR or double feed detected" msgstr "ВиÑвлено OMR або подвійне подаваннÑ" -#: backend/fujitsu.c:4475 +#: backend/fujitsu.c:4479 #, no-c-format msgid "Power saving" msgstr "Ð—Ð°Ð¾Ñ‰Ð°Ð´Ð¶ÐµÐ½Ð½Ñ ÐµÐ½ÐµÑ€Ð³Ñ–Ñ—" -#: backend/fujitsu.c:4476 +#: backend/fujitsu.c:4480 #, no-c-format msgid "Scanner in power saving mode" msgstr "Сканер перебуває у режимі Ð·Ð°Ð¾Ñ‰Ð°Ð´Ð¶ÐµÐ½Ð½Ñ ÐµÐ½ÐµÑ€Ð³Ñ–Ñ—" -#: backend/fujitsu.c:4499 +#: backend/fujitsu.c:4503 #, no-c-format msgid "Manual feed" msgstr "ÐŸÐ¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð²Ñ€ÑƒÑ‡Ð½Ñƒ" -#: backend/fujitsu.c:4500 +#: backend/fujitsu.c:4504 #, no-c-format msgid "Manual feed selected" msgstr "Вибрано режим Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð²Ñ€ÑƒÑ‡Ð½Ñƒ" -#: backend/fujitsu.c:4523 +#: backend/fujitsu.c:4527 #, no-c-format msgid "Function" msgstr "ФункціÑ" -#: backend/fujitsu.c:4524 +#: backend/fujitsu.c:4528 #, no-c-format msgid "Function character on screen" msgstr "Функціональний Ñимвол на екрані" -#: backend/fujitsu.c:4535 +#: backend/fujitsu.c:4539 #, no-c-format msgid "Ink low" msgstr "ЗакінчуютьÑÑ Ñ‡Ð¾Ñ€Ð½Ð¸Ð»Ð°" -#: backend/fujitsu.c:4536 +#: backend/fujitsu.c:4540 #, no-c-format msgid "Imprinter ink running low" msgstr "ЛишилоÑÑ Ð¼Ð°Ð»Ð¾ чорнила Ð´Ð»Ñ Ð½Ð°Ð´Ð´Ñ€ÑƒÐºÑƒ" -#: backend/fujitsu.c:4547 +#: backend/fujitsu.c:4551 #, no-c-format msgid "Double feed" msgstr "Подвійне подаваннÑ" -#: backend/fujitsu.c:4548 +#: backend/fujitsu.c:4552 #, no-c-format msgid "Double feed detected" msgstr "ВиÑвлено подвійне подаваннÑ" -#: backend/fujitsu.c:4559 +#: backend/fujitsu.c:4563 #, no-c-format msgid "Error code" msgstr "Код помилки" -#: backend/fujitsu.c:4560 +#: backend/fujitsu.c:4564 #, no-c-format msgid "Hardware error code" msgstr "Код апаратної помилки" -#: backend/fujitsu.c:4571 +#: backend/fujitsu.c:4575 #, no-c-format msgid "Skew angle" msgstr "Кут перекошуваннÑ" -#: backend/fujitsu.c:4572 +#: backend/fujitsu.c:4576 #, no-c-format msgid "Requires black background for scanning" msgstr "Потребує чорного тла Ð´Ð»Ñ ÑкануваннÑ" -#: backend/fujitsu.c:4583 +#: backend/fujitsu.c:4587 #, no-c-format msgid "Ink remaining" msgstr "ЛишилоÑÑ Ñ‡Ð¾Ñ€Ð½Ð¸Ð»Ð°" -#: backend/fujitsu.c:4584 +#: backend/fujitsu.c:4588 #, no-c-format msgid "Imprinter ink level" msgstr "Рівень чорнила Ð´Ð»Ñ Ð½Ð°Ð´Ð´Ñ€ÑƒÐºÑƒ" -#: backend/fujitsu.c:4595 +#: backend/fujitsu.c:4599 #, no-c-format msgid "Density" msgstr "ЩільніÑÑ‚ÑŒ" -#: backend/fujitsu.c:4596 +#: backend/fujitsu.c:4600 #, no-c-format msgid "Density dial" msgstr "Ðабирач щільноÑÑ‚Ñ–" -#: backend/fujitsu.c:4607 backend/fujitsu.c:4608 +#: backend/fujitsu.c:4611 backend/fujitsu.c:4612 #, no-c-format msgid "Duplex switch" msgstr "Перемикач двобічного" -#: backend/genesys.cc:5437 +#: backend/genesys/genesys.cpp:4160 #, no-c-format msgid "Request backend to remove border from pages digitally" msgstr "" "Вимагати від програмного Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ñ– зі Ñторінок у " "автоматичному режимі" -#: backend/genesys.cc:5446 backend/kvs1025_opt.c:912 +#: backend/genesys/genesys.cpp:4169 backend/kvs1025_opt.c:912 #, no-c-format msgid "Request driver to discard pages with low numbers of dark pixels" msgstr "" "Вимагати від драйвера Ð²Ñ–Ð´ÐºÐ¸Ð´Ð°Ð½Ð½Ñ Ñторінок з надто низькою кількіÑÑ‚ÑŽ " "темних пікÑелів" -#: backend/genesys.cc:5456 backend/kvs1025_opt.c:892 +#: backend/genesys/genesys.cpp:4179 backend/kvs1025_opt.c:892 #, no-c-format msgid "Software derotate" msgstr "Програмне уÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ" -#: backend/genesys.cc:5457 backend/kvs1025_opt.c:894 +#: backend/genesys/genesys.cpp:4180 backend/kvs1025_opt.c:894 #, no-c-format msgid "Request driver to detect and correct 90 degree image rotation" msgstr "" "Вимагати від драйвера виÑÐ²Ð»ÐµÐ½Ð½Ñ Ñ– Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð¾Ð±ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° 90 " "градуÑів" -#: backend/genesys.cc:5486 backend/pixma_sane_options.c:314 +#: backend/genesys/genesys.cpp:4210 backend/pixma/pixma_sane_options.c:314 #, no-c-format msgid "Extras" msgstr "Додаткові" -#: backend/genesys.cc:5506 backend/pixma_sane_options.c:336 +#: backend/genesys/genesys.cpp:4230 backend/pixma/pixma_sane_options.c:336 #, no-c-format msgid "Dynamic threshold curve, from light to dark, normally 50-65" msgstr "" "Крива динамічного порогового значеннÑ, від Ñвітлого до темного, типово " "50-65" -#: backend/genesys.cc:5515 -#, no-c-format -msgid "Disable dynamic lineart" -msgstr "Вимкнути динамічне штрихуваннÑ" - -#: backend/genesys.cc:5517 -#, no-c-format -msgid "" -"Disable use of a software adaptive algorithm to generate lineart relying " -"instead on hardware lineart." -msgstr "" -"Вимкнути викориÑÑ‚Ð°Ð½Ð½Ñ Ð°Ð´Ð°Ð¿Ñ‚Ð¸Ð²Ð½Ð¾Ð³Ð¾ програмного алгоритму Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ " -"ÑˆÑ‚Ñ€Ð¸Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¼Ñ–ÑÑ‚ÑŒ апаратного алгоритму штрихуваннÑ." - -#: backend/genesys.cc:5533 +#: backend/genesys/genesys.cpp:4240 #, no-c-format msgid "Disable interpolation" msgstr "Вимкнути інтерполÑцію" -#: backend/genesys.cc:5536 +#: backend/genesys/genesys.cpp:4243 #, no-c-format msgid "" "When using high resolutions where the horizontal resolution is smaller " @@ -3130,34 +3155,34 @@ msgstr "" "роздільна здатніÑÑ‚ÑŒ менша за вертикальну, вимикає горизонтальну " "інтерполÑцію." -#: backend/genesys.cc:5545 +#: backend/genesys/genesys.cpp:4252 #, no-c-format msgid "Color filter" msgstr "Фільтр кольору" -#: backend/genesys.cc:5548 +#: backend/genesys/genesys.cpp:4255 #, no-c-format msgid "When using gray or lineart this option selects the used color." msgstr "" "За викориÑÑ‚Ð°Ð½Ð½Ñ Ð´Ñ€ÑƒÐºÑƒ у півтонах або штрихового друку за допомогою цього " "пункту можна обрати колір друку." -#: backend/genesys.cc:5574 +#: backend/genesys/genesys.cpp:4279 #, no-c-format msgid "Calibration file" msgstr "Файл калібруваннÑ" -#: backend/genesys.cc:5575 +#: backend/genesys/genesys.cpp:4280 #, no-c-format msgid "Specify the calibration file to use" msgstr "Вкажіть файл даних калібруваннÑ, Ñкі буде викориÑтано" -#: backend/genesys.cc:5592 +#: backend/genesys/genesys.cpp:4297 #, no-c-format msgid "Calibration cache expiration time" msgstr "Строк дії кешу калібруваннÑ" -#: backend/genesys.cc:5593 +#: backend/genesys/genesys.cpp:4298 #, no-c-format msgid "" "Time (in minutes) before a cached calibration expires. A value of 0 " @@ -3168,12 +3193,12 @@ msgstr "" "Від’ємні Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ð·Ð½Ð°Ñ‡Ð°ÑŽÑ‚ÑŒ, що обмежень на Ñтрок дії кешу не " "накладатиметьÑÑ." -#: backend/genesys.cc:5603 +#: backend/genesys/genesys.cpp:4308 #, no-c-format msgid "Lamp off time" msgstr "Ð§Ð°Ñ Ð²Ð¸Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð»Ð°Ð¼Ð¿Ð¸" -#: backend/genesys.cc:5606 +#: backend/genesys/genesys.cpp:4311 #, no-c-format msgid "" "The lamp will be turned off after the given time (in minutes). A value " @@ -3182,90 +3207,111 @@ msgstr "" "Лампу буде вимкнено, коли Ñпливе вказаний Ñ‡Ð°Ñ (у хвилинах). Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ " "рівне 0 означатиме, що лампа не вимикатиметьÑÑ." -#: backend/genesys.cc:5616 +#: backend/genesys/genesys.cpp:4321 #, no-c-format msgid "Lamp off during scan" msgstr "Ð’Ð¸Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð»Ð°Ð¼Ð¿Ð¸ під Ñ‡Ð°Ñ ÑкануваннÑ" -#: backend/genesys.cc:5617 +#: backend/genesys/genesys.cpp:4322 #, no-c-format msgid "The lamp will be turned off during scan. " msgstr "Лампу буде вимкнено під Ñ‡Ð°Ñ ÑкануваннÑ. " -#: backend/genesys.cc:5643 backend/genesys.cc:5644 +#: backend/genesys/genesys.cpp:4349 backend/genesys/genesys.cpp:4350 #, no-c-format msgid "File button" msgstr "Кнопка «File»" -#: backend/genesys.cc:5688 backend/genesys.cc:5689 +#: backend/genesys/genesys.cpp:4394 backend/genesys/genesys.cpp:4395 #, no-c-format msgid "OCR button" msgstr "Кнопка «OCR»" -#: backend/genesys.cc:5700 backend/genesys.cc:5701 +#: backend/genesys/genesys.cpp:4406 backend/genesys/genesys.cpp:4407 #, no-c-format msgid "Power button" msgstr "Кнопка «Power»" -#: backend/genesys.cc:5712 backend/genesys.cc:5713 +#: backend/genesys/genesys.cpp:4418 backend/genesys/genesys.cpp:4419 #, no-c-format msgid "Extra button" msgstr "Додаткова кнопка" -#: backend/genesys.cc:5724 backend/gt68xx.c:755 +#: backend/genesys/genesys.cpp:4430 backend/gt68xx.c:755 #, no-c-format -msgid "Need calibration" +msgid "Needs calibration" msgstr "Потребує калібруваннÑ" -#: backend/genesys.cc:5725 backend/gt68xx.c:756 +#: backend/genesys/genesys.cpp:4431 backend/gt68xx.c:756 backend/p5.c:1928 #, no-c-format msgid "The scanner needs calibration for the current settings" msgstr "Ð”Ð»Ñ Ð·Ð°ÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¸Ñ… параметрів потрібне калібруваннÑ" -#: backend/genesys.cc:5735 backend/gt68xx.c:780 backend/gt68xx.c:781 -#: backend/pixma_sane_options.c:226 backend/plustek.c:1080 +#: backend/genesys/genesys.cpp:4442 backend/gt68xx.c:780 +#: backend/gt68xx.c:781 backend/p5.c:1937 backend/p5.c:1938 +#: backend/pixma/pixma_sane_options.c:226 backend/plustek.c:1080 #, no-c-format msgid "Buttons" msgstr "Кнопки" -#: backend/genesys.cc:5744 backend/gt68xx.c:787 backend/hp5400_sane.c:392 -#: backend/hp-option.h:97 backend/niash.c:726 backend/plustek.c:941 +#: backend/genesys/genesys.cpp:4451 backend/gt68xx.c:787 +#: backend/hp-option.h:97 backend/hp5400_sane.c:392 backend/niash.c:726 +#: backend/p5.c:1945 backend/plustek.c:941 #, no-c-format msgid "Calibrate" msgstr "Відкалібрувати" -#: backend/genesys.cc:5746 backend/gt68xx.c:789 +#: backend/genesys/genesys.cpp:4453 backend/gt68xx.c:789 backend/p5.c:1947 #, no-c-format msgid "Start calibration using special sheet" msgstr "Почати ÐºÐ°Ð»Ñ–Ð±Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° допомогою Ñпеціального аркуша" -#: backend/genesys.cc:5758 backend/gt68xx.c:802 +#: backend/genesys/genesys.cpp:4465 backend/gt68xx.c:802 backend/p5.c:1958 #, no-c-format msgid "Clear calibration" msgstr "Спорожнити дані калібруваннÑ" -#: backend/genesys.cc:5759 backend/gt68xx.c:803 +#: backend/genesys/genesys.cpp:4466 backend/gt68xx.c:803 backend/p5.c:1960 #, no-c-format msgid "Clear calibration cache" msgstr "Спорожнити кеш калібруваннÑ" -#: backend/genesys.cc:5769 +#: backend/genesys/genesys.cpp:4476 #, no-c-format msgid "Force calibration" msgstr "ПримуÑове калібруваннÑ" -#: backend/genesys.cc:5770 +#: backend/genesys/genesys.cpp:4477 #, no-c-format msgid "Force calibration ignoring all and any calibration caches" msgstr "" "ПримуÑове ÐºÐ°Ð»Ñ–Ð±Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð· ігноруваннÑм уÑÑ–Ñ… кешованих даних калібруваннÑ" -#: backend/gt68xx.c:149 backend/ma1509.c:108 backend/mustek.c:164 -#: backend/snapscan-options.c:87 backend/umax.c:182 +#: backend/genesys/genesys.cpp:4487 +#, no-c-format +msgid "Ignore internal offsets" +msgstr "Ігнорувати внутрішні відÑтупи" + +#: backend/genesys/genesys.cpp:4489 +#, no-c-format +msgid "" +"Acquires the image including the internal calibration areas of the " +"scanner" +msgstr "" +"ÐадÑилає запит щодо ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²ÐºÐ»ÑŽÑ‡Ð½Ð¾ із внутрішніми " +"облаÑÑ‚Ñми ÐºÐ°Ð»Ñ–Ð±Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñканера" + +#: backend/genesys/genesys.h:79 backend/gt68xx.c:149 backend/ma1509.c:108 +#: backend/mustek.c:164 backend/snapscan-options.c:87 backend/umax.c:182 #, no-c-format msgid "Transparency Adapter" msgstr "Ðдаптер плівок" +#: backend/genesys/genesys.h:80 +#, no-c-format +msgid "Transparency Adapter Infrared" +msgstr "Ðдаптер плівок Ð´Ð»Ñ Ñ–Ð½Ñ„Ñ€Ð°Ñ‡ÐµÑ€Ð²Ð¾Ð½Ð¾Ð³Ð¾ ÑкануваннÑ" + #: backend/gt68xx.c:470 #, no-c-format msgid "Gray mode color" @@ -3374,6 +3420,314 @@ msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾ÐµÑ„Ñ–Ñ†Ñ–Ñ”Ð½Ñ‚Ð° контраÑтноÑÑ‚Ñ–" msgid "Sets the gamma value of all channels." msgstr "Визначає Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾ÐµÑ„Ñ–Ñ†Ñ–Ñ”Ð½Ñ‚Ð° контраÑтноÑÑ‚Ñ– Ð´Ð»Ñ Ð²ÑÑ–Ñ… каналів." +#: backend/hp-option.c:2987 +#, no-c-format +msgid "Advanced Options" +msgstr "Додаткові параметри" + +#: backend/hp-option.c:3044 +#, no-c-format +msgid "Coarse" +msgstr "Грубе" + +#: backend/hp-option.c:3045 +#, no-c-format +msgid "Fine" +msgstr "ВиÑокої ÑкоÑÑ‚Ñ–" + +#: backend/hp-option.c:3046 +#, no-c-format +msgid "Bayer" +msgstr "СекціÑ" + +#: backend/hp-option.c:3049 backend/hp-option.c:3100 +#, no-c-format +msgid "Custom" +msgstr "Ðетипова" + +#: backend/hp-option.c:3090 backend/hp-option.c:3146 +#: backend/hp-option.c:3161 +#, no-c-format +msgid "Auto" +msgstr "Ðвто" + +#: backend/hp-option.c:3091 +#, no-c-format +msgid "NTSC RGB" +msgstr "NTSC RGB" + +#: backend/hp-option.c:3092 +#, no-c-format +msgid "XPA RGB" +msgstr "XPA RGB" + +#: backend/hp-option.c:3093 +#, no-c-format +msgid "Pass-through" +msgstr "ПропуÑкати" + +#: backend/hp-option.c:3094 +#, no-c-format +msgid "NTSC Gray" +msgstr "Чорно-біле NTSC" + +#: backend/hp-option.c:3095 +#, no-c-format +msgid "XPA Gray" +msgstr "Чорно-біле XPA" + +#: backend/hp-option.c:3147 +#, no-c-format +msgid "Slow" +msgstr "Повільно" + +#: backend/hp-option.c:3148 backend/hp-option.c:3255 +#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 +#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 +#, no-c-format +msgid "Normal" +msgstr "Звичайна" + +#: backend/hp-option.c:3149 +#, no-c-format +msgid "Fast" +msgstr "Швидко" + +#: backend/hp-option.c:3150 +#, no-c-format +msgid "Extra Fast" +msgstr "Дуже швидко" + +#: backend/hp-option.c:3163 +#, no-c-format +msgid "2-pixel" +msgstr "Двоточкове" + +#: backend/hp-option.c:3164 +#, no-c-format +msgid "4-pixel" +msgstr "Чотириточкове" + +#: backend/hp-option.c:3165 +#, no-c-format +msgid "8-pixel" +msgstr "ВоÑьмиточкове" + +#: backend/hp-option.c:3176 +#, no-c-format +msgid "Print" +msgstr "Друк" + +#: backend/hp-option.c:3177 backend/hp3900_sane.c:427 +#: backend/hp3900_sane.c:1019 +#, no-c-format +msgid "Slide" +msgstr "Слайд" + +#: backend/hp-option.c:3178 +#, no-c-format +msgid "Film-strip" +msgstr "Плівка" + +#: backend/hp-option.c:3256 backend/hp5590.c:93 +#, no-c-format +msgid "ADF" +msgstr "ÐПД" + +#: backend/hp-option.c:3257 +#, no-c-format +msgid "XPA" +msgstr "XPA" + +#: backend/hp-option.c:3331 backend/hp-option.c:3344 +#, no-c-format +msgid "Conditional" +msgstr "Умовно" + +#: backend/hp-option.c:3417 +#, no-c-format +msgid "Experiment" +msgstr "ЕкÑперимент" + +#: backend/hp-option.h:60 +#, no-c-format +msgid "Sharpening" +msgstr "Збільшенні різкоÑÑ‚Ñ–" + +#: backend/hp-option.h:61 +#, no-c-format +msgid "Set sharpening value." +msgstr "Визначає величину Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ñ€Ñ–Ð·ÐºÐ¾ÑÑ‚Ñ–." + +#: backend/hp-option.h:66 +#, no-c-format +msgid "Auto Threshold" +msgstr "Ðвтоматичне порогове значеннÑ" + +#: backend/hp-option.h:68 +#, no-c-format +msgid "Enable automatic determination of threshold for line-art scans." +msgstr "" +"Увімкнути автоматичне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ€Ð¾Ð³Ð¾Ð²Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ " +"штрихових зображень." + +#: backend/hp-option.h:74 +#, no-c-format +msgid "Select smoothing filter." +msgstr "Визначити фільтр згладжуваннÑ." + +#: backend/hp-option.h:79 +#, no-c-format +msgid "Unload media after scan" +msgstr "Вивантажувати ноÑій піÑÐ»Ñ ÑкануваннÑ" + +#: backend/hp-option.h:80 +#, no-c-format +msgid "Unloads the media after a scan." +msgstr "Вивантажує ноÑій піÑÐ»Ñ ÑкануваннÑ." + +#: backend/hp-option.h:85 +#, no-c-format +msgid "Change document" +msgstr "Змінити документ" + +#: backend/hp-option.h:86 +#, no-c-format +msgid "Change Document." +msgstr "Змінити документ." + +#: backend/hp-option.h:91 +#, no-c-format +msgid "Unload" +msgstr "Вивантажити" + +#: backend/hp-option.h:92 +#, no-c-format +msgid "Unload Document." +msgstr "Вивантажити документ." + +#: backend/hp-option.h:98 +#, no-c-format +msgid "Start calibration process." +msgstr "Почати процедуру калібруваннÑ." + +#: backend/hp-option.h:103 +#, no-c-format +msgid "Media" +msgstr "ÐоÑій" + +#: backend/hp-option.h:104 +#, no-c-format +msgid "Set type of media." +msgstr "Визначити тип ноÑÑ–Ñ." + +#: backend/hp-option.h:109 +#, no-c-format +msgid "Exposure time" +msgstr "Ð§Ð°Ñ ÐµÐºÑпозиції" + +#: backend/hp-option.h:111 +#, no-c-format +msgid "" +"A longer exposure time lets the scanner collect more light. Suggested " +"use is 175% for prints, 150% for normal slides and \"Negative\" for " +"negative film. For dark (underexposed) images you can increase this " +"value." +msgstr "" +"Триваліша витримка надаÑÑ‚ÑŒ змогу Ñканеру накопичити більше Ñвітла. " +"Рекомендуємо вам ÑкориÑтатиÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñм 175% Ð´Ð»Ñ Ð´Ñ€ÑƒÐºÐ¾Ð²Ð°Ð½Ð¸Ñ… документів, " +"150% Ð´Ð»Ñ Ð·Ð²Ð¸Ñ‡Ð°Ð¹Ð½Ð¸Ñ… Ñлайдів та «Ðегатив» Ð´Ð»Ñ Ð½ÐµÐ³Ð°Ñ‚Ð¸Ð²Ñ–Ð². Ð”Ð»Ñ Ñ‚ÐµÐ¼Ð½Ð¸Ñ… " +"(недоекÑпонованих) зображень ви можете збільшити це значеннÑ." + +#: backend/hp-option.h:119 backend/hp-option.h:126 +#, no-c-format +msgid "Color Matrix" +msgstr "ÐœÐ°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²" + +#: backend/hp-option.h:121 +#, no-c-format +msgid "Set the scanner's color matrix." +msgstr "Визначити матрицю кольорів Ñканера." + +#: backend/hp-option.h:127 +#, no-c-format +msgid "Custom color matrix." +msgstr "Ðетипова Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²." + +#: backend/hp-option.h:132 +#, no-c-format +msgid "Mono Color Matrix" +msgstr "Чорно-біла Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²" + +#: backend/hp-option.h:133 +#, no-c-format +msgid "Custom color matrix for grayscale scans." +msgstr "Ðетипова Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð² Ð´Ð»Ñ Ñ‡Ð¾Ñ€Ð½Ð¾-білих зображень." + +#: backend/hp-option.h:138 +#, no-c-format +msgid "Mirror horizontal" +msgstr "Віддзеркалити горизонтально" + +#: backend/hp-option.h:139 +#, no-c-format +msgid "Mirror image horizontally." +msgstr "Віддзеркалити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ горизонталі." + +#: backend/hp-option.h:144 +#, no-c-format +msgid "Mirror vertical" +msgstr "Віддзеркалити вертикально" + +#: backend/hp-option.h:145 +#, no-c-format +msgid "Mirror image vertically." +msgstr "Віддзеркалити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ вертикалі." + +#: backend/hp-option.h:150 +#, no-c-format +msgid "Update options" +msgstr "Оновити параметри" + +#: backend/hp-option.h:151 +#, no-c-format +msgid "Update options." +msgstr "Оновити параметри." + +#: backend/hp-option.h:156 +#, no-c-format +msgid "8 bit output" +msgstr "8-бітовий вивід" + +#: backend/hp-option.h:158 +#, no-c-format +msgid "" +"Use bit depth greater eight internally, but output only eight bits." +msgstr "" +"Ð”Ð»Ñ Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½ÑŒÐ¾Ñ— обробки викориÑтовувати глибини кольорів, більші за 8-" +"бітові, але виводити дані лише у 8-бітовому форматі." + +#: backend/hp-option.h:164 +#, no-c-format +msgid "Front button wait" +msgstr "Очікувати натиÑÐºÐ°Ð½Ð½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ у передній чаÑтині" + +#: backend/hp-option.h:165 +#, no-c-format +msgid "Wait to scan for front-panel button push." +msgstr "" +"Ðе починати ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ натиÑÐºÐ°Ð½Ð½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ на передній панелі Ñканера." + +#: backend/hp-option.h:172 +#, no-c-format +msgid "Shut off lamp" +msgstr "Вимкнути лампу" + +#: backend/hp-option.h:173 +#, no-c-format +msgid "Shut off scanner lamp." +msgstr "Вимкнути лампу Ñканера." + #: backend/hp3500.c:1020 #, no-c-format msgid "Geometry Group" @@ -3384,12 +3738,6 @@ msgstr "Група розташуваннÑ" msgid "Scan Mode Group" msgstr "Група режимів ÑкануваннÑ" -#: backend/hp3900_sane.c:427 backend/hp3900_sane.c:1019 -#: backend/hp-option.c:3177 -#, no-c-format -msgid "Slide" -msgstr "Слайд" - #: backend/hp3900_sane.c:1405 #, no-c-format msgid "Scanner model" @@ -3397,14 +3745,14 @@ msgstr "Модель Ñканера" #: backend/hp3900_sane.c:1408 #, no-c-format -msgid "Allows one to test device behaviour with other supported models" +msgid "Allows one to test device behavior with other supported models" msgstr "" "Ðадає змогу перевірити поведінку приÑтрою з викориÑтаннÑм інших " "підтримуваних моделей" #: backend/hp3900_sane.c:1422 #, no-c-format -msgid "Image colours will be inverted" +msgid "Image colors will be inverted" msgstr "Кольори Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð±ÑƒÐ´Ðµ інвертовано" #: backend/hp3900_sane.c:1436 @@ -3594,11 +3942,6 @@ msgstr "Вмикає або вимикає лампу." msgid "Calibrates for black and white level." msgstr "Калібрує Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€Ñ–Ð²Ð½Ñ Ñ‡Ð¾Ñ€Ð½Ð¾Ð³Ð¾ и білого." -#: backend/hp5590.c:93 backend/hp-option.c:3256 -#, no-c-format -msgid "ADF" -msgstr "ÐПД" - #: backend/hp5590.c:95 #, no-c-format msgid "TMA Slides" @@ -3719,302 +4062,6 @@ msgstr "" "Ñк Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ форматі r*65536+256*g+b або Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¾Ð½Ñƒ Ñірого (типове " "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ â€” фіолетовий або Ñірий)" -#: backend/hp-option.c:2987 -#, no-c-format -msgid "Advanced Options" -msgstr "Додаткові параметри" - -#: backend/hp-option.c:3044 -#, no-c-format -msgid "Coarse" -msgstr "Грубе" - -#: backend/hp-option.c:3045 -#, no-c-format -msgid "Fine" -msgstr "ВиÑокої ÑкоÑÑ‚Ñ–" - -#: backend/hp-option.c:3046 -#, no-c-format -msgid "Bayer" -msgstr "СекціÑ" - -#: backend/hp-option.c:3049 backend/hp-option.c:3100 -#, no-c-format -msgid "Custom" -msgstr "Ðетипова" - -#: backend/hp-option.c:3090 backend/hp-option.c:3146 -#: backend/hp-option.c:3161 -#, no-c-format -msgid "Auto" -msgstr "Ðвто" - -#: backend/hp-option.c:3091 -#, no-c-format -msgid "NTSC RGB" -msgstr "NTSC RGB" - -#: backend/hp-option.c:3092 -#, no-c-format -msgid "XPA RGB" -msgstr "XPA RGB" - -#: backend/hp-option.c:3093 -#, no-c-format -msgid "Pass-through" -msgstr "ПропуÑкати" - -#: backend/hp-option.c:3094 -#, no-c-format -msgid "NTSC Gray" -msgstr "Чорно-біле NTSC" - -#: backend/hp-option.c:3095 -#, no-c-format -msgid "XPA Gray" -msgstr "Чорно-біле XPA" - -#: backend/hp-option.c:3147 -#, no-c-format -msgid "Slow" -msgstr "Повільно" - -#: backend/hp-option.c:3148 backend/hp-option.c:3255 -#: backend/kvs40xx_opt.c:230 backend/matsushita.c:244 backend/mustek.c:149 -#: backend/plustek.c:234 backend/plustek_pp.c:203 backend/u12.c:155 -#, no-c-format -msgid "Normal" -msgstr "Звичайна" - -#: backend/hp-option.c:3149 -#, no-c-format -msgid "Fast" -msgstr "Швидко" - -#: backend/hp-option.c:3150 -#, no-c-format -msgid "Extra Fast" -msgstr "Дуже швидко" - -#: backend/hp-option.c:3163 -#, no-c-format -msgid "2-pixel" -msgstr "Двоточкове" - -#: backend/hp-option.c:3164 -#, no-c-format -msgid "4-pixel" -msgstr "Чотириточкове" - -#: backend/hp-option.c:3165 -#, no-c-format -msgid "8-pixel" -msgstr "ВоÑьмиточкове" - -#: backend/hp-option.c:3176 -#, no-c-format -msgid "Print" -msgstr "Друк" - -#: backend/hp-option.c:3178 -#, no-c-format -msgid "Film-strip" -msgstr "Плівка" - -#: backend/hp-option.c:3257 -#, no-c-format -msgid "XPA" -msgstr "XPA" - -#: backend/hp-option.c:3331 backend/hp-option.c:3344 -#, no-c-format -msgid "Conditional" -msgstr "Умовно" - -#: backend/hp-option.c:3417 -#, no-c-format -msgid "Experiment" -msgstr "ЕкÑперимент" - -#: backend/hp-option.h:60 -#, no-c-format -msgid "Sharpening" -msgstr "Збільшенні різкоÑÑ‚Ñ–" - -#: backend/hp-option.h:61 -#, no-c-format -msgid "Set sharpening value." -msgstr "Визначає величину Ð·Ð±Ñ–Ð»ÑŒÑˆÐµÐ½Ð½Ñ Ñ€Ñ–Ð·ÐºÐ¾ÑÑ‚Ñ–." - -#: backend/hp-option.h:66 -#, no-c-format -msgid "Auto Threshold" -msgstr "Ðвтоматичне порогове значеннÑ" - -#: backend/hp-option.h:68 -#, no-c-format -msgid "Enable automatic determination of threshold for line-art scans." -msgstr "" -"Увімкнути автоматичне Ð²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ€Ð¾Ð³Ð¾Ð²Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ " -"штрихових зображень." - -#: backend/hp-option.h:74 -#, no-c-format -msgid "Select smoothing filter." -msgstr "Визначити фільтр згладжуваннÑ." - -#: backend/hp-option.h:79 -#, no-c-format -msgid "Unload media after scan" -msgstr "Вивантажувати ноÑій піÑÐ»Ñ ÑкануваннÑ" - -#: backend/hp-option.h:80 -#, no-c-format -msgid "Unloads the media after a scan." -msgstr "Вивантажує ноÑій піÑÐ»Ñ ÑкануваннÑ." - -#: backend/hp-option.h:85 -#, no-c-format -msgid "Change document" -msgstr "Змінити документ" - -#: backend/hp-option.h:86 -#, no-c-format -msgid "Change Document." -msgstr "Змінити документ." - -#: backend/hp-option.h:91 -#, no-c-format -msgid "Unload" -msgstr "Вивантажити" - -#: backend/hp-option.h:92 -#, no-c-format -msgid "Unload Document." -msgstr "Вивантажити документ." - -#: backend/hp-option.h:98 -#, no-c-format -msgid "Start calibration process." -msgstr "Почати процедуру калібруваннÑ." - -#: backend/hp-option.h:103 -#, no-c-format -msgid "Media" -msgstr "ÐоÑій" - -#: backend/hp-option.h:104 -#, no-c-format -msgid "Set type of media." -msgstr "Визначити тип ноÑÑ–Ñ." - -#: backend/hp-option.h:109 -#, no-c-format -msgid "Exposure time" -msgstr "Ð§Ð°Ñ ÐµÐºÑпозиції" - -#: backend/hp-option.h:111 -#, no-c-format -msgid "" -"A longer exposure time lets the scanner collect more light. Suggested " -"use is 175% for prints, 150% for normal slides and \"Negative\" for " -"negative film. For dark (underexposed) images you can increase this " -"value." -msgstr "" -"Триваліша витримка надаÑÑ‚ÑŒ змогу Ñканеру накопичити більше Ñвітла. " -"Рекомендуємо вам ÑкориÑтатиÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñм 175% Ð´Ð»Ñ Ð´Ñ€ÑƒÐºÐ¾Ð²Ð°Ð½Ð¸Ñ… документів, " -"150% Ð´Ð»Ñ Ð·Ð²Ð¸Ñ‡Ð°Ð¹Ð½Ð¸Ñ… Ñлайдів та «Ðегатив» Ð´Ð»Ñ Ð½ÐµÐ³Ð°Ñ‚Ð¸Ð²Ñ–Ð². Ð”Ð»Ñ Ñ‚ÐµÐ¼Ð½Ð¸Ñ… " -"(недоекÑпонованих) зображень ви можете збільшити це значеннÑ." - -#: backend/hp-option.h:119 backend/hp-option.h:126 -#, no-c-format -msgid "Color Matrix" -msgstr "ÐœÐ°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²" - -#: backend/hp-option.h:121 -#, no-c-format -msgid "Set the scanners color matrix." -msgstr "Визначити матрицю кольорів Ñканера." - -#: backend/hp-option.h:127 -#, no-c-format -msgid "Custom color matrix." -msgstr "Ðетипова Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²." - -#: backend/hp-option.h:132 -#, no-c-format -msgid "Mono Color Matrix" -msgstr "Чорно-біла Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²" - -#: backend/hp-option.h:133 -#, no-c-format -msgid "Custom color matrix for grayscale scans." -msgstr "Ðетипова Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð² Ð´Ð»Ñ Ñ‡Ð¾Ñ€Ð½Ð¾-білих зображень." - -#: backend/hp-option.h:138 -#, no-c-format -msgid "Mirror horizontal" -msgstr "Віддзеркалити горизонтально" - -#: backend/hp-option.h:139 -#, no-c-format -msgid "Mirror image horizontally." -msgstr "Віддзеркалити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ горизонталі." - -#: backend/hp-option.h:144 -#, no-c-format -msgid "Mirror vertical" -msgstr "Віддзеркалити вертикально" - -#: backend/hp-option.h:145 -#, no-c-format -msgid "Mirror image vertically." -msgstr "Віддзеркалити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ вертикалі." - -#: backend/hp-option.h:150 -#, no-c-format -msgid "Update options" -msgstr "Оновити параметри" - -#: backend/hp-option.h:151 -#, no-c-format -msgid "Update options." -msgstr "Оновити параметри." - -#: backend/hp-option.h:156 -#, no-c-format -msgid "8 bit output" -msgstr "8-бітовий вивід" - -#: backend/hp-option.h:158 -#, no-c-format -msgid "Use bit depth greater eight internally, but output only eight bits." -msgstr "" -"Ð”Ð»Ñ Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½ÑŒÐ¾Ñ— обробки викориÑтовувати глибини кольорів, більші за 8-" -"бітові, але виводити дані лише у 8-бітовому форматі." - -#: backend/hp-option.h:164 -#, no-c-format -msgid "Front button wait" -msgstr "Очікувати натиÑÐºÐ°Ð½Ð½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ у передній чаÑтині" - -#: backend/hp-option.h:165 -#, no-c-format -msgid "Wait to scan for front-panel button push." -msgstr "" -"Ðе починати ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ натиÑÐºÐ°Ð½Ð½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ¸ на передній панелі Ñканера." - -#: backend/hp-option.h:172 -#, no-c-format -msgid "Shut off lamp" -msgstr "Вимкнути лампу" - -#: backend/hp-option.h:173 -#, no-c-format -msgid "Shut off scanner lamp." -msgstr "Вимкнути лампу Ñканера." - #: backend/kvs1025.h:51 backend/kvs20xx_opt.c:295 backend/kvs40xx_opt.c:516 #: backend/matsushita.h:219 #, no-c-format @@ -4113,7 +4160,7 @@ msgid "single" msgstr "однобічний" #: backend/kvs1025_opt.c:73 backend/kvs20xx.c:462 backend/kvs20xx_opt.c:56 -#: backend/kvs40xx.c:704 backend/kvs40xx.c:722 backend/kvs40xx_opt.c:102 +#: backend/kvs40xx.c:705 backend/kvs40xx.c:723 backend/kvs40xx_opt.c:102 #: backend/kvs40xx_opt.c:1087 #, no-c-format msgid "continuous" @@ -4282,8 +4329,8 @@ msgstr "ЕПТ" #: backend/kvs1025_opt.c:229 #, no-c-format -msgid "linier" -msgstr "лінійна" +msgid "linear" +msgstr "лінійне" #: backend/kvs1025_opt.c:241 backend/kvs20xx_opt.c:138 #: backend/kvs40xx_opt.c:224 @@ -4412,7 +4459,7 @@ msgstr "Визначає виразніÑÑ‚ÑŒ зображеннÑ" #: backend/kvs1025_opt.c:807 backend/kvs1025_opt.c:808 #: backend/matsushita.c:1300 backend/matsushita.c:1301 -#: backend/pixma_sane_options.c:112 +#: backend/pixma/pixma_sane_options.c:112 #, no-c-format msgid "Gamma" msgstr "Гама" @@ -4485,11 +4532,11 @@ msgstr "" "Вимагати від драйвера Ð²Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ñ– зі Ñторінок у автоматичному " "режимі" -#: backend/kvs20xx_opt.c:233 backend/kvs40xx_opt.c:396 +#: backend/kvs20xx_opt.c:233 #, no-c-format msgid "" -"Length Control Mode is a mode that the scanner reads up to the shorter " -"length of actual paper or logical document length." +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length." msgstr "" "У режимі ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð¾ÑŽ Ñканер читає дані до найкоротшої з таких " "довжин: дійÑної довжини аркуша паперу або логічної довжини документа." @@ -4523,12 +4570,12 @@ msgstr "B4" #: backend/kvs40xx_opt.c:231 #, no-c-format -msgid "High sensivity" +msgid "High sensitivity" msgstr "ВиÑока чутливіÑÑ‚ÑŒ" #: backend/kvs40xx_opt.c:232 #, no-c-format -msgid "Low sensivity" +msgid "Low sensitivity" msgstr "Ðизька чутливіÑÑ‚ÑŒ" #: backend/kvs40xx_opt.c:243 @@ -4551,6 +4598,15 @@ msgstr "Звичайний режим" msgid "Enhanced mode" msgstr "Розширений режим" +#: backend/kvs40xx_opt.c:396 +#, no-c-format +msgid "" +"Length Control Mode causes the scanner to read the shorter of either the " +"length of the actual paper or logical document length" +msgstr "" +"У режимі ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð¾ÑŽ Ñканер читає дані до найкоротшої з таких " +"довжин: дійÑної довжини аркуша паперу або логічної довжини документа" + #: backend/kvs40xx_opt.c:405 #, no-c-format msgid "" @@ -4613,8 +4669,9 @@ msgstr "СтиÑÐºÐ°Ð½Ð½Ñ JPEG" #: backend/kvs40xx_opt.c:718 #, no-c-format -msgid "JPEG compression (yours application must be able to uncompress)" -msgstr "СтиÑÐºÐ°Ð½Ð½Ñ JPEG (ваша програма повинна мати змогу розпакувати дані)" +msgid "JPEG compression (your application must be able to uncompress)" +msgstr "" +"СтиÑÐºÐ°Ð½Ð½Ñ JPEG (ваша програма повинна мати змогу розпакувати дані)" #: backend/kvs40xx_opt.c:737 backend/kvs40xx_opt.c:738 #, no-c-format @@ -4648,12 +4705,12 @@ msgstr "ÐšÐ¾Ñ€Ð¸Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐºÐ¾ÑˆÑƒÐ²Ð°Ð½Ð½Ñ" #: backend/kvs40xx_opt.c:808 #, no-c-format -msgid "Stop scanner when a paper have been skewed" +msgid "Stop scanner if a sheet is skewed" msgstr "Зупинити ÑкануваннÑ, Ñкщо папір було перекошено" #: backend/kvs40xx_opt.c:809 #, no-c-format -msgid "Scanner will be stop when a paper have been skewed" +msgid "Scanner will stop if a sheet is skewed" msgstr "Ð¡ÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ зупинено, Ñкщо папір було вÑтавлено з нахилом" #: backend/kvs40xx_opt.c:816 @@ -4663,13 +4720,13 @@ msgstr "Обрізати до Ñправжньої облаÑÑ‚Ñ– зображе #: backend/kvs40xx_opt.c:817 #, no-c-format -msgid "Scanner automatically detect image area and crop it" +msgid "Scanner will automatically detect image area and crop to it" msgstr "Сканер автоматично визначає облаÑÑ‚ÑŒ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñ– обрізає його" #: backend/kvs40xx_opt.c:827 #, no-c-format -msgid "It is right and left reversing" -msgstr "ÐŸÐµÑ€ÐµÐ²ÐµÑ€Ñ‚Ð°Ð½Ð½Ñ Ð»Ñ–Ð²Ð¾Ñ€ÑƒÑ‡ Ñ– праворуч" +msgid "Left/right mirror image" +msgstr "Віддзеркалити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð³Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð¾" #: backend/kvs40xx_opt.c:834 backend/kvs40xx_opt.c:835 #, no-c-format @@ -4706,52 +4763,52 @@ msgstr "Ð¡ÐµÐºÑ†Ñ–Ñ 8x8" msgid "8x8 Vertical Line" msgstr "8x8 Вертикальна лініÑ" -#: backend/lexmark.c:273 backend/umax_pp.c:715 +#: backend/lexmark.c:273 backend/umax_pp.c:705 #, no-c-format msgid "Gain" msgstr "ПідÑиленнÑ" -#: backend/lexmark.c:274 backend/umax_pp.c:716 +#: backend/lexmark.c:274 backend/umax_pp.c:706 #, no-c-format msgid "Color channels gain settings" msgstr "Параметри підÑÐ¸Ð»ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñ–Ð² кольорів" -#: backend/lexmark.c:283 backend/umax_pp.c:723 +#: backend/lexmark.c:283 backend/umax_pp.c:713 #, no-c-format msgid "Gray gain" msgstr "ПідÑÐ¸Ð»ÐµÐ½Ð½Ñ Ñірого" -#: backend/lexmark.c:284 backend/umax_pp.c:724 +#: backend/lexmark.c:284 backend/umax_pp.c:714 #, no-c-format msgid "Sets gray channel gain" msgstr "Визначає підÑÐ¸Ð»ÐµÐ½Ð½Ñ Ñірого каналу" -#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:735 +#: backend/lexmark.c:297 backend/plustek.c:1001 backend/umax_pp.c:725 #, no-c-format msgid "Red gain" msgstr "ПідÑÐ¸Ð»ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð²Ð¾Ð½Ð¾Ð³Ð¾" -#: backend/lexmark.c:298 backend/umax_pp.c:736 +#: backend/lexmark.c:298 backend/umax_pp.c:726 #, no-c-format msgid "Sets red channel gain" msgstr "Визначає підÑÐ¸Ð»ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ червоного" -#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:747 +#: backend/lexmark.c:311 backend/plustek.c:1017 backend/umax_pp.c:737 #, no-c-format msgid "Green gain" msgstr "ПідÑÐ¸Ð»ÐµÐ½Ð½Ñ Ð·ÐµÐ»ÐµÐ½Ð¾Ð³Ð¾" -#: backend/lexmark.c:312 backend/umax_pp.c:748 +#: backend/lexmark.c:312 backend/umax_pp.c:738 #, no-c-format msgid "Sets green channel gain" msgstr "Визначає підÑÐ¸Ð»ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ зеленого" -#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:759 +#: backend/lexmark.c:325 backend/plustek.c:1033 backend/umax_pp.c:749 #, no-c-format msgid "Blue gain" msgstr "ПідÑÐ¸Ð»ÐµÐ½Ð½Ñ Ñинього" -#: backend/lexmark.c:326 backend/umax_pp.c:760 +#: backend/lexmark.c:326 backend/umax_pp.c:750 #, no-c-format msgid "Sets blue channel gain" msgstr "Визначає підÑÐ¸Ð»ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ Ñинього" @@ -4837,7 +4894,7 @@ msgstr "Одна Ñторінка" msgid "All pages" msgstr "Ð’ÑÑ– Ñторінки" -#: backend/matsushita.c:1034 backend/plustek.c:1333 +#: backend/matsushita.c:1034 backend/p5_device.c:8 backend/plustek.c:1333 #, no-c-format msgid "sheetfed scanner" msgstr "Ñканер з подачею аркушів" @@ -5001,7 +5058,8 @@ msgstr "СкалÑрна гама Ñинього" #: backend/microtek2.h:665 #, no-c-format msgid "Selects a value for scalar gamma correction (blue channel)" -msgstr "Визначає Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑкалÑрного Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð³Ð°Ð¼Ð¸ (канал Ñинього)." +msgstr "" +"Визначає Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑкалÑрного Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ Ð³Ð°Ð¼Ð¸ (канал Ñинього)." #: backend/microtek2.h:669 #, no-c-format @@ -5268,7 +5326,8 @@ msgstr "ЯÑкравіÑÑ‚ÑŒ зеленого" #: backend/mustek.c:4457 #, no-c-format -msgid "Controls the brightness of the green channel of the acquired image." +msgid "" +"Controls the brightness of the green channel of the acquired image." msgstr "Керує ÑÑкравіÑÑ‚ÑŽ каналу зеленого у отриманому зображенні." #: backend/mustek.c:4469 @@ -5350,27 +5409,32 @@ msgstr "" "Розігрівати, до Ñталої ÑÑкравоÑÑ‚Ñ– лампи, не наполÑгати на 40-ти " "Ñекундному розігріві." -#: backend/pixma.c:397 +#: backend/p5.c:1926 +#, no-c-format +msgid "Need calibration" +msgstr "Потребує калібруваннÑ" + +#: backend/pixma/pixma.c:397 #, no-c-format msgid "Negative color" msgstr "Кольоровий негатив" -#: backend/pixma.c:402 +#: backend/pixma/pixma.c:402 #, no-c-format msgid "Negative gray" msgstr "Чорно-білий негатив" -#: backend/pixma.c:415 +#: backend/pixma/pixma.c:415 #, no-c-format msgid "48 bits color" msgstr "48-бітовий колір" -#: backend/pixma.c:420 +#: backend/pixma/pixma.c:420 #, no-c-format msgid "16 bits gray" msgstr "16-бітовий Ñірий" -#: backend/pixma_sane_options.c:84 +#: backend/pixma/pixma_sane_options.c:84 #, no-c-format msgid "" "Selects the scan source (such as a document-feeder). Set source before " @@ -5380,12 +5444,12 @@ msgstr "" "Ð’Ñтановіть джерело перед режимом Ñ– роздільною здатніÑÑ‚ÑŽ. Відновлює " "автоматично визначені Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ та роздільної здатноÑÑ‚Ñ–." -#: backend/pixma_sane_options.c:98 +#: backend/pixma/pixma_sane_options.c:98 #, no-c-format msgid "Button-controlled scan" msgstr "Кероване кнопкою ÑкануваннÑ" -#: backend/pixma_sane_options.c:99 +#: backend/pixma/pixma_sane_options.c:99 #, no-c-format msgid "" "When enabled, scan process will not start immediately. To proceed, press " @@ -5396,40 +5460,40 @@ msgstr "" "негайно. Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ, натиÑніть кнопку «SCAN» (MP150) або " "«COLOR» (Ð´Ð»Ñ Ñ–Ð½ÑˆÐ¸Ñ… моделей). Ð”Ð»Ñ ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð°Ñ‚Ð¸Ñніть кнопку «GRAY»." -#: backend/pixma_sane_options.c:232 +#: backend/pixma/pixma_sane_options.c:232 #, no-c-format msgid "Update button state" msgstr "Оновити Ñтан кнопки" -#: backend/pixma_sane_options.c:244 +#: backend/pixma/pixma_sane_options.c:244 #, no-c-format msgid "Button 1" msgstr "Кнопка 1" -#: backend/pixma_sane_options.c:258 +#: backend/pixma/pixma_sane_options.c:258 #, no-c-format msgid "Button 2" msgstr "Кнопка 2" -#: backend/pixma_sane_options.c:272 +#: backend/pixma/pixma_sane_options.c:272 #, no-c-format msgid "Type of original to scan" msgstr "Тип оригіналу Ð´Ð»Ñ ÑкануваннÑ" -#: backend/pixma_sane_options.c:286 +#: backend/pixma/pixma_sane_options.c:286 #, no-c-format msgid "Target operation type" msgstr "Тип дії Ð´Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñƒ" -#: backend/pixma_sane_options.c:348 +#: backend/pixma/pixma_sane_options.c:348 #, no-c-format msgid "ADF Waiting Time" msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ ÐПД" -#: backend/pixma_sane_options.c:349 +#: backend/pixma/pixma_sane_options.c:349 #, no-c-format msgid "" -"When set, the scanner searches the waiting time in seconds for a new " +"When set, the scanner waits upto the specified time in seconds for a new " "document inserted into the automatic document feeder." msgstr "" "Якщо визначено, Ñканер шукатиме новий документ, вÑтавлений до приÑтрою " @@ -5520,7 +5584,7 @@ msgstr "Ðналогова оболонка" msgid "Red gain value of the AFE" msgstr "Ð—Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ–Ð´ÑÐ¸Ð»ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð²Ð¾Ð½Ð¾Ð³Ð¾ AFE" -#: backend/plustek.c:1009 backend/umax_pp.c:792 +#: backend/plustek.c:1009 backend/umax_pp.c:782 #, no-c-format msgid "Red offset" msgstr "Ð—Ð¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð²Ð¾Ð½Ð¾Ð³Ð¾" @@ -5797,7 +5861,7 @@ msgstr "" msgid "This option reflects the status of a scanner button." msgstr "Цей пункт відповідає Ñтану кнопки ÑкануваннÑ." -#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:639 +#: backend/rts8891.c:2840 backend/umax.c:5795 backend/umax_pp.c:629 #, no-c-format msgid "Lamp on" msgstr "Увімкнути лампу" @@ -5807,12 +5871,12 @@ msgstr "Увімкнути лампу" msgid "Turn on scanner lamp" msgstr "Увімкнути лампу Ñканера" -#: backend/rts8891.c:2851 backend/umax1220u.c:248 backend/umax.c:5812 +#: backend/rts8891.c:2851 backend/umax.c:5812 backend/umax1220u.c:248 #, no-c-format msgid "Lamp off" msgstr "Вимкнути лампу" -#: backend/rts8891.c:2852 backend/umax1220u.c:249 backend/umax.c:5813 +#: backend/rts8891.c:2852 backend/umax.c:5813 backend/umax1220u.c:249 #, no-c-format msgid "Turn off scanner lamp" msgstr "Вимкнути лампу Ñканера" @@ -5959,12 +6023,12 @@ msgstr "Точка фокуÑуваннÑ" #: backend/snapscan-options.c:930 #, no-c-format -msgid "Colour lines per read" +msgid "Color lines per read" msgstr "Кольорових ліній на ÑÐµÐ°Ð½Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ" #: backend/snapscan-options.c:942 #, no-c-format -msgid "Greyscale lines per read" +msgid "Grayscale lines per read" msgstr "Чорно-білих ліній на ÑÐµÐ°Ð½Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ" #: backend/stv680.c:974 @@ -6128,7 +6192,8 @@ msgstr "Ð“Ñ€Ð°Ð½Ð¸Ñ†Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ" #: backend/test.c:485 #, no-c-format -msgid "Limit the amount of data transferred with each call to sane_read()." +msgid "" +"Limit the amount of data transferred with each call to sane_read()." msgstr "" "Обмежити об’єм даних, що передаютьÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ виклику sane_read()." @@ -6626,52 +6691,52 @@ msgstr "Режим калібруваннÑ" msgid "Define calibration mode" msgstr "Визначає режим калібруваннÑ" -#: backend/umax_pp.c:640 +#: backend/umax_pp.c:630 #, no-c-format msgid "Sets lamp on/off" msgstr "Визначає Ñтан вмиканнÑ/Ð²Ð¸Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð»Ð°Ð¼Ð¿Ð¸" -#: backend/umax_pp.c:649 +#: backend/umax_pp.c:639 #, no-c-format msgid "UTA on" msgstr "Увімкнути UTA" -#: backend/umax_pp.c:650 +#: backend/umax_pp.c:640 #, no-c-format msgid "Sets UTA on/off" msgstr "Увімкнути/Вимкнути UTA" -#: backend/umax_pp.c:771 +#: backend/umax_pp.c:761 #, no-c-format msgid "Offset" msgstr "ЗÑув" -#: backend/umax_pp.c:773 +#: backend/umax_pp.c:763 #, no-c-format msgid "Color channels offset settings" msgstr "Параметри зÑуву каналів кольорів" -#: backend/umax_pp.c:780 +#: backend/umax_pp.c:770 #, no-c-format msgid "Gray offset" msgstr "ЗÑув Ñірого" -#: backend/umax_pp.c:781 +#: backend/umax_pp.c:771 #, no-c-format msgid "Sets gray channel offset" msgstr "Визначає зÑув каналу Ñірого" -#: backend/umax_pp.c:793 +#: backend/umax_pp.c:783 #, no-c-format msgid "Sets red channel offset" msgstr "Визначає зÑув каналу червоного" -#: backend/umax_pp.c:805 +#: backend/umax_pp.c:795 #, no-c-format msgid "Sets green channel offset" msgstr "Визначає зÑув каналу зеленого" -#: backend/umax_pp.c:817 +#: backend/umax_pp.c:807 #, no-c-format msgid "Sets blue channel offset" msgstr "Визначає зÑув каналу Ñинього" diff --git a/sanei/Makefile.am b/sanei/Makefile.am index a197343..46d3ff4 100644 --- a/sanei/Makefile.am +++ b/sanei/Makefile.am @@ -5,7 +5,7 @@ ## included LICENSE file for license information. AM_CPPFLAGS += -I. -I$(srcdir) -I$(top_builddir)/include \ - -I$(top_srcdir)/include $(USB_CFLAGS) + -I$(top_srcdir)/include $(USB_CFLAGS) $(XML_CFLAGS) noinst_LTLIBRARIES = libsanei.la diff --git a/sanei/sanei_init_debug.c b/sanei/sanei_init_debug.c index 946aee9..3cde74e 100644 --- a/sanei/sanei_init_debug.c +++ b/sanei/sanei_init_debug.c @@ -58,6 +58,8 @@ #include <sys/socket.h> #endif #include <sys/stat.h> +#include <time.h> +#include <sys/time.h> #ifdef HAVE_OS2_H # define INCL_DOS @@ -148,7 +150,13 @@ sanei_debug_msg } else { - fprintf (stderr, "[%s] ", be); + struct timeval tv; + struct tm *t; + + gettimeofday (&tv, NULL); + t = localtime (&tv.tv_sec); + + fprintf (stderr, "[%02d:%02d:%02d.%06ld] [%s] ", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec, be); vfprintf (stderr, fmt, ap); } diff --git a/sanei/sanei_scsi.c b/sanei/sanei_scsi.c index ca3dbb0..b69f78f 100644 --- a/sanei/sanei_scsi.c +++ b/sanei/sanei_scsi.c @@ -615,7 +615,7 @@ open_aspi (void) DBG (1, "OS/2: unique id is '%s'\n", PSRBlock->u.inq.unique_id); strcpy (tmpAspi, "asXXXXXX"); - mktemp (tmpAspi); + mkstemp (tmpAspi); DBG (2, "open_aspi: open temporary file '%s'\n", tmpAspi); tmp = fopen (tmpAspi, "w"); if (!tmp) @@ -3271,8 +3271,8 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel, ccb = cam_getccb (dev); /* Build the CCB */ - bzero (&(&ccb->ccb_h)[1], sizeof (struct ccb_scsiio)); - bcopy (cmd, &ccb->csio.cdb_io.cdb_bytes, cmd_size); + memset (&(&ccb->ccb_h)[1], 0, sizeof (struct ccb_scsiio)); + memcpy (&ccb->csio.cdb_io.cdb_bytes, cmd, cmd_size); /* * Set the data direction flags. @@ -3368,7 +3368,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel, int retval = 0; /* build ccb for device match */ - bzero (&cdm, sizeof (cdm)); + memset (&cdm, 0, sizeof (cdm)); cdm.ccb_h.func_code = XPT_DEV_MATCH; /* result buffer */ @@ -3454,7 +3454,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel, } /* build ccb for device match */ - bzero (&cdm, sizeof (cdm)); + memset (&cdm, 0, sizeof (cdm)); cdm.ccb_h.func_code = XPT_DEV_MATCH; /* result buffer */ @@ -4449,7 +4449,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel, memcpy (databuf, (u_char *) src, src_size); } - bzero (sensebuf, 128); + memset (sensebuf, 0, 128); /* * Do SCSI request... @@ -5358,7 +5358,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel, memcpy (&cdb.cdb, cmd, cmd_size); if (dst && dst_size) { - bzero (dst, *dst_size); + memset (dst, 0, *dst_size); range.address = (IOVirtualAddress) dst; range.length = *dst_size; transferCount = *dst_size; @@ -5699,7 +5699,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel, DBG (6, "isRead dst_size:%ld\n", *dst_size); /* Zero the buffer. */ - bzero (dst, *dst_size); + memset (dst, 0, *dst_size); /* Configure the virtual range for the buffer. */ range.address = (long) dst; @@ -5722,8 +5722,8 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel, /* zero the senseData and CDB */ - bzero (&senseData, sizeof (senseData)); - bzero (cdb, sizeof (cdb)); + memset (&senseData, 0, sizeof (senseData)); + memset (cdb, 0, sizeof (cdb)); /* copy the command data */ memcpy (cdb, cmd, cmd_size); diff --git a/sanei/sanei_usb.c b/sanei/sanei_usb.c index 6fd6040..db0f452 100644 --- a/sanei/sanei_usb.c +++ b/sanei/sanei_usb.c @@ -49,6 +49,7 @@ #include "../include/sane/config.h" #include <stdlib.h> +#include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -62,6 +63,9 @@ #include <dirent.h> #include <time.h> +#if WITH_USB_RECORD_REPLAY +#include <libxml/tree.h> +#endif #ifdef HAVE_RESMGR #include <resmgr.h> @@ -174,6 +178,34 @@ static int device_number=0; * count number of time sanei_usb has been initialized */ static int initialized=0; +typedef enum +{ + sanei_usb_testing_mode_disabled = 0, + + sanei_usb_testing_mode_record, // records the communication with the slave + // but does not change the USB stack in any + // way + sanei_usb_testing_mode_replay, // replays the communication with the scanner + // recorded earlier +} +sanei_usb_testing_mode; + +// Whether testing mode has been enabled +static sanei_usb_testing_mode testing_mode = sanei_usb_testing_mode_disabled; + +#if WITH_USB_RECORD_REPLAY +static int testing_development_mode = 0; +int testing_known_commands_input_failed = 0; +unsigned testing_last_known_seq = 0; +SANE_String testing_record_backend = NULL; +xmlNode* testing_append_commands_node = NULL; + +// XML file from which we read testing data +SANE_String testing_xml_path = NULL; +xmlDoc* testing_xml_doc = NULL; +xmlNode* testing_xml_next_tx_node = NULL; +#endif // WITH_USB_RECORD_REPLAY + #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB) static int libusb_timeout = 30 * 1000; /* 30 seconds */ #endif /* HAVE_LIBUSB_LEGACY */ @@ -455,6 +487,859 @@ sanei_libusb_strerror (int errcode) } #endif /* HAVE_LIBUSB */ +#if WITH_USB_RECORD_REPLAY +SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path, + int development_mode) +{ + testing_mode = sanei_usb_testing_mode_replay; + testing_development_mode = development_mode; + + // TODO: we'll leak if noone ever inits sane_usb properly + testing_xml_path = strdup(path); + testing_xml_doc = xmlReadFile(testing_xml_path, NULL, 0); + if (!testing_xml_doc) + return SANE_STATUS_ACCESS_DENIED; + + return SANE_STATUS_GOOD; +} + +#define FAIL_TEST(func, ...) \ + do { \ + DBG(1, "%s: FAIL: ", func); \ + DBG(1, __VA_ARGS__); \ + fail_test(); \ + } while (0) + +#define FAIL_TEST_TX(func, node, ...) \ + do { \ + sanei_xml_print_seq_if_any(node, func); \ + DBG(1, "%s: FAIL: ", func); \ + DBG(1, __VA_ARGS__); \ + fail_test(); \ + } while (0) + +void fail_test() +{ +} + +SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, SANE_String_Const be_name) +{ + testing_mode = sanei_usb_testing_mode_record; + testing_record_backend = strdup(be_name); + testing_xml_path = strdup(path); + + return SANE_STATUS_GOOD; +} + +static xmlNode* sanei_xml_find_first_child_with_name(xmlNode* parent, + const char* name) +{ + xmlNode* curr_child = xmlFirstElementChild(parent); + while (curr_child != NULL) + { + if (xmlStrcmp(curr_child->name, (const xmlChar*)name) == 0) + return curr_child; + curr_child = xmlNextElementSibling(curr_child); + } + return NULL; +} + +static xmlNode* sanei_xml_find_next_child_with_name(xmlNode* child, + const char* name) +{ + xmlNode* curr_child = xmlNextElementSibling(child); + while (curr_child != NULL) + { + if (xmlStrcmp(curr_child->name, (const xmlChar*)name) == 0) + return curr_child; + curr_child = xmlNextElementSibling(curr_child); + } + return NULL; +} + +// a wrapper to get rid of -Wpointer-sign warnings in a single place +static char* sanei_xml_get_prop(xmlNode* node, const char* name) +{ + return (char*)xmlGetProp(node, (const xmlChar*)name); +} + +// returns -1 if attribute is not found +static int sanei_xml_get_prop_uint(xmlNode* node, const char* name) +{ + char* attr = sanei_xml_get_prop(node, name); + if (attr == NULL) + { + return -1; + } + + unsigned attr_uint = strtoul(attr, NULL, 0); + xmlFree(attr); + return attr_uint; +} + +static void sanei_xml_print_seq_if_any(xmlNode* node, const char* parent_fun) +{ + char* attr = sanei_xml_get_prop(node, "seq"); + if (attr == NULL) + return; + + DBG(1, "%s: FAIL: in transaction with seq %s:\n", parent_fun, attr); + xmlFree(attr); +} + +// Checks whether transaction should be ignored. We ignore get_descriptor and +// set_configuration transactions. The latter is ignored because +// set_configuration is called in sanei_usb_open outside test path. +static int sanei_xml_is_transaction_ignored(xmlNode* node) +{ + if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0) + return 0; + + if (sanei_xml_get_prop_uint(node, "endpoint_number") != 0) + return 0; + + int is_direction_in = 0; + int is_direction_out = 0; + + char* attr = sanei_xml_get_prop(node, "direction"); + if (attr == NULL) + return 0; + + if (strcmp(attr, "IN") == 0) + is_direction_in = 1; + if (strcmp(attr, "OUT") == 0) + is_direction_out = 1; + xmlFree(attr); + + unsigned bRequest = sanei_xml_get_prop_uint(node, "bRequest"); + if (bRequest == USB_REQ_GET_DESCRIPTOR && is_direction_in) + { + if (sanei_xml_get_prop_uint(node, "bmRequestType") != 0x80) + return 0; + return 1; + } + if (bRequest == USB_REQ_SET_CONFIGURATION && is_direction_out) + return 1; + + return 0; +} + +static xmlNode* sanei_xml_skip_non_tx_nodes(xmlNode* node) +{ + const char* known_node_names[] = { + "control_tx", "bulk_tx", "interrupt_tx", "debug", "known_commands_end" + }; + + while (node != NULL) + { + int found = 0; + for (unsigned i = 0; i < sizeof(known_node_names) / + sizeof(known_node_names[0]); ++i) + { + if (xmlStrcmp(node->name, (const xmlChar*) known_node_names[i]) == 0) + { + found = 1; + break; + } + } + + if (found && sanei_xml_is_transaction_ignored(node) == 0) + { + break; + } + + node = xmlNextElementSibling(node); + } + return node; +} + +static int sanei_xml_is_known_commands_end(xmlNode* node) +{ + if (!testing_development_mode || node == NULL) + return 0; + return xmlStrcmp(node->name, (const xmlChar*)"known_commands_end") == 0; +} + +// returns next transaction node that is not get_descriptor +static xmlNode* sanei_xml_peek_next_tx_node() +{ + return testing_xml_next_tx_node; +} + +// returns next transaction node that is not get_descriptor +static xmlNode* sanei_xml_get_next_tx_node() +{ + xmlNode* next = testing_xml_next_tx_node; + + if (sanei_xml_is_known_commands_end(next)) + { + testing_append_commands_node = xmlPreviousElementSibling(next); + return next; + } + + testing_xml_next_tx_node = + xmlNextElementSibling(testing_xml_next_tx_node); + + testing_xml_next_tx_node = + sanei_xml_skip_non_tx_nodes(testing_xml_next_tx_node); + + return next; +} + +#define CHAR_TYPE_INVALID -1 +#define CHAR_TYPE_SPACE -2 + +static int8_t sanei_xml_char_types[256] = +{ + /* 0x00-0x0f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, + /* 0x10-0x1f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x20-0x2f */ -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x30-0x3f */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + /* 0x40-0x4f */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x50-0x5f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x60-0x6f */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x70-0x7f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x80-0x8f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x90-0x9f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0xa0-0xaf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0xb0-0xbf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0xc0-0xcf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0xd0-0xdf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0xe0-0xef */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 0xf0-0xff */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; + +static char* sanei_xml_get_hex_data_slow_path(xmlNode* node, xmlChar* content, xmlChar* cur_content, + char* ret_data, char* cur_ret_data, size_t* size) +{ + int num_nibbles = 0; + unsigned cur_nibble = 0; + + while (*cur_content != 0) + { + while (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) + cur_content++; + + if (*cur_content == 0) + break; + + // don't use stroul because it will parse in big-endian and data is in + // little endian + uint8_t c = *cur_content; + int8_t ci = sanei_xml_char_types[c]; + if (ci == CHAR_TYPE_INVALID) + { + FAIL_TEST_TX(__func__, node, "unexpected character %c\n", c); + cur_content++; + continue; + } + + cur_nibble = (cur_nibble << 4) | ci; + num_nibbles++; + + if (num_nibbles == 2) + { + *cur_ret_data++ = cur_nibble; + cur_nibble = 0; + num_nibbles = 0; + } + cur_content++; + } + *size = cur_ret_data - ret_data; + xmlFree(content); + return ret_data; +} + +// Parses hex data in XML text node in the format of '00 11 ab 3f', etc. to +// binary string. The size is returned as *size. The caller is responsible for +// freeing the returned value +static char* sanei_xml_get_hex_data(xmlNode* node, size_t* size) +{ + xmlChar* content = xmlNodeGetContent(node); + + // let's overallocate to simplify the implementation. We expect the string + // to be deallocated soon anyway + char* ret_data = malloc(strlen((const char*)content) / 2 + 2); + char* cur_ret_data = ret_data; + + xmlChar* cur_content = content; + + // the text to binary conversion takes most of the time spent in tests, so we + // take extra care to optimize it. We split the implementation into fast and + // slow path. The fast path utilizes the knowledge that there will be no spaces + // within bytes. When this assumption does not hold, we switch to the slow path. + while (*cur_content != 0) + { + // most of the time there will be 1 or 2 spaces between bytes. Give the CPU + // chance to predict this by partially unrolling the while loop. + if (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) + { + cur_content++; + if (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) + { + cur_content++; + while (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) + cur_content++; + } + } + + if (*cur_content == 0) + break; + + // don't use stroul because it will parse in big-endian and data is in + // little endian + int8_t ci1 = sanei_xml_char_types[(uint8_t)*cur_content]; + int8_t ci2 = sanei_xml_char_types[(uint8_t)*(cur_content + 1)]; + + if (ci1 < 0 || ci2 < 0) + return sanei_xml_get_hex_data_slow_path(node, content, cur_content, ret_data, cur_ret_data, + size); + + *cur_ret_data++ = ci1 << 4 | ci2; + cur_content += 2; + } + *size = cur_ret_data - ret_data; + xmlFree(content); + return ret_data; +} + +// caller is responsible for freeing the returned pointer +static char* sanei_binary_to_hex_data(const char* data, size_t size, + size_t* out_size) +{ + char* hex_data = malloc(size * 4); + size_t hex_size = 0; + + for (size_t i = 0; i < size; ++i) + { + hex_size += snprintf(hex_data + hex_size, 3, "%02hhx", data[i]); + if (i + 1 != size) + { + if ((i + 1) % 32 == 0) + hex_data[hex_size++] = '\n'; + else + hex_data[hex_size++] = ' '; + } + } + hex_data[hex_size] = 0; + if (out_size) + *out_size = hex_size; + return hex_data; +} + + +static void sanei_xml_set_data(xmlNode* node, const char* data) +{ + // FIXME: remove existing children + xmlAddChild(node, xmlNewText((const xmlChar*)data)); +} + +// Writes binary data to XML node as a child text node in the hex format of +// '00 11 ab 3f'. +static void sanei_xml_set_hex_data(xmlNode* node, const char* data, + size_t size) +{ + char* hex_data = sanei_binary_to_hex_data(data, size, NULL); + sanei_xml_set_data(node, hex_data); + free(hex_data); +} + +static void sanei_xml_set_hex_attr(xmlNode* node, const char* attr_name, + unsigned attr_value) +{ + const int buf_size = 128; + char buf[buf_size]; + if (attr_value > 0xffffff) + snprintf(buf, buf_size, "0x%x", attr_value); + else if (attr_value > 0xffff) + snprintf(buf, buf_size, "0x%06x", attr_value); + else if (attr_value > 0xff) + snprintf(buf, buf_size, "0x%04x", attr_value); + else + snprintf(buf, buf_size, "0x%02x", attr_value); + + xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf); +} + +static void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name, + unsigned attr_value) +{ + const int buf_size = 128; + char buf[buf_size]; + snprintf(buf, buf_size, "%d", attr_value); + xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf); +} + +static xmlNode* sanei_xml_append_command(xmlNode* sibling, + int indent, xmlNode* e_command) +{ + if (indent) + { + xmlNode* e_indent = xmlNewText((const xmlChar*)"\n "); + sibling = xmlAddNextSibling(sibling, e_indent); + } + return xmlAddNextSibling(sibling, e_command); +} + +static void sanei_xml_command_common_props(xmlNode* node, int endpoint_number, + const char* direction) +{ + xmlNewProp(node, (const xmlChar*)"time_usec", (const xmlChar*)"0"); + sanei_xml_set_uint_attr(node, "seq", ++testing_last_known_seq); + sanei_xml_set_uint_attr(node, "endpoint_number", endpoint_number); + xmlNewProp(node, (const xmlChar*)"direction", (const xmlChar*)direction); +} + +static void sanei_xml_record_seq(xmlNode* node) +{ + int seq = sanei_xml_get_prop_uint(node, "seq"); + if (seq > 0) + testing_last_known_seq = seq; +} + +static void sanei_xml_break() +{ +} + +static void sanei_xml_break_if_needed(xmlNode* node) +{ + char* attr = sanei_xml_get_prop(node, "debug_break"); + if (attr != NULL) + { + sanei_xml_break(); + xmlFree(attr); + } +} + +// returns 1 on success +static int sanei_usb_check_attr(xmlNode* node, const char* attr_name, + const char* expected, const char* parent_fun) +{ + char* attr = sanei_xml_get_prop(node, attr_name); + if (attr == NULL) + { + FAIL_TEST_TX(parent_fun, node, "no %s attribute\n", attr_name); + return 0; + } + + if (strcmp(attr, expected) != 0) + { + FAIL_TEST_TX(parent_fun, node, "unexpected %s attribute: %s, wanted %s\n", + attr_name, attr, expected); + xmlFree(attr); + return 0; + } + xmlFree(attr); + return 1; +} + +// returns 1 on success +static int sanei_usb_attr_is(xmlNode* node, const char* attr_name, + const char* expected) +{ + char* attr = sanei_xml_get_prop(node, attr_name); + if (attr == NULL) + return 0; + + if (strcmp(attr, expected) != 0) + { + xmlFree(attr); + return 0; + } + xmlFree(attr); + return 1; +} + +// returns 0 on success +static int sanei_usb_check_attr_uint(xmlNode* node, const char* attr_name, + unsigned expected, const char* parent_fun) +{ + char* attr = sanei_xml_get_prop(node, attr_name); + if (attr == NULL) + { + FAIL_TEST_TX(parent_fun, node, "no %s attribute\n", attr_name); + return 0; + } + + unsigned attr_int = strtoul(attr, NULL, 0); + if (attr_int != expected) + { + FAIL_TEST_TX(parent_fun, node, + "unexpected %s attribute: %s, wanted 0x%x\n", + attr_name, attr, expected); + xmlFree(attr); + return 0; + } + xmlFree(attr); + return 1; +} + +static int sanei_usb_attr_is_uint(xmlNode* node, const char* attr_name, + unsigned expected) +{ + char* attr = sanei_xml_get_prop(node, attr_name); + if (attr == NULL) + return 0; + + unsigned attr_int = strtoul(attr, NULL, 0); + if (attr_int != expected) + { + xmlFree(attr); + return 0; + } + xmlFree(attr); + return 1; +} + +// returns 1 on data equality +static int sanei_usb_check_data_equal(xmlNode* node, + const char* data, + size_t data_size, + const char* expected_data, + size_t expected_size, + const char* parent_fun) +{ + if ((data_size == expected_size) && + (memcmp(data, expected_data, data_size) == 0)) + return 1; + + char* data_hex = sanei_binary_to_hex_data(data, data_size, NULL); + char* expected_hex = sanei_binary_to_hex_data(expected_data, expected_size, + NULL); + + if (data_size == expected_size) + FAIL_TEST_TX(parent_fun, node, "data differs (size %lu):\n", data_size); + else + FAIL_TEST_TX(parent_fun, node, + "data differs (got size %lu, expected %lu):\n", + data_size, expected_size); + + FAIL_TEST(parent_fun, "got: %s\n", data_hex); + FAIL_TEST(parent_fun, "expected: %s\n", expected_hex); + free(data_hex); + free(expected_hex); + return 0; +} + +SANE_String sanei_usb_testing_get_backend() +{ + if (testing_xml_doc == NULL) + return NULL; + + xmlNode* el_root = xmlDocGetRootElement(testing_xml_doc); + if (xmlStrcmp(el_root->name, (const xmlChar*)"device_capture") != 0) + { + FAIL_TEST(__func__, "the given file is not USB capture\n"); + return NULL; + } + + char* attr = sanei_xml_get_prop(el_root, "backend"); + if (attr == NULL) + { + FAIL_TEST(__func__, "no backend attr in description node\n"); + return NULL; + } + // duplicate using strdup so that the caller can use free() + char* ret = strdup(attr); + xmlFree(attr); + return ret; +} + +SANE_Bool sanei_usb_is_replay_mode_enabled() +{ + if (testing_mode == sanei_usb_testing_mode_replay) + return SANE_TRUE; + + return SANE_FALSE; +} + +static void sanei_usb_record_debug_msg(xmlNode* node, SANE_String_Const message) +{ + int node_was_null = node == NULL; + if (node_was_null) + node = testing_append_commands_node; + + xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"debug"); + sanei_xml_set_uint_attr(e_tx, "seq", ++testing_last_known_seq); + xmlNewProp(e_tx, (const xmlChar*)"message", (const xmlChar*)message); + + node = sanei_xml_append_command(node, node_was_null, e_tx); + + if (node_was_null) + testing_append_commands_node = node; +} + +static void sanei_usb_record_replace_debug_msg(xmlNode* node, SANE_String_Const message) +{ + if (!testing_development_mode) + return; + + testing_last_known_seq--; + sanei_usb_record_debug_msg(node, message); + xmlUnlinkNode(node); + xmlFreeNode(node); +} + +static void sanei_usb_replay_debug_msg(SANE_String_Const message) +{ + if (testing_known_commands_input_failed) + return; + + xmlNode* node = sanei_xml_get_next_tx_node(); + if (node == NULL) + { + FAIL_TEST(__func__, "no more transactions\n"); + return; + } + + if (sanei_xml_is_known_commands_end(node)) + { + sanei_usb_record_debug_msg(NULL, message); + return; + } + + sanei_xml_record_seq(node); + sanei_xml_break_if_needed(node); + + if (xmlStrcmp(node->name, (const xmlChar*)"debug") != 0) + { + FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", + (const char*) node->name); + sanei_usb_record_replace_debug_msg(node, message); + } + + if (!sanei_usb_check_attr(node, "message", message, __func__)) + { + sanei_usb_record_replace_debug_msg(node, message); + } +} + +extern void sanei_usb_testing_record_message(SANE_String_Const message) +{ + if (testing_mode == sanei_usb_testing_mode_record) + { + sanei_usb_record_debug_msg(NULL, message); + } + if (testing_mode == sanei_usb_testing_mode_replay) + { + sanei_usb_replay_debug_msg(message); + } +} + +static void sanei_usb_add_endpoint(device_list_type* device, + SANE_Int transfer_type, + SANE_Int ep_address, + SANE_Int ep_direction); + +static SANE_Status sanei_usb_testing_init() +{ + DBG_INIT(); + + if (testing_mode == sanei_usb_testing_mode_record) + { + testing_xml_doc = xmlNewDoc((const xmlChar*)"1.0"); + return SANE_STATUS_GOOD; + } + + if (device_number != 0) + return SANE_STATUS_INVAL; // already opened + + xmlNode* el_root = xmlDocGetRootElement(testing_xml_doc); + if (xmlStrcmp(el_root->name, (const xmlChar*)"device_capture") != 0) + { + DBG(1, "%s: the given file is not USB capture\n", __func__); + return SANE_STATUS_INVAL; + } + + xmlNode* el_description = + sanei_xml_find_first_child_with_name(el_root, "description"); + if (el_description == NULL) + { + DBG(1, "%s: could not find description node\n", __func__); + return SANE_STATUS_INVAL; + } + + int device_id = sanei_xml_get_prop_uint(el_description, "id_vendor"); + if (device_id < 0) + { + DBG(1, "%s: no id_vendor attr in description node\n", __func__); + return SANE_STATUS_INVAL; + } + + int product_id = sanei_xml_get_prop_uint(el_description, "id_product"); + if (product_id < 0) + { + DBG(1, "%s: no id_product attr in description node\n", __func__); + return SANE_STATUS_INVAL; + } + + xmlNode* el_configurations = + sanei_xml_find_first_child_with_name(el_description, "configurations"); + if (el_configurations == NULL) + { + DBG(1, "%s: could not find configurations node\n", __func__); + return SANE_STATUS_INVAL; + } + + xmlNode* el_configuration = + sanei_xml_find_first_child_with_name(el_configurations, "configuration"); + if (el_configuration == NULL) + { + DBG(1, "%s: no configuration nodes\n", __func__); + return SANE_STATUS_INVAL; + } + + while (el_configuration != NULL) + { + xmlNode* el_interface = + sanei_xml_find_first_child_with_name(el_configuration, "interface"); + + while (el_interface != NULL) + { + device_list_type device; + memset(&device, 0, sizeof(device)); + device.devname = strdup(testing_xml_path); + + // other code shouldn't depend on methon because testing_mode is + // sanei_usb_testing_mode_replay + device.method = sanei_usb_method_libusb; + device.vendor = device_id; + device.product = product_id; + + device.interface_nr = sanei_xml_get_prop_uint(el_interface, "number"); + if (device.interface_nr < 0) + { + DBG(1, "%s: no number attr in interface node\n", __func__); + return SANE_STATUS_INVAL; + } + + xmlNode* el_endpoint = + sanei_xml_find_first_child_with_name(el_interface, "endpoint"); + + while (el_endpoint != NULL) + { + char* transfer_attr = sanei_xml_get_prop(el_endpoint, + "transfer_type"); + int address = sanei_xml_get_prop_uint(el_endpoint, "address"); + char* direction_attr = sanei_xml_get_prop(el_endpoint, + "direction"); + + int direction_is_in = strcmp(direction_attr, "IN") == 0 ? 1 : 0; + int transfer_type = -1; + if (strcmp(transfer_attr, "INTERRUPT") == 0) + transfer_type = USB_ENDPOINT_TYPE_INTERRUPT; + else if (strcmp(transfer_attr, "BULK") == 0) + transfer_type = USB_ENDPOINT_TYPE_BULK; + else if (strcmp(transfer_attr, "ISOCHRONOUS") == 0) + transfer_type = USB_ENDPOINT_TYPE_ISOCHRONOUS; + else if (strcmp(transfer_attr, "CONTROL") == 0) + transfer_type = USB_ENDPOINT_TYPE_CONTROL; + else + { + DBG(3, "%s: unknown endpoint type %s\n", + __func__, transfer_attr); + } + + if (transfer_type >= 0) + { + sanei_usb_add_endpoint(&device, transfer_type, address, + direction_is_in); + } + + xmlFree(transfer_attr); + xmlFree(direction_attr); + + el_endpoint = + sanei_xml_find_next_child_with_name(el_endpoint, "endpoint"); + } + device.alt_setting = 0; + device.missing = 0; + + memcpy(&(devices[device_number]), &device, sizeof(device)); + device_number++; + + el_interface = sanei_xml_find_next_child_with_name(el_interface, + "interface"); + } + el_configuration = + sanei_xml_find_next_child_with_name(el_configurations, + "configuration"); + } + + xmlNode* el_transactions = + sanei_xml_find_first_child_with_name(el_root, "transactions"); + + if (el_transactions == NULL) + { + DBG(1, "%s: could not find transactions node\n", __func__); + return SANE_STATUS_INVAL; + } + + xmlNode* el_transaction = xmlFirstElementChild(el_transactions); + el_transaction = sanei_xml_skip_non_tx_nodes(el_transaction); + + if (el_transaction == NULL) + { + DBG(1, "%s: no transactions within capture\n", __func__); + return SANE_STATUS_INVAL; + } + + testing_xml_next_tx_node = el_transaction; + + return SANE_STATUS_GOOD; +} + +static void sanei_usb_testing_exit() +{ + if (testing_development_mode || testing_mode == sanei_usb_testing_mode_record) + { + if (testing_mode == sanei_usb_testing_mode_record) + { + xmlAddNextSibling(testing_append_commands_node, xmlNewText((const xmlChar*)"\n ")); + free(testing_record_backend); + } + xmlSaveFileEnc(testing_xml_path, testing_xml_doc, "UTF-8"); + } + xmlFreeDoc(testing_xml_doc); + free(testing_xml_path); + xmlCleanupParser(); +} +#else // WITH_USB_RECORD_REPLAY +SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path, + int development_mode) +{ + (void) path; + (void) development_mode; + + DBG(1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +} + +SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, SANE_String_Const be_name) +{ + (void) path; + (void) be_name; + + DBG(1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +} + +SANE_String sanei_usb_testing_get_backend() +{ + return NULL; +} + +SANE_Bool sanei_usb_is_replay_mode_enabled() +{ + return SANE_FALSE; +} + +void sanei_usb_testing_record_message(SANE_String_Const message) +{ + (void) message; +} +#endif // WITH_USB_RECORD_REPLAY + void sanei_usb_init (void) { @@ -473,6 +1358,26 @@ sanei_usb_init (void) if(device_number==0) memset (devices, 0, sizeof (devices)); +#if WITH_USB_RECORD_REPLAY + if (testing_mode != sanei_usb_testing_mode_disabled) + { + if (initialized == 0) + { + if (sanei_usb_testing_init() != SANE_STATUS_GOOD) + { + DBG(1, "%s: failed initializing fake USB stack\n", __func__); + return; + } + } + + if (testing_mode == sanei_usb_testing_mode_replay) + { + initialized++; + return; + } + } +#endif + /* initialize USB with old libusb library */ #ifdef HAVE_LIBUSB_LEGACY DBG (4, "%s: Looking for libusb devices\n", __func__); @@ -499,7 +1404,12 @@ sanei_usb_init (void) } #ifdef DBG_LEVEL if (DBG_LEVEL > 4) +#if LIBUSB_API_VERSION >= 0x01000106 + libusb_set_option (sanei_usb_ctx, LIBUSB_OPTION_LOG_LEVEL, + LIBUSB_LOG_LEVEL_INFO); +#else libusb_set_debug (sanei_usb_ctx, 3); +#endif /* LIBUSB_API_VERSION */ #endif /* DBG_LEVEL */ } #endif /* HAVE_LIBUSB */ @@ -533,6 +1443,13 @@ int i; /* if we reach 0, free allocated resources */ if(initialized==0) { +#if WITH_USB_RECORD_REPLAY + if (testing_mode != sanei_usb_testing_mode_disabled) + { + sanei_usb_testing_exit(); + } +#endif // WITH_USB_RECORD_REPLAY + /* free allocated resources */ DBG (4, "%s: freeing resources\n", __func__); for (i = 0; i < device_number; i++) @@ -1038,6 +1955,11 @@ sanei_usb_scan_devices (void) return; } + if (testing_mode == sanei_usb_testing_mode_replay) + { + // device added in sanei_usb_testing_init() + return; + } /* we mark all already detected devices as missing */ /* each scan method will reset this value to 0 (not missing) * when storing the device */ @@ -1262,7 +2184,7 @@ sanei_usb_set_endpoint (SANE_Int dn, SANE_Int ep_type, SANE_Int ep) } } -#if HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS +#if HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS || WITH_USB_RECORD_REPLAY static const char* sanei_usb_transfer_type_desc(SANE_Int transfer_type) { switch (transfer_type) @@ -1365,6 +2287,64 @@ sanei_usb_get_endpoint (SANE_Int dn, SANE_Int ep_type) } } +#if WITH_USB_RECORD_REPLAY +static void sanei_usb_record_open(SANE_Int dn) +{ + xmlNode* e_root = xmlNewNode(NULL, (const xmlChar*) "device_capture"); + xmlDocSetRootElement(testing_xml_doc, e_root); + xmlNewProp(e_root, (const xmlChar*)"backend", (const xmlChar*) testing_record_backend); + + xmlNode* e_description = xmlNewChild(e_root, NULL, (const xmlChar*) "description", NULL); + sanei_xml_set_hex_attr(e_description, "id_vendor", devices[dn].vendor); + sanei_xml_set_hex_attr(e_description, "id_product", devices[dn].product); + + xmlNode* e_configurations = xmlNewChild(e_description, NULL, + (const xmlChar*) "configurations", NULL); + xmlNode* e_configuration = xmlNewChild(e_configurations, NULL, + (const xmlChar*) "configuration", NULL); + sanei_xml_set_uint_attr(e_configuration, "number", 1); + + xmlNode* e_interface = xmlNewChild(e_configuration, NULL, (const xmlChar*) "interface", NULL); + sanei_xml_set_uint_attr(e_interface, "number", devices[dn].interface_nr); + + struct endpoint_data_desc { + const char* transfer_type; + const char* direction; + SANE_Int ep_address; + }; + + struct endpoint_data_desc endpoints[8] = + { + { "BULK", "IN", devices[dn].bulk_in_ep }, + { "BULK", "OUT", devices[dn].bulk_out_ep }, + { "ISOCHRONOUS", "IN", devices[dn].iso_in_ep }, + { "ISOCHRONOUS", "OUT", devices[dn].iso_out_ep }, + { "INTERRUPT", "IN", devices[dn].int_in_ep }, + { "INTERRUPT", "OUT", devices[dn].int_out_ep }, + { "CONTROL", "IN", devices[dn].control_in_ep }, + { "CONTROL", "OUT", devices[dn].control_out_ep } + }; + + for (int i = 0; i < 8; ++i) + { + if (endpoints[i].ep_address) + { + xmlNode* e_endpoint = xmlNewChild(e_interface, NULL, (const xmlChar*)"endpoint", NULL); + xmlNewProp(e_endpoint, (const xmlChar*)"transfer_type", + (const xmlChar*) endpoints[i].transfer_type); + sanei_xml_set_uint_attr(e_endpoint, "number", endpoints[i].ep_address & 0x0f); + xmlNewProp(e_endpoint, (const xmlChar*)"direction", + (const xmlChar*) endpoints[i].direction); + sanei_xml_set_hex_attr(e_endpoint, "address", endpoints[i].ep_address); + } + } + xmlNode* e_transactions = xmlNewChild(e_root, NULL, (const xmlChar*)"transactions", NULL); + + // add an empty node so that we have something to append to + testing_append_commands_node = xmlAddChild(e_transactions, xmlNewText((const xmlChar*)""));; +} +#endif // WITH_USB_RECORD_REPLAY + SANE_Status sanei_usb_open (SANE_String_Const devname, SANE_Int * dn) { @@ -1400,7 +2380,13 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn) return SANE_STATUS_INVAL; } - if (devices[devcount].method == sanei_usb_method_libusb) + if (testing_mode == sanei_usb_testing_mode_replay) + { + DBG (1, "sanei_usb_open: opening fake USB device\n"); + // the device configuration has been already filled in + // sanei_usb_testing_init() + } + else if (devices[devcount].method == sanei_usb_method_libusb) { #ifdef HAVE_LIBUSB_LEGACY struct usb_device *dev; @@ -1915,6 +2901,16 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn) return SANE_STATUS_INVAL; } + if (testing_mode == sanei_usb_testing_mode_record) + { +#if WITH_USB_RECORD_REPLAY + sanei_usb_record_open(devcount); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + devices[devcount].open = SANE_TRUE; *dn = devcount; DBG (3, "sanei_usb_open: opened usb device `%s' (*dn=%d)\n", @@ -1948,7 +2944,11 @@ sanei_usb_close (SANE_Int dn) dn); return; } - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_replay) + { + DBG (1, "sanei_usb_close: closing fake USB device\n"); + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) close (devices[dn].fd); else if (devices[dn].method == sanei_usb_method_usbcalls) { @@ -2001,6 +3001,9 @@ sanei_usb_close (SANE_Int dn) void sanei_usb_set_timeout (SANE_Int __sane_unused__ timeout) { + if (testing_mode == sanei_usb_testing_mode_replay) + return; + #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB) libusb_timeout = timeout; #else @@ -2028,6 +3031,9 @@ sanei_usb_clear_halt (SANE_Int dn) return SANE_STATUS_INVAL; } + if (testing_mode == sanei_usb_testing_mode_replay) + return SANE_STATUS_GOOD; + #ifdef HAVE_LIBUSB_LEGACY int ret; @@ -2085,6 +3091,9 @@ sanei_usb_clear_halt (SANE_Int dn) SANE_Status sanei_usb_reset (SANE_Int __sane_unused__ dn) { + if (testing_mode == sanei_usb_testing_mode_replay) + return SANE_STATUS_GOOD; + #ifdef HAVE_LIBUSB_LEGACY int ret; @@ -2110,6 +3119,160 @@ sanei_usb_reset (SANE_Int __sane_unused__ dn) return SANE_STATUS_GOOD; } +#if WITH_USB_RECORD_REPLAY +// returns non-negative value on success, -1 on failure +static int sanei_usb_replay_next_read_bulk_packet_size(SANE_Int dn) +{ + xmlNode* node = sanei_xml_peek_next_tx_node(); + if (node == NULL) + return -1; + + if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) + { + return -1; + } + + if (!sanei_usb_attr_is(node, "direction", "IN")) + return -1; + if (!sanei_usb_attr_is_uint(node, "endpoint_number", + devices[dn].bulk_in_ep & 0x0f)) + return -1; + + size_t got_size = 0; + char* got_data = sanei_xml_get_hex_data(node, &got_size); + free(got_data); + return got_size; +} + +static void sanei_usb_record_read_bulk(xmlNode* node, SANE_Int dn, + SANE_Byte* buffer, + size_t size, ssize_t read_size) +{ + int node_was_null = node == NULL; + if (node_was_null) + node = testing_append_commands_node; + + xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"bulk_tx"); + sanei_xml_command_common_props(e_tx, devices[dn].bulk_in_ep & 0x0f, "IN"); + + if (buffer == NULL) + { + const int buf_size = 128; + char buf[buf_size]; + snprintf(buf, buf_size, "(unknown read of allowed size %ld)", size); + xmlNode* e_content = xmlNewText((const xmlChar*)buf); + xmlAddChild(e_tx, e_content); + } + else + { + if (read_size >= 0) + { + sanei_xml_set_hex_data(e_tx, (const char*)buffer, read_size); + } + else + { + xmlNewProp(e_tx, (const xmlChar*)"error", (const xmlChar*)"timeout"); + } + } + + node = sanei_xml_append_command(node, node_was_null, e_tx); + + if (node_was_null) + testing_append_commands_node = node; +} + +static void sanei_usb_record_replace_read_bulk(xmlNode* node, SANE_Int dn, + SANE_Byte* buffer, + size_t size, size_t read_size) +{ + if (!testing_development_mode) + return; + testing_known_commands_input_failed = 1; + testing_last_known_seq--; + sanei_usb_record_read_bulk(node, dn, buffer, size, read_size); + xmlUnlinkNode(node); + xmlFreeNode(node); +} + +static int sanei_usb_replay_read_bulk(SANE_Int dn, SANE_Byte* buffer, + size_t size) +{ + // libusb may potentially combine multiple IN packets into a single transfer. + // We recontruct that by looking into the next packet. If it can be + // included into the current transfer without + size_t wanted_size = size; + size_t total_got_size = 0; + while (wanted_size > 0) + { + if (testing_known_commands_input_failed) + return -1; + + xmlNode* node = sanei_xml_get_next_tx_node(); + if (node == NULL) + { + FAIL_TEST(__func__, "no more transactions\n"); + return -1; + } + + if (sanei_xml_is_known_commands_end(node)) + { + sanei_usb_record_read_bulk(NULL, dn, NULL, 0, size); + testing_known_commands_input_failed = 1; + return -1; + } + + sanei_xml_record_seq(node); + sanei_xml_break_if_needed(node); + + if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) + { + FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", + (const char*) node->name); + sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); + return -1; + } + + if (!sanei_usb_check_attr(node, "direction", "IN", __func__)) + { + sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); + return -1; + } + if (!sanei_usb_check_attr_uint(node, "endpoint_number", + devices[dn].bulk_in_ep & 0x0f, + __func__)) + { + sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); + return -1; + } + + size_t got_size = 0; + char* got_data = sanei_xml_get_hex_data(node, &got_size); + + if (got_size > wanted_size) + { + FAIL_TEST_TX(__func__, node, + "got more data than wanted (%lu vs %lu)\n", + got_size, wanted_size); + free(got_data); + sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); + return -1; + } + + memcpy(buffer + total_got_size, got_data, got_size); + free(got_data); + total_got_size += got_size; + wanted_size -= got_size; + + int next_size = sanei_usb_replay_next_read_bulk_packet_size(dn); + if (next_size < 0) + return total_got_size; + if ((size_t) next_size > wanted_size) + return total_got_size; + } + return total_got_size; +} +#endif // WITH_USB_RECORD_REPLAY + SANE_Status sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size) { @@ -2129,7 +3292,16 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size) DBG (5, "sanei_usb_read_bulk: trying to read %lu bytes\n", (unsigned long) *size); - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_replay) + { +#if WITH_USB_RECORD_REPLAY + read_size = sanei_usb_replay_read_bulk(dn, buffer, *size); +#else + DBG(1, "%s: USB record-replay mode support missing\n", __func__); + return SANE_STATUS_UNSUPPORTED; +#endif + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) { read_size = read (devices[dn].fd, buffer, *size); @@ -2236,8 +3408,22 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size) return SANE_STATUS_INVAL; } + if (testing_mode == sanei_usb_testing_mode_record) + { +#if WITH_USB_RECORD_REPLAY + sanei_usb_record_read_bulk(NULL, dn, buffer, *size, read_size); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + if (read_size < 0) { + *size = 0; + if (testing_mode != sanei_usb_testing_mode_disabled) + return SANE_STATUS_IO_ERROR; + #ifdef HAVE_LIBUSB_LEGACY if (devices[dn].method == sanei_usb_method_libusb) usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_in_ep); @@ -2245,7 +3431,6 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size) if (devices[dn].method == sanei_usb_method_libusb) libusb_clear_halt (devices[dn].lu_handle, devices[dn].bulk_in_ep); #endif - *size = 0; return SANE_STATUS_IO_ERROR; } if (read_size == 0) @@ -2263,6 +3448,165 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size) return SANE_STATUS_GOOD; } +#if WITH_USB_RECORD_REPLAY +static int sanei_usb_record_write_bulk(xmlNode* node, SANE_Int dn, + const SANE_Byte* buffer, + size_t size, size_t write_size) +{ + int node_was_null = node == NULL; + if (node_was_null) + node = testing_append_commands_node; + + xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"bulk_tx"); + sanei_xml_command_common_props(e_tx, devices[dn].bulk_out_ep & 0x0f, "OUT"); + sanei_xml_set_hex_data(e_tx, (const char*)buffer, size); + // FIXME: output write_size + + node = sanei_xml_append_command(node, node_was_null, e_tx); + + if (node_was_null) + testing_append_commands_node = node; + return write_size; +} + +static void sanei_usb_record_replace_write_bulk(xmlNode* node, SANE_Int dn, + const SANE_Byte* buffer, + size_t size, size_t write_size) +{ + if (!testing_development_mode) + return; + testing_last_known_seq--; + sanei_usb_record_write_bulk(node, dn, buffer, size, write_size); + xmlUnlinkNode(node); + xmlFreeNode(node); +} + +// returns non-negative value on success, -1 on failure +static int sanei_usb_replay_next_write_bulk_packet_size(SANE_Int dn) +{ + xmlNode* node = sanei_xml_peek_next_tx_node(); + if (node == NULL) + return -1; + + if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) + { + return -1; + } + + if (!sanei_usb_attr_is(node, "direction", "OUT")) + return -1; + if (!sanei_usb_attr_is_uint(node, "endpoint_number", + devices[dn].bulk_out_ep & 0x0f)) + return -1; + + size_t got_size = 0; + char* got_data = sanei_xml_get_hex_data(node, &got_size); + free(got_data); + return got_size; +} + +static int sanei_usb_replay_write_bulk(SANE_Int dn, const SANE_Byte* buffer, + size_t size) +{ + size_t wanted_size = size; + size_t total_wrote_size = 0; + while (wanted_size > 0) + { + if (testing_known_commands_input_failed) + return -1; + + xmlNode* node = sanei_xml_get_next_tx_node(); + if (node == NULL) + { + FAIL_TEST(__func__, "no more transactions\n"); + return -1; + } + + if (sanei_xml_is_known_commands_end(node)) + { + sanei_usb_record_write_bulk(NULL, dn, buffer, size, size); + return size; + } + + sanei_xml_record_seq(node); + sanei_xml_break_if_needed(node); + + if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) + { + FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", + (const char*) node->name); + sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); + return -1; + } + + if (!sanei_usb_check_attr(node, "direction", "OUT", __func__)) + { + sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); + return -1; + } + if (!sanei_usb_check_attr_uint(node, "endpoint_number", + devices[dn].bulk_out_ep & 0x0f, + __func__)) + { + sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); + return -1; + } + + size_t wrote_size = 0; + char* wrote_data = sanei_xml_get_hex_data(node, &wrote_size); + + if (wrote_size > wanted_size) + { + FAIL_TEST_TX(__func__, node, + "wrote more data than wanted (%lu vs %lu)\n", + wrote_size, wanted_size); + if (!testing_development_mode) + { + free(wrote_data); + return -1; + } + sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); + wrote_size = size; + } + else if (!sanei_usb_check_data_equal(node, + ((const char*) buffer) + + total_wrote_size, + wrote_size, + wrote_data, wrote_size, + __func__)) + { + if (!testing_development_mode) + { + free(wrote_data); + return -1; + } + sanei_usb_record_replace_write_bulk(node, dn, buffer, size, + size); + wrote_size = size; + } + + free(wrote_data); + if (wrote_size < wanted_size && + sanei_usb_replay_next_write_bulk_packet_size(dn) < 0) + { + FAIL_TEST_TX(__func__, node, + "wrote less data than wanted (%lu vs %lu)\n", + wrote_size, wanted_size); + if (!testing_development_mode) + { + return -1; + } + sanei_usb_record_replace_write_bulk(node, dn, buffer, size, + size); + wrote_size = size; + } + total_wrote_size += wrote_size; + wanted_size -= wrote_size; + } + return total_wrote_size; +} +#endif + SANE_Status sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size) { @@ -2284,7 +3628,16 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size) if (debug_level > 10) print_buffer (buffer, *size); - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_replay) + { +#if WITH_USB_RECORD_REPLAY + write_size = sanei_usb_replay_write_bulk(dn, buffer, *size); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) { write_size = write (devices[dn].fd, buffer, *size); @@ -2391,9 +3744,22 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size) return SANE_STATUS_INVAL; } + if (testing_mode == sanei_usb_testing_mode_record) + { +#if WITH_USB_RECORD_REPLAY + sanei_usb_record_write_bulk(NULL, dn, buffer, *size, write_size); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + if (write_size < 0) { *size = 0; + if (testing_mode != sanei_usb_testing_mode_disabled) + return SANE_STATUS_IO_ERROR; + #ifdef HAVE_LIBUSB_LEGACY if (devices[dn].method == sanei_usb_method_libusb) usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_out_ep); @@ -2409,6 +3775,161 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size) return SANE_STATUS_GOOD; } +#if WITH_USB_RECORD_REPLAY +static void +sanei_usb_record_control_msg(xmlNode* node, + SANE_Int dn, SANE_Int rtype, SANE_Int req, + SANE_Int value, SANE_Int index, SANE_Int len, + const SANE_Byte* data) +{ + (void) dn; + + int node_was_null = node == NULL; + if (node_was_null) + node = testing_append_commands_node; + + xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"control_tx"); + + int direction_is_in = (rtype & 0x80) == 0x80; + sanei_xml_command_common_props(e_tx, rtype & 0x1f, + direction_is_in ? "IN" : "OUT"); + sanei_xml_set_hex_attr(e_tx, "bmRequestType", rtype); + sanei_xml_set_hex_attr(e_tx, "bRequest", req); + sanei_xml_set_hex_attr(e_tx, "wValue", value); + sanei_xml_set_hex_attr(e_tx, "wIndex", index); + sanei_xml_set_hex_attr(e_tx, "wLength", len); + + if (direction_is_in && data == NULL) + { + const int buf_size = 128; + char buf[buf_size]; + snprintf(buf, buf_size, "(unknown read of size %d)", len); + xmlNode* e_content = xmlNewText((const xmlChar*)buf); + xmlAddChild(e_tx, e_content); + } + else + { + sanei_xml_set_hex_data(e_tx, (const char*)data, len); + } + + node = sanei_xml_append_command(node, node_was_null, e_tx); + + if (node_was_null) + testing_append_commands_node = node; +} + + +static SANE_Status +sanei_usb_record_replace_control_msg(xmlNode* node, + SANE_Int dn, SANE_Int rtype, SANE_Int req, + SANE_Int value, SANE_Int index, SANE_Int len, + const SANE_Byte* data) +{ + if (!testing_development_mode) + return SANE_STATUS_IO_ERROR; + + SANE_Status ret = SANE_STATUS_GOOD; + int direction_is_in = (rtype & 0x80) == 0x80; + if (direction_is_in) + { + testing_known_commands_input_failed = 1; + ret = SANE_STATUS_IO_ERROR; + } + + testing_last_known_seq--; + sanei_usb_record_control_msg(node, dn, rtype, req, value, index, len, data); + xmlUnlinkNode(node); + xmlFreeNode(node); + return ret; +} + +static SANE_Status +sanei_usb_replay_control_msg(SANE_Int dn, SANE_Int rtype, SANE_Int req, + SANE_Int value, SANE_Int index, SANE_Int len, + SANE_Byte* data) +{ + (void) dn; + + if (testing_known_commands_input_failed) + return -1; + + xmlNode* node = sanei_xml_get_next_tx_node(); + if (node == NULL) + { + FAIL_TEST(__func__, "no more transactions\n"); + return SANE_STATUS_IO_ERROR; + } + + int direction_is_in = (rtype & 0x80) == 0x80; + SANE_Byte* rdata = direction_is_in ? NULL : data; + + if (sanei_xml_is_known_commands_end(node)) + { + sanei_usb_record_control_msg(NULL, dn, rtype, req, value, index, len, + rdata); + if (direction_is_in) + { + testing_known_commands_input_failed = 1; + return SANE_STATUS_IO_ERROR; + } + return SANE_STATUS_GOOD; + } + + sanei_xml_record_seq(node); + sanei_xml_break_if_needed(node); + + if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0) + { + FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", + (const char*) node->name); + return sanei_usb_record_replace_control_msg(node, dn, rtype, req, value, + index, len, rdata); + } + + if (!sanei_usb_check_attr(node, "direction", direction_is_in ? "IN" : "OUT", + __func__) || + !sanei_usb_check_attr_uint(node, "bmRequestType", rtype, __func__) || + !sanei_usb_check_attr_uint(node, "bRequest", req, __func__) || + !sanei_usb_check_attr_uint(node, "wValue", value, __func__) || + !sanei_usb_check_attr_uint(node, "wIndex", index, __func__) || + !sanei_usb_check_attr_uint(node, "wLength", len, __func__)) + { + return sanei_usb_record_replace_control_msg(node, dn, rtype, req, value, + index, len, rdata); + } + + size_t tx_data_size = 0; + char* tx_data = sanei_xml_get_hex_data(node, &tx_data_size); + + if (direction_is_in) + { + if (tx_data_size != (size_t)len) + { + FAIL_TEST_TX(__func__, node, + "got different amount of data than wanted (%lu vs %lu)\n", + tx_data_size, (size_t)len); + free(tx_data); + return sanei_usb_record_replace_control_msg(node, dn, rtype, req, + value, index, len, rdata); + } + memcpy(data, tx_data, tx_data_size); + } + else + { + if (!sanei_usb_check_data_equal(node, + (const char*)data, len, + tx_data, tx_data_size, __func__)) + { + free(tx_data); + return sanei_usb_record_replace_control_msg(node, dn, rtype, req, + value, index, len, rdata); + } + } + free(tx_data); + return SANE_STATUS_GOOD; +} +#endif + SANE_Status sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req, SANE_Int value, SANE_Int index, SANE_Int len, @@ -2426,6 +3947,16 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req, if (!(rtype & 0x80) && debug_level > 10) print_buffer (data, len); + if (testing_mode == sanei_usb_testing_mode_replay) + { +#if WITH_USB_RECORD_REPLAY + return sanei_usb_replay_control_msg(dn, rtype, req, value, index, len, + data); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } if (devices[dn].method == sanei_usb_method_scanner_driver) { #if defined(__linux__) @@ -2537,9 +4068,141 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req, devices[dn].method); return SANE_STATUS_UNSUPPORTED; } + + if (testing_mode == sanei_usb_testing_mode_record) + { +#if WITH_USB_RECORD_REPLAY + // TODO: record in the error code path too + sanei_usb_record_control_msg(NULL, dn, rtype, req, value, index, len, + data); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } return SANE_STATUS_GOOD; } +#if WITH_USB_RECORD_REPLAY +static void sanei_usb_record_read_int(xmlNode* node, + SANE_Int dn, SANE_Byte* buffer, + size_t size, ssize_t read_size) +{ + (void) size; + + int node_was_null = node == NULL; + if (node_was_null) + node = testing_append_commands_node; + + xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"interrupt_tx"); + + sanei_xml_command_common_props(e_tx, devices[dn].int_in_ep & 0x0f, "IN"); + + if (buffer == NULL) + { + const int buf_size = 128; + char buf[buf_size]; + snprintf(buf, buf_size, "(unknown read of wanted size %ld)", read_size); + xmlNode* e_content = xmlNewText((const xmlChar*)buf); + xmlAddChild(e_tx, e_content); + } + else + { + if (read_size >= 0) + { + sanei_xml_set_hex_data(e_tx, (const char*)buffer, read_size); + } + else + { + xmlNewProp(e_tx, (const xmlChar*)"error", (const xmlChar*)"timeout"); + } + } + + node = sanei_xml_append_command(node, node_was_null, e_tx); + + if (node_was_null) + testing_append_commands_node = node; +} + +static void sanei_usb_record_replace_read_int(xmlNode* node, + SANE_Int dn, SANE_Byte* buffer, + size_t size, size_t read_size) +{ + if (!testing_development_mode) + return; + testing_known_commands_input_failed = 1; + testing_last_known_seq--; + sanei_usb_record_read_int(node, dn, buffer, size, read_size); + xmlUnlinkNode(node); + xmlFreeNode(node); +} + +static int sanei_usb_replay_read_int(SANE_Int dn, SANE_Byte* buffer, + size_t size) +{ + if (testing_known_commands_input_failed) + return -1; + + size_t wanted_size = size; + + xmlNode* node = sanei_xml_get_next_tx_node(); + if (node == NULL) + { + FAIL_TEST(__func__, "no more transactions\n"); + return -1; + } + + if (sanei_xml_is_known_commands_end(node)) + { + sanei_usb_record_read_int(NULL, dn, NULL, 0, size); + testing_known_commands_input_failed = 1; + return -1; + } + + sanei_xml_record_seq(node); + sanei_xml_break_if_needed(node); + + if (xmlStrcmp(node->name, (const xmlChar*)"interrupt_tx") != 0) + { + FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", + (const char*) node->name); + sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); + return -1; + } + + if (!sanei_usb_check_attr(node, "direction", "IN", __func__)) + { + sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); + return -1; + } + + if (!sanei_usb_check_attr_uint(node, "endpoint_number", + devices[dn].int_in_ep & 0x0f, + __func__)) + { + sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); + return -1; + } + + size_t tx_data_size = 0; + char* tx_data = sanei_xml_get_hex_data(node, &tx_data_size); + + if (tx_data_size > wanted_size) + { + FAIL_TEST_TX(__func__, node, + "got more data than wanted (%lu vs %lu)\n", + tx_data_size, wanted_size); + sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); + free(tx_data); + return -1; + } + + memcpy((char*) buffer, tx_data, tx_data_size); + free(tx_data); + return tx_data_size; +} +#endif // WITH_USB_RECORD_REPLAY + SANE_Status sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) { @@ -2562,7 +4225,16 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) DBG (5, "sanei_usb_read_int: trying to read %lu bytes\n", (unsigned long) *size); - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_replay) + { +#if WITH_USB_RECORD_REPLAY + read_size = sanei_usb_replay_read_int(dn, buffer, *size); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) { DBG (1, "sanei_usb_read_int: access method %d not implemented\n", devices[dn].method); @@ -2658,8 +4330,22 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) return SANE_STATUS_INVAL; } + if (testing_mode == sanei_usb_testing_mode_record) + { +#if WITH_USB_RECORD_REPLAY + sanei_usb_record_read_int(NULL, dn, buffer, *size, read_size); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + if (read_size < 0) { + *size = 0; + if (testing_mode != sanei_usb_testing_mode_disabled) + return SANE_STATUS_IO_ERROR; + #ifdef HAVE_LIBUSB_LEGACY if (devices[dn].method == sanei_usb_method_libusb) if (stalled) @@ -2669,7 +4355,6 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) if (stalled) libusb_clear_halt (devices[dn].lu_handle, devices[dn].int_in_ep); #endif - *size = 0; return SANE_STATUS_IO_ERROR; } if (read_size == 0) @@ -2687,6 +4372,58 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size) return SANE_STATUS_GOOD; } +#if WITH_USB_RECORD_REPLAY +static SANE_Status sanei_usb_replay_set_configuration(SANE_Int dn, + SANE_Int configuration) +{ + (void) dn; + + xmlNode* node = sanei_xml_get_next_tx_node(); + if (node == NULL) + { + FAIL_TEST(__func__, "no more transactions\n"); + return SANE_STATUS_IO_ERROR; + } + + sanei_xml_record_seq(node); + sanei_xml_break_if_needed(node); + + if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0) + { + FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", + (const char*) node->name); + return SANE_STATUS_IO_ERROR; + } + + if (!sanei_usb_check_attr(node, "direction", "OUT", __func__)) + return SANE_STATUS_IO_ERROR; + + if (!sanei_usb_check_attr_uint(node, "bmRequestType", 0, __func__)) + return SANE_STATUS_IO_ERROR; + + if (!sanei_usb_check_attr_uint(node, "bRequest", 9, __func__)) + return SANE_STATUS_IO_ERROR; + + if (!sanei_usb_check_attr_uint(node, "wValue", configuration, __func__)) + return SANE_STATUS_IO_ERROR; + + if (!sanei_usb_check_attr_uint(node, "wIndex", 0, __func__)) + return SANE_STATUS_IO_ERROR; + + if (!sanei_usb_check_attr_uint(node, "wLength", 0, __func__)) + return SANE_STATUS_IO_ERROR; + + return SANE_STATUS_GOOD; +} + +static void sanei_usb_record_set_configuration(SANE_Int dn, + SANE_Int configuration) +{ + (void) dn; (void) configuration; + // TODO +} +#endif // WITH_USB_RECORD_REPLAY + SANE_Status sanei_usb_set_configuration (SANE_Int dn, SANE_Int configuration) { @@ -2700,7 +4437,26 @@ sanei_usb_set_configuration (SANE_Int dn, SANE_Int configuration) DBG (5, "sanei_usb_set_configuration: configuration = %d\n", configuration); - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_record) + { +#if WITH_USB_RECORD_REPLAY + sanei_usb_record_set_configuration(dn, configuration); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + + if (testing_mode == sanei_usb_testing_mode_replay) + { +#if WITH_USB_RECORD_REPLAY + return sanei_usb_replay_set_configuration(dn, configuration); +#else + DBG (1, "USB record-replay mode support is missing\n"); + return SANE_STATUS_UNSUPPORTED; +#endif + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) { #if defined(__linux__) return SANE_STATUS_GOOD; @@ -2770,7 +4526,11 @@ sanei_usb_claim_interface (SANE_Int dn, SANE_Int interface_number) DBG (5, "sanei_usb_claim_interface: interface_number = %d\n", interface_number); - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_replay) + { + return SANE_STATUS_GOOD; + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) { #if defined(__linux__) return SANE_STATUS_GOOD; @@ -2837,7 +4597,11 @@ sanei_usb_release_interface (SANE_Int dn, SANE_Int interface_number) } DBG (5, "sanei_usb_release_interface: interface_number = %d\n", interface_number); - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_replay) + { + return SANE_STATUS_GOOD; + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) { #if defined(__linux__) return SANE_STATUS_GOOD; @@ -2903,7 +4667,11 @@ sanei_usb_set_altinterface (SANE_Int dn, SANE_Int alternate) devices[dn].alt_setting = alternate; - if (devices[dn].method == sanei_usb_method_scanner_driver) + if (testing_mode == sanei_usb_testing_mode_replay) + { + return SANE_STATUS_GOOD; + } + else if (devices[dn].method == sanei_usb_method_scanner_driver) { #if defined(__linux__) return SANE_STATUS_GOOD; @@ -2955,6 +4723,25 @@ sanei_usb_set_altinterface (SANE_Int dn, SANE_Int alternate) } } +static SANE_Status +sanei_usb_replay_get_descriptor(SANE_Int dn, + struct sanei_usb_dev_descriptor *desc) +{ + (void) dn; + (void) desc; + return SANE_STATUS_UNSUPPORTED; + // ZZTODO +} + +static void +sanei_usb_record_get_descriptor(SANE_Int dn, + struct sanei_usb_dev_descriptor *desc) +{ + (void) dn; + (void) desc; + // ZZTODO +} + extern SANE_Status sanei_usb_get_descriptor( SANE_Int dn, struct sanei_usb_dev_descriptor __sane_unused__ @@ -2968,6 +4755,11 @@ sanei_usb_get_descriptor( SANE_Int dn, return SANE_STATUS_INVAL; } + if (testing_mode == sanei_usb_testing_mode_replay) + { + return sanei_usb_replay_get_descriptor(dn, desc); + } + DBG (5, "sanei_usb_get_descriptor\n"); #ifdef HAVE_LIBUSB_LEGACY { @@ -3013,5 +4805,11 @@ sanei_usb_get_descriptor( SANE_Int dn, return SANE_STATUS_UNSUPPORTED; } #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */ + + if (testing_mode == sanei_usb_testing_mode_record) + { + sanei_usb_record_get_descriptor(dn, desc); + } + return SANE_STATUS_GOOD; } diff --git a/sanei/sanei_wire.c b/sanei/sanei_wire.c index 32cd1a0..85021d1 100644 --- a/sanei/sanei_wire.c +++ b/sanei/sanei_wire.c @@ -150,7 +150,7 @@ sanei_w_space (Wire * w, size_t howmuch) } void -sanei_w_void (Wire * w) +sanei_w_void (Wire * w, void __sane_unused__ * v) { DBG (3, "sanei_w_void: wire %d (void debug output)\n", w->io.fd); } diff --git a/testsuite/backend/genesys/Makefile.am b/testsuite/backend/genesys/Makefile.am index 1332cf8..818a523 100644 --- a/testsuite/backend/genesys/Makefile.am +++ b/testsuite/backend/genesys/Makefile.am @@ -6,18 +6,30 @@ TEST_LDADD = \ ../../../sanei/libsanei.la \ + ../../../sanei/sanei_usb.lo \ + ../../../sanei/sanei_magic.lo \ ../../../lib/liblib.la \ ../../../backend/libgenesys.la \ ../../../backend/sane_strstatus.lo \ - $(MATH_LIB) $(USB_LIBS) $(PTHREAD_LIBS) + $(MATH_LIB) $(USB_LIBS) $(XML_LIBS) $(PTHREAD_LIBS) -check_PROGRAMS = genesys_tests -TESTS = $(check_PROGRAMS) +check_PROGRAMS = genesys_unit_tests genesys_session_config_tests +TESTS = genesys_unit_tests AM_CPPFLAGS += -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include $(USB_CFLAGS) \ - -DBACKEND_NAME=genesys + -DBACKEND_NAME=genesys -DTESTSUITE_BACKEND_GENESYS_SRCDIR=$(srcdir) -genesys_tests_SOURCES = tests.cc tests.h minigtest.cc minigtest.h \ - tests_calibration.cc +genesys_unit_tests_SOURCES = tests.cpp tests.h \ + minigtest.cpp minigtest.h tests_printers.h \ + tests_calibration.cpp \ + tests_image.cpp \ + tests_image_pipeline.cpp \ + tests_motor.cpp \ + tests_row_buffer.cpp \ + tests_utilities.cpp -genesys_tests_LDADD = $(TEST_LDADD) +genesys_unit_tests_LDADD = $(TEST_LDADD) + +genesys_session_config_tests_SOURCES = session_config_test.cpp + +genesys_session_config_tests_LDADD = $(TEST_LDADD) diff --git a/testsuite/backend/genesys/minigtest.cc b/testsuite/backend/genesys/minigtest.cpp index 5ca73c2..8afb62a 100644 --- a/testsuite/backend/genesys/minigtest.cc +++ b/testsuite/backend/genesys/minigtest.cpp @@ -22,6 +22,8 @@ #include "minigtest.h" +#define DEBUG_DECLARE_ONLY + size_t s_num_successes = 0; size_t s_num_failures = 0; diff --git a/testsuite/backend/genesys/minigtest.h b/testsuite/backend/genesys/minigtest.h index 752efe1..9a38e77 100644 --- a/testsuite/backend/genesys/minigtest.h +++ b/testsuite/backend/genesys/minigtest.h @@ -38,7 +38,7 @@ inline void print_location(std::ostream& out, const char* function, const char* template<class T, class U> void check_equal(const T& t, const U& u, const char* function, const char* path, unsigned line) { - if (t != u) { + if (!(t == u)) { s_num_failures++; std::cerr << "FAILURE at "; print_location(std::cerr, function, path, line); @@ -64,14 +64,48 @@ inline void check_true(bool x, const char* function, const char* path, unsigned std::cerr << "\n"; } +inline void check_raises_success(const char* function, const char* path, unsigned line) +{ + s_num_successes++; + std::cerr << "SUCCESS at "; + print_location(std::cerr, function, path, line); + std::cerr << "\n"; +} + +inline void check_raises_did_not_raise(const char* function, const char* path, unsigned line) +{ + s_num_failures++; + std::cerr << "FAILURE at "; + print_location(std::cerr, function, path, line); + std::cerr << " : did not raise exception\n"; + +} + +inline void check_raises_raised_unexpected(const char* function, const char* path, unsigned line) +{ + s_num_failures++; + std::cerr << "FAILURE at "; + print_location(std::cerr, function, path, line); + std::cerr << " : unexpected exception raised\n"; +} #define ASSERT_EQ(x, y) do { check_equal((x), (y), __func__, __FILE__, __LINE__); } \ while (false) #define ASSERT_TRUE(x) do { check_true(bool(x), __func__, __FILE__, __LINE__); } \ while (false) -#define ASSERT_FALSE(x) do { !check_true(bool(x), __func__, __FILE__, __LINE__); } \ +#define ASSERT_FALSE(x) do { check_true(!bool(x), __func__, __FILE__, __LINE__); } \ while (false) +#define ASSERT_RAISES(x, T) \ + do { try { \ + x; \ + check_raises_did_not_raise(__func__, __FILE__, __LINE__); \ + } catch (const T&) { \ + check_raises_success(__func__, __FILE__, __LINE__); \ + } catch (...) { \ + check_raises_raised_unexpected(__func__, __FILE__, __LINE__); \ + } } while (false) + int finish_tests(); #endif diff --git a/testsuite/backend/genesys/session_config_test.cpp b/testsuite/backend/genesys/session_config_test.cpp new file mode 100644 index 0000000..72043bb --- /dev/null +++ b/testsuite/backend/genesys/session_config_test.cpp @@ -0,0 +1,503 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "../../../backend/genesys/device.h" +#include "../../../backend/genesys/enums.h" +#include "../../../backend/genesys/error.h" +#include "../../../backend/genesys/low.h" +#include "../../../backend/genesys/genesys.h" +#include "../../../backend/genesys/test_settings.h" +#include "../../../backend/genesys/test_scanner_interface.h" +#include "../../../backend/genesys/utilities.h" +#include "../../../include/sane/saneopts.h" +#include "sys/stat.h" +#include <cstdio> +#include <cstring> +#include <fstream> +#include <sstream> +#include <string> +#include <unordered_set> + +#define XSTR(s) STR(s) +#define STR(s) #s +#define CURR_SRCDIR XSTR(TESTSUITE_BACKEND_GENESYS_SRCDIR) + +struct TestConfig +{ + std::uint16_t vendor_id = 0; + std::uint16_t product_id = 0; + std::string model_name; + genesys::ScanMethod method = genesys::ScanMethod::FLATBED; + genesys::ScanColorMode color_mode = genesys::ScanColorMode::COLOR_SINGLE_PASS; + unsigned depth = 0; + unsigned resolution = 0; + + std::string name() const + { + std::stringstream out; + out << "capture_" << model_name + << '_' << method + << '_' << color_mode + << "_depth" << depth + << "_dpi" << resolution; + return out.str(); + } + +}; + +class SaneOptions +{ +public: + void fetch(SANE_Handle handle) + { + handle_ = handle; + options_.resize(1); + options_[0] = fetch_option(0); + + if (std::strcmp(options_[0].name, SANE_NAME_NUM_OPTIONS) != 0 || + options_[0].type != SANE_TYPE_INT) + { + throw std::runtime_error("Expected option number option"); + } + int option_count = 0; + TIE(sane_control_option(handle, 0, SANE_ACTION_GET_VALUE, &option_count, nullptr)); + + options_.resize(option_count); + for (int i = 0; i < option_count; ++i) { + options_[i] = fetch_option(i); + } + } + + void close() + { + handle_ = nullptr; + } + + bool get_value_bool(const std::string& name) const + { + auto i = find_option(name, SANE_TYPE_BOOL); + int value = 0; + TIE(sane_control_option(handle_, i, SANE_ACTION_GET_VALUE, &value, nullptr)); + return value; + } + + void set_value_bool(const std::string& name, bool value) + { + auto i = find_option(name, SANE_TYPE_BOOL); + int value_int = value; + TIE(sane_control_option(handle_, i, SANE_ACTION_SET_VALUE, &value_int, nullptr)); + } + + bool get_value_button(const std::string& name) const + { + auto i = find_option(name, SANE_TYPE_BUTTON); + int value = 0; + TIE(sane_control_option(handle_, i, SANE_ACTION_GET_VALUE, &value, nullptr)); + return value; + } + + void set_value_button(const std::string& name, bool value) + { + auto i = find_option(name, SANE_TYPE_BUTTON); + int value_int = value; + TIE(sane_control_option(handle_, i, SANE_ACTION_SET_VALUE, &value_int, nullptr)); + } + + int get_value_int(const std::string& name) const + { + auto i = find_option(name, SANE_TYPE_INT); + int value = 0; + TIE(sane_control_option(handle_, i, SANE_ACTION_GET_VALUE, &value, nullptr)); + return value; + } + + void set_value_int(const std::string& name, int value) + { + auto i = find_option(name, SANE_TYPE_INT); + TIE(sane_control_option(handle_, i, SANE_ACTION_SET_VALUE, &value, nullptr)); + } + + float get_value_float(const std::string& name) const + { + auto i = find_option(name, SANE_TYPE_FIXED); + int value = 0; + TIE(sane_control_option(handle_, i, SANE_ACTION_GET_VALUE, &value, nullptr)); + return static_cast<float>(SANE_UNFIX(value)); + } + + void set_value_float(const std::string& name, float value) + { + auto i = find_option(name, SANE_TYPE_FIXED); + int value_int = SANE_FIX(value); + TIE(sane_control_option(handle_, i, SANE_ACTION_SET_VALUE, &value_int, nullptr)); + } + + std::string get_value_string(const std::string& name) const + { + auto i = find_option(name, SANE_TYPE_STRING); + std::string value; + value.resize(options_[i].size + 1); + TIE(sane_control_option(handle_, i, SANE_ACTION_GET_VALUE, &value.front(), nullptr)); + value.resize(std::strlen(&value.front())); + return value; + } + + void set_value_string(const std::string& name, const std::string& value) + { + auto i = find_option(name, SANE_TYPE_STRING); + TIE(sane_control_option(handle_, i, SANE_ACTION_SET_VALUE, + const_cast<char*>(&value.front()), nullptr)); + } + +private: + SANE_Option_Descriptor fetch_option(int index) + { + const auto* option = sane_get_option_descriptor(handle_, index); + if (option == nullptr) { + throw std::runtime_error("Got nullptr option"); + } + return *option; + } + + std::size_t find_option(const std::string& name, SANE_Value_Type type) const + { + for (std::size_t i = 0; i < options_.size(); ++i) { + if (options_[i].name == name) { + if (options_[i].type != type) { + throw std::runtime_error("Option has incorrect type"); + } + return i; + } + } + throw std::runtime_error("Could not find option"); + } + + SANE_Handle handle_; + std::vector<SANE_Option_Descriptor> options_; +}; + + +void build_checkpoint(const genesys::Genesys_Device& dev, + genesys::TestScannerInterface& iface, + const std::string& checkpoint_name, + std::stringstream& out) +{ + out << "\n\n================\n" + << "Checkpoint: " << checkpoint_name << "\n" + << "================\n\n" + << "dev: " << genesys::format_indent_braced_list(4, dev) << "\n\n" + << "iface.cached_regs: " + << genesys::format_indent_braced_list(4, iface.cached_regs()) << "\n\n" + << "iface.cached_fe_regs: " + << genesys::format_indent_braced_list(4, iface.cached_fe_regs()) << "\n\n" + << "iface.last_progress_message: " << iface.last_progress_message() << "\n\n"; + out << "iface.slope_tables: {\n"; + for (const auto& kv : iface.recorded_slope_tables()) { + out << " " << kv.first << ": {"; + for (unsigned i = 0; i < kv.second.size(); ++i) { + if (i % 10 == 0) { + out << "\n "; + } + out << ' ' << kv.second[i]; + } + out << "\n }\n"; + } + out << "}\n"; + if (iface.recorded_key_values().empty()) { + out << "iface.recorded_key_values: []\n"; + } else { + out << "iface.recorded_key_values: {\n"; + for (const auto& kv : iface.recorded_key_values()) { + out << " " << kv.first << " : " << kv.second << '\n'; + } + out << "}\n"; + } + iface.recorded_key_values().clear(); + out << "\n"; +} + +void run_single_test_scan(const TestConfig& config, std::stringstream& out) +{ + auto build_checkpoint_wrapper = [&](const genesys::Genesys_Device& dev, + genesys::TestScannerInterface& iface, + const std::string& checkpoint_name) + { + build_checkpoint(dev, iface, checkpoint_name, out); + }; + + genesys::enable_testing_mode(config.vendor_id, config.product_id, build_checkpoint_wrapper); + + SANE_Handle handle; + + TIE(sane_init(nullptr, nullptr)); + TIE(sane_open(genesys::get_testing_device_name().c_str(), &handle)); + + SaneOptions options; + options.fetch(handle); + + options.set_value_button("force-calibration", true); + options.set_value_string(SANE_NAME_SCAN_SOURCE, + genesys::scan_method_to_option_string(config.method)); + options.set_value_string(SANE_NAME_SCAN_MODE, + genesys::scan_color_mode_to_option_string(config.color_mode)); + if (config.color_mode != genesys::ScanColorMode::LINEART) { + options.set_value_int(SANE_NAME_BIT_DEPTH, config.depth); + } + options.set_value_int(SANE_NAME_SCAN_RESOLUTION, config.resolution); + options.close(); + + TIE(sane_start(handle)); + + SANE_Parameters params; + TIE(sane_get_parameters(handle, ¶ms)); + + int buffer_size = 1024 * 1024; + std::vector<std::uint8_t> buffer; + buffer.resize(buffer_size); + + std::uint64_t total_data_size = std::uint64_t(params.bytes_per_line) * params.lines; + std::uint64_t total_got_data = 0; + + while (total_got_data < total_data_size) { + int ask_len = std::min<std::size_t>(buffer_size, total_data_size - total_got_data); + + int got_data = 0; + auto status = sane_read(handle, buffer.data(), ask_len, &got_data); + total_got_data += got_data; + if (status == SANE_STATUS_EOF) { + break; + } + TIE(status); + } + + sane_cancel(handle); + sane_close(handle); + sane_exit(); + + genesys::disable_testing_mode(); +} + +std::string read_file_to_string(const std::string& path) +{ + std::ifstream in; + in.open(path); + if (!in.is_open()) { + return ""; + } + std::stringstream in_str; + in_str << in.rdbuf(); + return in_str.str(); +} + +void write_string_to_file(const std::string& path, const std::string& contents) +{ + std::ofstream out; + out.open(path); + if (!out.is_open()) { + throw std::runtime_error("Could not open output file: " + path); + } + out << contents; + out.close(); +} + +struct TestResult +{ + bool success = true; + TestConfig config; + std::string failure_message; +}; + +TestResult perform_single_test(const TestConfig& config, const std::string& check_directory, + const std::string& output_directory) +{ + TestResult test_result; + test_result.config = config; + + std::stringstream result_output_stream; + std::string exception_output; + try { + run_single_test_scan(config, result_output_stream); + } catch (const std::exception& exc) { + exception_output = std::string("got exception: ") + typeid(exc).name() + + " with message\n" + exc.what() + "\n"; + test_result.success = false; + test_result.failure_message += exception_output; + } catch (...) { + exception_output = "got unknown exception\n"; + test_result.success = false; + test_result.failure_message += exception_output; + } + auto result_output = result_output_stream.str(); + if (!exception_output.empty()) { + result_output += "\n\n" + exception_output; + } + + auto test_filename = config.name() + ".txt"; + auto expected_session_path = check_directory + "/" + test_filename; + auto current_session_path = output_directory + "/" + test_filename; + + auto expected_output = read_file_to_string(expected_session_path); + + bool has_output = !output_directory.empty(); + + if (has_output) { + mkdir(output_directory.c_str(), 0777); + // note that check_directory and output_directory may be the same, so make sure removal + // happens after the expected output has already been read. + std::remove(current_session_path.c_str()); + } + + if (expected_output.empty()) { + test_result.failure_message += "the expected data file does not exist\n"; + test_result.success = false; + } else if (expected_output != result_output) { + test_result.failure_message += "expected and current output are not equal\n"; + if (has_output) { + test_result.failure_message += "To examine, run:\ndiff -u \"" + current_session_path + + "\" \"" + expected_session_path + "\"\n"; + } + test_result.success = false; + } + + if (has_output) { + write_string_to_file(current_session_path, result_output); + } + return test_result; +} + +std::vector<TestConfig> get_all_test_configs() +{ + genesys::genesys_init_usb_device_tables(); + + std::vector<TestConfig> configs; + std::unordered_set<std::string> model_names; + + for (const auto& usb_dev : *genesys::s_usb_devices) { + if (usb_dev.model.flags & GENESYS_FLAG_UNTESTED) { + continue; + } + if (model_names.find(usb_dev.model.name) != model_names.end()) { + continue; + } + model_names.insert(usb_dev.model.name); + + for (auto scan_mode : { genesys::ScanColorMode::LINEART, + genesys::ScanColorMode::GRAY, + genesys::ScanColorMode::COLOR_SINGLE_PASS }) { + + auto depth_values = usb_dev.model.bpp_gray_values; + if (scan_mode == genesys::ScanColorMode::COLOR_SINGLE_PASS) { + depth_values = usb_dev.model.bpp_color_values; + } + for (unsigned depth : depth_values) { + for (auto method_resolutions : usb_dev.model.resolutions) { + for (auto method : method_resolutions.methods) { + for (unsigned resolution : method_resolutions.get_resolutions()) { + TestConfig config; + config.vendor_id = usb_dev.vendor; + config.product_id = usb_dev.product; + config.model_name = usb_dev.model.name; + config.method = method; + config.depth = depth; + config.resolution = resolution; + config.color_mode = scan_mode; + configs.push_back(config); + } + } + } + } + } + } + return configs; +} + +void print_help() +{ + std::cerr << "Usage:\n" + << "session_config_test [--test={test_name}] {check_directory} [{output_directory}]\n" + << "session_config_test --help\n" + << "session_config_test --print_test_names\n"; +} + +int main(int argc, const char* argv[]) +{ + std::string check_directory; + std::string output_directory; + std::string test_name_filter; + bool print_test_names = false; + + for (int argi = 1; argi < argc; ++argi) { + std::string arg = argv[argi]; + if (arg.rfind("--test=", 0) == 0) { + test_name_filter = arg.substr(7); + } else if (arg == "-h" || arg == "--help") { + print_help(); + return 0; + } else if (arg == "--print_test_names") { + print_test_names = true; + } else if (check_directory.empty()) { + check_directory = arg; + } else if (output_directory.empty()) { + output_directory = arg; + } + } + + auto configs = get_all_test_configs(); + + if (print_test_names) { + for (const auto& config : configs) { + std::cout << config.name() << "\n"; + } + return 0; + } + + if (check_directory.empty()) { + print_help(); + return 1; + } + + bool test_success = true; + for (unsigned i = 0; i < configs.size(); ++i) { + const auto& config = configs[i]; + + if (!test_name_filter.empty() && config.name() != test_name_filter) { + continue; + } + + auto result = perform_single_test(config, check_directory, output_directory); + std::cerr << "(" << i << "/" << configs.size() << "): " + << (result.success ? "SUCCESS: " : "FAIL: ") + << result.config.name() << "\n"; + if (!result.success) { + std::cerr << result.failure_message; + } + + test_success &= result.success; + } + + if (!test_success) { + return 1; + } + return 0; +} diff --git a/testsuite/backend/genesys/tests.cc b/testsuite/backend/genesys/tests.cpp index 40b1b3e..5fe0084 100644 --- a/testsuite/backend/genesys/tests.cc +++ b/testsuite/backend/genesys/tests.cpp @@ -20,11 +20,18 @@ MA 02111-1307, USA. */ +#define DEBUG_DECLARE_ONLY + #include "tests.h" #include "minigtest.h" int main() { - test_calibration_parsing(); + genesys::test_calibration_parsing(); + genesys::test_image(); + genesys::test_image_pipeline(); + genesys::test_motor(); + genesys::test_row_buffer(); + genesys::test_utilities(); return finish_tests(); } diff --git a/testsuite/backend/genesys/tests.h b/testsuite/backend/genesys/tests.h index f4e4d2e..c48c586 100644 --- a/testsuite/backend/genesys/tests.h +++ b/testsuite/backend/genesys/tests.h @@ -23,6 +23,15 @@ #ifndef SANE_TESTSUITE_BACKEND_GENESYS_GENESYS_UNIT_TEST_H #define SANE_TESTSUITE_BACKEND_GENESYS_GENESYS_UNIT_TEST_H +namespace genesys { + void test_calibration_parsing(); +void test_image(); +void test_image_pipeline(); +void test_motor(); +void test_row_buffer(); +void test_utilities(); + +} // namespace genesys #endif diff --git a/testsuite/backend/genesys/tests_calibration.cc b/testsuite/backend/genesys/tests_calibration.cpp index 959037a..559f8a8 100644 --- a/testsuite/backend/genesys/tests_calibration.cc +++ b/testsuite/backend/genesys/tests_calibration.cpp @@ -20,28 +20,31 @@ MA 02111-1307, USA. */ +#define DEBUG_DECLARE_ONLY + #include "tests.h" #include "minigtest.h" -#include "../../../backend/genesys_low.h" +#include "../../../backend/genesys/low.h" #include <sstream> -#define DEBUG_DECLARE_ONLY +namespace genesys { Genesys_Calibration_Cache create_fake_calibration_entry() { Genesys_Calibration_Cache calib; - calib.used_setup.pixels = 10020; - calib.used_setup.lines = 150; - calib.used_setup.xres = 100.5; + calib.params.channels = 3; + calib.params.depth = 8; + calib.params.lines = 100; + calib.params.pixels = 200; GenesysFrontendLayout wolfson_layout; wolfson_layout.offset_addr = { 0x20, 0x21, 0x22 }; wolfson_layout.gain_addr = { 0x28, 0x29, 0x2a }; Genesys_Frontend fe; - fe.fe_id = DAC_WOLFSON_UMAX; + fe.id = AdcId::WOLFSON_UMAX; fe.layout = wolfson_layout; fe.regs = { { 0x00, 0x00 }, @@ -62,11 +65,11 @@ Genesys_Calibration_Cache create_fake_calibration_entry() calib.frontend = fe; Genesys_Sensor sensor; - sensor.sensor_id = CCD_UMAX; + sensor.sensor_id = SensorId::CCD_UMAX; sensor.optical_res = 1200; sensor.black_pixels = 48; sensor.dummy_pixel = 64; - sensor.CCD_start_xoffset = 0; + sensor.ccd_start_xoffset = 0; sensor.sensor_pixels = 10800; sensor.fau_gain_white_ref = 210; sensor.gain_white_ref = 230; @@ -128,3 +131,5 @@ void test_calibration_parsing() { test_calibration_roundtrip(); } + +} // namespace genesys diff --git a/testsuite/backend/genesys/tests_image.cpp b/testsuite/backend/genesys/tests_image.cpp new file mode 100644 index 0000000..bc8b923 --- /dev/null +++ b/testsuite/backend/genesys/tests_image.cpp @@ -0,0 +1,576 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "tests.h" +#include "minigtest.h" +#include "tests_printers.h" + +#include "../../../backend/genesys/image.h" +#include "../../../backend/genesys/image_pipeline.h" +#include <vector> + +namespace genesys { + +void test_get_pixel_from_row() +{ + std::vector<std::uint8_t> data = { + 0x12, 0x34, 0x56, 0x67, 0x89, 0xab, + 0xcd, 0xef, 0x21, 0x43, 0x65, 0x87 + }; + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::I1), + Pixel(0, 0, 0)); + ASSERT_EQ(get_pixel_from_row(data.data(), 3, PixelFormat::I1), + Pixel(0xffff, 0xffff, 0xffff)); + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::RGB111), + Pixel(0, 0, 0)); + ASSERT_EQ(get_pixel_from_row(data.data(), 1, PixelFormat::RGB111), + Pixel(0xffff, 0, 0)); + ASSERT_EQ(get_pixel_from_row(data.data(), 2, PixelFormat::RGB111), + Pixel(0xffff, 0, 0)); + ASSERT_EQ(get_pixel_from_row(data.data(), 3, PixelFormat::RGB111), + Pixel(0, 0xffff, 0xffff)); + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::I8), + Pixel(0x1212, 0x1212, 0x1212)); + ASSERT_EQ(get_pixel_from_row(data.data(), 1, PixelFormat::I8), + Pixel(0x3434, 0x3434, 0x3434)); + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::RGB888), + Pixel(0x1212, 0x3434, 0x5656)); + ASSERT_EQ(get_pixel_from_row(data.data(), 1, PixelFormat::RGB888), + Pixel(0x6767, 0x8989, 0xabab)); + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::BGR888), + Pixel(0x5656, 0x3434, 0x1212)); + ASSERT_EQ(get_pixel_from_row(data.data(), 1, PixelFormat::BGR888), + Pixel(0xabab, 0x8989, 0x6767)); + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::I16), + Pixel(0x3412, 0x3412, 0x3412)); + ASSERT_EQ(get_pixel_from_row(data.data(), 1, PixelFormat::I16), + Pixel(0x6756, 0x6756, 0x6756)); + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::RGB161616), + Pixel(0x3412, 0x6756, 0xab89)); + ASSERT_EQ(get_pixel_from_row(data.data(), 1, PixelFormat::RGB161616), + Pixel(0xefcd, 0x4321, 0x8765)); + ASSERT_EQ(get_pixel_from_row(data.data(), 0, PixelFormat::BGR161616), + Pixel(0xab89, 0x6756, 0x3412)); + ASSERT_EQ(get_pixel_from_row(data.data(), 1, PixelFormat::BGR161616), + Pixel(0x8765, 0x4321, 0xefcd)); +} + +void test_set_pixel_to_row() +{ + using Data = std::vector<std::uint8_t>; + Data data; + data.resize(12, 0); + + auto reset = [&]() { std::fill(data.begin(), data.end(), 0); }; + + Pixel pixel; + + pixel = Pixel(0x8000, 0x8000, 0x8000); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::I1); + ASSERT_EQ(data, Data({0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x8000, 0x8000, 0x8000); + set_pixel_to_row(data.data(), 2, pixel, PixelFormat::I1); + ASSERT_EQ(data, Data({0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x8000, 0x8000, 0x8000); + set_pixel_to_row(data.data(), 8, pixel, PixelFormat::I1); + ASSERT_EQ(data, Data({0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x8000, 0x0000, 0x8000); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x8000, 0x0000, 0x8000); + set_pixel_to_row(data.data(), 1, pixel, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x8000, 0x0000, 0x8000); + set_pixel_to_row(data.data(), 8, pixel, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1200, 0x1200, 0x1200); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::I8); + ASSERT_EQ(data, Data({0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1200, 0x1200, 0x1200); + set_pixel_to_row(data.data(), 2, pixel, PixelFormat::I8); + ASSERT_EQ(data, Data({0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1200, 0x3400, 0x5600); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::RGB888); + ASSERT_EQ(data, Data({0x12, 0x34, 0x56, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1200, 0x3400, 0x5600); + set_pixel_to_row(data.data(), 1, pixel, PixelFormat::RGB888); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x12, 0x34, 0x56, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1200, 0x3400, 0x5600); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::BGR888); + ASSERT_EQ(data, Data({0x56, 0x34, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1200, 0x3400, 0x5600); + set_pixel_to_row(data.data(), 1, pixel, PixelFormat::BGR888); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x56, 0x34, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1234, 0x1234, 0x1234); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::I16); + ASSERT_EQ(data, Data({0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1234, 0x1234, 0x1234); + set_pixel_to_row(data.data(), 1, pixel, PixelFormat::I16); + ASSERT_EQ(data, Data({0x00, 0x00, 0x34, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1234, 0x5678, 0x9abc); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::RGB161616); + ASSERT_EQ(data, Data({0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1234, 0x5678, 0x9abc); + set_pixel_to_row(data.data(), 1, pixel, PixelFormat::RGB161616); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a})); + reset(); + + pixel = Pixel(0x1234, 0x5678, 0x9abc); + set_pixel_to_row(data.data(), 0, pixel, PixelFormat::BGR161616); + ASSERT_EQ(data, Data({0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = Pixel(0x1234, 0x5678, 0x9abc); + set_pixel_to_row(data.data(), 1, pixel, PixelFormat::BGR161616); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12})); + reset(); +} + +void test_get_raw_pixel_from_row() +{ + std::vector<std::uint8_t> data = { + 0x12, 0x34, 0x56, 0x67, 0x89, 0xab, + 0xcd, 0xef, 0x21, 0x43, 0x65, 0x87 + }; + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::I1), + RawPixel(0x0)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 3, PixelFormat::I1), + RawPixel(0x1)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::RGB111), + RawPixel(0)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 1, PixelFormat::RGB111), + RawPixel(0x4)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 2, PixelFormat::RGB111), + RawPixel(0x4)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 3, PixelFormat::RGB111), + RawPixel(0x3)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::I8), + RawPixel(0x12)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 1, PixelFormat::I8), + RawPixel(0x34)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::RGB888), + RawPixel(0x12, 0x34, 0x56)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 1, PixelFormat::RGB888), + RawPixel(0x67, 0x89, 0xab)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::BGR888), + RawPixel(0x12, 0x34, 0x56)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 1, PixelFormat::BGR888), + RawPixel(0x67, 0x89, 0xab)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::I16), + RawPixel(0x12, 0x34)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 1, PixelFormat::I16), + RawPixel(0x56, 0x67)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::RGB161616), + RawPixel(0x12, 0x34, 0x56, 0x67, 0x89, 0xab)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 1, PixelFormat::RGB161616), + RawPixel(0xcd, 0xef, 0x21, 0x43, 0x65, 0x87)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 0, PixelFormat::BGR161616), + RawPixel(0x12, 0x34, 0x56, 0x67, 0x89, 0xab)); + ASSERT_EQ(get_raw_pixel_from_row(data.data(), 1, PixelFormat::BGR161616), + RawPixel(0xcd, 0xef, 0x21, 0x43, 0x65, 0x87)); +} + +void test_set_raw_pixel_to_row() +{ + using Data = std::vector<std::uint8_t>; + Data data; + data.resize(12, 0); + + auto reset = [&]() { std::fill(data.begin(), data.end(), 0); }; + + RawPixel pixel; + + pixel = RawPixel(0x01); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::I1); + ASSERT_EQ(data, Data({0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x01); + set_raw_pixel_to_row(data.data(), 2, pixel, PixelFormat::I1); + ASSERT_EQ(data, Data({0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x01); + set_raw_pixel_to_row(data.data(), 8, pixel, PixelFormat::I1); + ASSERT_EQ(data, Data({0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x05); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x05); + set_raw_pixel_to_row(data.data(), 1, pixel, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x05); + set_raw_pixel_to_row(data.data(), 8, pixel, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x12); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::I8); + ASSERT_EQ(data, Data({0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x12); + set_raw_pixel_to_row(data.data(), 2, pixel, PixelFormat::I8); + ASSERT_EQ(data, Data({0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x12, 0x34, 0x56); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::RGB888); + ASSERT_EQ(data, Data({0x12, 0x34, 0x56, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x12, 0x34, 0x56); + set_raw_pixel_to_row(data.data(), 1, pixel, PixelFormat::RGB888); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x12, 0x34, 0x56, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x12, 0x34, 0x56); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::BGR888); + ASSERT_EQ(data, Data({0x12, 0x34, 0x56, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x12, 0x34, 0x56); + set_raw_pixel_to_row(data.data(), 1, pixel, PixelFormat::BGR888); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x12, 0x34, 0x56, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x34, 0x12); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::I16); + ASSERT_EQ(data, Data({0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x34, 0x12); + set_raw_pixel_to_row(data.data(), 1, pixel, PixelFormat::I16); + ASSERT_EQ(data, Data({0x00, 0x00, 0x34, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::RGB161616); + ASSERT_EQ(data, Data({0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a); + set_raw_pixel_to_row(data.data(), 1, pixel, PixelFormat::RGB161616); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a})); + reset(); + + pixel = RawPixel(0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a); + set_raw_pixel_to_row(data.data(), 0, pixel, PixelFormat::BGR161616); + ASSERT_EQ(data, Data({0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + pixel = RawPixel(0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a); + set_raw_pixel_to_row(data.data(), 1, pixel, PixelFormat::BGR161616); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a})); + reset(); +} + +void test_get_raw_channel_from_row() +{ + std::vector<std::uint8_t> data = { + 0x12, 0x34, 0x56, 0x67, 0x89, 0xab, + 0xcd, 0xef, 0x21, 0x43, 0x65, 0x87 + }; + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::I1), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 3, 0, PixelFormat::I1), 1); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 1, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 2, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 0, PixelFormat::RGB111), 1); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 1, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 2, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 2, 0, PixelFormat::RGB111), 1); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 2, 1, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 2, 2, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 3, 0, PixelFormat::RGB111), 0); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 3, 1, PixelFormat::RGB111), 1); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 3, 2, PixelFormat::RGB111), 1); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::I8), 0x12); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 0, PixelFormat::I8), 0x34); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::RGB888), 0x12); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 1, PixelFormat::RGB888), 0x34); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 2, PixelFormat::RGB888), 0x56); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 0, PixelFormat::RGB888), 0x67); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 1, PixelFormat::RGB888), 0x89); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 2, PixelFormat::RGB888), 0xab); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::BGR888), 0x12); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 1, PixelFormat::BGR888), 0x34); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 2, PixelFormat::BGR888), 0x56); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 0, PixelFormat::BGR888), 0x67); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 1, PixelFormat::BGR888), 0x89); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 2, PixelFormat::BGR888), 0xab); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::I16), 0x3412); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 0, PixelFormat::I16), 0x6756); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::RGB161616), 0x3412); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 1, PixelFormat::RGB161616), 0x6756); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 2, PixelFormat::RGB161616), 0xab89); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 0, PixelFormat::RGB161616), 0xefcd); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 1, PixelFormat::RGB161616), 0x4321); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 2, PixelFormat::RGB161616), 0x8765); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 0, PixelFormat::BGR161616), 0x3412); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 1, PixelFormat::BGR161616), 0x6756); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 0, 2, PixelFormat::BGR161616), 0xab89); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 0, PixelFormat::BGR161616), 0xefcd); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 1, PixelFormat::BGR161616), 0x4321); + ASSERT_EQ(get_raw_channel_from_row(data.data(), 1, 2, PixelFormat::BGR161616), 0x8765); +} + +void test_set_raw_channel_to_row() +{ + using Data = std::vector<std::uint8_t>; + Data data; + data.resize(12, 0); + + auto reset = [&]() { std::fill(data.begin(), data.end(), 0); }; + + set_raw_channel_to_row(data.data(), 0, 0, 1, PixelFormat::I1); + ASSERT_EQ(data, Data({0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 2, 0, 1, PixelFormat::I1); + ASSERT_EQ(data, Data({0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 8, 0, 1, PixelFormat::I1); + ASSERT_EQ(data, Data({0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 0, 1, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 1, 1, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 2, 1, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 8, 0, 1, PixelFormat::RGB111); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 0, 0x12, PixelFormat::I8); + ASSERT_EQ(data, Data({0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 2, 0, 0x12, PixelFormat::I8); + ASSERT_EQ(data, Data({0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + for (auto format : { PixelFormat::RGB888, PixelFormat::BGR888 }) { + set_raw_channel_to_row(data.data(), 0, 0, 0x12, format); + ASSERT_EQ(data, Data({0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 1, 0x12, format); + ASSERT_EQ(data, Data({0x00, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 2, 0x12, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 1, 0, 0x12, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 1, 1, 0x12, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 1, 2, 0x12, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + } + + set_raw_channel_to_row(data.data(), 0, 0, 0x1234, PixelFormat::I16); + ASSERT_EQ(data, Data({0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 1, 0, 0x1234, PixelFormat::I16); + ASSERT_EQ(data, Data({0x00, 0x00, 0x34, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + for (auto format : { PixelFormat::RGB161616, PixelFormat::BGR161616 }) { + set_raw_channel_to_row(data.data(), 0, 0, 0x1234, format); + ASSERT_EQ(data, Data({0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 1, 0x1234, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x34, 0x12, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 0, 2, 0x1234, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x34, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 1, 0, 0x1234, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x34, 0x12, 0x00, 0x00, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 1, 1, 0x1234, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x34, 0x12, 0x00, 0x00})); + reset(); + + set_raw_channel_to_row(data.data(), 1, 2, 0x1234, format); + ASSERT_EQ(data, Data({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x34, 0x12})); + reset(); + } +} + +void test_convert_pixel_row_format() +{ + // The actual work is done in set_channel_to_row and get_channel_from_row, so we don't need + // to test all format combinations. + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x12, 0x34, 0x56, + 0x78, 0x98, 0xab, + 0xcd, 0xef, 0x21, + }; + Data out_data; + out_data.resize(in_data.size() * 2); + + convert_pixel_row_format(in_data.data(), PixelFormat::RGB888, + out_data.data(), PixelFormat::BGR161616, 3); + + Data expected_data = { + 0x56, 0x56, 0x34, 0x34, 0x12, 0x12, + 0xab, 0xab, 0x98, 0x98, 0x78, 0x78, + 0x21, 0x21, 0xef, 0xef, 0xcd, 0xcd, + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_image() +{ + test_get_pixel_from_row(); + test_set_pixel_to_row(); + test_get_raw_pixel_from_row(); + test_set_raw_pixel_to_row(); + test_get_raw_channel_from_row(); + test_set_raw_channel_to_row(); + test_convert_pixel_row_format(); +} + +} // namespace genesys diff --git a/testsuite/backend/genesys/tests_image_pipeline.cpp b/testsuite/backend/genesys/tests_image_pipeline.cpp new file mode 100644 index 0000000..d4853d2 --- /dev/null +++ b/testsuite/backend/genesys/tests_image_pipeline.cpp @@ -0,0 +1,519 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "tests.h" +#include "minigtest.h" +#include "tests_printers.h" + +#include "../../../backend/genesys/image_pipeline.h" + +#include <numeric> + +namespace genesys { + +void test_image_buffer_genesys_usb() +{ + std::vector<std::size_t> requests; + + auto on_read_usb = [&](std::size_t x, std::uint8_t* data) + { + (void) data; + requests.push_back(x); + }; + + FakeBufferModel model; + model.push_step(453120, 1); + model.push_step(56640, 3540); + ImageBufferGenesysUsb buffer{1086780, model, on_read_usb}; + + std::vector<std::uint8_t> dummy; + dummy.resize(1086780); + + ASSERT_TRUE(buffer.get_data(453120, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + + std::vector<std::size_t> expected = { + 453120, 56576, 56576, 56576, 56832, 56576, 56576, 56576, 56832, 56576, 56576, 56576, 11008 + }; + ASSERT_EQ(requests, expected); +} + +void test_image_buffer_genesys_usb_capped_remaining_bytes() +{ + std::vector<std::size_t> requests; + + auto on_read_usb = [&](std::size_t x, std::uint8_t* data) + { + (void) data; + requests.push_back(x); + }; + + FakeBufferModel model; + model.push_step(453120, 1); + model.push_step(56640, 3540); + ImageBufferGenesysUsb buffer{1086780, model, on_read_usb}; + + std::vector<std::uint8_t> dummy; + dummy.resize(1086780); + + ASSERT_TRUE(buffer.get_data(453120, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + ASSERT_TRUE(buffer.get_data(56640, dummy.data())); + buffer.set_remaining_size(10000); + ASSERT_FALSE(buffer.get_data(56640, dummy.data())); + + std::vector<std::size_t> expected = { + // note that the sizes are rounded-up to 256 bytes + 453120, 56576, 56576, 56576, 56832, 10240 + }; + ASSERT_EQ(requests, expected); +} + +void test_node_buffered_callable_source() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11 + }; + + std::size_t chunk_size = 3; + std::size_t curr_index = 0; + + auto data_source_cb = [&](std::size_t size, std::uint8_t* out_data) + { + ASSERT_EQ(size, chunk_size); + std::copy(in_data.begin() + curr_index, + in_data.begin() + curr_index + chunk_size, out_data); + curr_index += chunk_size; + return true; + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeBufferedCallableSource>(4, 3, PixelFormat::I8, + chunk_size, data_source_cb); + + Data out_data; + out_data.resize(4); + + ASSERT_EQ(curr_index, 0u); + + ASSERT_TRUE(stack.get_next_row_data(out_data.data())); + ASSERT_EQ(out_data, Data({0, 1, 2, 3})); + ASSERT_EQ(curr_index, 6u); + + ASSERT_TRUE(stack.get_next_row_data(out_data.data())); + ASSERT_EQ(out_data, Data({4, 5, 6, 7})); + ASSERT_EQ(curr_index, 9u); + + ASSERT_TRUE(stack.get_next_row_data(out_data.data())); + ASSERT_EQ(out_data, Data({8, 9, 10, 11})); + ASSERT_EQ(curr_index, 12u); +} + +void test_node_format_convert() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x12, 0x34, 0x56, + 0x78, 0x98, 0xab, + 0xcd, 0xef, 0x21, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(3, 1, PixelFormat::RGB888, + std::move(in_data)); + stack.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::BGR161616); + + ASSERT_EQ(stack.get_output_width(), 3u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 6u * 3); + ASSERT_EQ(stack.get_output_format(), PixelFormat::BGR161616); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + 0x56, 0x56, 0x34, 0x34, 0x12, 0x12, + 0xab, 0xab, 0x98, 0x98, 0x78, 0x78, + 0x21, 0x21, 0xef, 0xef, 0xcd, 0xcd, + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_desegment_1_line() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 1, 5, 9, 13, 17, + 3, 7, 11, 15, 19, + 2, 6, 10, 14, 18, + 4, 8, 12, 16, 20, + 21, 25, 29, 33, 37, + 23, 27, 31, 35, 39, + 22, 26, 30, 34, 38, + 24, 28, 32, 36, 40, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(20, 2, PixelFormat::I8, + std::move(in_data)); + stack.push_node<ImagePipelineNodeDesegment>(20, std::vector<unsigned>{ 0, 2, 1, 3 }, 5, 1, 1); + + ASSERT_EQ(stack.get_output_width(), 20u); + ASSERT_EQ(stack.get_output_height(), 2u); + ASSERT_EQ(stack.get_output_row_bytes(), 20u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::I8); + + auto out_data = stack.get_all_data(); + + Data expected_data; + expected_data.resize(40, 0); + std::iota(expected_data.begin(), expected_data.end(), 1); // will fill with 1, 2, 3, ..., 40 + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_deinterleave_lines_i8() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, + 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(10, 2, PixelFormat::I8, + std::move(in_data)); + stack.push_node<ImagePipelineNodeDeinterleaveLines>(2, 1); + + ASSERT_EQ(stack.get_output_width(), 20u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 20u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::I8); + + auto out_data = stack.get_all_data(); + + Data expected_data; + expected_data.resize(20, 0); + std::iota(expected_data.begin(), expected_data.end(), 1); // will fill with 1, 2, 3, ..., 20 + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_deinterleave_lines_rgb888() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 1, 2, 3, 7, 8, 9, 13, 14, 15, 19, 20, 21, + 4, 5, 6, 10, 11, 12, 16, 17, 18, 22, 23, 24, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(4, 2, PixelFormat::RGB888, + std::move(in_data)); + stack.push_node<ImagePipelineNodeDeinterleaveLines>(2, 1); + + ASSERT_EQ(stack.get_output_width(), 8u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 24u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB888); + + auto out_data = stack.get_all_data(); + + Data expected_data; + expected_data.resize(24, 0); + std::iota(expected_data.begin(), expected_data.end(), 1); // will fill with 1, 2, 3, ..., 20 + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_swap_16bit_endian() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x10, 0x20, 0x30, 0x11, 0x21, 0x31, + 0x12, 0x22, 0x32, 0x13, 0x23, 0x33, + 0x14, 0x24, 0x34, 0x15, 0x25, 0x35, + 0x16, 0x26, 0x36, 0x17, 0x27, 0x37, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(4, 1, PixelFormat::RGB161616, + std::move(in_data)); + stack.push_node<ImagePipelineNodeSwap16BitEndian>(); + + ASSERT_EQ(stack.get_output_width(), 4u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 24u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB161616); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + 0x20, 0x10, 0x11, 0x30, 0x31, 0x21, + 0x22, 0x12, 0x13, 0x32, 0x33, 0x23, + 0x24, 0x14, 0x15, 0x34, 0x35, 0x25, + 0x26, 0x16, 0x17, 0x36, 0x37, 0x27, + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_merge_mono_lines() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(8, 3, PixelFormat::I8, + std::move(in_data)); + stack.push_node<ImagePipelineNodeMergeMonoLines>(ColorOrder::RGB); + + ASSERT_EQ(stack.get_output_width(), 8u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 24u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB888); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + 0x10, 0x20, 0x30, 0x11, 0x21, 0x31, + 0x12, 0x22, 0x32, 0x13, 0x23, 0x33, + 0x14, 0x24, 0x34, 0x15, 0x25, 0x35, + 0x16, 0x26, 0x36, 0x17, 0x27, 0x37, + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_split_mono_lines() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x10, 0x20, 0x30, 0x11, 0x21, 0x31, + 0x12, 0x22, 0x32, 0x13, 0x23, 0x33, + 0x14, 0x24, 0x34, 0x15, 0x25, 0x35, + 0x16, 0x26, 0x36, 0x17, 0x27, 0x37, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(8, 1, PixelFormat::RGB888, + std::move(in_data)); + stack.push_node<ImagePipelineNodeSplitMonoLines>(); + + ASSERT_EQ(stack.get_output_width(), 8u); + ASSERT_EQ(stack.get_output_height(), 3u); + ASSERT_EQ(stack.get_output_row_bytes(), 8u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::I8); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_component_shift_lines() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x10, 0x20, 0x30, 0x11, 0x21, 0x31, 0x12, 0x22, 0x32, 0x13, 0x23, 0x33, + 0x14, 0x24, 0x34, 0x15, 0x25, 0x35, 0x16, 0x26, 0x36, 0x17, 0x27, 0x37, + 0x18, 0x28, 0x38, 0x19, 0x29, 0x39, 0x1a, 0x2a, 0x3a, 0x1b, 0x2b, 0x3b, + 0x1c, 0x2c, 0x3c, 0x1d, 0x2d, 0x3d, 0x1e, 0x2e, 0x3e, 0x1f, 0x2f, 0x3f, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(4, 4, PixelFormat::RGB888, + std::move(in_data)); + stack.push_node<ImagePipelineNodeComponentShiftLines>(0, 1, 2); + + ASSERT_EQ(stack.get_output_width(), 4u); + ASSERT_EQ(stack.get_output_height(), 2u); + ASSERT_EQ(stack.get_output_row_bytes(), 12u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB888); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + 0x10, 0x24, 0x38, 0x11, 0x25, 0x39, 0x12, 0x26, 0x3a, 0x13, 0x27, 0x3b, + 0x14, 0x28, 0x3c, 0x15, 0x29, 0x3d, 0x16, 0x2a, 0x3e, 0x17, 0x2b, 0x3f, + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_pixel_shift_lines() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x10, 0x20, 0x30, 0x11, 0x21, 0x31, 0x12, 0x22, 0x32, 0x13, 0x23, 0x33, + 0x14, 0x24, 0x34, 0x15, 0x25, 0x35, 0x16, 0x26, 0x36, 0x17, 0x27, 0x37, + 0x18, 0x28, 0x38, 0x19, 0x29, 0x39, 0x1a, 0x2a, 0x3a, 0x1b, 0x2b, 0x3b, + 0x1c, 0x2c, 0x3c, 0x1d, 0x2d, 0x3d, 0x1e, 0x2e, 0x3e, 0x1f, 0x2f, 0x3f, + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(4, 4, PixelFormat::RGB888, + std::move(in_data)); + stack.push_node<ImagePipelineNodePixelShiftLines>(std::vector<std::size_t>{0, 2}); + + ASSERT_EQ(stack.get_output_width(), 4u); + ASSERT_EQ(stack.get_output_height(), 2u); + ASSERT_EQ(stack.get_output_row_bytes(), 12u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB888); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + 0x10, 0x20, 0x30, 0x19, 0x29, 0x39, 0x12, 0x22, 0x32, 0x1b, 0x2b, 0x3b, + 0x14, 0x24, 0x34, 0x1d, 0x2d, 0x3d, 0x16, 0x26, 0x36, 0x1f, 0x2f, 0x3f, + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_calibrate_8bit() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x20, 0x38, 0x38 + }; + + std::vector<std::uint16_t> bottom = { + 0x1000, 0x2000, 0x3000 + }; + + std::vector<std::uint16_t> top = { + 0x3000, 0x4000, 0x5000 + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(1, 1, PixelFormat::RGB888, + std::move(in_data)); + stack.push_node<ImagePipelineNodeCalibrate>(bottom, top); + + ASSERT_EQ(stack.get_output_width(), 1u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 3u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB888); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + // note that we don't handle rounding properly in the implementation + 0x80, 0xc1, 0x41 + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_node_calibrate_16bit() +{ + using Data = std::vector<std::uint8_t>; + + Data in_data = { + 0x00, 0x20, 0x00, 0x38, 0x00, 0x38 + }; + + std::vector<std::uint16_t> bottom = { + 0x1000, 0x2000, 0x3000 + }; + + std::vector<std::uint16_t> top = { + 0x3000, 0x4000, 0x5000 + }; + + ImagePipelineStack stack; + stack.push_first_node<ImagePipelineNodeArraySource>(1, 1, PixelFormat::RGB161616, + std::move(in_data)); + stack.push_node<ImagePipelineNodeCalibrate>(bottom, top); + + ASSERT_EQ(stack.get_output_width(), 1u); + ASSERT_EQ(stack.get_output_height(), 1u); + ASSERT_EQ(stack.get_output_row_bytes(), 6u); + ASSERT_EQ(stack.get_output_format(), PixelFormat::RGB161616); + + auto out_data = stack.get_all_data(); + + Data expected_data = { + // note that we don't handle rounding properly in the implementation + 0x00, 0x80, 0xff, 0xbf, 0x00, 0x40 + }; + + ASSERT_EQ(out_data, expected_data); +} + +void test_image_pipeline() +{ + test_image_buffer_genesys_usb(); + test_image_buffer_genesys_usb_capped_remaining_bytes(); + test_node_buffered_callable_source(); + test_node_format_convert(); + test_node_desegment_1_line(); + test_node_deinterleave_lines_i8(); + test_node_deinterleave_lines_rgb888(); + test_node_swap_16bit_endian(); + test_node_merge_mono_lines(); + test_node_split_mono_lines(); + test_node_component_shift_lines(); + test_node_pixel_shift_lines(); + test_node_calibrate_8bit(); + test_node_calibrate_16bit(); +} + +} // namespace genesys diff --git a/testsuite/backend/genesys/tests_motor.cpp b/testsuite/backend/genesys/tests_motor.cpp new file mode 100644 index 0000000..07ca693 --- /dev/null +++ b/testsuite/backend/genesys/tests_motor.cpp @@ -0,0 +1,365 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "tests.h" +#include "minigtest.h" +#include "tests_printers.h" + +#include "../../../backend/genesys/low.h" +#include "../../../backend/genesys/enums.h" + +namespace genesys { + +void test_create_slope_table3() +{ + auto asic_type = AsicType::GL841; + auto max_table_size = get_slope_table_max_size(asic_type); + + Genesys_Motor motor; + motor.id = MotorId::CANON_LIDE_200; + motor.base_ydpi = 1200; + motor.optical_ydpi = 6400; + motor.slopes.push_back(MotorSlope::create_from_steps(10000, 1000, 20)); + motor.slopes.push_back(MotorSlope::create_from_steps(10000, 1000, 20)); + motor.slopes.push_back(MotorSlope::create_from_steps(10000, 1000, 16)); + + auto table = sanei_genesys_create_slope_table3(asic_type, motor, StepType::FULL, 10000, + motor.base_ydpi); + + ASSERT_EQ(table.pixeltime_sum, 10000u); + ASSERT_EQ(table.steps_count, 1u); + + std::vector<std::uint16_t> expected_steps = { + 10000, + }; + expected_steps.resize(max_table_size, 10000); + + ASSERT_EQ(table.table, expected_steps); + + table = sanei_genesys_create_slope_table3(asic_type, motor, StepType::FULL, 2000, + motor.base_ydpi); + + ASSERT_EQ(table.pixeltime_sum, 33830u); + ASSERT_EQ(table.steps_count, 7u); + + expected_steps = { + 10000, 10000, 4099, 3028, 2511, 2192, 2000 + }; + expected_steps.resize(max_table_size, 2000); + + ASSERT_EQ(table.table, expected_steps); + + table = sanei_genesys_create_slope_table3(asic_type, motor, StepType::HALF, 10000, + motor.base_ydpi); + + ASSERT_EQ(table.pixeltime_sum, 5000u); + ASSERT_EQ(table.steps_count, 1u); + + expected_steps = { + 5000, + }; + expected_steps.resize(max_table_size, 5000); + + + ASSERT_EQ(table.table, expected_steps); + + table = sanei_genesys_create_slope_table3(asic_type, motor, StepType::HALF, 2000, + motor.base_ydpi); + + ASSERT_EQ(table.pixeltime_sum, 16914u); + ASSERT_EQ(table.steps_count, 7u); + + expected_steps = { + 5000, 5000, 2049, 1514, 1255, 1096, 1000 + }; + expected_steps.resize(max_table_size, 1000); + + ASSERT_EQ(table.table, expected_steps); + + table = sanei_genesys_create_slope_table3(asic_type, motor, StepType::QUARTER, 10000, + motor.base_ydpi); + + ASSERT_EQ(table.pixeltime_sum, 2500u); + ASSERT_EQ(table.steps_count, 1u); + + expected_steps = { + 2500, + }; + expected_steps.resize(max_table_size, 2500); + + + ASSERT_EQ(table.table, expected_steps); + + table = sanei_genesys_create_slope_table3(asic_type, motor, StepType::QUARTER, 2000, + motor.base_ydpi); + + ASSERT_EQ(table.pixeltime_sum, 7680u); + ASSERT_EQ(table.steps_count, 6u); + + expected_steps = { + 2500, 2500, 932, 683, 565, 500 + }; + expected_steps.resize(max_table_size, 500); + + ASSERT_EQ(table.table, expected_steps); +} + +void test_create_slope_table_small_full_step() +{ + unsigned max_table_size = 1024; + + // created approximately from LIDE 110 slow table: { 62464, 7896, 2632, 0 } + MotorSlope slope; + slope.initial_speed_w = 62464; + slope.max_speed_w = 2632; + slope.acceleration = 1.2e-8; + + auto table = create_slope_table(slope, 5000, StepType::FULL, 4, 8, max_table_size); + + std::vector<std::uint16_t> expected_table = { + 62464, 62464, 6420, 5000 + }; + expected_table.resize(max_table_size, 5000); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 8u); + ASSERT_EQ(table.pixeltime_sum, 156348u); + + + table = create_slope_table(slope, 3000, StepType::FULL, 4, 8, max_table_size); + + expected_table = { + 62464, 62464, 6420, 4552, 3720, 3223, 3000 + }; + expected_table.resize(max_table_size, 3000); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 8u); + ASSERT_EQ(table.pixeltime_sum, 148843u); +} + +void test_create_slope_table_small_full_step_target_speed_too_high() +{ + unsigned max_table_size = 1024; + + // created approximately from LIDE 110 slow table: { 62464, 7896, 2632, 0 } + MotorSlope slope; + slope.initial_speed_w = 62464; + slope.max_speed_w = 2632; + slope.acceleration = 1.2e-8; + + auto table = create_slope_table(slope, 2000, StepType::FULL, 4, 8, max_table_size); + + std::vector<std::uint16_t> expected_table = { + 62464, 62464, 6420, 4552, 3720, 3223, 2883, 2632 + }; + expected_table.resize(max_table_size, 2632); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 8u); + ASSERT_EQ(table.pixeltime_sum, 148358u); +} + +void test_create_slope_table_small_half_step() +{ + unsigned max_table_size = 1024; + + // created approximately from LIDE 110 slow table: { 62464, 7896, 2632, 0 } + MotorSlope slope; + slope.initial_speed_w = 62464; + slope.max_speed_w = 2632; + slope.acceleration = 1.2e-8; + + auto table = create_slope_table(slope, 5000, StepType::HALF, 4, 8, max_table_size); + + std::vector<std::uint16_t> expected_table = { + 31232, 31232, 3210, 2500 + }; + expected_table.resize(max_table_size, 2500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 8u); + ASSERT_EQ(table.pixeltime_sum, 78174u); + + + table = create_slope_table(slope, 3000, StepType::HALF, 4, 8, max_table_size); + + expected_table = { + 31232, 31232, 3210, 2276, 1860, 1611, 1500 + }; + expected_table.resize(max_table_size, 1500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 8u); + ASSERT_EQ(table.pixeltime_sum, 74421u); +} + +void test_create_slope_table_large_full_step() +{ + unsigned max_table_size = 1024; + + /* created approximately from Canon 8600F table: + 54612, 54612, 34604, 26280, 21708, 18688, 16564, 14936, 13652, 12616, + 11768, 11024, 10400, 9872, 9392, 8960, 8584, 8240, 7940, 7648, + 7404, 7160, 6948, 6732, 6544, 6376, 6208, 6056, 5912, 5776, + 5644, 5520, 5408, 5292, 5192, 5092, 5000, 4908, 4820, 4736, + 4660, 4580, 4508, 4440, 4368, 4304, 4240, 4184, 4124, 4068, + 4012, 3960, 3908, 3860, 3808, 3764, 3720, 3676, 3636, 3592, + 3552, 3516, 3476, 3440, 3400, 3368, 3332, 3300, 3268, 3236, + 3204, 3176, 3148, 3116, 3088, 3060, 3036, 3008, 2984, 2956, + 2932, 2908, 2884, 2860, 2836, 2816, 2796, 2772, 2752, 2732, + 2708, 2692, 2672, 2652, 2632, 2616, 2596, 2576, 2560, 2544, + 2528, 2508, 2492, 2476, 2460, 2444, 2432, 2416, 2400, 2384, + 2372, 2356, 2344, 2328, 2316, 2304, 2288, 2276, 2260, 2252, + 2236, 2224, 2212, 2200, 2188, 2176, 2164, 2156, 2144, 2132, + 2120, 2108, 2100, 2088, 2080, 2068, 2056, 2048, 2036, 2028, + 2020, 2008, 2000, 1988, 1980, 1972, 1964, 1952, 1944, 1936, + 1928, 1920, 1912, 1900, 1892, 1884, 1876, 1868, 1860, 1856, + 1848, 1840, 1832, 1824, 1816, 1808, 1800, 1796, 1788, 1780, + 1772, 1764, 1760, 1752, 1744, 1740, 1732, 1724, 1720, 1712, + 1708, 1700, 1692, 1688, 1680, 1676, 1668, 1664, 1656, 1652, + 1644, 1640, 1636, 1628, 1624, 1616, 1612, 1608, 1600, 1596, + 1592, 1584, 1580, 1576, 1568, 1564, 1560, 1556, 1548, 1544, + 1540, 1536, 1528, 1524, 1520, 1516, 1512, 1508, 1500, + */ + MotorSlope slope; + slope.initial_speed_w = 54612; + slope.max_speed_w = 1500; + slope.acceleration = 1.013948e-9; + + auto table = create_slope_table(slope, 3000, StepType::FULL, 4, 8, max_table_size); + + std::vector<std::uint16_t> expected_table = { + 54612, 54612, 20570, 15090, 12481, 10880, 9770, 8943, 8295, 7771, + 7335, 6964, 6645, 6366, 6120, 5900, 5702, 5523, 5359, 5210, + 5072, 4945, 4826, 4716, 4613, 4517, 4426, 4341, 4260, 4184, + 4111, 4043, 3977, 3915, 3855, 3799, 3744, 3692, 3642, 3594, + 3548, 3503, 3461, 3419, 3379, 3341, 3304, 3268, 3233, 3199, + 3166, 3135, 3104, 3074, 3045, 3017, 3000, + }; + expected_table.resize(max_table_size, 3000); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 60u); + ASSERT_EQ(table.pixeltime_sum, 412616u); + + + table = create_slope_table(slope, 1500, StepType::FULL, 4, 8, max_table_size); + + expected_table = { + 54612, 54612, 20570, 15090, 12481, 10880, 9770, 8943, 8295, 7771, + 7335, 6964, 6645, 6366, 6120, 5900, 5702, 5523, 5359, 5210, + 5072, 4945, 4826, 4716, 4613, 4517, 4426, 4341, 4260, 4184, + 4111, 4043, 3977, 3915, 3855, 3799, 3744, 3692, 3642, 3594, + 3548, 3503, 3461, 3419, 3379, 3341, 3304, 3268, 3233, 3199, + 3166, 3135, 3104, 3074, 3045, 3017, 2989, 2963, 2937, 2911, + 2886, 2862, 2839, 2816, 2794, 2772, 2750, 2729, 2709, 2689, + 2670, 2651, 2632, 2614, 2596, 2578, 2561, 2544, 2527, 2511, + 2495, 2480, 2464, 2449, 2435, 2420, 2406, 2392, 2378, 2364, + 2351, 2338, 2325, 2313, 2300, 2288, 2276, 2264, 2252, 2241, + 2229, 2218, 2207, 2196, 2186, 2175, 2165, 2155, 2145, 2135, + 2125, 2115, 2106, 2096, 2087, 2078, 2069, 2060, 2051, 2042, + 2034, 2025, 2017, 2009, 2000, 1992, 1984, 1977, 1969, 1961, + 1953, 1946, 1938, 1931, 1924, 1917, 1910, 1903, 1896, 1889, + 1882, 1875, 1869, 1862, 1855, 1849, 1843, 1836, 1830, 1824, + 1818, 1812, 1806, 1800, 1794, 1788, 1782, 1776, 1771, 1765, + 1760, 1754, 1749, 1743, 1738, 1733, 1727, 1722, 1717, 1712, + 1707, 1702, 1697, 1692, 1687, 1682, 1677, 1673, 1668, 1663, + 1659, 1654, 1649, 1645, 1640, 1636, 1631, 1627, 1623, 1618, + 1614, 1610, 1606, 1601, 1597, 1593, 1589, 1585, 1581, 1577, + 1573, 1569, 1565, 1561, 1557, 1554, 1550, 1546, 1542, 1539, + 1535, 1531, 1528, 1524, 1520, 1517, 1513, 1510, 1506, 1503, + 1500, + }; + expected_table.resize(max_table_size, 1500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 224u); + ASSERT_EQ(table.pixeltime_sum, 734910u); +} + +void test_create_slope_table_large_half_step() +{ + unsigned max_table_size = 1024; + + // created approximately from Canon 8600F table, see the full step test for the data + + MotorSlope slope; + slope.initial_speed_w = 54612; + slope.max_speed_w = 1500; + slope.acceleration = 1.013948e-9; + + auto table = create_slope_table(slope, 3000, StepType::HALF, 4, 8, max_table_size); + + std::vector<std::uint16_t> expected_table = { + 27306, 27306, 10285, 7545, 6240, 5440, 4885, 4471, 4147, 3885, + 3667, 3482, 3322, 3183, 3060, 2950, 2851, 2761, 2679, 2605, + 2536, 2472, 2413, 2358, 2306, 2258, 2213, 2170, 2130, 2092, + 2055, 2021, 1988, 1957, 1927, 1899, 1872, 1846, 1821, 1797, + 1774, 1751, 1730, 1709, 1689, 1670, 1652, 1634, 1616, 1599, + 1583, 1567, 1552, 1537, 1522, 1508, 1500, + }; + expected_table.resize(max_table_size, 1500); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 60u); + ASSERT_EQ(table.pixeltime_sum, 206294u); + + + table = create_slope_table(slope, 1500, StepType::HALF, 4, 8, max_table_size); + + expected_table = { + 27306, 27306, 10285, 7545, 6240, 5440, 4885, 4471, 4147, 3885, + 3667, 3482, 3322, 3183, 3060, 2950, 2851, 2761, 2679, 2605, + 2536, 2472, 2413, 2358, 2306, 2258, 2213, 2170, 2130, 2092, + 2055, 2021, 1988, 1957, 1927, 1899, 1872, 1846, 1821, 1797, + 1774, 1751, 1730, 1709, 1689, 1670, 1652, 1634, 1616, 1599, + 1583, 1567, 1552, 1537, 1522, 1508, 1494, 1481, 1468, 1455, + 1443, 1431, 1419, 1408, 1397, 1386, 1375, 1364, 1354, 1344, + 1335, 1325, 1316, 1307, 1298, 1289, 1280, 1272, 1263, 1255, + 1247, 1240, 1232, 1224, 1217, 1210, 1203, 1196, 1189, 1182, + 1175, 1169, 1162, 1156, 1150, 1144, 1138, 1132, 1126, 1120, + 1114, 1109, 1103, 1098, 1093, 1087, 1082, 1077, 1072, 1067, + 1062, 1057, 1053, 1048, 1043, 1039, 1034, 1030, 1025, 1021, + 1017, 1012, 1008, 1004, 1000, 996, 992, 988, 984, 980, + 976, 973, 969, 965, 962, 958, 955, 951, 948, 944, + 941, 937, 934, 931, 927, 924, 921, 918, 915, 912, + 909, 906, 903, 900, 897, 894, 891, 888, 885, 882, + 880, 877, 874, 871, 869, 866, 863, 861, 858, 856, + 853, 851, 848, 846, 843, 841, 838, 836, 834, 831, + 829, 827, 824, 822, 820, 818, 815, 813, 811, 809, + 807, 805, 803, 800, 798, 796, 794, 792, 790, 788, + 786, 784, 782, 780, 778, 777, 775, 773, 771, 769, + 767, 765, 764, 762, 760, 758, 756, 755, 753, 751, + 750, + }; + expected_table.resize(max_table_size, 750); + ASSERT_EQ(table.table, expected_table); + ASSERT_EQ(table.steps_count, 224u); + ASSERT_EQ(table.pixeltime_sum, 367399u); +} + +void test_motor() +{ + test_create_slope_table3(); + test_create_slope_table_small_full_step(); + test_create_slope_table_small_full_step_target_speed_too_high(); + test_create_slope_table_small_half_step(); + test_create_slope_table_large_full_step(); + test_create_slope_table_large_half_step(); +} + +} // namespace genesys diff --git a/testsuite/backend/genesys/tests_printers.h b/testsuite/backend/genesys/tests_printers.h new file mode 100644 index 0000000..90becea --- /dev/null +++ b/testsuite/backend/genesys/tests_printers.h @@ -0,0 +1,62 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#ifndef SANE_TESTSUITE_BACKEND_GENESYS_TESTS_PRINTERS_H +#define SANE_TESTSUITE_BACKEND_GENESYS_TESTS_PRINTERS_H + +#include "../../../backend/genesys/image_pixel.h" +#include "../../../backend/genesys/utilities.h" +#include <iostream> +#include <iomanip> +#include <vector> + +template<class T> +std::ostream& operator<<(std::ostream& str, const std::vector<T>& arg) +{ + str << genesys::format_vector_unsigned(4, arg) << '\n'; + return str; +} + +inline std::ostream& operator<<(std::ostream& str, const genesys::PixelFormat& arg) +{ + str << static_cast<unsigned>(arg); + return str; +} + +inline std::ostream& operator<<(std::ostream& str, const genesys::Pixel& arg) +{ + str << "{ " << arg.r << ", " << arg.g << ", " << arg.b << " }"; + return str; +} + +inline std::ostream& operator<<(std::ostream& str, const genesys::RawPixel& arg) +{ + auto flags = str.flags(); + str << std::hex; + for (auto el : arg.data) { + str << static_cast<unsigned>(el) << " "; + } + str.flags(flags); + return str; +} + +#endif diff --git a/testsuite/backend/genesys/tests_row_buffer.cpp b/testsuite/backend/genesys/tests_row_buffer.cpp new file mode 100644 index 0000000..73ca86c --- /dev/null +++ b/testsuite/backend/genesys/tests_row_buffer.cpp @@ -0,0 +1,91 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "tests.h" +#include "minigtest.h" +#include "tests_printers.h" + +#include "../../../backend/genesys/low.h" + +#include <numeric> + +namespace genesys { + +void test_row_buffer_push_pop_forward(unsigned size) +{ + RowBuffer buf{1}; + + ASSERT_TRUE(buf.empty()); + for (unsigned i = 0; i < size; i++) { + buf.push_back(); + *buf.get_back_row_ptr() = i; + for (unsigned j = 0; j < i + 1; j++) { + ASSERT_EQ(*buf.get_row_ptr(j), j); + } + } + ASSERT_FALSE(buf.empty()); + + for (unsigned i = 0; i < 10; i++) { + ASSERT_EQ(buf.height(), size); + ASSERT_EQ(static_cast<unsigned>(*buf.get_front_row_ptr()), i); + buf.pop_front(); + ASSERT_EQ(buf.height(), size - 1); + buf.push_back(); + *buf.get_back_row_ptr() = i + size; + } +} + +void test_row_buffer_push_pop_backward(unsigned size) +{ + RowBuffer buf{1}; + + ASSERT_TRUE(buf.empty()); + for (unsigned i = 0; i < size; i++) { + buf.push_front(); + *buf.get_front_row_ptr() = i; + for (unsigned j = 0; j < i + 1; j++) { + ASSERT_EQ(*buf.get_row_ptr(j), i - j); + } + } + ASSERT_FALSE(buf.empty()); + + for (unsigned i = 0; i < 10; i++) { + ASSERT_EQ(buf.height(), size); + ASSERT_EQ(static_cast<unsigned>(*buf.get_back_row_ptr()), i); + buf.pop_back(); + ASSERT_EQ(buf.height(), size - 1); + buf.push_front(); + *buf.get_front_row_ptr() = i + size; + } +} + +void test_row_buffer() +{ + for (unsigned size = 1; size < 5; ++size) { + test_row_buffer_push_pop_forward(size); + test_row_buffer_push_pop_backward(size); + } +} + +} // namespace genesys diff --git a/testsuite/backend/genesys/tests_utilities.cpp b/testsuite/backend/genesys/tests_utilities.cpp new file mode 100644 index 0000000..49b9abe --- /dev/null +++ b/testsuite/backend/genesys/tests_utilities.cpp @@ -0,0 +1,110 @@ +/* sane - Scanner Access Now Easy. + + Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. +*/ + +#define DEBUG_DECLARE_ONLY + +#include "tests.h" +#include "minigtest.h" +#include "tests_printers.h" + +#include "../../../backend/genesys/utilities.h" + +namespace genesys { + +void test_utilities_compute_array_percentile_approx_empty() +{ + std::vector<std::uint16_t> data; + data.resize(1, 0); + + ASSERT_RAISES(compute_array_percentile_approx(data.data(), data.data(), 0, 0, 0.0f), + SaneException); +} + +void test_utilities_compute_array_percentile_approx_single_line() +{ + std::vector<std::uint16_t> data = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + std::vector<std::uint16_t> expected = data; + std::vector<std::uint16_t> result; + result.resize(data.size(), 0); + + compute_array_percentile_approx(result.data(), data.data(), 1, data.size(), 0.5f); + ASSERT_EQ(result, expected); +} + +void test_utilities_compute_array_percentile_approx_multiple_lines() +{ + std::vector<std::uint16_t> data = { + 5, 17, 4, 14, 3, 9, 9, 5, 10, 1, + 6, 1, 0, 18, 8, 5, 11, 11, 15, 12, + 6, 8, 7, 3, 2, 15, 5, 12, 3, 3, + 6, 12, 17, 6, 7, 7, 1, 6, 3, 18, + 10, 5, 8, 0, 14, 3, 3, 7, 10, 5, + 18, 7, 3, 11, 0, 14, 12, 19, 18, 11, + 5, 16, 2, 9, 8, 2, 7, 6, 11, 18, + 16, 5, 2, 2, 14, 18, 19, 13, 16, 1, + 5, 9, 14, 6, 17, 16, 1, 1, 16, 0, + 19, 18, 4, 12, 0, 7, 15, 3, 2, 6, + }; + std::vector<std::uint16_t> result; + result.resize(10, 0); + + std::vector<std::uint16_t> expected = { + 5, 1, 0, 0, 0, 2, 1, 1, 2, 0, + }; + compute_array_percentile_approx(result.data(), data.data(), 10, 10, 0.0f); + ASSERT_EQ(result, expected); + + expected = { + 5, 5, 2, 3, 2, 5, 3, 5, 3, 1, + }; + compute_array_percentile_approx(result.data(), data.data(), 10, 10, 0.25f); + ASSERT_EQ(result, expected); + + expected = { + 6, 9, 4, 9, 8, 9, 9, 7, 11, 6, + }; + compute_array_percentile_approx(result.data(), data.data(), 10, 10, 0.5f); + ASSERT_EQ(result, expected); + + expected = { + 16, 16, 8, 12, 14, 15, 12, 12, 16, 12, + }; + compute_array_percentile_approx(result.data(), data.data(), 10, 10, 0.75f); + ASSERT_EQ(result, expected); + + expected = { + 19, 18, 17, 18, 17, 18, 19, 19, 18, 18, + }; + compute_array_percentile_approx(result.data(), data.data(), 10, 10, 1.0f); + ASSERT_EQ(result, expected); +} + +void test_utilities() +{ + test_utilities_compute_array_percentile_approx_empty(); + test_utilities_compute_array_percentile_approx_single_line(); + test_utilities_compute_array_percentile_approx_multiple_lines(); +} + +} // namespace genesys diff --git a/testsuite/sanei/Makefile.am b/testsuite/sanei/Makefile.am index 24fc01e..8da530c 100644 --- a/testsuite/sanei/Makefile.am +++ b/testsuite/sanei/Makefile.am @@ -10,12 +10,14 @@ EXTRA_DIST = data/boolean.conf data/empty.conf data/fixed.conf data/int.conf \ data/wrong-fixed.conf data/wrong-range.conf \ data/wrong-string-list.conf -TEST_LDADD = ../../sanei/libsanei.la ../../lib/liblib.la $(MATH_LIB) $(USB_LIBS) $(PTHREAD_LIBS) +TEST_LDADD = ../../sanei/libsanei.la ../../lib/liblib.la \ + $(MATH_LIB) $(USB_LIBS) $(XML_LIBS) $(PTHREAD_LIBS) check_PROGRAMS = sanei_usb_test test_wire sanei_check_test sanei_config_test sanei_constrain_test TESTS = $(check_PROGRAMS) -AM_CPPFLAGS += -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include $(USB_CFLAGS) +AM_CPPFLAGS += -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include \ + $(USB_CFLAGS) $(XML_CFLAGS) sanei_constrain_test_SOURCES = sanei_constrain_test.c sanei_constrain_test_LDADD = $(TEST_LDADD) diff --git a/testsuite/tools/data/ascii.ref b/testsuite/tools/data/ascii.ref index 4d66732..20c2bf2 100644 --- a/testsuite/tools/data/ascii.ref +++ b/testsuite/tools/data/ascii.ref @@ -5709,7 +5709,7 @@ backend `genesys' status basic url *none* comment `clone of the HP 2400C' - model `ScanJet 3670C' + model `ScanJet 3670' interface `USB' usb-vendor-id `0x03f0' usb-product-id `0x1405' @@ -5722,7 +5722,7 @@ backend `genesys' usb-product-id `0x1405' status complete url *none* - comment `1200x1200 dpi max, same as HP 3670C' + comment `1200x1200 dpi max, same as HP 3670' model `ScanJet 4850C' interface `USB' usb-vendor-id `0x03f0' diff --git a/testsuite/tools/data/db.ref b/testsuite/tools/data/db.ref index d51729a..3828667 100644 --- a/testsuite/tools/data/db.ref +++ b/testsuite/tools/data/db.ref @@ -66,7 +66,7 @@ 0x03f0 0x1205 root:scanner 0664 # Hewlett-Packard ScanJet 4570C | Hewlett-Packard ScanJet 5500C 0x03f0 0x1305 root:scanner 0664 -# Hewlett-Packard ScanJet 3670C | Hewlett-Packard ScanJet 3690C +# Hewlett-Packard ScanJet 3670 | Hewlett-Packard ScanJet 3690C 0x03f0 0x1405 root:scanner 0664 # Hewlett-Packard ScanJet 5590 0x03f0 0x1705 root:scanner 0664 diff --git a/testsuite/tools/data/hal-new.ref b/testsuite/tools/data/hal-new.ref index c9b7f80..fc48a71 100644 --- a/testsuite/tools/data/hal-new.ref +++ b/testsuite/tools/data/hal-new.ref @@ -175,7 +175,7 @@ <append key="info.capabilities" type="strlist">scanner</append> <merge key="scanner.access_method" type="string">proprietary</merge> </match> - <!-- Hewlett-Packard ScanJet 3670C | Hewlett-Packard ScanJet 3690C --> + <!-- Hewlett-Packard ScanJet 3670 | Hewlett-Packard ScanJet 3690C --> <match key="usb.product_id" int="0x1405"> <append key="info.capabilities" type="strlist">scanner</append> <merge key="scanner.access_method" type="string">proprietary</merge> diff --git a/testsuite/tools/data/hal.ref b/testsuite/tools/data/hal.ref index 18490f2..68ef92a 100644 --- a/testsuite/tools/data/hal.ref +++ b/testsuite/tools/data/hal.ref @@ -175,7 +175,7 @@ <append key="info.capabilities" type="strlist">scanner</append> <merge key="scanner.access_method" type="string">proprietary</merge> </match> - <!-- Hewlett-Packard ScanJet 3670C | Hewlett-Packard ScanJet 3690C --> + <!-- Hewlett-Packard ScanJet 3670 | Hewlett-Packard ScanJet 3690C --> <match key="usb.product_id" int="0x1405"> <append key="info.capabilities" type="strlist">scanner</append> <merge key="scanner.access_method" type="string">proprietary</merge> diff --git a/testsuite/tools/data/html-backends-split.ref b/testsuite/tools/data/html-backends-split.ref index 3455e20..bd8d154 100644 --- a/testsuite/tools/data/html-backends-split.ref +++ b/testsuite/tools/data/html-backends-split.ref @@ -5991,7 +5991,7 @@ Kyocera <td>clone of the HP 2400C</td> </tr> <tr> -<td align=center>ScanJet 3670C</td> +<td align=center>ScanJet 3670</td> <td align=center>USB</td> <td align=center>0x03f0/0x1405</td> <td align=center><font color="#007000">Complete</font></td> @@ -6002,7 +6002,7 @@ Kyocera <td align=center>USB</td> <td align=center>0x03f0/0x1405</td> <td align=center><font color="#007000">Complete</font></td> -<td>1200x1200 dpi max, same as HP 3670C</td> +<td>1200x1200 dpi max, same as HP 3670</td> </tr> <tr> <td align=center>ScanJet 4850C</td> diff --git a/testsuite/tools/data/html-mfgs.ref b/testsuite/tools/data/html-mfgs.ref index f82b30c..1b34bb4 100644 --- a/testsuite/tools/data/html-mfgs.ref +++ b/testsuite/tools/data/html-mfgs.ref @@ -12078,7 +12078,7 @@ hpljm1005<br>(0) </td> <td align=center><a href="man/sane-hp3500.5.html">sane-hp3500</a></td> </tr> -<tr><td align=center>ScanJet 3670C</td> +<tr><td align=center>ScanJet 3670</td> <td align=center>USB</td> <td align=center>0x03f0/0x1405</td> <td align=center><font color="#007000">Complete</font></td> @@ -12093,7 +12093,7 @@ hpljm1005<br>(0) <td align=center>USB</td> <td align=center>0x03f0/0x1405</td> <td align=center><font color="#007000">Complete</font></td> -<td>1200x1200 dpi max, same as HP 3670C</td> +<td>1200x1200 dpi max, same as HP 3670</td> <td align=center> <a href="http://www.meier-geinitz.de/sane/genesys-backend/">genesys</a> <br>(1.0-63) diff --git a/testsuite/tools/data/hwdb.ref b/testsuite/tools/data/hwdb.ref index 7d029e0..9adc73f 100644 --- a/testsuite/tools/data/hwdb.ref +++ b/testsuite/tools/data/hwdb.ref @@ -97,7 +97,7 @@ usb:v03F0p1205* usb:v03F0p1305* libsane_matched=yes -# Hewlett-Packard ScanJet 3670C | Hewlett-Packard ScanJet 3690C +# Hewlett-Packard ScanJet 3670 | Hewlett-Packard ScanJet 3690C usb:v03F0p1405* libsane_matched=yes diff --git a/testsuite/tools/data/testfile.desc b/testsuite/tools/data/testfile.desc index e59aed3..bae4099 100644 --- a/testsuite/tools/data/testfile.desc +++ b/testsuite/tools/data/testfile.desc @@ -4894,7 +4894,7 @@ :status :basic :comment "clone of the HP 2400C" -:model "ScanJet 3670C" +:model "ScanJet 3670" :interface "USB" :usbid "0x03f0" "0x1405" :status :complete @@ -4904,7 +4904,7 @@ :interface "USB" :usbid "0x03f0" "0x1405" :status :complete -:comment "1200x1200 dpi max, same as HP 3670C" +:comment "1200x1200 dpi max, same as HP 3670" :model "ScanJet 4850C" :interface "USB" diff --git a/testsuite/tools/data/udev+acl.ref b/testsuite/tools/data/udev+acl.ref index 4721034..bcedd50 100644 --- a/testsuite/tools/data/udev+acl.ref +++ b/testsuite/tools/data/udev+acl.ref @@ -81,7 +81,7 @@ ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1105", ENV{libsane_matched}="yes" ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1205", ENV{libsane_matched}="yes" # Hewlett-Packard ScanJet 4570C | Hewlett-Packard ScanJet 5500C ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1305", ENV{libsane_matched}="yes" -# Hewlett-Packard ScanJet 3670C | Hewlett-Packard ScanJet 3690C +# Hewlett-Packard ScanJet 3670 | Hewlett-Packard ScanJet 3690C ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1405", ENV{libsane_matched}="yes" # Hewlett-Packard ScanJet 5590 ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1705", ENV{libsane_matched}="yes" diff --git a/testsuite/tools/data/udev.ref b/testsuite/tools/data/udev.ref index 9a221fc..bd448af 100644 --- a/testsuite/tools/data/udev.ref +++ b/testsuite/tools/data/udev.ref @@ -81,7 +81,7 @@ ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1105", MODE="0664", GROUP="scanner", ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1205", MODE="0664", GROUP="scanner", ENV{libsane_matched}="yes" # Hewlett-Packard ScanJet 4570C | Hewlett-Packard ScanJet 5500C ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1305", MODE="0664", GROUP="scanner", ENV{libsane_matched}="yes" -# Hewlett-Packard ScanJet 3670C | Hewlett-Packard ScanJet 3690C +# Hewlett-Packard ScanJet 3670 | Hewlett-Packard ScanJet 3690C ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1405", MODE="0664", GROUP="scanner", ENV{libsane_matched}="yes" # Hewlett-Packard ScanJet 5590 ATTRS{idVendor}=="03f0", ATTRS{idProduct}=="1705", MODE="0664", GROUP="scanner", ENV{libsane_matched}="yes" diff --git a/testsuite/tools/data/usermap.ref b/testsuite/tools/data/usermap.ref index e02d73a..b1d5a9f 100644 --- a/testsuite/tools/data/usermap.ref +++ b/testsuite/tools/data/usermap.ref @@ -64,7 +64,7 @@ libusbscanner 0x0003 0x03f0 0x1105 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0 libusbscanner 0x0003 0x03f0 0x1205 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # Hewlett-Packard ScanJet 4570C | Hewlett-Packard ScanJet 5500C libusbscanner 0x0003 0x03f0 0x1305 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 -# Hewlett-Packard ScanJet 3670C | Hewlett-Packard ScanJet 3690C +# Hewlett-Packard ScanJet 3670 | Hewlett-Packard ScanJet 3690C libusbscanner 0x0003 0x03f0 0x1405 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # Hewlett-Packard ScanJet 5590 libusbscanner 0x0003 0x03f0 0x1705 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 diff --git a/testsuite/tools/data/xml.ref b/testsuite/tools/data/xml.ref index 0618093..3c5b861 100644 --- a/testsuite/tools/data/xml.ref +++ b/testsuite/tools/data/xml.ref @@ -6609,7 +6609,7 @@ <url>*none*</url> <comment>clone of the HP 2400C</comment> </model> - <model name="ScanJet 3670C"> + <model name="ScanJet 3670"> <interface>USB</interface> <usbvendorid>0x03f0</usbvendorid> <usbproductid>0x1405</usbproductid> @@ -6623,7 +6623,7 @@ <usbproductid>0x1405</usbproductid> <status>complete</status> <url>*none*</url> - <comment>1200x1200 dpi max, same as HP 3670C</comment> + <comment>1200x1200 dpi max, same as HP 3670</comment> </model> <model name="ScanJet 4850C"> <interface>USB</interface> diff --git a/tools/Makefile.am b/tools/Makefile.am index 684815a..105d178 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -42,15 +42,15 @@ if have_usblib sane_find_scanner_SOURCES += check-usb-chip.c endif sane_find_scanner_LDADD = ../sanei/libsanei.la ../lib/liblib.la \ - $(USB_LIBS) $(IEEE1284_LIBS) $(SCSI_LIBS) \ + $(USB_LIBS) $(IEEE1284_LIBS) $(SCSI_LIBS) $(XML_LIBS) \ ../backend/sane_strstatus.lo gamma4scanimage_SOURCES = gamma4scanimage.c gamma4scanimage_LDADD = $(MATH_LIB) -umax_pp_SOURCES = umax_pp.c -umax_pp_LDADD = ../sanei/libsanei.la ../lib/liblib.la $(MATH_LIB) \ - ../backend/umax_pp_low.lo +umax_pp_SOURCES = umax_pp.c +umax_pp_SOURCES += ../backend/umax_pp_low.c +umax_pp_LDADD = ../sanei/libsanei.la ../lib/liblib.la $(MATH_LIB) sane_desc_SOURCES = sane-desc.c sane_desc_LDADD = ../sanei/libsanei.la ../lib/liblib.la diff --git a/tools/create-changelog.sh b/tools/create-changelog.sh index a0b8d91..bb3c8f2 100755 --- a/tools/create-changelog.sh +++ b/tools/create-changelog.sh @@ -4,7 +4,7 @@ # # License: GPL-3.0+ -git log --date=iso8601 --decorate=short 1.0.27..HEAD \ +git log --date=iso8601 --decorate=short 1.0.28..HEAD \ | sed 's/^[ \t]*$//' \ > ChangeLog @@ -12,5 +12,5 @@ cat << EOF >> ChangeLog ---------------------------------------------------------------------- Older ChangeLog entries can be found in the ChangeLogs/ directory on a -file per release basis. Please note that 1.0.26 was never released. +file per release basis. Please note that version 1.0.26 was skipped. EOF diff --git a/tools/sane-find-scanner.c b/tools/sane-find-scanner.c index a62ceac..ac25c55 100644 --- a/tools/sane-find-scanner.c +++ b/tools/sane-find-scanner.c @@ -1611,7 +1611,7 @@ main (int argc, char **argv) usage (0); exit (0); } - + // fall through default: printf ("unknown option: -%c, try -h for help\n", (*ap)[1]); exit (0); @@ -2009,7 +2009,12 @@ main (int argc, char **argv) } if (verbose > 3) +#if LIBUSB_API_VERSION >= 0x01000106 + libusb_set_option (sfs_usb_ctx, LIBUSB_OPTION_LOG_LEVEL, + LIBUSB_LOG_LEVEL_INFO); +#else libusb_set_debug (sfs_usb_ctx, 3); +#endif devcnt = libusb_get_device_list (sfs_usb_ctx, &devlist); if (devcnt < 0) diff --git a/tools/umax_pp.c b/tools/umax_pp.c index 7b127e3..eabf900 100644 --- a/tools/umax_pp.c +++ b/tools/umax_pp.c @@ -32,7 +32,7 @@ main (int argc, char **argv) char dbgstr[80]; int probe = 0; int port = 0; - char *name = NULL; + const char *name = NULL; int scan = 0; int lamp = -1; int i; diff --git a/tools/update-upstreams.sh b/tools/update-upstreams.sh index 3fde735..3a5e94a 100755 --- a/tools/update-upstreams.sh +++ b/tools/update-upstreams.sh @@ -6,11 +6,11 @@ fetch () { if type curl 2>/dev/null >/dev/null ; then - curl --silent --location --remote-name $1 + curl --location --remote-name $1 return fi if type wget 2>/dev/null >/dev/null ; then - wget --quiet --output-document $(echo $1 | sed 's,.*/,,') $1 + wget --output-document $(echo $1 | sed 's,.*/,,') $1 fi } |