Skip to content

Commit

Permalink
Merge pull request #799 from manuc66/feature/support-full-scan-size
Browse files Browse the repository at this point in the history
Feature/support full scan size
  • Loading branch information
manuc66 authored Nov 25, 2023
2 parents 9928f3b + e924a74 commit a5b8453
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 11 deletions.
4 changes: 4 additions & 0 deletions src/DeviceCapabilities.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export interface DeviceCapabilities {
supportsMultiItemScanFromPlaten: boolean;
useWalkupScanToComp: boolean;
platenMaxWidth: number | null;
platenMaxHeight: number | null;
adfMaxWidth: number | null;
adfMaxHeight: number | null;
}
44 changes: 43 additions & 1 deletion src/ScanCaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,23 @@ import { Parser } from "xml2js";
const parser = new Parser();
import { promisify } from "util";
const parseString = promisify<string, ScanCapsData>(parser.parseString);
export interface ScanCapsData {}

export interface ScanCapsData {
ScanCaps: {
Platen: {
InputSourceCaps: {
MaxWidth: number;
MaxHeight: number;
}[];
}[];
Adf: {
InputSourceCaps: {
MaxWidth: number;
MaxHeight: number;
}[];
}[];
};
}

export default class ScanCaps {
private readonly data: ScanCapsData;
Expand All @@ -16,4 +32,30 @@ export default class ScanCaps {
const parsed = await parseString(content);
return new ScanCaps(parsed);
}

get PlatenMaxWidth(): number | null {
return (
this.data["ScanCaps"]["Platen"][0]["InputSourceCaps"][0]["MaxWidth"] ||
null
);
}

get PlatenMaxHeight(): number | null {
return (
this.data["ScanCaps"]["Platen"][0]["InputSourceCaps"][0]["MaxHeight"] ||
null
);
}

get AdfMaxWidth(): number | null {
return (
this.data["ScanCaps"]["Adf"][0]["InputSourceCaps"][0]["MaxWidth"] || null
);
}

get AdfMaxHeight(): number | null {
return (
this.data["ScanCaps"]["Adf"][0]["InputSourceCaps"][0]["MaxHeight"] || null
);
}
}
16 changes: 15 additions & 1 deletion src/ScanJobSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@ export default class ScanJobSettings {
private readonly inputSource: "Adf" | "Platen";
private readonly contentType: "Document" | "Photo";
private readonly resolution: number;
private readonly width: number | null;
private readonly height: number | null;
private readonly isDuplex: boolean;

constructor(
inputSource: "Adf" | "Platen",
contentType: "Document" | "Photo",
resolution: number,
width: number | null,
height: number | null,
isDuplex: boolean,
) {
this.inputSource = inputSource;
this.contentType = contentType;
this.resolution = resolution;
this.width = width;
this.height = height;
this.isDuplex = isDuplex;
}

Expand All @@ -25,7 +31,7 @@ export default class ScanJobSettings {
'<ScanSettings xmlns="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19 Scan Schema - 0.26.xsd">\n' +
"\t<XResolution>200</XResolution>\n" +
"\t<YResolution>200</YResolution>\n" +
"\t<XStart>33</XStart>\n" +
"\t<XStart>0</XStart>\n" +
"\t<YStart>0</YStart>\n" +
"\t<Width>2481</Width>\n" +
"\t<Height>3507</Height>\n" +
Expand Down Expand Up @@ -53,6 +59,14 @@ export default class ScanJobSettings {
parsed.ScanSettings.XResolution[0] = this.resolution;
parsed.ScanSettings.YResolution[0] = this.resolution;

if (this.width !== null) {
parsed.ScanSettings.Width = this.width;
}

if (this.height !== null) {
parsed.ScanSettings.Height = this.height;
}

parsed.ScanSettings.InputSource[0] = this.inputSource;
if (this.inputSource === "Adf" && this.isDuplex) {
parsed.ScanSettings["AdfOptions"] = [{ AdfOption: ["Duplex"] }];
Expand Down
42 changes: 40 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ async function adfAutoscanCmd(
);
console.log(`Temp folder: ${tempFolder}`);

const deviceCapabilities = await readDeviceCapabilities();

let scanCount = 0;
let keepActive = true;
let errorCount = 0;
Expand All @@ -123,7 +125,13 @@ async function adfAutoscanCmd(

console.log(`Scan event captured, saving scan #${scanCount}`);

await scanFromAdf(scanCount, folder, tempFolder, adfAutoScanConfig);
await scanFromAdf(
scanCount,
folder,
tempFolder,
adfAutoScanConfig,
deviceCapabilities,
);
} catch (e) {
console.log(e);
if (await HPApi.isAlive()) {
Expand Down Expand Up @@ -204,6 +212,14 @@ function setupScanParameters(command: Command): Command {
"-r, --resolution <dpi>",
"Resolution in DPI of the scans (default: 200)",
);
command.option(
"-w, --width <width>",
"With in pixel of the scans (default: 2481)",
);
command.option(
"-h, --height <height>",
"Height in pixel of the scans (default: 3507)",
);
return command;
}

Expand Down Expand Up @@ -253,11 +269,33 @@ function getScanConfiguration(parentOption: OptionValues) {
filePattern: parentOption.pattern || getConfig("pattern"),
};

const configWidth = (
parentOption.width ||
getConfig("width") ||
0
).toString();
const width =
configWidth.toLowerCase() === "max"
? Number.MAX_SAFE_INTEGER
: parseInt(configWidth, 10);

const configHeight = (
parentOption.width ||
getConfig("height") ||
"0"
).toString();
const height =
configWidth.toLowerCase() === "max"
? Number.MAX_SAFE_INTEGER
: parseInt(configHeight, 10);

const scanConfig: ScanConfig = {
resolution: parseInt(
parentOption.resolution || getConfig("resolution") || 200,
parentOption.resolution || getConfig("resolution") || "200",
10,
),
width: width,
height: height,
directoryConfig,
};
return scanConfig;
Expand Down
8 changes: 7 additions & 1 deletion src/readDeviceCapabilities.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DeviceCapabilities } from "./DeviceCapabilities";
import HPApi from "./HPApi";
import WalkupScanToCompCaps from "./WalkupScanToCompCaps";
import ScanCaps from "./ScanCaps";

export async function readDeviceCapabilities(): Promise<DeviceCapabilities> {
let supportsMultiItemScanFromPlaten = true;
Expand Down Expand Up @@ -30,17 +31,22 @@ export async function readDeviceCapabilities(): Promise<DeviceCapabilities> {
console.log("Unknown device!");
}

let scanCaps: ScanCaps | null = null;
if (discoveryTree.ScanJobManifestURI != null) {
const scanJobManifest = await HPApi.getScanJobManifest(
discoveryTree.ScanJobManifestURI,
);
if (scanJobManifest.ScanCapsURI != null) {
await HPApi.getScanCaps(scanJobManifest.ScanCapsURI);
scanCaps = await HPApi.getScanCaps(scanJobManifest.ScanCapsURI);
}
}

return {
supportsMultiItemScanFromPlaten,
useWalkupScanToComp: walkupScanToCompCaps != null,
platenMaxWidth: scanCaps?.PlatenMaxWidth || null,
platenMaxHeight: scanCaps?.PlatenMaxHeight || null,
adfMaxWidth: scanCaps?.AdfMaxWidth || null,
adfMaxHeight: scanCaps?.AdfMaxHeight || null,
};
}
58 changes: 58 additions & 0 deletions src/scanProcessing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,48 @@ function isPdf(
}
}

export function getScanWidth(
scanConfig: ScanConfig,
inputSource: "Adf" | "Platen",
deviceCapabilities: DeviceCapabilities,
) {
if (scanConfig.width && scanConfig.width > 0) {
const maxWidth =
inputSource === "Adf"
? deviceCapabilities.adfMaxWidth
: deviceCapabilities.platenMaxWidth;

if (maxWidth && scanConfig.width > maxWidth) {
return maxWidth;
} else {
return scanConfig.width;
}
} else {
return null;
}
}

export function getScanHeight(
scanConfig: ScanConfig,
inputSource: "Adf" | "Platen",
deviceCapabilities: DeviceCapabilities,
) {
if (scanConfig.height && scanConfig.height > 0) {
const maxHeight =
inputSource === "Adf"
? deviceCapabilities.adfMaxHeight
: deviceCapabilities.platenMaxHeight;

if (maxHeight && scanConfig.height > maxHeight) {
return maxHeight;
} else {
return scanConfig.height;
}
} else {
return null;
}
}

export async function saveScan(
event: Event,
folder: string,
Expand Down Expand Up @@ -396,11 +438,15 @@ export async function saveScan(
console.log("Afd is : " + scanStatus.adfState);

const inputSource = scanStatus.getInputSource();
const scanWidth = getScanWidth(scanConfig, inputSource, deviceCapabilities);
const scanHeight = getScanHeight(scanConfig, inputSource, deviceCapabilities);

const scanJobSettings = new ScanJobSettings(
inputSource,
contentType,
scanConfig.resolution,
scanWidth,
scanHeight,
isDuplex,
);

Expand Down Expand Up @@ -441,6 +487,8 @@ export type DirectoryConfig = {
};
export type ScanConfig = {
resolution: number;
width: number | null;
height: number | null;
directoryConfig: DirectoryConfig;
};
export type AdfAutoScanConfig = ScanConfig & {
Expand All @@ -455,6 +503,7 @@ export async function scanFromAdf(
folder: string,
tempFolder: string,
adfAutoScanConfig: AdfAutoScanConfig,
deviceCapabilities: DeviceCapabilities,
) {
let destinationFolder: string;
let contentType: "Document" | "Photo";
Expand All @@ -469,10 +518,19 @@ export async function scanFromAdf(
destinationFolder = folder;
}

const scanWidth = getScanWidth(adfAutoScanConfig, "Adf", deviceCapabilities);
const scanHeight = getScanHeight(
adfAutoScanConfig,
"Adf",
deviceCapabilities,
);

const scanJobSettings = new ScanJobSettings(
"Adf",
contentType,
adfAutoScanConfig.resolution,
scanWidth,
scanHeight,
adfAutoScanConfig.isDuplex,
);

Expand Down
15 changes: 12 additions & 3 deletions test/ScanJobSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as fs from "fs/promises";
describe("ScanJobSettings", () => {
describe("toXML", () => {
it("Allows to describe an ADF two side", async () => {
const scanJobSettings = new ScanJobSettings("Adf", "Document", 200, true);
const scanJobSettings = new ScanJobSettings("Adf", "Document", 200, null, null, true);

const content: string = await fs.readFile(
path.resolve(__dirname, "./asset/adf_duplex_job.xml"), {encoding:'utf8' }
Expand All @@ -16,7 +16,7 @@ describe("ScanJobSettings", () => {
});

it("Allows to describe an ADF single side", async () => {
const scanJobSettings = new ScanJobSettings("Adf", "Document", 200, false);
const scanJobSettings = new ScanJobSettings("Adf", "Document", 200, null, null, false);

const content: string = await fs.readFile(
path.resolve(__dirname, "./asset/adf_simplex_job.xml"), {encoding:'utf8' }
Expand All @@ -25,12 +25,21 @@ describe("ScanJobSettings", () => {
});

it("Allows to describe dpi of 300", async () => {
const scanJobSettings = new ScanJobSettings("Adf", "Document", 300, false);
const scanJobSettings = new ScanJobSettings("Adf", "Document", 300, null, null, false);

const content: string = await fs.readFile(
path.resolve(__dirname, "./asset/300_dpi_job.xml"), {encoding:'utf8' }
);
expect((await scanJobSettings.toXML()).trimEnd()).to.be.eq(content.trimEnd().replace(/\r\n/g, "\n"));
});

it ("Allows to describe a custom width and height", async () => {
const scanJobSettings = new ScanJobSettings("Adf", "Document", 200, 1000, 4000, false);

const content: string = await fs.readFile(
path.resolve(__dirname, "./asset/adf_simplex_custom_job.xml"), {encoding:'utf8' }
);
expect((await scanJobSettings.toXML()).trimEnd()).to.be.eq(content.trimEnd().replace(/\r\n/g, "\n"));
})
});
});
2 changes: 1 addition & 1 deletion test/asset/300_dpi_job.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ScanSettings xmlns="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19 Scan Schema - 0.26.xsd">
<XResolution>300</XResolution>
<YResolution>300</YResolution>
<XStart>33</XStart>
<XStart>0</XStart>
<YStart>0</YStart>
<Width>2481</Width>
<Height>3507</Height>
Expand Down
2 changes: 1 addition & 1 deletion test/asset/adf_duplex_job.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<ScanSettings xmlns="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.hp.com/schemas/imaging/con/cnx/scan/2008/08/19 Scan Schema - 0.26.xsd">
<XResolution>200</XResolution>
<YResolution>200</YResolution>
<XStart>33</XStart>
<XStart>0</XStart>
<YStart>0</YStart>
<Width>2481</Width>
<Height>3507</Height>
Expand Down
Loading

0 comments on commit a5b8453

Please sign in to comment.