Skip to content

Commit

Permalink
Fix scanimage -A parsing with [advanced]
Browse files Browse the repository at this point in the history
Issue #564

There are cases where `scanimage -A` outputs an additional square bracketed item on a parameter line such as:

```
    --contrast -127..127 [0] [advanced]
```

The old regex only assumed this happened once - which was good enough for 6 years or so. It seems that it can happen twice.

The regex has been updated to have a non-greedy match for the first one (`default`) and there is a subsequent optional non-capturing group for the second, which for want of a better name is referred here as `meta`.

It turns out that this pattern has been seen before with `[read-only]` but that was benign since it was treated as a default to ignore. For that reason, the `enabled` flag has to be altered too.

Associated unit test added.
  • Loading branch information
sbs20 committed Feb 18, 2023
1 parent a9f775d commit 436a164
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 5 deletions.
8 changes: 3 additions & 5 deletions packages/server/src/classes/feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ module.exports = class Feature {
this.load();
}

get enabled() {
return !['inactive', 'read-only'].includes(this.default);
}

asRange() {
this.default = round(Number(this.default));
const range = /(.*?)(?:\s|$)/g.exec(this.parameters);
Expand Down Expand Up @@ -68,10 +64,12 @@ module.exports = class Feature {
}

load() {
const match = /^\s*([-]{1,2}[-a-zA-Z0-9]+) ?(.*) \[(.*)\]$/g.exec(this.text);
const match = /^\s*([-]{1,2}[-a-zA-Z0-9]+) ?(.*?) \[(.*?)\](?: \[(.*?)\])?$/g.exec(this.text);
this.name = match[1];
this.default = match[3];
this.parameters = match[2];
this.meta = match[4];
this.enabled = this.default !== 'inactive' && this.meta !== 'read-only';

this.parameters = this.parameters.replace(/^auto\|/, '');
if (this.enabled) {
Expand Down
35 changes: 35 additions & 0 deletions packages/server/test/device.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,39 @@ describe('Device', () => {
assert.strictEqual(device.features['-y'].default, 431.8);
});

it('scanimage-a13.txt', () => {
const file = FileInfo.create('test/resource/scanimage-a13.txt');
const device = Device.from(file.toText());

assert.strictEqual(device.id, 'hpaio:/usb/PSC_1600_series?serial=MY4C3C30Z5L0');
assert.deepStrictEqual(device.features['--mode'].options, ['Lineart', 'Gray', 'Color']);
assert.strictEqual(device.features['--mode'].default, 'Color');
assert.deepStrictEqual(device.features['--resolution'].options, [75, 100, 150, 200, 300, 600, 1200]);
assert.strictEqual(device.features['--resolution'].default, 75);
assert.strictEqual(device.features['--contrast'].limits[0], -127);
assert.strictEqual(device.features['--contrast'].limits[1], 127);
assert.strictEqual(device.features['--contrast'].interval, 1);
assert.strictEqual(device.features['--contrast'].default, 0);
assert.strictEqual(device.features['--contrast'].meta, 'advanced');
assert.strictEqual(device.features['--brightness'].limits[0], -127);
assert.strictEqual(device.features['--brightness'].limits[1], 127);
assert.strictEqual(device.features['--brightness'].interval, 1);
assert.strictEqual(device.features['--brightness'].default, 0);
assert.strictEqual(device.features['--brightness'].meta, 'advanced');
assert.deepStrictEqual(device.features['--source'].options, ['Flatbed']);
assert.strictEqual(device.features['--source'].default, 'Flatbed');
assert.strictEqual(device.features['--source'].meta, 'advanced');
assert.strictEqual(device.features['-l'].limits[0], 0);
assert.strictEqual(device.features['-l'].limits[1], 215.9);
assert.strictEqual(device.features['-l'].default, 0);
assert.strictEqual(device.features['-t'].limits[0], 0);
assert.strictEqual(device.features['-t'].limits[1], 296.9);
assert.strictEqual(device.features['-t'].default, 0);
assert.strictEqual(device.features['-x'].limits[0], 0);
assert.strictEqual(device.features['-x'].limits[1], 215.9);
assert.strictEqual(device.features['-x'].default, 215.9);
assert.strictEqual(device.features['-y'].limits[0], 0);
assert.strictEqual(device.features['-y'].limits[1], 296.9);
assert.strictEqual(device.features['-y'].default, 296.9);
});
});
36 changes: 36 additions & 0 deletions packages/server/test/resource/scanimage-a13.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

All options specific to device `hpaio:/usb/PSC_1600_series?serial=MY4C3C30Z5L0':
Scan mode:
--mode Lineart|Gray|Color [Color]
Selects the scan mode (e.g., lineart, monochrome, or color).
--resolution 75|100|150|200|300|600|1200dpi [75]
Sets the resolution of the scanned image.
Advanced:
--contrast -127..127 [0] [advanced]
Controls the contrast of the acquired image.
--brightness -127..127 [0] [advanced]
Controls the brightness of the acquired image.
--compression None|JPEG [JPEG] [advanced]
Selects the scanner compression method for faster scans, possibly at
the expense of image quality.
--jpeg-quality 0..100 [10] [advanced]
Sets the scanner JPEG compression factor. Larger numbers mean better
compression, and smaller numbers mean better image quality.
--batch-scan[=(yes|no)] [no] [advanced]
Enables continuous scanning with automatic document feeder (ADF).
--source Flatbed [Flatbed] [advanced]
Selects the scan source (such as a document-feeder).
--duplex[=(yes|no)] [inactive]
Enables scanning on both sides of the page.
Geometry:
--length-measurement Unknown|Approximate|Padded [Padded] [advanced]
Selects how the scanned image length is measured and reported, which
is impossible to know in advance for scrollfed scans.
-l 0..215.9mm [0]
Top-left x position of scan area.
-t 0..296.926mm [0]
Top-left y position of scan area.
-x 0..215.9mm [215.9]
Width of scan-area.
-y 0..296.926mm [296.926]
Height of scan-area.

0 comments on commit 436a164

Please sign in to comment.