@trustchex/react-native-sdk 1.495.10 → 1.495.11
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/android/build.gradle +10 -0
- package/android/libs/jj2000-5.2.jar +0 -0
- package/android/src/main/java/com/trustchex/reactnativesdk/ImageDecoderModule.kt +88 -0
- package/android/src/main/java/com/trustchex/reactnativesdk/Jp2PgxDecoder.kt +135 -0
- package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKPackage.kt +12 -0
- package/android/src/test/java/com/trustchex/reactnativesdk/Jp2PgxDecoderTest.kt +143 -0
- package/android/src/test/resources/jp2/gray.jp2 +0 -0
- package/android/src/test/resources/jp2/solid_color.j2k +0 -0
- package/android/src/test/resources/jp2/solid_color.jp2 +0 -0
- package/lib/module/Shared/Components/EIDScanner.js +8 -5
- package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +19 -16
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +43 -4
- package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +22 -0
- package/lib/module/Shared/EIDReader/eidReader.js +11 -9
- package/lib/module/Shared/Libs/jp2Decode.js +12 -11
- package/lib/module/Shared/Services/DataUploadService.js +16 -4
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts +21 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +15 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/jp2Decode.d.ts +4 -3
- package/lib/typescript/src/Shared/Libs/jp2Decode.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Shared/Components/EIDScanner.tsx +7 -5
- package/src/Shared/Components/IdentityDocumentCamera.flows.ts +29 -18
- package/src/Shared/Components/IdentityDocumentCamera.tsx +48 -3
- package/src/Shared/Components/IdentityDocumentCamera.types.ts +21 -0
- package/src/Shared/Components/IdentityDocumentCamera.utils.ts +24 -0
- package/src/Shared/EIDReader/eidReader.ts +11 -9
- package/src/Shared/Libs/jp2Decode.ts +15 -11
- package/src/Shared/Services/DataUploadService.ts +41 -8
- package/src/version.ts +1 -1
|
@@ -6,26 +6,27 @@ import { NativeModules, Platform } from 'react-native';
|
|
|
6
6
|
* Native JPEG2000 decoder bridge.
|
|
7
7
|
*
|
|
8
8
|
* The passport chip portrait (DG2) is frequently stored as JPEG2000
|
|
9
|
-
* (image/jp2). React Native's <Image>
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* iOS
|
|
14
|
-
*
|
|
15
|
-
*
|
|
9
|
+
* (image/jp2). React Native's <Image> CANNOT render a JP2 data URI on EITHER
|
|
10
|
+
* platform — iOS's UIImage-backed <Image> refuses it, and Android's Fresco/Skia
|
|
11
|
+
* pipeline has no JPEG2000 decoder (the chip photo showed as a blank/white
|
|
12
|
+
* placeholder). Both platforms therefore need a native round-trip to JPEG:
|
|
13
|
+
* - iOS: ImageIO decodes JPEG2000 natively.
|
|
14
|
+
* - Android: the bundled pure-Java jj2000 decoder (no ImageIO/NDK).
|
|
15
|
+
* Both are exposed as the `ImageDecoderModule.decodeJp2ToJpeg` native method.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
const ImageDecoder = NativeModules.ImageDecoderModule;
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Decode a JPEG2000 buffer to JPEG using the native iOS
|
|
21
|
+
* Decode a JPEG2000 buffer to JPEG using the native decoder (iOS ImageIO /
|
|
22
|
+
* Android jj2000).
|
|
22
23
|
*
|
|
23
24
|
* Returns the JPEG bytes + mime type on success, or null when native decode is
|
|
24
|
-
* unavailable (
|
|
25
|
-
*
|
|
25
|
+
* unavailable (the module isn't linked) or fails — callers should fall back to
|
|
26
|
+
* their existing behaviour (keep raw JP2).
|
|
26
27
|
*/
|
|
27
28
|
export async function decodeJp2ToJpeg(jp2Buffer) {
|
|
28
|
-
if (Platform.OS !== 'ios' || !ImageDecoder?.decodeJp2ToJpeg) {
|
|
29
|
+
if (Platform.OS !== 'ios' && Platform.OS !== 'android' || !ImageDecoder?.decodeJp2ToJpeg) {
|
|
29
30
|
return null;
|
|
30
31
|
}
|
|
31
32
|
try {
|
|
@@ -92,7 +92,7 @@ export class DataUploadService {
|
|
|
92
92
|
// every entry is deleted in the finally below, whether the upload succeeds
|
|
93
93
|
// or not.
|
|
94
94
|
const tempPaths = [];
|
|
95
|
-
const writeTempImage = async (fileName, base64Data) => {
|
|
95
|
+
const writeTempImage = async (fileName, base64Data, mimeType = 'image/jpeg') => {
|
|
96
96
|
const filePath = decodeURIComponent(`${RNFS.TemporaryDirectoryPath}/${fileName}`);
|
|
97
97
|
await RNFS.writeFile(filePath, base64Data, 'base64');
|
|
98
98
|
tempPaths.push(filePath);
|
|
@@ -100,10 +100,19 @@ export class DataUploadService {
|
|
|
100
100
|
name: 'files',
|
|
101
101
|
filename: fileName,
|
|
102
102
|
filepath: filePath,
|
|
103
|
-
filetype
|
|
103
|
+
// The filename extension AND this filetype must reflect the REAL format.
|
|
104
|
+
// The backend keys its jp2→jpeg conversion off the .jp2 extension, so a
|
|
105
|
+
// raw JP2 mislabeled as .jpg/image/jpeg reaches face-verification as a
|
|
106
|
+
// corrupt JPEG and is rejected. Pass the actual mimeType for anything
|
|
107
|
+
// that isn't already JPEG (the chip portrait can be jp2/png).
|
|
108
|
+
filetype: mimeType
|
|
104
109
|
});
|
|
105
110
|
return filePath;
|
|
106
111
|
};
|
|
112
|
+
|
|
113
|
+
// Pick a file extension that matches the image's real mime type so the
|
|
114
|
+
// backend handles it correctly (it converts .jp2 → jpeg on receipt).
|
|
115
|
+
const extensionForMime = mimeType => mimeType === 'image/jp2' ? 'jp2' : mimeType === 'image/png' ? 'png' : 'jpg';
|
|
107
116
|
try {
|
|
108
117
|
// Add document front image
|
|
109
118
|
const frontImage = scannedDocument?.frontImage;
|
|
@@ -117,10 +126,13 @@ export class DataUploadService {
|
|
|
117
126
|
await writeTempImage('DOCUMENT_BACK_IMAGE.jpg', backImage);
|
|
118
127
|
}
|
|
119
128
|
|
|
120
|
-
// Add face image from document
|
|
129
|
+
// Add face image from document. The NFC chip portrait (DG2) can be JPEG,
|
|
130
|
+
// PNG (JS-decoded), or — when native JP2 decode was unavailable — raw JP2,
|
|
131
|
+
// so the extension/filetype must track the real mime type, not assume JPEG.
|
|
121
132
|
const faceImage = scannedDocument?.faceImage;
|
|
122
133
|
if (faceImage && faceImage !== '') {
|
|
123
|
-
|
|
134
|
+
const faceMime = scannedDocument?.faceImageMimeType || 'image/jpeg';
|
|
135
|
+
await writeTempImage(`FACE_IMAGE.${extensionForMime(faceMime)}`, faceImage, faceMime);
|
|
124
136
|
}
|
|
125
137
|
|
|
126
138
|
// Add secondary face image from document (optional)
|
package/lib/module/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EIDScanner.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/EIDScanner.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAwBpD,UAAU,eAAe;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CACd,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,KACtB,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/C;AAED,QAAA,MAAM,UAAU,GAAI,6FAOjB,eAAe,
|
|
1
|
+
{"version":3,"file":"EIDScanner.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/EIDScanner.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAwBpD,UAAU,eAAe;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CACd,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,KACtB,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/C;AAED,QAAA,MAAM,UAAU,GAAI,6FAOjB,eAAe,4CA8yBjB,CAAC;AA4NF,eAAe,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"AA0EA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,2BAA2B,EAK5B,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAMnE,QAAA,MAAM,sBAAsB,GAAI,uDAI7B,2BAA2B,4CAmmF7B,CAAC;AAiIF,eAAe,sBAAsB,CAAC"}
|
|
@@ -105,5 +105,5 @@ export declare function handleIDBackFlow(mrzText: string | null, mrzFields: MRZF
|
|
|
105
105
|
* self-corrects: SCAN_ID_BACK simply won't find an ID-back MRZ/barcode and the
|
|
106
106
|
* user can cancel, which is far better than skipping the back of every real ID.
|
|
107
107
|
*/
|
|
108
|
-
export declare function getNextStepAfterHologram(detectedDocumentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', currentFrameDocType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', mrzDocCode: string | undefined): 'COMPLETED' | 'SCAN_ID_BACK';
|
|
108
|
+
export declare function getNextStepAfterHologram(detectedDocumentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', currentFrameDocType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', mrzDocCode: string | undefined, sawPassportSignal?: boolean): 'COMPLETED' | 'SCAN_ID_BACK';
|
|
109
109
|
//# sourceMappingURL=IdentityDocumentCamera.flows.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.flows.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.flows.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAgB,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAcpD,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,cAAc,GACd,qBAAqB,GACrB,sBAAsB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,oBAAoB,GACpB,qBAAqB,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;CAC3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,iBAAiB,EAAE,OAAO,EAC1B,WAAW,EAAE,OAAO,EACpB,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,OAAO,GACpB,kBAAkB,CAgEpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,UAAU,EAAE,MAAM,GACjB,iBAAiB,CA0EnB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,QAAQ,EAAE,OAAO,EACjB,iBAAiB,EAAE,OAAO,EAC1B,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,WAAW,EAAE,OAAO,GACnB,gBAAgB,CA2DlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,wBAAwB,CACtC,oBAAoB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACrE,mBAAmB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACpE,UAAU,EAAE,MAAM,GAAG,SAAS,EAM9B,iBAAiB,GAAE,OAAe,GACjC,WAAW,GAAG,cAAc,CAuB9B"}
|
|
@@ -102,6 +102,27 @@ export interface Barcode {
|
|
|
102
102
|
import type { MRZFields } from '../Types/mrzFields';
|
|
103
103
|
export type ScanStep = 'SCAN_ID_FRONT_OR_PASSPORT' | 'SCAN_ID_BACK' | 'SCAN_HOLOGRAM' | 'COMPLETED';
|
|
104
104
|
export type ScanStatus = 'SEARCHING' | 'SCANNING' | 'SCANNED' | 'INCORRECT';
|
|
105
|
+
/**
|
|
106
|
+
* What the camera has classified the document in view as.
|
|
107
|
+
*
|
|
108
|
+
* The single most important property of a document type is whether it has a
|
|
109
|
+
* BACK SIDE that still needs scanning — that is what drives the scan flow:
|
|
110
|
+
*
|
|
111
|
+
* PASSPORT — ICAO TD3 booklet. The MRZ, photo and all data live on ONE page
|
|
112
|
+
* (the data page). There is NO second machine-readable side, so a
|
|
113
|
+
* passport must NEVER be routed to SCAN_ID_BACK. Detected by the
|
|
114
|
+
* TD3 MRZ document code 'P' / the passport MRZ pattern.
|
|
115
|
+
* ID_FRONT — the photo/front side of a TD1/TD2 ID card. The front carries the
|
|
116
|
+
* photo + signature but usually NO MRZ (the MRZ is on the back),
|
|
117
|
+
* so the front alone is NOT enough — it MUST be followed by a back
|
|
118
|
+
* scan (SCAN_ID_BACK).
|
|
119
|
+
* ID_BACK — the back side of a TD1/TD2 ID card. Carries the MRZ (document
|
|
120
|
+
* code 'I'/'A'/'C') and usually a barcode. Terminal side.
|
|
121
|
+
* UNKNOWN — not yet classified, or signals conflict.
|
|
122
|
+
*
|
|
123
|
+
* Use `documentHasBackSide()` / `isPassportDocumentCode()` rather than comparing
|
|
124
|
+
* these strings ad-hoc, so the "is this a passport?" rule lives in one place.
|
|
125
|
+
*/
|
|
105
126
|
export type DocumentType = 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN';
|
|
106
127
|
export type CompletedStep = 'SCAN_ID_FRONT_OR_PASSPORT' | 'SCAN_ID_BACK' | 'SCAN_HOLOGRAM' | null;
|
|
107
128
|
export type BoundsWithRotation = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.types.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.types.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,21 @@ import type { MRZFields } from '../Types/mrzFields';
|
|
|
5
5
|
* Per ICAO 9303, valid ID card codes start with 'I', 'A', or 'C'.
|
|
6
6
|
*/
|
|
7
7
|
export declare function isIDCardDocumentCode(code: string | null | undefined): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Checks if a document code represents a passport (ICAO TD3).
|
|
10
|
+
* Per ICAO 9303 Part 4, the first character of a passport MRZ document code is
|
|
11
|
+
* 'P' — for the ordinary `P<`, the German `PP`, and the diplomatic/service/
|
|
12
|
+
* official `PD`/`PS`/`PO` variants alike.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isPassportDocumentCode(code: string | null | undefined): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Single source of truth for "does this document have a second side left to
|
|
17
|
+
* scan?". A passport's data all lives on one page, so it has no back; an ID
|
|
18
|
+
* card's MRZ lives on the back, so an ID front always does. Used by the
|
|
19
|
+
* post-front / post-hologram routing so the "ask for the back side?" decision
|
|
20
|
+
* is never re-derived ad-hoc (the bug where passports were sent to SCAN_ID_BACK).
|
|
21
|
+
*/
|
|
22
|
+
export declare function documentHasBackSide(documentType: DocumentType): boolean;
|
|
8
23
|
/**
|
|
9
24
|
* Frame-to-screen coordinate transform using FILL_CENTER scaling
|
|
10
25
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.utils.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eidReader.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/EIDReader/eidReader.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"eidReader.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/EIDReader/eidReader.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AA2Y7C,QAAA,MAAM,SAAS,GACb,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,cAAc,MAAM,EACpB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAC5C,OAAO,CACN;IACE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACD,SAAS,CA+XZ,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
2
|
/**
|
|
3
|
-
* Decode a JPEG2000 buffer to JPEG using the native iOS
|
|
3
|
+
* Decode a JPEG2000 buffer to JPEG using the native decoder (iOS ImageIO /
|
|
4
|
+
* Android jj2000).
|
|
4
5
|
*
|
|
5
6
|
* Returns the JPEG bytes + mime type on success, or null when native decode is
|
|
6
|
-
* unavailable (
|
|
7
|
-
*
|
|
7
|
+
* unavailable (the module isn't linked) or fails — callers should fall back to
|
|
8
|
+
* their existing behaviour (keep raw JP2).
|
|
8
9
|
*/
|
|
9
10
|
export declare function decodeJp2ToJpeg(jp2Buffer: Buffer): Promise<{
|
|
10
11
|
base64: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jp2Decode.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/jp2Decode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAsBhC
|
|
1
|
+
{"version":3,"file":"jp2Decode.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/jp2Decode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAsBhC;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAkBtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataUploadService.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Services/DataUploadService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAQhE;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM;YAKb,0BAA0B;IAexC;;OAEG;IACG,kBAAkB,CACtB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,uBAAuB,EACxC,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"DataUploadService.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Services/DataUploadService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAQhE;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM;YAKb,0BAA0B;IAexC;;OAEG;IACG,kBAAkB,CACtB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,uBAAuB,EACxC,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,IAAI,CAAC;IA8DhB;;OAEG;IACG,WAAW,CACf,gBAAgB,EAAE,MAAM,EACxB,eAAe,CAAC,EAAE,uBAAuB,EACzC,iBAAiB,CAAC,EAAE,iBAAiB,EACrC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC;IAmLhB;;OAEG;IACG,mBAAmB,CACvB,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,EACvC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,OAAO,CAAC;IAuGnB,OAAO,CAAC,iBAAiB;CAY1B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "1.495.
|
|
1
|
+
export declare const SDK_VERSION = "1.495.11";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -643,12 +643,14 @@ const EIDScanner = ({
|
|
|
643
643
|
<View style={styles.idCardPhotoContainer}>
|
|
644
644
|
<View style={styles.idCardPhotoFrame}>
|
|
645
645
|
{documentFaceImage &&
|
|
646
|
+
// The chip portrait (DG2) is JPEG2000, which RN's <Image>
|
|
647
|
+
// can't render on either platform — the native decoder
|
|
648
|
+
// (iOS ImageIO / Android jj2000) converts it to JPEG (or
|
|
649
|
+
// the small-image JS fallback to PNG) before this point.
|
|
650
|
+
// A raw image/jp2 would render as a blank box, so we only
|
|
651
|
+
// accept the decoded formats and otherwise show '?'.
|
|
646
652
|
(documentFaceImageMimeType === 'image/jpeg' ||
|
|
647
|
-
documentFaceImageMimeType === 'image/png'
|
|
648
|
-
// Android's <Image> decodes a raw JP2 data URI; on iOS
|
|
649
|
-
// the chip JP2 is converted to JPEG before this point
|
|
650
|
-
// (native ImageIO), so iOS never reaches here as jp2.
|
|
651
|
-
documentFaceImageMimeType === 'image/jp2') ? (
|
|
653
|
+
documentFaceImageMimeType === 'image/png') ? (
|
|
652
654
|
<Image
|
|
653
655
|
source={{
|
|
654
656
|
uri: `data:${documentFaceImageMimeType};base64,${documentFaceImage}`,
|
|
@@ -28,10 +28,14 @@
|
|
|
28
28
|
* - No face, has MRZ with code 'I'
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
import type { Face } from './IdentityDocumentCamera.types';
|
|
31
|
+
import type { Face, DocumentType } from './IdentityDocumentCamera.types';
|
|
32
32
|
import type { MRZFields } from '../Types/mrzFields';
|
|
33
33
|
import { PASSPORT_MRZ_PATTERN } from './IdentityDocumentCamera.constants';
|
|
34
|
-
import {
|
|
34
|
+
import {
|
|
35
|
+
isIDCardDocumentCode,
|
|
36
|
+
isPassportDocumentCode,
|
|
37
|
+
documentHasBackSide,
|
|
38
|
+
} from './IdentityDocumentCamera.utils';
|
|
35
39
|
|
|
36
40
|
/**
|
|
37
41
|
* After this many retry attempts for ID_FRONT flow, proceed with face detection alone
|
|
@@ -350,27 +354,34 @@ export function handleIDBackFlow(
|
|
|
350
354
|
export function getNextStepAfterHologram(
|
|
351
355
|
detectedDocumentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN',
|
|
352
356
|
currentFrameDocType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN',
|
|
353
|
-
mrzDocCode: string | undefined
|
|
357
|
+
mrzDocCode: string | undefined,
|
|
358
|
+
// True if a passport MRZ pattern / 'P' code was seen in ANY front frame this
|
|
359
|
+
// session — not just the accepting one. The passport MRZ is dense and often
|
|
360
|
+
// OCRs a few frames AFTER the face + signature, so a passport can get locked
|
|
361
|
+
// as ID_FRONT before its MRZ is read. Latching the signal across frames is
|
|
362
|
+
// what stops that passport from being wrongly routed to SCAN_ID_BACK here.
|
|
363
|
+
sawPassportSignal: boolean = false
|
|
354
364
|
): 'COMPLETED' | 'SCAN_ID_BACK' {
|
|
355
|
-
//
|
|
365
|
+
// Resolve to a single document type, passport-biased: any positive passport
|
|
366
|
+
// signal wins (a passport must never wait for a back that does not exist),
|
|
367
|
+
// then positive ID-card evidence (a non-'P' MRZ code, or an ID_FRONT
|
|
368
|
+
// classification — an ID front legitimately has no MRZ, so the classification
|
|
369
|
+
// is the only signal we get), else UNKNOWN.
|
|
356
370
|
const isPassport =
|
|
371
|
+
sawPassportSignal ||
|
|
357
372
|
detectedDocumentType === 'PASSPORT' ||
|
|
358
373
|
currentFrameDocType === 'PASSPORT' ||
|
|
359
|
-
mrzDocCode
|
|
360
|
-
|
|
361
|
-
if (isPassport) {
|
|
362
|
-
return 'COMPLETED';
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Positive ID-card evidence → scan the back. Either a non-'P' MRZ code, or a
|
|
366
|
-
// front classified as ID_FRONT (an ID front legitimately has no MRZ, so the
|
|
367
|
-
// classification is the only signal we get).
|
|
368
|
-
const hasIdCardMrzCode = !!mrzDocCode && mrzDocCode !== 'P';
|
|
374
|
+
isPassportDocumentCode(mrzDocCode);
|
|
375
|
+
const hasIdCardMrzCode = !!mrzDocCode && !isPassportDocumentCode(mrzDocCode);
|
|
369
376
|
const isIdFront =
|
|
370
377
|
detectedDocumentType === 'ID_FRONT' || currentFrameDocType === 'ID_FRONT';
|
|
371
|
-
if (hasIdCardMrzCode || isIdFront) {
|
|
372
|
-
return 'SCAN_ID_BACK';
|
|
373
|
-
}
|
|
374
378
|
|
|
375
|
-
|
|
379
|
+
const resolved: DocumentType = isPassport
|
|
380
|
+
? 'PASSPORT'
|
|
381
|
+
: hasIdCardMrzCode || isIdFront
|
|
382
|
+
? 'ID_FRONT'
|
|
383
|
+
: 'UNKNOWN';
|
|
384
|
+
|
|
385
|
+
// Single source of truth for "is there a back side left to scan?".
|
|
386
|
+
return documentHasBackSide(resolved) ? 'SCAN_ID_BACK' : 'COMPLETED';
|
|
376
387
|
}
|
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
areMRZFieldsEqual,
|
|
48
48
|
hasRequiredMRZFields,
|
|
49
49
|
validateFacePosition,
|
|
50
|
+
isPassportDocumentCode,
|
|
50
51
|
} from './IdentityDocumentCamera.utils';
|
|
51
52
|
import {
|
|
52
53
|
handlePassportFlow,
|
|
@@ -178,6 +179,15 @@ const IdentityDocumentCamera = ({
|
|
|
178
179
|
>('UNKNOWN');
|
|
179
180
|
const consistentDocTypeCount = useRef(0);
|
|
180
181
|
|
|
182
|
+
// Latches true the moment a passport MRZ pattern / 'P' document code is seen in
|
|
183
|
+
// ANY front frame this session. The passport MRZ is dense and often OCRs a few
|
|
184
|
+
// frames AFTER the face + signature, so without this a passport can be locked
|
|
185
|
+
// as ID_FRONT (which has no MRZ on its front) and then wrongly asked for a back
|
|
186
|
+
// side that does not exist. Once latched, the front is never accepted as
|
|
187
|
+
// ID_FRONT and the post-hologram routing always completes instead of scanning
|
|
188
|
+
// a back. Reset only when a brand-new scan session starts.
|
|
189
|
+
const sawPassportSignal = useRef(false);
|
|
190
|
+
|
|
181
191
|
// Frame quality tracking - persist across callbacks
|
|
182
192
|
const lastFrameQuality = useRef({
|
|
183
193
|
hasAcceptableQuality: true,
|
|
@@ -325,6 +335,7 @@ const IdentityDocumentCamera = ({
|
|
|
325
335
|
lastValidMRZText.current = null;
|
|
326
336
|
lastValidMRZFields.current = null;
|
|
327
337
|
validMRZConsecutiveCount.current = 0;
|
|
338
|
+
sawPassportSignal.current = false;
|
|
328
339
|
mrzAggregator.current.reset();
|
|
329
340
|
setMrzReliable(false);
|
|
330
341
|
// Start a fresh diagnostics session for the support report.
|
|
@@ -666,6 +677,15 @@ const IdentityDocumentCamera = ({
|
|
|
666
677
|
|
|
667
678
|
// Reset MRZ retry counter for each new step so retries start fresh
|
|
668
679
|
mrzDetectionCurrentRetryCount.current = 0;
|
|
680
|
+
// A transition back to the initial front step means a brand-new document
|
|
681
|
+
// scan is starting, so the sticky passport signal from any previous
|
|
682
|
+
// document must NOT carry over — otherwise an ID card scanned after a
|
|
683
|
+
// passport (without the camera unfocusing) would be forced into the
|
|
684
|
+
// passport flow and skip its back side. (The focus-based reset above only
|
|
685
|
+
// fires when the camera goes inactive.)
|
|
686
|
+
if (nextStepType === 'SCAN_ID_FRONT_OR_PASSPORT') {
|
|
687
|
+
sawPassportSignal.current = false;
|
|
688
|
+
}
|
|
669
689
|
// Only clear MRZ text when entering SCAN_ID_BACK (new MRZ expected).
|
|
670
690
|
// Preserve across SCAN_HOLOGRAM so passport completion has MRZ data.
|
|
671
691
|
if (nextStepType === 'SCAN_ID_BACK') {
|
|
@@ -1764,7 +1784,8 @@ const IdentityDocumentCamera = ({
|
|
|
1764
1784
|
const nextStepAfterHologram = getNextStepAfterHologram(
|
|
1765
1785
|
detectedDocumentType,
|
|
1766
1786
|
documentType,
|
|
1767
|
-
mrzDocCode
|
|
1787
|
+
mrzDocCode,
|
|
1788
|
+
sawPassportSignal.current
|
|
1768
1789
|
);
|
|
1769
1790
|
|
|
1770
1791
|
transitionStepWithCallback(
|
|
@@ -1783,11 +1804,35 @@ const IdentityDocumentCamera = ({
|
|
|
1783
1804
|
// INITIAL SCAN STEP - Detect document type and validate
|
|
1784
1805
|
// ============================================================================
|
|
1785
1806
|
if (nextStep === 'SCAN_ID_FRONT_OR_PASSPORT') {
|
|
1807
|
+
// Latch ANY passport signal seen in a front frame — the parsed 'P' code
|
|
1808
|
+
// OR the raw passport MRZ pattern (which survives even when full MRZ
|
|
1809
|
+
// parsing fails). The passport MRZ often OCRs a few frames after the
|
|
1810
|
+
// face + signature, so we remember it across frames; once latched, this
|
|
1811
|
+
// front can never be accepted as an ID card / asked for a back side.
|
|
1812
|
+
// Only AUTHORITATIVE passport signals latch — a parsed MRZ document code
|
|
1813
|
+
// of 'P', or a settled PASSPORT classification. We deliberately do NOT
|
|
1814
|
+
// latch on a raw PASSPORT_MRZ_PATTERN substring match against OCR text:
|
|
1815
|
+
// that loose test can fire on ID-card MRZ noise, and because the latch is
|
|
1816
|
+
// sticky and one-directional a single false match would force the
|
|
1817
|
+
// passport flow for the rest of the session and silently skip the ID
|
|
1818
|
+
// card's back side. The parsed 'P' code still covers the lagging-MRZ case
|
|
1819
|
+
// (it just requires the MRZ to have actually parsed first).
|
|
1820
|
+
if (
|
|
1821
|
+
isPassportDocumentCode(parsedMRZData?.fields?.documentCode) ||
|
|
1822
|
+
documentType === 'PASSPORT' ||
|
|
1823
|
+
detectedDocumentType === 'PASSPORT'
|
|
1824
|
+
) {
|
|
1825
|
+
sawPassportSignal.current = true;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1786
1828
|
// Determine which flow handler to use.
|
|
1787
1829
|
// Current-frame passport detection always takes precedence over a locked
|
|
1788
|
-
// ID_FRONT — passport MRZ may not appear until later frames.
|
|
1830
|
+
// ID_FRONT — passport MRZ may not appear until later frames. A latched
|
|
1831
|
+
// passport signal also forces the passport flow, so a passport that was
|
|
1832
|
+
// momentarily locked as ID_FRONT (before its MRZ was read) is corrected
|
|
1833
|
+
// instead of being driven into the ID-card back-side flow.
|
|
1789
1834
|
const flowDocumentType =
|
|
1790
|
-
documentType === 'PASSPORT'
|
|
1835
|
+
documentType === 'PASSPORT' || sawPassportSignal.current
|
|
1791
1836
|
? 'PASSPORT'
|
|
1792
1837
|
: detectedDocumentType !== 'UNKNOWN'
|
|
1793
1838
|
? detectedDocumentType
|
|
@@ -115,6 +115,27 @@ export type ScanStep =
|
|
|
115
115
|
|
|
116
116
|
export type ScanStatus = 'SEARCHING' | 'SCANNING' | 'SCANNED' | 'INCORRECT';
|
|
117
117
|
|
|
118
|
+
/**
|
|
119
|
+
* What the camera has classified the document in view as.
|
|
120
|
+
*
|
|
121
|
+
* The single most important property of a document type is whether it has a
|
|
122
|
+
* BACK SIDE that still needs scanning — that is what drives the scan flow:
|
|
123
|
+
*
|
|
124
|
+
* PASSPORT — ICAO TD3 booklet. The MRZ, photo and all data live on ONE page
|
|
125
|
+
* (the data page). There is NO second machine-readable side, so a
|
|
126
|
+
* passport must NEVER be routed to SCAN_ID_BACK. Detected by the
|
|
127
|
+
* TD3 MRZ document code 'P' / the passport MRZ pattern.
|
|
128
|
+
* ID_FRONT — the photo/front side of a TD1/TD2 ID card. The front carries the
|
|
129
|
+
* photo + signature but usually NO MRZ (the MRZ is on the back),
|
|
130
|
+
* so the front alone is NOT enough — it MUST be followed by a back
|
|
131
|
+
* scan (SCAN_ID_BACK).
|
|
132
|
+
* ID_BACK — the back side of a TD1/TD2 ID card. Carries the MRZ (document
|
|
133
|
+
* code 'I'/'A'/'C') and usually a barcode. Terminal side.
|
|
134
|
+
* UNKNOWN — not yet classified, or signals conflict.
|
|
135
|
+
*
|
|
136
|
+
* Use `documentHasBackSide()` / `isPassportDocumentCode()` rather than comparing
|
|
137
|
+
* these strings ad-hoc, so the "is this a passport?" rule lives in one place.
|
|
138
|
+
*/
|
|
118
139
|
export type DocumentType = 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN';
|
|
119
140
|
|
|
120
141
|
export type CompletedStep =
|
|
@@ -21,6 +21,30 @@ export function isIDCardDocumentCode(code: string | null | undefined): boolean {
|
|
|
21
21
|
return code.startsWith('I') || code.startsWith('A') || code.startsWith('C');
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Checks if a document code represents a passport (ICAO TD3).
|
|
26
|
+
* Per ICAO 9303 Part 4, the first character of a passport MRZ document code is
|
|
27
|
+
* 'P' — for the ordinary `P<`, the German `PP`, and the diplomatic/service/
|
|
28
|
+
* official `PD`/`PS`/`PO` variants alike.
|
|
29
|
+
*/
|
|
30
|
+
export function isPassportDocumentCode(
|
|
31
|
+
code: string | null | undefined
|
|
32
|
+
): boolean {
|
|
33
|
+
if (!code) return false;
|
|
34
|
+
return code.startsWith('P');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Single source of truth for "does this document have a second side left to
|
|
39
|
+
* scan?". A passport's data all lives on one page, so it has no back; an ID
|
|
40
|
+
* card's MRZ lives on the back, so an ID front always does. Used by the
|
|
41
|
+
* post-front / post-hologram routing so the "ask for the back side?" decision
|
|
42
|
+
* is never re-derived ad-hoc (the bug where passports were sent to SCAN_ID_BACK).
|
|
43
|
+
*/
|
|
44
|
+
export function documentHasBackSide(documentType: DocumentType): boolean {
|
|
45
|
+
return documentType === 'ID_FRONT';
|
|
46
|
+
}
|
|
47
|
+
|
|
24
48
|
/**
|
|
25
49
|
* Frame-to-screen coordinate transform using FILL_CENTER scaling
|
|
26
50
|
*/
|
|
@@ -248,10 +248,11 @@ async function convertJP2IfNeeded(
|
|
|
248
248
|
return { base64: imageBuffer.toString('base64'), mimeType };
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
// Prefer the native decoder (iOS ImageIO). It decodes
|
|
252
|
-
//
|
|
253
|
-
// <Image> can't render a raw image/jp2 data URI
|
|
254
|
-
// decoder entirely. Returns null
|
|
251
|
+
// Prefer the native decoder (iOS ImageIO / Android jj2000). It decodes
|
|
252
|
+
// JPEG2000 of any size off the JS thread, so it fixes the on-screen preview on
|
|
253
|
+
// BOTH platforms (RN's <Image> can't render a raw image/jp2 data URI on either)
|
|
254
|
+
// and avoids the slow pure-JS decoder entirely. Returns null only when the
|
|
255
|
+
// native module is unavailable/unlinked or it fails → fall through.
|
|
255
256
|
const native = await decodeJp2ToJpeg(imageBuffer);
|
|
256
257
|
if (native) {
|
|
257
258
|
debugLog(
|
|
@@ -261,11 +262,12 @@ async function convertJP2IfNeeded(
|
|
|
261
262
|
return native;
|
|
262
263
|
}
|
|
263
264
|
|
|
264
|
-
//
|
|
265
|
-
// JP2. The face image is still captured
|
|
266
|
-
// accept JPEG2000); only the on-screen
|
|
267
|
-
// NFC read COMPLETE instead of hanging.
|
|
268
|
-
//
|
|
265
|
+
// Native decode unavailable AND too large to decode synchronously in JS
|
|
266
|
+
// without freezing the UI — keep the raw JP2. The face image is still captured
|
|
267
|
+
// (the verification backend / face-match accept JPEG2000); only the on-screen
|
|
268
|
+
// preview can't render it. This lets the NFC read COMPLETE instead of hanging.
|
|
269
|
+
// In normal operation the native path above handles this on both platforms; we
|
|
270
|
+
// only reach here if the native module failed or isn't linked.
|
|
269
271
|
if (imageBuffer.length > MAX_JP2_DECODE_BYTES) {
|
|
270
272
|
debugLog(
|
|
271
273
|
'EID',
|
|
@@ -5,13 +5,13 @@ import { Buffer } from 'buffer';
|
|
|
5
5
|
* Native JPEG2000 decoder bridge.
|
|
6
6
|
*
|
|
7
7
|
* The passport chip portrait (DG2) is frequently stored as JPEG2000
|
|
8
|
-
* (image/jp2). React Native's <Image>
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* iOS
|
|
13
|
-
*
|
|
14
|
-
*
|
|
8
|
+
* (image/jp2). React Native's <Image> CANNOT render a JP2 data URI on EITHER
|
|
9
|
+
* platform — iOS's UIImage-backed <Image> refuses it, and Android's Fresco/Skia
|
|
10
|
+
* pipeline has no JPEG2000 decoder (the chip photo showed as a blank/white
|
|
11
|
+
* placeholder). Both platforms therefore need a native round-trip to JPEG:
|
|
12
|
+
* - iOS: ImageIO decodes JPEG2000 natively.
|
|
13
|
+
* - Android: the bundled pure-Java jj2000 decoder (no ImageIO/NDK).
|
|
14
|
+
* Both are exposed as the `ImageDecoderModule.decodeJp2ToJpeg` native method.
|
|
15
15
|
*/
|
|
16
16
|
interface ImageDecoderNativeModule {
|
|
17
17
|
decodeJp2ToJpeg(base64Jp2: string): Promise<string>;
|
|
@@ -22,16 +22,20 @@ const ImageDecoder = (
|
|
|
22
22
|
).ImageDecoderModule;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Decode a JPEG2000 buffer to JPEG using the native iOS
|
|
25
|
+
* Decode a JPEG2000 buffer to JPEG using the native decoder (iOS ImageIO /
|
|
26
|
+
* Android jj2000).
|
|
26
27
|
*
|
|
27
28
|
* Returns the JPEG bytes + mime type on success, or null when native decode is
|
|
28
|
-
* unavailable (
|
|
29
|
-
*
|
|
29
|
+
* unavailable (the module isn't linked) or fails — callers should fall back to
|
|
30
|
+
* their existing behaviour (keep raw JP2).
|
|
30
31
|
*/
|
|
31
32
|
export async function decodeJp2ToJpeg(
|
|
32
33
|
jp2Buffer: Buffer
|
|
33
34
|
): Promise<{ base64: string; mimeType: string } | null> {
|
|
34
|
-
if (
|
|
35
|
+
if (
|
|
36
|
+
(Platform.OS !== 'ios' && Platform.OS !== 'android') ||
|
|
37
|
+
!ImageDecoder?.decodeJp2ToJpeg
|
|
38
|
+
) {
|
|
35
39
|
return null;
|
|
36
40
|
}
|
|
37
41
|
try {
|