web-sdk-pp-detection 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/dist/browser-global.js +67 -19
- package/dist/browser-global.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +67 -19
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -141,6 +141,7 @@ interface PPDetectionProgressEvent {
|
|
|
141
141
|
readonly fallback?: PPDetectionFallback;
|
|
142
142
|
}
|
|
143
143
|
interface CreatePPDetectionOptions {
|
|
144
|
+
readonly allowExperimental?: boolean;
|
|
144
145
|
readonly allowFallback?: boolean;
|
|
145
146
|
readonly backend?: BackendPreference;
|
|
146
147
|
readonly cache?: boolean | "memory" | "indexeddb";
|
|
@@ -401,6 +402,7 @@ declare class PPDetectionError extends Error {
|
|
|
401
402
|
}
|
|
402
403
|
|
|
403
404
|
interface SelectExecutionOptions {
|
|
405
|
+
readonly allowExperimental?: boolean;
|
|
404
406
|
readonly backend?: BackendPreference;
|
|
405
407
|
readonly precision?: Precision;
|
|
406
408
|
readonly executionMode?: ExecutionMode;
|
|
@@ -633,7 +635,7 @@ declare class IndexedDBModelCache implements ModelCache {
|
|
|
633
635
|
declare global {
|
|
634
636
|
var __PPDETECTION_SCRIPT_URL__: string | undefined;
|
|
635
637
|
}
|
|
636
|
-
declare const CURRENT_SDK_VERSION = "0.
|
|
638
|
+
declare const CURRENT_SDK_VERSION = "0.3.1";
|
|
637
639
|
|
|
638
640
|
declare function probePPDetectionCapabilities(options?: CapabilityProbeOptions): DetectionCapabilities;
|
|
639
641
|
|
package/dist/index.js
CHANGED
|
@@ -371,34 +371,58 @@ function clipBicubic(value) {
|
|
|
371
371
|
const rounded = value >> BICUBIC_PRECISION_BITS;
|
|
372
372
|
return Math.max(0, Math.min(255, rounded));
|
|
373
373
|
}
|
|
374
|
-
function
|
|
374
|
+
function writeBicubicChannels(raster, resizedWidth, resizedHeight, target) {
|
|
375
375
|
const horizontal = createBicubicAxis(raster.width, resizedWidth);
|
|
376
376
|
const vertical = createBicubicAxis(raster.height, resizedHeight);
|
|
377
|
-
const
|
|
377
|
+
const rowStride = resizedWidth * 3;
|
|
378
|
+
const intermediate = new Uint8Array(raster.height * rowStride);
|
|
378
379
|
for (let y = 0; y < raster.height; y += 1) {
|
|
380
|
+
const sourceRow = y * raster.width * 4;
|
|
381
|
+
const targetRow = y * rowStride;
|
|
379
382
|
for (let x = 0; x < resizedWidth; x += 1) {
|
|
380
383
|
const [start, count] = horizontal.bounds[x];
|
|
381
384
|
const coefficients = horizontal.coefficients[x];
|
|
382
|
-
let
|
|
385
|
+
let red = BICUBIC_ROUNDING;
|
|
386
|
+
let green = BICUBIC_ROUNDING;
|
|
387
|
+
let blue = BICUBIC_ROUNDING;
|
|
388
|
+
let source2 = sourceRow + start * 4;
|
|
383
389
|
for (let index = 0; index < count; index += 1) {
|
|
384
|
-
|
|
390
|
+
const coefficient = coefficients[index];
|
|
391
|
+
red += raster.rgba[source2] * coefficient;
|
|
392
|
+
green += raster.rgba[source2 + 1] * coefficient;
|
|
393
|
+
blue += raster.rgba[source2 + 2] * coefficient;
|
|
394
|
+
source2 += 4;
|
|
385
395
|
}
|
|
386
|
-
|
|
396
|
+
const offset = targetRow + x * 3;
|
|
397
|
+
intermediate[offset] = clipBicubic(red);
|
|
398
|
+
intermediate[offset + 1] = clipBicubic(green);
|
|
399
|
+
intermediate[offset + 2] = clipBicubic(blue);
|
|
387
400
|
}
|
|
388
401
|
}
|
|
389
|
-
const
|
|
402
|
+
const plane = target.inputWidth * target.inputHeight;
|
|
390
403
|
for (let y = 0; y < resizedHeight; y += 1) {
|
|
391
404
|
const [start, count] = vertical.bounds[y];
|
|
392
405
|
const coefficients = vertical.coefficients[y];
|
|
406
|
+
const sourceRow = start * rowStride;
|
|
407
|
+
const targetRow = (y + target.padTop) * target.inputWidth + target.padLeft;
|
|
393
408
|
for (let x = 0; x < resizedWidth; x += 1) {
|
|
394
|
-
let
|
|
409
|
+
let red = BICUBIC_ROUNDING;
|
|
410
|
+
let green = BICUBIC_ROUNDING;
|
|
411
|
+
let blue = BICUBIC_ROUNDING;
|
|
412
|
+
let source2 = sourceRow + x * 3;
|
|
395
413
|
for (let index = 0; index < count; index += 1) {
|
|
396
|
-
|
|
414
|
+
const coefficient = coefficients[index];
|
|
415
|
+
red += intermediate[source2] * coefficient;
|
|
416
|
+
green += intermediate[source2 + 1] * coefficient;
|
|
417
|
+
blue += intermediate[source2 + 2] * coefficient;
|
|
418
|
+
source2 += rowStride;
|
|
397
419
|
}
|
|
398
|
-
|
|
420
|
+
const offset = targetRow + x;
|
|
421
|
+
target.data[offset] = target.values[clipBicubic(red)];
|
|
422
|
+
target.data[plane + offset] = target.values[256 + clipBicubic(green)];
|
|
423
|
+
target.data[plane * 2 + offset] = target.values[512 + clipBicubic(blue)];
|
|
399
424
|
}
|
|
400
425
|
}
|
|
401
|
-
return output;
|
|
402
426
|
}
|
|
403
427
|
function preprocessImage(raster, preprocessing) {
|
|
404
428
|
const inputWidth = preprocessing.size.width;
|
|
@@ -425,18 +449,35 @@ function preprocessImage(raster, preprocessing) {
|
|
|
425
449
|
const mean = normalize ? preprocessing.mean ?? [0, 0, 0] : [0, 0, 0];
|
|
426
450
|
const std = normalize ? preprocessing.std ?? [1, 1, 1] : [1, 1, 1];
|
|
427
451
|
const interpolation2 = preprocessing.interpolation ?? "bilinear";
|
|
452
|
+
const bicubicValues = doResize && interpolation2 === "bicubic" ? new Float32Array(256 * 3) : void 0;
|
|
428
453
|
for (let channel = 0; channel < 3; channel += 1) {
|
|
429
454
|
const padding = normalize && mean[channel] !== 0 ? -mean[channel] / std[channel] : 0;
|
|
430
455
|
data.fill(padding, channel * plane, (channel + 1) * plane);
|
|
431
|
-
|
|
456
|
+
if (bicubicValues) {
|
|
457
|
+
for (let pixel = 0; pixel < 256; pixel += 1) {
|
|
458
|
+
const scaled = rescale ? pixel * preprocessing.rescaleFactor : pixel;
|
|
459
|
+
bicubicValues[channel * 256 + pixel] = normalize ? (scaled - mean[channel]) / std[channel] : scaled;
|
|
460
|
+
}
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
432
463
|
for (let y = 0; y < resizedHeight; y += 1) {
|
|
433
464
|
for (let x = 0; x < resizedWidth; x += 1) {
|
|
434
|
-
const pixel =
|
|
465
|
+
const pixel = doResize ? bilinearChannel(raster, x, y, resizedWidth, resizedHeight, channel) : sampleChannel(raster, x, y, channel);
|
|
435
466
|
const scaled = rescale ? pixel * preprocessing.rescaleFactor : pixel;
|
|
436
467
|
data[channel * plane + (y + padTop) * inputWidth + x + padLeft] = normalize ? (scaled - mean[channel]) / std[channel] : scaled;
|
|
437
468
|
}
|
|
438
469
|
}
|
|
439
470
|
}
|
|
471
|
+
if (bicubicValues) {
|
|
472
|
+
writeBicubicChannels(raster, resizedWidth, resizedHeight, {
|
|
473
|
+
data,
|
|
474
|
+
inputWidth,
|
|
475
|
+
inputHeight,
|
|
476
|
+
padLeft,
|
|
477
|
+
padTop,
|
|
478
|
+
values: bicubicValues
|
|
479
|
+
});
|
|
480
|
+
}
|
|
440
481
|
return {
|
|
441
482
|
data,
|
|
442
483
|
dims: [1, 3, inputHeight, inputWidth],
|
|
@@ -2031,13 +2072,19 @@ function selectExecutionPlan(options, capabilities, manifest) {
|
|
|
2031
2072
|
if (executionMode === "worker" && !capabilities.worker) {
|
|
2032
2073
|
fail("CAPABILITY_UNSUPPORTED", "\u8BF7\u6C42\u7684 worker \u4E0D\u53EF\u7528", { executionMode });
|
|
2033
2074
|
}
|
|
2034
|
-
const
|
|
2035
|
-
(candidate) => candidate.precision === requestedPrecision && candidate.status !== "
|
|
2036
|
-
);
|
|
2075
|
+
const matchingVariants = manifest.variants?.filter(
|
|
2076
|
+
(candidate) => candidate.precision === requestedPrecision && candidate.status !== "blocked"
|
|
2077
|
+
) ?? [];
|
|
2078
|
+
const variant3 = matchingVariants.find((candidate) => candidate.status !== "labs") ?? (options.allowExperimental === true ? matchingVariants.find((candidate) => candidate.status === "labs") : void 0);
|
|
2037
2079
|
if (!variant3) {
|
|
2038
|
-
fail(
|
|
2039
|
-
|
|
2040
|
-
|
|
2080
|
+
fail(
|
|
2081
|
+
"MODEL_INCOMPATIBLE",
|
|
2082
|
+
options.allowExperimental === true ? `manifest \u6CA1\u6709\u53EF\u7528\u7684 ${requestedPrecision} \u53D8\u4F53` : `manifest \u6CA1\u6709\u53EF\u7528\u7684 ${requestedPrecision} \u7A33\u5B9A\u53D8\u4F53`,
|
|
2083
|
+
{
|
|
2084
|
+
requestedPrecision,
|
|
2085
|
+
allowExperimental: options.allowExperimental === true
|
|
2086
|
+
}
|
|
2087
|
+
);
|
|
2041
2088
|
}
|
|
2042
2089
|
const candidates = candidatesForBackend(requestedBackend, capabilities).filter(
|
|
2043
2090
|
(backend) => variant3.backends.includes(backend)
|
|
@@ -2213,7 +2260,7 @@ var WorkerBridge = class {
|
|
|
2213
2260
|
};
|
|
2214
2261
|
|
|
2215
2262
|
// src/index.ts
|
|
2216
|
-
var CURRENT_SDK_VERSION = "0.
|
|
2263
|
+
var CURRENT_SDK_VERSION = "0.3.1";
|
|
2217
2264
|
function probePPDetectionCapabilities(options = {}) {
|
|
2218
2265
|
return probeCapabilities(options);
|
|
2219
2266
|
}
|
|
@@ -2328,6 +2375,7 @@ async function createPPDetection(options = {}) {
|
|
|
2328
2375
|
options.onProgress?.({ phase: "manifest", status: "complete" });
|
|
2329
2376
|
const plan = selectExecutionPlan(
|
|
2330
2377
|
{
|
|
2378
|
+
allowExperimental: options.allowExperimental,
|
|
2331
2379
|
backend: options.backend,
|
|
2332
2380
|
precision: options.precision === "auto" ? void 0 : options.precision,
|
|
2333
2381
|
executionMode: options.executionMode,
|