@ekyc_qoobiss/qbs-ect-cmp 3.6.27 → 3.6.28

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.
Files changed (148) hide show
  1. package/dist/cjs/agreement-check_19.cjs.entry.js +9498 -0
  2. package/dist/cjs/base-component-aa9e52bf.js +832 -0
  3. package/dist/cjs/index-41696e0e.js +1573 -0
  4. package/dist/cjs/index.cjs.js +2 -0
  5. package/dist/cjs/loader-dots.cjs.entry.js +19 -0
  6. package/dist/cjs/loader.cjs.js +22 -0
  7. package/dist/cjs/qbs-ect-cmp.cjs.js +23 -0
  8. package/dist/cjs/random-actions.cjs.entry.js +23 -0
  9. package/dist/collection/assets/canvas-masks/face_green.svg +8 -0
  10. package/dist/collection/assets/canvas-masks/face_white.svg +8 -0
  11. package/dist/collection/assets/canvas-masks/id_green.svg +6 -0
  12. package/dist/collection/assets/canvas-masks/id_white.svg +6 -0
  13. package/dist/collection/assets/complete.svg +4 -0
  14. package/dist/collection/assets/landing/device.svg +14 -0
  15. package/dist/collection/assets/landing/id.svg +3 -0
  16. package/dist/collection/assets/landing/info.svg +3 -0
  17. package/dist/collection/assets/landing/validation.svg +16 -0
  18. package/dist/collection/assets/loader.svg +29 -0
  19. package/dist/collection/collection-manifest.json +32 -0
  20. package/dist/collection/components/base-component.js +63 -0
  21. package/dist/collection/components/common/agreement-check/agreement-check.css +0 -0
  22. package/dist/collection/components/common/agreement-check/agreement-check.js +104 -0
  23. package/dist/collection/components/common/camera-error/camera-error.css +0 -0
  24. package/dist/{qbs-ect-cmp/camera-error.entry.js → collection/components/common/camera-error/camera-error.js} +52 -20
  25. package/dist/collection/components/common/capture-error/capture-error.css +0 -0
  26. package/dist/{qbs-ect-cmp/capture-error.entry.js → collection/components/common/capture-error/capture-error.js} +63 -16
  27. package/dist/collection/components/common/how-to-info/how-to-info.css +0 -0
  28. package/dist/collection/components/common/how-to-info/how-to-info.js +121 -0
  29. package/dist/collection/components/common/id-back-capture/id-back-capture.css +35 -0
  30. package/dist/{qbs-ect-cmp/id-back-capture.entry.js → collection/components/common/id-back-capture/id-back-capture.js} +94 -24
  31. package/dist/collection/components/common/id-capture/id-capture.css +35 -0
  32. package/dist/{qbs-ect-cmp/id-capture.entry.js → collection/components/common/id-capture/id-capture.js} +94 -24
  33. package/dist/collection/components/common/id-tilt/id-tilt.css +35 -0
  34. package/dist/{qbs-ect-cmp/id-tilt.entry.js → collection/components/common/id-tilt/id-tilt.js} +94 -24
  35. package/dist/collection/components/common/random-actions/random-actions.css +0 -0
  36. package/dist/collection/components/common/random-actions/random-actions.js +24 -0
  37. package/dist/collection/components/common/selfie-capture/selfie-capture.css +7 -0
  38. package/dist/{qbs-ect-cmp/selfie-capture.entry.js → collection/components/common/selfie-capture/selfie-capture.js} +95 -24
  39. package/dist/collection/components/common/selfie-tilt/selfie-tilt.css +7 -0
  40. package/dist/{qbs-ect-cmp/selfie-tilt.entry.js → collection/components/common/selfie-tilt/selfie-tilt.js} +95 -24
  41. package/dist/collection/components/controls/camera/camera.css +47 -0
  42. package/dist/collection/components/controls/camera/camera.js +289 -0
  43. package/dist/collection/components/controls/loader-dots/loader-dots.css +61 -0
  44. package/dist/collection/components/controls/loader-dots/loader-dots.js +18 -0
  45. package/dist/collection/components/flow/agreement-info/agreement-info.css +0 -0
  46. package/dist/{qbs-ect-cmp/agreement-info.entry.js → collection/components/flow/agreement-info/agreement-info.js} +57 -18
  47. package/dist/collection/components/flow/end-redirect/end-redirect.css +128 -0
  48. package/dist/collection/components/flow/end-redirect/end-redirect.js +47 -0
  49. package/dist/collection/components/flow/error-end/error-end.css +0 -0
  50. package/dist/collection/components/flow/error-end/error-end.js +61 -0
  51. package/dist/collection/components/flow/landing-validation/landing-validation.css +0 -0
  52. package/dist/collection/components/flow/landing-validation/landing-validation.js +122 -0
  53. package/dist/collection/components/flow/mobile-redirect/mobile-redirect.css +10 -0
  54. package/dist/collection/components/flow/mobile-redirect/mobile-redirect.js +143 -0
  55. package/dist/collection/components/flow/process-id/process-id.css +0 -0
  56. package/dist/{qbs-ect-cmp/process-id.entry.js → collection/components/flow/process-id/process-id.js} +100 -32
  57. package/dist/collection/components/flow/sms-code-validation/sms-code-validation.css +0 -0
  58. package/dist/{qbs-ect-cmp/sms-code-validation.entry.js → collection/components/flow/sms-code-validation/sms-code-validation.js} +63 -30
  59. package/dist/collection/components/flow/user-liveness/user-liveness.css +0 -0
  60. package/dist/{qbs-ect-cmp/user-liveness.entry.js → collection/components/flow/user-liveness/user-liveness.js} +91 -25
  61. package/dist/collection/components/identification-component/identification-component.css +991 -0
  62. package/dist/collection/components/identification-component/identification-component.js +408 -0
  63. package/dist/collection/global.js +0 -0
  64. package/dist/collection/helpers/ApiCall.js +223 -0
  65. package/dist/{qbs-ect-cmp/Cameras-dfbebc29.js → collection/helpers/Cameras.js} +6 -9
  66. package/dist/collection/helpers/DeviceDetection.js +85 -0
  67. package/dist/collection/helpers/Events.js +58 -0
  68. package/dist/collection/helpers/ML5.js +38 -0
  69. package/dist/collection/helpers/Stream.js +229 -0
  70. package/dist/collection/helpers/TranslationUtils.js +37 -0
  71. package/dist/collection/helpers/canvas.js +10 -0
  72. package/dist/collection/helpers/index.js +21 -0
  73. package/dist/collection/helpers/security.js +25 -0
  74. package/dist/collection/helpers/store.js +48 -0
  75. package/dist/collection/helpers/textValues.js +48 -0
  76. package/dist/collection/index.js +1 -0
  77. package/dist/collection/libs/FaceML5Detector/FaceML5Detector.js +182 -0
  78. package/dist/collection/libs/FaceML5Detector/FacePose.js +85 -0
  79. package/dist/collection/libs/IDML5Detector/IDML5Detector.js +99 -0
  80. package/dist/{qbs-ect-cmp/IDPose-181bcb25.js → collection/libs/IDML5Detector/IDPose.js} +2 -4
  81. package/dist/{qbs-ect-cmp/CaptureFlow-db5d90a4.js → collection/models/CaptureFlow.js} +4 -6
  82. package/dist/collection/models/FlowStatus.js +14 -0
  83. package/dist/collection/models/FlowSteps.js +30 -0
  84. package/dist/collection/models/IAbortResult.js +1 -0
  85. package/dist/collection/models/IAddRequest.js +1 -0
  86. package/dist/collection/models/IAgreement.js +1 -0
  87. package/dist/collection/models/ICamera.js +1 -0
  88. package/dist/{qbs-ect-cmp/IDevice-15ecfdeb.js → collection/models/IDevice.js} +4 -6
  89. package/dist/collection/models/IEctStore.js +1 -0
  90. package/dist/collection/models/IGeneration.js +1 -0
  91. package/dist/collection/models/ILinkSend.js +1 -0
  92. package/dist/collection/models/ILogResult.js +1 -0
  93. package/dist/collection/models/IOrderStatus.js +1 -0
  94. package/dist/collection/models/IOtpCheck.js +1 -0
  95. package/dist/collection/models/IOtpSend.js +1 -0
  96. package/dist/collection/models/ITranslationValues.js +1 -0
  97. package/dist/collection/models/IUploadFile.js +1 -0
  98. package/dist/collection/models/IVerificationMode.js +5 -0
  99. package/dist/collection/models/OrderStatuses.js +8 -0
  100. package/dist/{qbs-ect-cmp/utils-8225f0b7.js → collection/utils/utils.js} +8 -10
  101. package/dist/esm/agreement-check_19.entry.js +9476 -0
  102. package/dist/{qbs-ect-cmp/base-component-2e490fd9.js → esm/base-component-b7f50d31.js} +384 -62
  103. package/dist/esm/index-cf54a432.js +1543 -0
  104. package/dist/esm/index.js +1 -0
  105. package/dist/{qbs-ect-cmp → esm}/loader-dots.entry.js +1 -1
  106. package/dist/esm/loader.js +18 -0
  107. package/dist/esm/polyfills/core-js.js +11 -0
  108. package/dist/esm/polyfills/css-shim.js +1 -0
  109. package/dist/esm/polyfills/dom.js +79 -0
  110. package/dist/esm/polyfills/es5-html-element.js +1 -0
  111. package/dist/esm/polyfills/index.js +34 -0
  112. package/dist/esm/polyfills/system.js +6 -0
  113. package/dist/esm/qbs-ect-cmp.js +18 -0
  114. package/dist/{qbs-ect-cmp → esm}/random-actions.entry.js +2 -4
  115. package/dist/index.cjs.js +1 -0
  116. package/dist/index.js +1 -0
  117. package/dist/loader/cdn.js +3 -0
  118. package/dist/loader/index.cjs.js +3 -0
  119. package/dist/loader/index.d.ts +21 -0
  120. package/dist/loader/index.es2017.js +3 -0
  121. package/dist/loader/index.js +4 -0
  122. package/dist/loader/package.json +11 -0
  123. package/dist/qbs-ect-cmp/index.esm.js +0 -1
  124. package/dist/qbs-ect-cmp/p-054dc5b3.entry.js +1 -0
  125. package/dist/qbs-ect-cmp/p-215a7e76.entry.js +1 -0
  126. package/dist/qbs-ect-cmp/p-7bedffaa.js +1 -0
  127. package/dist/qbs-ect-cmp/p-8942656c.js +2 -0
  128. package/dist/qbs-ect-cmp/p-c32a782a.entry.js +1373 -0
  129. package/dist/qbs-ect-cmp/qbs-ect-cmp.css +1 -320
  130. package/dist/qbs-ect-cmp/qbs-ect-cmp.esm.js +1 -148
  131. package/package.json +1 -1
  132. package/dist/qbs-ect-cmp/ML5-657ef934.js +0 -1370
  133. package/dist/qbs-ect-cmp/Stream-b867a2be.js +0 -3104
  134. package/dist/qbs-ect-cmp/_commonjsHelpers-321aa363.js +0 -44
  135. package/dist/qbs-ect-cmp/agreement-check.entry.js +0 -41
  136. package/dist/qbs-ect-cmp/app-globals-0f993ce5.js +0 -3
  137. package/dist/qbs-ect-cmp/camera-comp.entry.js +0 -103
  138. package/dist/qbs-ect-cmp/css-shim-b7d3d95f.js +0 -4
  139. package/dist/qbs-ect-cmp/dom-64053c71.js +0 -73
  140. package/dist/qbs-ect-cmp/end-redirect.entry.js +0 -25
  141. package/dist/qbs-ect-cmp/error-end.entry.js +0 -19
  142. package/dist/qbs-ect-cmp/how-to-info.entry.js +0 -52
  143. package/dist/qbs-ect-cmp/identification-component.entry.js +0 -909
  144. package/dist/qbs-ect-cmp/index-78a05b9e.js +0 -3371
  145. package/dist/qbs-ect-cmp/landing-validation.entry.js +0 -90
  146. package/dist/qbs-ect-cmp/mobile-redirect.entry.js +0 -2984
  147. package/dist/qbs-ect-cmp/shadow-css-98135883.js +0 -387
  148. package/dist/qbs-ect-cmp/textValues-6bcc85dd.js +0 -302
@@ -1,3104 +0,0 @@
1
- import { M as ML5 } from './ML5-657ef934.js';
2
- import { d as delay, b as blobToBase64 } from './utils-8225f0b7.js';
3
- import { s as state } from './textValues-6bcc85dd.js';
4
- import { c as createCommonjsModule } from './_commonjsHelpers-321aa363.js';
5
- import { M as MobileOS, B as Browser } from './IDevice-15ecfdeb.js';
6
-
7
- const idWhiteSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzM1IiBoZWlnaHQ9IjIzOCIgdmlld0JveD0iMCAwIDMzNSAyMzgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+DQo8cGF0aCBkPSJNMzM0Ljg4NiA0Ni45MjQxSDMyNy45MDhWNy45NzUzN0gyODguMjczVjAuOTkzMTY0SDMzNC44ODZWNDYuOTI0MVoiIGZpbGw9IiNFNkU2RTYiLz4NCjxwYXRoIGQ9Ik0zMzUuMDAxIDIzNy4wMDdIMjg5LjA3VjIzMC4wMjVIMzI4LjAxOVYxOTAuMzlIMzM1LjAwMVYyMzcuMDA3WiIgZmlsbD0iI0U2RTZFNiIvPg0KPHBhdGggZD0iTTQ2LjcyNzEgMjM3LjAwN0gwLjEwOTg2M1YxOTEuMDcySDcuMDkyMDdWMjMwLjAyNUg0Ni43MjcxVjIzNy4wMDdaIiBmaWxsPSIjRTZFNkU2Ii8+DQo8cGF0aCBkPSJNNi45ODE3MiA0Ny42MTA0SC0wLjAwMDQ4ODI4MVYwLjk5MzE2NEg0NS45MzA1VjcuOTc1MzdINi45ODE3MlY0Ny42MTA0WiIgZmlsbD0iI0U2RTZFNiIvPg0KPC9zdmc+DQo=';
8
-
9
- const idGreenSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzM1IiBoZWlnaHQ9IjIzOCIgdmlld0JveD0iMCAwIDMzNSAyMzgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+DQo8cGF0aCBkPSJNMzM0Ljg4NiA0Ni45MjQxSDMyNy45MDhWNy45NzUzN0gyODguMjczVjAuOTkzMTY0SDMzNC44ODZWNDYuOTI0MVoiIGZpbGw9IiM0Y2E1ODUiLz4NCjxwYXRoIGQ9Ik0zMzUuMDAxIDIzNy4wMDdIMjg5LjA3VjIzMC4wMjVIMzI4LjAxOVYxOTAuMzlIMzM1LjAwMVYyMzcuMDA3WiIgZmlsbD0iIzRjYTU4NSIvPg0KPHBhdGggZD0iTTQ2LjcyNzEgMjM3LjAwN0gwLjEwOTg2M1YxOTEuMDcySDcuMDkyMDdWMjMwLjAyNUg0Ni43MjcxVjIzNy4wMDdaIiBmaWxsPSIjNGNhNTg1Ii8+DQo8cGF0aCBkPSJNNi45ODE3MiA0Ny42MTA0SC0wLjAwMDQ4ODI4MVYwLjk5MzE2NEg0NS45MzA1VjcuOTc1MzdINi45ODE3MlY0Ny42MTA0WiIgZmlsbD0iIzRjYTU4NSIvPg0KPC9zdmc+DQo=';
10
-
11
- var VerificationMode;
12
- (function (VerificationMode) {
13
- VerificationMode[VerificationMode["Full"] = 0] = "Full";
14
- VerificationMode[VerificationMode["Tilt"] = 1] = "Tilt";
15
- })(VerificationMode || (VerificationMode = {}));
16
-
17
- class IDML5Detector {
18
- static getInstance(stream, isMobile) {
19
- if (!IDML5Detector.instance) {
20
- IDML5Detector.instance = new IDML5Detector(stream, isMobile);
21
- }
22
- return IDML5Detector.instance;
23
- }
24
- constructor(stream, _isMobile) {
25
- this.MAX_DETECTION = 1000 * 25;
26
- this.initTime = null;
27
- this.checked = false;
28
- this.start = null;
29
- this.stream = stream;
30
- this.ml5 = ML5.getInstance();
31
- }
32
- updateHtmlElements(videoElement, canvasElement, _component) {
33
- this.videoElement = videoElement;
34
- this.canvasElement = canvasElement;
35
- // this.component = component;
36
- }
37
- initDetector(mode) {
38
- this.initTime = Date.now();
39
- this.continue = true;
40
- if (mode == VerificationMode.Full)
41
- this.targetedLabel = 'full';
42
- else
43
- this.targetedLabel = 'tilted';
44
- // this.width = this.videoElement.videoWidth;
45
- // this.height = this.videoElement.videoHeight;
46
- this.drawFrame('white');
47
- delay(2000).then(() => this.classifyVideo());
48
- }
49
- classifyVideo() {
50
- if (this.checked) {
51
- if (this.start == null)
52
- this.start = Date.now();
53
- if (Date.now() > this.start + 500) {
54
- this.continue = false;
55
- this.stream.verificationReady();
56
- }
57
- }
58
- if (Date.now() - this.initTime >= this.MAX_DETECTION) {
59
- this.continue = false;
60
- this.stream.timeElapsed();
61
- }
62
- if (this.continue)
63
- this.ml5.classifier.classify(this.videoElement, this.gotResults.bind(this));
64
- }
65
- async gotResults(error, results) {
66
- if (error) {
67
- alert(error);
68
- this.stream.timeElapsed();
69
- return;
70
- }
71
- if (results[0].label == this.targetedLabel && results[0].confidence > 0.9 && !this.checked) {
72
- this.checked = true;
73
- this.stream.autoCapturing();
74
- await this.drawFrame('green');
75
- }
76
- if (results[0].label == this.targetedLabel && results[0].confidence > 0.8 && !this.checked) {
77
- this.checked = true;
78
- await this.drawFrame('green');
79
- }
80
- this.classifyVideo();
81
- }
82
- async drawFrame(color, persistent = false) {
83
- return new Promise(resolve => {
84
- const img = new Image();
85
- if (color == 'green')
86
- img.src = idGreenSvg;
87
- else
88
- img.src = idWhiteSvg;
89
- img.onload = async () => {
90
- const canvas = this.canvasElement;
91
- const canvasContext = canvas.getContext('2d');
92
- const hRatio = canvas.width / img.width;
93
- const vRatio = canvas.height / img.height;
94
- const ratio = Math.min(hRatio, vRatio);
95
- const paddingX = 150;
96
- const paddingY = 150;
97
- const centerShift_x = (canvas.width - img.width * ratio) / 2;
98
- const centerShift_y = (canvas.height - img.height * ratio) / 2;
99
- canvasContext.drawImage(img, 0, 0, img.width, img.height, centerShift_x + paddingX, centerShift_y + paddingY, img.width * ratio - paddingX * 2, img.height * ratio - paddingY * 2);
100
- if (color != 'white' && !persistent) {
101
- await delay(1000);
102
- this.drawFrame('white');
103
- }
104
- resolve();
105
- };
106
- });
107
- }
108
- }
109
-
110
- var FacePose;
111
- (function (FacePose) {
112
- FacePose[FacePose["LookLeft"] = 0] = "LookLeft";
113
- FacePose[FacePose["LookRight"] = 1] = "LookRight";
114
- FacePose[FacePose["LookUp"] = 2] = "LookUp";
115
- FacePose[FacePose["LookDown"] = 3] = "LookDown";
116
- //TiltLeft,
117
- //TiltRight,
118
- FacePose[FacePose["Main"] = 4] = "Main";
119
- })(FacePose || (FacePose = {}));
120
- class FacePosePick {
121
- static randomEnum(anEnum) {
122
- const enumValues = Object.keys(anEnum)
123
- .map(n => Number.parseInt(n))
124
- .filter(n => !Number.isNaN(n));
125
- const randomIndex = Math.floor(Math.random() * (enumValues.length - 1));
126
- const randomEnumValue = enumValues[randomIndex];
127
- return randomEnumValue;
128
- }
129
- }
130
- class FaceLandmarks {
131
- constructor(result, w, h) {
132
- this.leftEye = this.centerOfPoints(result.parts.rightEye, w, h);
133
- this.rightEye = this.centerOfPoints(result.parts.leftEye, w, h);
134
- this.leftEyeBrow = this.centerOfPoints(result.parts.rightEyeBrow, w, h);
135
- this.rightEyeBrow = this.centerOfPoints(result.parts.leftEyeBrow, w, h);
136
- this.mouth = this.centerOfPoints(result.parts.mouth, w, h);
137
- this.nose = this.centerOfPoints(result.parts.nose, w, h);
138
- }
139
- eyesDistance() {
140
- return Math.round(Math.hypot(this.leftEye.x - this.rightEye.x, this.leftEye.y - this.rightEye.y));
141
- }
142
- eyesLevel() {
143
- return Math.round(this.leftEye.y - this.rightEye.y);
144
- }
145
- eyesCenter() {
146
- var fp = new FacePoint();
147
- fp.x = Math.round((this.leftEye.x + this.rightEye.x) / 2);
148
- fp.y = Math.round((this.leftEye.y + this.rightEye.y) / 2);
149
- return fp;
150
- }
151
- leftEyeNoseDistanceX() {
152
- return Math.abs(this.leftEye.x - this.nose.x);
153
- }
154
- rightEyeNoseDistanceX() {
155
- return Math.abs(this.rightEye.x - this.nose.x);
156
- }
157
- leftEyeNoseDistanceY() {
158
- return Math.abs(this.leftEye.y - this.nose.y);
159
- }
160
- rightEyeNoseDistanceY() {
161
- return Math.abs(this.rightEye.y - this.nose.y);
162
- }
163
- eyesNoseDistance() {
164
- return Math.round(Math.hypot(this.eyesCenter().x - this.nose.x, this.eyesCenter().y - this.nose.y));
165
- }
166
- noseMouthDistance() {
167
- return Math.round(Math.hypot(this.nose.x - this.mouth.x, this.nose.y - this.mouth.y));
168
- }
169
- eyesMouthDistance() {
170
- return Math.round(Math.hypot(this.eyesCenter().x - this.mouth.x, this.eyesCenter().y - this.mouth.y));
171
- }
172
- leftEyeEyeBrowDistance() {
173
- return Math.round(Math.hypot(this.leftEye.x - this.leftEyeBrow.x, this.leftEye.y - this.leftEyeBrow.y));
174
- }
175
- rightEyeEyeBrowDistance() {
176
- return Math.round(Math.hypot(this.rightEye.x - this.rightEyeBrow.x, this.rightEye.y - this.rightEyeBrow.y));
177
- }
178
- centerOfPoints(arr, _width, _height) {
179
- var minX, maxX, minY, maxY;
180
- for (var i = 0; i < arr.length; i++) {
181
- minX = arr[i].x < minX || minX == null ? arr[i].x : minX;
182
- maxX = arr[i].x > maxX || maxX == null ? arr[i].x : maxX;
183
- minY = arr[i].y < minY || minY == null ? arr[i].y : minY;
184
- maxY = arr[i].y > maxY || maxY == null ? arr[i].y : maxY;
185
- }
186
- var point = [(minX + maxX) / 2, (minY + maxY) / 2];
187
- var fp = new FacePoint();
188
- fp.x = Math.round(point[0]);
189
- fp.y = Math.round(point[1]);
190
- return fp;
191
- }
192
- }
193
- class FacePoint {
194
- }
195
-
196
- const faceWhiteSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUwIiBoZWlnaHQ9IjIyNC45OTk5OTk5OTk5OTk5NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHZlcnNpb249IjEuMSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQogPGc+DQogIDx0aXRsZT5MYXllciAxPC90aXRsZT4NCiAgPGcgc3Ryb2tlPSJudWxsIiBpZD0iTGF5ZXIgMSI+DQogICA8cGF0aCBzdHJva2U9IiNmZmZmZmYiIGlkPSJzdmdfMSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZmlsbD0ibm9uZSIgZD0ibTc0LjI3NzY1LDYuOTI3NjFjLTExLjM3NTk3LC0wLjAxNzEzIC0zMy41NjU1MSw1LjEwNDMzIC00Ni44MTMxNiwxOS40OTQ4MWMtNi43NDE0Myw3LjMyMjkyIC0xOC4xMjI2OSwyMy4wNjk2NyAtMTkuMjY3NTgsNTkuNjEzNjljLTAuNTE5MDYsMTYuNTY5MjEgNS4wNDUyNCw2MC42MjUzMyAxMC4yNDAwNiw3Ni40Njc3NWMzLjYzMTMsMTEuMDc0NjggMjcuNDgyMTUsNDMuOTMzNDkgNDQuNDkwNiw1My42ODI1MWM0LjgwNzkxLDIuNzU1NDYgMTEuMjk2NjgsMi42ODI1MSAxMi40MjI1NSwyLjY4MjUxYzEuMTg4NzYsLTAuMDg0NTcgNy4zMzAyNiwwLjA3Mjk0IDEyLjEzNzY1LC0yLjY4MjUxYzE3LjAwODQ2LC05Ljc0OTAyIDQwLjQwMjA4LC00Mi43Njg1MSA0NC40OTA2LC01My42ODI1MWM0LjQwMDM4LC0xMS43NDQ5MSAxMC43NTk2NSwtNTkuODk4NTQgMTAuMjQwMDYsLTc2LjQ2Nzc1Yy0xLjE0NDg5LC0zNi41NDQwMiAtMTIuNTI2MTUsLTUyLjI5MDc3IC0xOS4yNjc1OCwtNTkuNjEzNjljLTEzLjI0NzY1LC0xNC4zOTA0OCAtMzUuMzA2NjMsLTE5LjUyOTMzIC00Ni43NzgyNywtMTkuNDk0ODFjLTAuNzQ2ODgsMC4wMDIyMiAtMS44OTQ5NCwwIC0xLjg5NDk0LDB6IiBzdHJva2Utd2lkdGg9IjciLz4NCiAgPC9nPg0KIDwvZz4NCjwvc3ZnPg0K';
197
-
198
- const faceGreenSvg = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUwIiBoZWlnaHQ9IjIyNC45OTk5OTk5OTk5OTk5NyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIHZlcnNpb249IjEuMSIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQogPGc+DQogIDx0aXRsZT5MYXllciAxPC90aXRsZT4NCiAgPGcgc3Ryb2tlPSJudWxsIiBpZD0iTGF5ZXIgMSI+DQogICA8cGF0aCBzdHJva2U9IiM0Y2E1ODUiIGlkPSJzdmdfMSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZmlsbD0ibm9uZSIgZD0ibTc0LjI3NzY1LDYuOTI3NjFjLTExLjM3NTk3LC0wLjAxNzEzIC0zMy41NjU1MSw1LjEwNDMzIC00Ni44MTMxNiwxOS40OTQ4MWMtNi43NDE0Myw3LjMyMjkyIC0xOC4xMjI2OSwyMy4wNjk2NyAtMTkuMjY3NTgsNTkuNjEzNjljLTAuNTE5MDYsMTYuNTY5MjEgNS4wNDUyNCw2MC42MjUzMyAxMC4yNDAwNiw3Ni40Njc3NWMzLjYzMTMsMTEuMDc0NjggMjcuNDgyMTUsNDMuOTMzNDkgNDQuNDkwNiw1My42ODI1MWM0LjgwNzkxLDIuNzU1NDYgMTEuMjk2NjgsMi42ODI1MSAxMi40MjI1NSwyLjY4MjUxYzEuMTg4NzYsLTAuMDg0NTcgNy4zMzAyNiwwLjA3Mjk0IDEyLjEzNzY1LC0yLjY4MjUxYzE3LjAwODQ2LC05Ljc0OTAyIDQwLjQwMjA4LC00Mi43Njg1MSA0NC40OTA2LC01My42ODI1MWM0LjQwMDM4LC0xMS43NDQ5MSAxMC43NTk2NSwtNTkuODk4NTQgMTAuMjQwMDYsLTc2LjQ2Nzc1Yy0xLjE0NDg5LC0zNi41NDQwMiAtMTIuNTI2MTUsLTUyLjI5MDc3IC0xOS4yNjc1OCwtNTkuNjEzNjljLTEzLjI0NzY1LC0xNC4zOTA0OCAtMzUuMzA2NjMsLTE5LjUyOTMzIC00Ni43NzgyNywtMTkuNDk0ODFjLTAuNzQ2ODgsMC4wMDIyMiAtMS44OTQ5NCwwIC0xLjg5NDk0LDB6IiBzdHJva2Utd2lkdGg9IjciLz4NCiAgPC9nPg0KIDwvZz4NCjwvc3ZnPg0K';
199
-
200
- class FaceML5Detector {
201
- static getInstance(stream, isMobile) {
202
- if (!FaceML5Detector.instance) {
203
- FaceML5Detector.instance = new FaceML5Detector(stream, isMobile);
204
- }
205
- return FaceML5Detector.instance;
206
- }
207
- constructor(stream, isMobile) {
208
- this.MAX_DETECTION = 1000 * 30;
209
- this.initTime = null;
210
- this.validFaceFound = false;
211
- this.start = null;
212
- this.frontFace = null;
213
- this.presentedFacePose = null;
214
- this.validFacePose = false;
215
- this.checkPose = false;
216
- this.MAX_NUMBER_FACES = 1;
217
- this.MIN_FACE_SCORE = 0.65;
218
- // private readonly MIN_FACE_SIZE_FOR_MOBILE = 200;
219
- // private readonly MIN_FACE_SIZE_FOR_DESKTOP = 350;
220
- this.MIN_OCCUPIED_SPACE_FOR_DESKTOP = 15;
221
- this.MIN_OCCUPIED_SPACE_FOR_MOBILE = 20;
222
- this.X_OFFSET_FROM_FRAME = 0;
223
- this.Y_OFFSET_FROM_FRAME = 0;
224
- this.stream = stream;
225
- this.ml5 = ML5.getInstance();
226
- this.isMobile = isMobile;
227
- }
228
- updateHtmlElements(videoElement, canvasElement, _component) {
229
- this.videoElement = videoElement;
230
- this.canvasElement = canvasElement;
231
- // this.component = component;
232
- }
233
- initDetector(mode) {
234
- this.initTime = Date.now();
235
- this.continue = true;
236
- this.checkPose = mode == VerificationMode.Tilt;
237
- this.width = this.videoElement.videoWidth;
238
- this.height = this.videoElement.videoHeight;
239
- // this.videoRatio = getVideoRatio(this.videoElement);
240
- this.drawFrame('white');
241
- delay(2000).then(() => this.detectFaces());
242
- }
243
- detectFaces() {
244
- if (this.validFaceFound || this.validFacePose) {
245
- if (this.start == null)
246
- this.start = Date.now();
247
- if (Date.now() > this.start + 3000) {
248
- this.continue = false;
249
- this.stream.verificationReady();
250
- }
251
- }
252
- else if (Date.now() - this.initTime >= this.MAX_DETECTION) {
253
- this.continue = false;
254
- this.stream.timeElapsed();
255
- }
256
- // if (this.presentedFacePose != null && !this.validFacePose) {
257
- // this.continue = false;
258
- // this.stream.timeElapsed();
259
- // }
260
- if (this.continue)
261
- this.ml5.faceapi.detect(this.videoElement, this.gotResults.bind(this));
262
- }
263
- async gotResults(error, results) {
264
- if (error) {
265
- alert(error);
266
- this.stream.timeElapsed();
267
- return;
268
- }
269
- if (results.length > 0) {
270
- if (this.checkPose) {
271
- await this.checkFacePose(results);
272
- }
273
- else {
274
- if (this.isSingleFace(results) && this.checkProbability(results) && this.checkFaceSize(results) && this.checkFaceIndent(results)) {
275
- if (!this.validFaceFound) {
276
- this.validFaceFound = true;
277
- this.stream.autoCapturing();
278
- // this.frontFace = new FaceLandmarks(results[0], this.width, this.height);
279
- await this.drawFrame('green', true);
280
- }
281
- }
282
- }
283
- }
284
- this.detectFaces();
285
- }
286
- async drawFrame(color, persistent = false) {
287
- return new Promise(resolve => {
288
- const img = new Image();
289
- if (color == 'green')
290
- img.src = faceGreenSvg;
291
- else
292
- img.src = faceWhiteSvg;
293
- img.onload = async () => {
294
- const canvas = this.canvasElement;
295
- const canvasContext = canvas.getContext('2d');
296
- const hRatio = canvas.width / img.width;
297
- const vRatio = canvas.height / img.height;
298
- const ratio = Math.min(hRatio, vRatio);
299
- const portraitOrientation = canvas.width < canvas.height;
300
- const paddingX = !portraitOrientation ? 40 : 80;
301
- const paddingY = portraitOrientation ? 160 : 80;
302
- const centerShift_x = (canvas.width - img.width * ratio) / 2;
303
- const centerShift_y = (canvas.height - img.height * ratio) / 2;
304
- canvasContext.drawImage(img, 0, 0, img.width, img.height, centerShift_x + paddingX, centerShift_y + paddingY, img.width * ratio - paddingX * 2, img.height * ratio - paddingY * 2);
305
- if (color != 'white' && !persistent) {
306
- await delay(1000);
307
- this.drawFrame('white');
308
- }
309
- resolve();
310
- };
311
- });
312
- }
313
- isSingleFace(results) {
314
- return results.length == this.MAX_NUMBER_FACES;
315
- }
316
- checkProbability(result) {
317
- // console.log('prob: ' + result[0].detection.score);
318
- return result[0].detection.score > this.MIN_FACE_SCORE;
319
- }
320
- checkFaceSize(result) {
321
- const faceBox = result[0].detection.box;
322
- const { area } = faceBox;
323
- // const { width, height, area } = faceBox;
324
- const { imageHeight, imageWidth } = result[0].detection;
325
- const occupiedSize = 100 / ((imageHeight * imageWidth) / area);
326
- // const minSide = Math.min(width / this.videoRatio, height / this.videoRatio);
327
- // console.log('size: ' + occupiedSize +'/'+(this.isMobile ? this.MIN_OCCUPIED_SPACE_FOR_MOBILE : this.MIN_OCCUPIED_SPACE_FOR_DESKTOP));
328
- return (
329
- // minSide > (this.isMobile ? this.MIN_FACE_SIZE_FOR_MOBILE : this.MIN_FACE_SIZE_FOR_DESKTOP) &&
330
- occupiedSize > (this.isMobile ? this.MIN_OCCUPIED_SPACE_FOR_MOBILE : this.MIN_OCCUPIED_SPACE_FOR_DESKTOP));
331
- }
332
- checkFaceIndent(result) {
333
- const faceBox = result[0].detection.box;
334
- const { top, left, bottom, right } = faceBox;
335
- const { imageHeight, imageWidth } = result[0].detection;
336
- const topIndent = (top * 100) / imageHeight;
337
- const leftIndent = (left * 100) / imageWidth;
338
- const rightIndent = ((imageWidth - right) * 100) / imageWidth;
339
- const bottomIndent = ((imageHeight - bottom) * 100) / imageHeight;
340
- // console.log('indent: '+topIndent+' | '+leftIndent+' | '+rightIndent+' | '+bottomIndent);
341
- return !(topIndent < this.Y_OFFSET_FROM_FRAME || leftIndent < this.X_OFFSET_FROM_FRAME || rightIndent < this.X_OFFSET_FROM_FRAME || bottomIndent < this.Y_OFFSET_FROM_FRAME);
342
- }
343
- async checkFacePose(results) {
344
- let face = new FaceLandmarks(results[0], this.width, this.height);
345
- // this.drawLandmarks(results);
346
- // this.drawPoints(face);
347
- if (this.frontFace == null) {
348
- this.frontFace = face;
349
- // await this.drawFrame('green');
350
- if (state.debug)
351
- console.log('face ok');
352
- }
353
- else if (this.frontFace != null && this.presentedFacePose == null) {
354
- let ff = this.frontFace;
355
- if (face.nose.y < ff.nose.y - ff.eyesDistance() * 0.4)
356
- this.presentedFacePose = FacePose.LookUp;
357
- if (face.nose.y > ff.nose.y + ff.eyesDistance() * 0.4)
358
- this.presentedFacePose = FacePose.LookDown;
359
- if (face.nose.x > ff.nose.x + ff.eyesDistance() * 0.5)
360
- this.presentedFacePose = FacePose.LookLeft;
361
- if (face.nose.x < ff.nose.x - ff.eyesDistance() * 0.5)
362
- this.presentedFacePose = FacePose.LookRight;
363
- if (this.stream.facePose !== null) {
364
- await delay(3000);
365
- this.validFacePose = true;
366
- await this.drawFrame('green', true);
367
- }
368
- }
369
- }
370
- }
371
-
372
- var piexif = createCommonjsModule(function (module, exports) {
373
- /* piexifjs
374
-
375
- The MIT License (MIT)
376
-
377
- Copyright (c) 2014, 2015 hMatoba(https://github.com/hMatoba)
378
-
379
- Permission is hereby granted, free of charge, to any person obtaining a copy
380
- of this software and associated documentation files (the "Software"), to deal
381
- in the Software without restriction, including without limitation the rights
382
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
383
- copies of the Software, and to permit persons to whom the Software is
384
- furnished to do so, subject to the following conditions:
385
-
386
- The above copyright notice and this permission notice shall be included in all
387
- copies or substantial portions of the Software.
388
-
389
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
390
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
391
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
392
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
393
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
394
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
395
- SOFTWARE.
396
- */
397
-
398
- (function () {
399
- "use strict";
400
- var that = {};
401
- that.version = "1.0.4";
402
-
403
- that.remove = function (jpeg) {
404
- var b64 = false;
405
- if (jpeg.slice(0, 2) == "\xff\xd8") {
406
- } else if (jpeg.slice(0, 23) == "data:image/jpeg;base64," || jpeg.slice(0, 22) == "data:image/jpg;base64,") {
407
- jpeg = atob(jpeg.split(",")[1]);
408
- b64 = true;
409
- } else {
410
- throw new Error("Given data is not jpeg.");
411
- }
412
-
413
- var segments = splitIntoSegments(jpeg);
414
- var newSegments = segments.filter(function(seg){
415
- return !(seg.slice(0, 2) == "\xff\xe1" &&
416
- seg.slice(4, 10) == "Exif\x00\x00");
417
- });
418
-
419
- var new_data = newSegments.join("");
420
- if (b64) {
421
- new_data = "data:image/jpeg;base64," + btoa(new_data);
422
- }
423
-
424
- return new_data;
425
- };
426
-
427
-
428
- that.insert = function (exif, jpeg) {
429
- var b64 = false;
430
- if (exif.slice(0, 6) != "\x45\x78\x69\x66\x00\x00") {
431
- throw new Error("Given data is not exif.");
432
- }
433
- if (jpeg.slice(0, 2) == "\xff\xd8") {
434
- } else if (jpeg.slice(0, 23) == "data:image/jpeg;base64," || jpeg.slice(0, 22) == "data:image/jpg;base64,") {
435
- jpeg = atob(jpeg.split(",")[1]);
436
- b64 = true;
437
- } else {
438
- throw new Error("Given data is not jpeg.");
439
- }
440
-
441
- var exifStr = "\xff\xe1" + pack(">H", [exif.length + 2]) + exif;
442
- var segments = splitIntoSegments(jpeg);
443
- var new_data = mergeSegments(segments, exifStr);
444
- if (b64) {
445
- new_data = "data:image/jpeg;base64," + btoa(new_data);
446
- }
447
-
448
- return new_data;
449
- };
450
-
451
-
452
- that.load = function (data) {
453
- var input_data;
454
- if (typeof (data) == "string") {
455
- if (data.slice(0, 2) == "\xff\xd8") {
456
- input_data = data;
457
- } else if (data.slice(0, 23) == "data:image/jpeg;base64," || data.slice(0, 22) == "data:image/jpg;base64,") {
458
- input_data = atob(data.split(",")[1]);
459
- } else if (data.slice(0, 4) == "Exif") {
460
- input_data = data.slice(6);
461
- } else {
462
- throw new Error("'load' gots invalid file data.");
463
- }
464
- } else {
465
- throw new Error("'load' gots invalid type argument.");
466
- }
467
-
468
- var exifDict = {};
469
- var exif_dict = {
470
- "0th": {},
471
- "Exif": {},
472
- "GPS": {},
473
- "Interop": {},
474
- "1st": {},
475
- "thumbnail": null
476
- };
477
- var exifReader = new ExifReader(input_data);
478
- if (exifReader.tiftag === null) {
479
- return exif_dict;
480
- }
481
-
482
- if (exifReader.tiftag.slice(0, 2) == "\x49\x49") {
483
- exifReader.endian_mark = "<";
484
- } else {
485
- exifReader.endian_mark = ">";
486
- }
487
-
488
- var pointer = unpack(exifReader.endian_mark + "L",
489
- exifReader.tiftag.slice(4, 8))[0];
490
- exif_dict["0th"] = exifReader.get_ifd(pointer, "0th");
491
-
492
- var first_ifd_pointer = exif_dict["0th"]["first_ifd_pointer"];
493
- delete exif_dict["0th"]["first_ifd_pointer"];
494
-
495
- if (34665 in exif_dict["0th"]) {
496
- pointer = exif_dict["0th"][34665];
497
- exif_dict["Exif"] = exifReader.get_ifd(pointer, "Exif");
498
- }
499
- if (34853 in exif_dict["0th"]) {
500
- pointer = exif_dict["0th"][34853];
501
- exif_dict["GPS"] = exifReader.get_ifd(pointer, "GPS");
502
- }
503
- if (40965 in exif_dict["Exif"]) {
504
- pointer = exif_dict["Exif"][40965];
505
- exif_dict["Interop"] = exifReader.get_ifd(pointer, "Interop");
506
- }
507
- if (first_ifd_pointer != "\x00\x00\x00\x00") {
508
- pointer = unpack(exifReader.endian_mark + "L",
509
- first_ifd_pointer)[0];
510
- exif_dict["1st"] = exifReader.get_ifd(pointer, "1st");
511
- if ((513 in exif_dict["1st"]) && (514 in exif_dict["1st"])) {
512
- var end = exif_dict["1st"][513] + exif_dict["1st"][514];
513
- var thumb = exifReader.tiftag.slice(exif_dict["1st"][513], end);
514
- exif_dict["thumbnail"] = thumb;
515
- }
516
- }
517
-
518
- return exif_dict;
519
- };
520
-
521
-
522
- that.dump = function (exif_dict_original) {
523
- var TIFF_HEADER_LENGTH = 8;
524
-
525
- var exif_dict = copy(exif_dict_original);
526
- var header = "Exif\x00\x00\x4d\x4d\x00\x2a\x00\x00\x00\x08";
527
- var exif_is = false;
528
- var gps_is = false;
529
- var interop_is = false;
530
- var first_is = false;
531
-
532
- var zeroth_ifd,
533
- exif_ifd,
534
- interop_ifd,
535
- gps_ifd,
536
- first_ifd;
537
-
538
- if ("0th" in exif_dict) {
539
- zeroth_ifd = exif_dict["0th"];
540
- } else {
541
- zeroth_ifd = {};
542
- }
543
-
544
- if ((("Exif" in exif_dict) && (Object.keys(exif_dict["Exif"]).length)) ||
545
- (("Interop" in exif_dict) && (Object.keys(exif_dict["Interop"]).length))) {
546
- zeroth_ifd[34665] = 1;
547
- exif_is = true;
548
- exif_ifd = exif_dict["Exif"];
549
- if (("Interop" in exif_dict) && Object.keys(exif_dict["Interop"]).length) {
550
- exif_ifd[40965] = 1;
551
- interop_is = true;
552
- interop_ifd = exif_dict["Interop"];
553
- } else if (Object.keys(exif_ifd).indexOf(that.ExifIFD.InteroperabilityTag.toString()) > -1) {
554
- delete exif_ifd[40965];
555
- }
556
- } else if (Object.keys(zeroth_ifd).indexOf(that.ImageIFD.ExifTag.toString()) > -1) {
557
- delete zeroth_ifd[34665];
558
- }
559
-
560
- if (("GPS" in exif_dict) && (Object.keys(exif_dict["GPS"]).length)) {
561
- zeroth_ifd[that.ImageIFD.GPSTag] = 1;
562
- gps_is = true;
563
- gps_ifd = exif_dict["GPS"];
564
- } else if (Object.keys(zeroth_ifd).indexOf(that.ImageIFD.GPSTag.toString()) > -1) {
565
- delete zeroth_ifd[that.ImageIFD.GPSTag];
566
- }
567
-
568
- if (("1st" in exif_dict) &&
569
- ("thumbnail" in exif_dict) &&
570
- (exif_dict["thumbnail"] != null)) {
571
- first_is = true;
572
- exif_dict["1st"][513] = 1;
573
- exif_dict["1st"][514] = 1;
574
- first_ifd = exif_dict["1st"];
575
- }
576
-
577
- var zeroth_set = _dict_to_bytes(zeroth_ifd, "0th", 0);
578
- var zeroth_length = (zeroth_set[0].length + exif_is * 12 + gps_is * 12 + 4 +
579
- zeroth_set[1].length);
580
-
581
- var exif_set,
582
- exif_bytes = "",
583
- exif_length = 0,
584
- gps_set,
585
- gps_bytes = "",
586
- gps_length = 0,
587
- interop_set,
588
- interop_bytes = "",
589
- interop_length = 0,
590
- first_set,
591
- first_bytes = "",
592
- thumbnail;
593
- if (exif_is) {
594
- exif_set = _dict_to_bytes(exif_ifd, "Exif", zeroth_length);
595
- exif_length = exif_set[0].length + interop_is * 12 + exif_set[1].length;
596
- }
597
- if (gps_is) {
598
- gps_set = _dict_to_bytes(gps_ifd, "GPS", zeroth_length + exif_length);
599
- gps_bytes = gps_set.join("");
600
- gps_length = gps_bytes.length;
601
- }
602
- if (interop_is) {
603
- var offset = zeroth_length + exif_length + gps_length;
604
- interop_set = _dict_to_bytes(interop_ifd, "Interop", offset);
605
- interop_bytes = interop_set.join("");
606
- interop_length = interop_bytes.length;
607
- }
608
- if (first_is) {
609
- var offset = zeroth_length + exif_length + gps_length + interop_length;
610
- first_set = _dict_to_bytes(first_ifd, "1st", offset);
611
- thumbnail = _get_thumbnail(exif_dict["thumbnail"]);
612
- if (thumbnail.length > 64000) {
613
- throw new Error("Given thumbnail is too large. max 64kB");
614
- }
615
- }
616
-
617
- var exif_pointer = "",
618
- gps_pointer = "",
619
- interop_pointer = "",
620
- first_ifd_pointer = "\x00\x00\x00\x00";
621
- if (exif_is) {
622
- var pointer_value = TIFF_HEADER_LENGTH + zeroth_length;
623
- var pointer_str = pack(">L", [pointer_value]);
624
- var key = 34665;
625
- var key_str = pack(">H", [key]);
626
- var type_str = pack(">H", [TYPES["Long"]]);
627
- var length_str = pack(">L", [1]);
628
- exif_pointer = key_str + type_str + length_str + pointer_str;
629
- }
630
- if (gps_is) {
631
- var pointer_value = TIFF_HEADER_LENGTH + zeroth_length + exif_length;
632
- var pointer_str = pack(">L", [pointer_value]);
633
- var key = 34853;
634
- var key_str = pack(">H", [key]);
635
- var type_str = pack(">H", [TYPES["Long"]]);
636
- var length_str = pack(">L", [1]);
637
- gps_pointer = key_str + type_str + length_str + pointer_str;
638
- }
639
- if (interop_is) {
640
- var pointer_value = (TIFF_HEADER_LENGTH +
641
- zeroth_length + exif_length + gps_length);
642
- var pointer_str = pack(">L", [pointer_value]);
643
- var key = 40965;
644
- var key_str = pack(">H", [key]);
645
- var type_str = pack(">H", [TYPES["Long"]]);
646
- var length_str = pack(">L", [1]);
647
- interop_pointer = key_str + type_str + length_str + pointer_str;
648
- }
649
- if (first_is) {
650
- var pointer_value = (TIFF_HEADER_LENGTH + zeroth_length +
651
- exif_length + gps_length + interop_length);
652
- first_ifd_pointer = pack(">L", [pointer_value]);
653
- var thumbnail_pointer = (pointer_value + first_set[0].length + 24 +
654
- 4 + first_set[1].length);
655
- var thumbnail_p_bytes = ("\x02\x01\x00\x04\x00\x00\x00\x01" +
656
- pack(">L", [thumbnail_pointer]));
657
- var thumbnail_length_bytes = ("\x02\x02\x00\x04\x00\x00\x00\x01" +
658
- pack(">L", [thumbnail.length]));
659
- first_bytes = (first_set[0] + thumbnail_p_bytes +
660
- thumbnail_length_bytes + "\x00\x00\x00\x00" +
661
- first_set[1] + thumbnail);
662
- }
663
-
664
- var zeroth_bytes = (zeroth_set[0] + exif_pointer + gps_pointer +
665
- first_ifd_pointer + zeroth_set[1]);
666
- if (exif_is) {
667
- exif_bytes = exif_set[0] + interop_pointer + exif_set[1];
668
- }
669
-
670
- return (header + zeroth_bytes + exif_bytes + gps_bytes +
671
- interop_bytes + first_bytes);
672
- };
673
-
674
-
675
- function copy(obj) {
676
- return JSON.parse(JSON.stringify(obj));
677
- }
678
-
679
-
680
- function _get_thumbnail(jpeg) {
681
- var segments = splitIntoSegments(jpeg);
682
- while (("\xff\xe0" <= segments[1].slice(0, 2)) && (segments[1].slice(0, 2) <= "\xff\xef")) {
683
- segments = [segments[0]].concat(segments.slice(2));
684
- }
685
- return segments.join("");
686
- }
687
-
688
-
689
- function _pack_byte(array) {
690
- return pack(">" + nStr("B", array.length), array);
691
- }
692
-
693
-
694
- function _pack_short(array) {
695
- return pack(">" + nStr("H", array.length), array);
696
- }
697
-
698
-
699
- function _pack_long(array) {
700
- return pack(">" + nStr("L", array.length), array);
701
- }
702
-
703
-
704
- function _value_to_bytes(raw_value, value_type, offset) {
705
- var four_bytes_over = "";
706
- var value_str = "";
707
- var length,
708
- new_value,
709
- num,
710
- den;
711
-
712
- if (value_type == "Byte") {
713
- length = raw_value.length;
714
- if (length <= 4) {
715
- value_str = (_pack_byte(raw_value) +
716
- nStr("\x00", 4 - length));
717
- } else {
718
- value_str = pack(">L", [offset]);
719
- four_bytes_over = _pack_byte(raw_value);
720
- }
721
- } else if (value_type == "Short") {
722
- length = raw_value.length;
723
- if (length <= 2) {
724
- value_str = (_pack_short(raw_value) +
725
- nStr("\x00\x00", 2 - length));
726
- } else {
727
- value_str = pack(">L", [offset]);
728
- four_bytes_over = _pack_short(raw_value);
729
- }
730
- } else if (value_type == "Long") {
731
- length = raw_value.length;
732
- if (length <= 1) {
733
- value_str = _pack_long(raw_value);
734
- } else {
735
- value_str = pack(">L", [offset]);
736
- four_bytes_over = _pack_long(raw_value);
737
- }
738
- } else if (value_type == "Ascii") {
739
- new_value = raw_value + "\x00";
740
- length = new_value.length;
741
- if (length > 4) {
742
- value_str = pack(">L", [offset]);
743
- four_bytes_over = new_value;
744
- } else {
745
- value_str = new_value + nStr("\x00", 4 - length);
746
- }
747
- } else if (value_type == "Rational") {
748
- if (typeof (raw_value[0]) == "number") {
749
- length = 1;
750
- num = raw_value[0];
751
- den = raw_value[1];
752
- new_value = pack(">L", [num]) + pack(">L", [den]);
753
- } else {
754
- length = raw_value.length;
755
- new_value = "";
756
- for (var n = 0; n < length; n++) {
757
- num = raw_value[n][0];
758
- den = raw_value[n][1];
759
- new_value += (pack(">L", [num]) +
760
- pack(">L", [den]));
761
- }
762
- }
763
- value_str = pack(">L", [offset]);
764
- four_bytes_over = new_value;
765
- } else if (value_type == "SRational") {
766
- if (typeof (raw_value[0]) == "number") {
767
- length = 1;
768
- num = raw_value[0];
769
- den = raw_value[1];
770
- new_value = pack(">l", [num]) + pack(">l", [den]);
771
- } else {
772
- length = raw_value.length;
773
- new_value = "";
774
- for (var n = 0; n < length; n++) {
775
- num = raw_value[n][0];
776
- den = raw_value[n][1];
777
- new_value += (pack(">l", [num]) +
778
- pack(">l", [den]));
779
- }
780
- }
781
- value_str = pack(">L", [offset]);
782
- four_bytes_over = new_value;
783
- } else if (value_type == "Undefined") {
784
- length = raw_value.length;
785
- if (length > 4) {
786
- value_str = pack(">L", [offset]);
787
- four_bytes_over = raw_value;
788
- } else {
789
- value_str = raw_value + nStr("\x00", 4 - length);
790
- }
791
- }
792
-
793
- var length_str = pack(">L", [length]);
794
-
795
- return [length_str, value_str, four_bytes_over];
796
- }
797
-
798
- function _dict_to_bytes(ifd_dict, ifd, ifd_offset) {
799
- var TIFF_HEADER_LENGTH = 8;
800
- var tag_count = Object.keys(ifd_dict).length;
801
- var entry_header = pack(">H", [tag_count]);
802
- var entries_length;
803
- if (["0th", "1st"].indexOf(ifd) > -1) {
804
- entries_length = 2 + tag_count * 12 + 4;
805
- } else {
806
- entries_length = 2 + tag_count * 12;
807
- }
808
- var entries = "";
809
- var values = "";
810
- var key;
811
-
812
- for (var key in ifd_dict) {
813
- if (typeof (key) == "string") {
814
- key = parseInt(key);
815
- }
816
- if ((ifd == "0th") && ([34665, 34853].indexOf(key) > -1)) {
817
- continue;
818
- } else if ((ifd == "Exif") && (key == 40965)) {
819
- continue;
820
- } else if ((ifd == "1st") && ([513, 514].indexOf(key) > -1)) {
821
- continue;
822
- }
823
-
824
- var raw_value = ifd_dict[key];
825
- var key_str = pack(">H", [key]);
826
- var value_type = TAGS[ifd][key]["type"];
827
- var type_str = pack(">H", [TYPES[value_type]]);
828
-
829
- if (typeof (raw_value) == "number") {
830
- raw_value = [raw_value];
831
- }
832
- var offset = TIFF_HEADER_LENGTH + entries_length + ifd_offset + values.length;
833
- var b = _value_to_bytes(raw_value, value_type, offset);
834
- var length_str = b[0];
835
- var value_str = b[1];
836
- var four_bytes_over = b[2];
837
-
838
- entries += key_str + type_str + length_str + value_str;
839
- values += four_bytes_over;
840
- }
841
-
842
- return [entry_header + entries, values];
843
- }
844
-
845
-
846
-
847
- function ExifReader(data) {
848
- var segments,
849
- app1;
850
- if (data.slice(0, 2) == "\xff\xd8") { // JPEG
851
- segments = splitIntoSegments(data);
852
- app1 = getExifSeg(segments);
853
- if (app1) {
854
- this.tiftag = app1.slice(10);
855
- } else {
856
- this.tiftag = null;
857
- }
858
- } else if (["\x49\x49", "\x4d\x4d"].indexOf(data.slice(0, 2)) > -1) { // TIFF
859
- this.tiftag = data;
860
- } else if (data.slice(0, 4) == "Exif") { // Exif
861
- this.tiftag = data.slice(6);
862
- } else {
863
- throw new Error("Given file is neither JPEG nor TIFF.");
864
- }
865
- }
866
-
867
- ExifReader.prototype = {
868
- get_ifd: function (pointer, ifd_name) {
869
- var ifd_dict = {};
870
- var tag_count = unpack(this.endian_mark + "H",
871
- this.tiftag.slice(pointer, pointer + 2))[0];
872
- var offset = pointer + 2;
873
- var t;
874
- if (["0th", "1st"].indexOf(ifd_name) > -1) {
875
- t = "Image";
876
- } else {
877
- t = ifd_name;
878
- }
879
-
880
- for (var x = 0; x < tag_count; x++) {
881
- pointer = offset + 12 * x;
882
- var tag = unpack(this.endian_mark + "H",
883
- this.tiftag.slice(pointer, pointer + 2))[0];
884
- var value_type = unpack(this.endian_mark + "H",
885
- this.tiftag.slice(pointer + 2, pointer + 4))[0];
886
- var value_num = unpack(this.endian_mark + "L",
887
- this.tiftag.slice(pointer + 4, pointer + 8))[0];
888
- var value = this.tiftag.slice(pointer + 8, pointer + 12);
889
-
890
- var v_set = [value_type, value_num, value];
891
- if (tag in TAGS[t]) {
892
- ifd_dict[tag] = this.convert_value(v_set);
893
- }
894
- }
895
-
896
- if (ifd_name == "0th") {
897
- pointer = offset + 12 * tag_count;
898
- ifd_dict["first_ifd_pointer"] = this.tiftag.slice(pointer, pointer + 4);
899
- }
900
-
901
- return ifd_dict;
902
- },
903
-
904
- convert_value: function (val) {
905
- var data = null;
906
- var t = val[0];
907
- var length = val[1];
908
- var value = val[2];
909
- var pointer;
910
-
911
- if (t == 1) { // BYTE
912
- if (length > 4) {
913
- pointer = unpack(this.endian_mark + "L", value)[0];
914
- data = unpack(this.endian_mark + nStr("B", length),
915
- this.tiftag.slice(pointer, pointer + length));
916
- } else {
917
- data = unpack(this.endian_mark + nStr("B", length), value.slice(0, length));
918
- }
919
- } else if (t == 2) { // ASCII
920
- if (length > 4) {
921
- pointer = unpack(this.endian_mark + "L", value)[0];
922
- data = this.tiftag.slice(pointer, pointer + length - 1);
923
- } else {
924
- data = value.slice(0, length - 1);
925
- }
926
- } else if (t == 3) { // SHORT
927
- if (length > 2) {
928
- pointer = unpack(this.endian_mark + "L", value)[0];
929
- data = unpack(this.endian_mark + nStr("H", length),
930
- this.tiftag.slice(pointer, pointer + length * 2));
931
- } else {
932
- data = unpack(this.endian_mark + nStr("H", length),
933
- value.slice(0, length * 2));
934
- }
935
- } else if (t == 4) { // LONG
936
- if (length > 1) {
937
- pointer = unpack(this.endian_mark + "L", value)[0];
938
- data = unpack(this.endian_mark + nStr("L", length),
939
- this.tiftag.slice(pointer, pointer + length * 4));
940
- } else {
941
- data = unpack(this.endian_mark + nStr("L", length),
942
- value);
943
- }
944
- } else if (t == 5) { // RATIONAL
945
- pointer = unpack(this.endian_mark + "L", value)[0];
946
- if (length > 1) {
947
- data = [];
948
- for (var x = 0; x < length; x++) {
949
- data.push([unpack(this.endian_mark + "L",
950
- this.tiftag.slice(pointer + x * 8, pointer + 4 + x * 8))[0],
951
- unpack(this.endian_mark + "L",
952
- this.tiftag.slice(pointer + 4 + x * 8, pointer + 8 + x * 8))[0]
953
- ]);
954
- }
955
- } else {
956
- data = [unpack(this.endian_mark + "L",
957
- this.tiftag.slice(pointer, pointer + 4))[0],
958
- unpack(this.endian_mark + "L",
959
- this.tiftag.slice(pointer + 4, pointer + 8))[0]
960
- ];
961
- }
962
- } else if (t == 7) { // UNDEFINED BYTES
963
- if (length > 4) {
964
- pointer = unpack(this.endian_mark + "L", value)[0];
965
- data = this.tiftag.slice(pointer, pointer + length);
966
- } else {
967
- data = value.slice(0, length);
968
- }
969
- } else if (t == 9) { // SLONG
970
- if (length > 1) {
971
- pointer = unpack(this.endian_mark + "L", value)[0];
972
- data = unpack(this.endian_mark + nStr("l", length),
973
- this.tiftag.slice(pointer, pointer + length * 4));
974
- } else {
975
- data = unpack(this.endian_mark + nStr("l", length),
976
- value);
977
- }
978
- } else if (t == 10) { // SRATIONAL
979
- pointer = unpack(this.endian_mark + "L", value)[0];
980
- if (length > 1) {
981
- data = [];
982
- for (var x = 0; x < length; x++) {
983
- data.push([unpack(this.endian_mark + "l",
984
- this.tiftag.slice(pointer + x * 8, pointer + 4 + x * 8))[0],
985
- unpack(this.endian_mark + "l",
986
- this.tiftag.slice(pointer + 4 + x * 8, pointer + 8 + x * 8))[0]
987
- ]);
988
- }
989
- } else {
990
- data = [unpack(this.endian_mark + "l",
991
- this.tiftag.slice(pointer, pointer + 4))[0],
992
- unpack(this.endian_mark + "l",
993
- this.tiftag.slice(pointer + 4, pointer + 8))[0]
994
- ];
995
- }
996
- } else {
997
- throw new Error("Exif might be wrong. Got incorrect value " +
998
- "type to decode. type:" + t);
999
- }
1000
-
1001
- if ((data instanceof Array) && (data.length == 1)) {
1002
- return data[0];
1003
- } else {
1004
- return data;
1005
- }
1006
- },
1007
- };
1008
-
1009
-
1010
- if (typeof window !== "undefined" && typeof window.btoa === "function") {
1011
- var btoa = window.btoa;
1012
- }
1013
- if (typeof btoa === "undefined") {
1014
- var btoa = function (input) { var output = "";
1015
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
1016
- var i = 0;
1017
- var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
1018
-
1019
- while (i < input.length) {
1020
-
1021
- chr1 = input.charCodeAt(i++);
1022
- chr2 = input.charCodeAt(i++);
1023
- chr3 = input.charCodeAt(i++);
1024
-
1025
- enc1 = chr1 >> 2;
1026
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
1027
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
1028
- enc4 = chr3 & 63;
1029
-
1030
- if (isNaN(chr2)) {
1031
- enc3 = enc4 = 64;
1032
- } else if (isNaN(chr3)) {
1033
- enc4 = 64;
1034
- }
1035
-
1036
- output = output +
1037
- keyStr.charAt(enc1) + keyStr.charAt(enc2) +
1038
- keyStr.charAt(enc3) + keyStr.charAt(enc4);
1039
-
1040
- }
1041
-
1042
- return output;
1043
- };
1044
- }
1045
-
1046
-
1047
- if (typeof window !== "undefined" && typeof window.atob === "function") {
1048
- var atob = window.atob;
1049
- }
1050
- if (typeof atob === "undefined") {
1051
- var atob = function (input) {
1052
- var output = "";
1053
- var chr1, chr2, chr3;
1054
- var enc1, enc2, enc3, enc4;
1055
- var i = 0;
1056
- var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
1057
-
1058
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
1059
-
1060
- while (i < input.length) {
1061
-
1062
- enc1 = keyStr.indexOf(input.charAt(i++));
1063
- enc2 = keyStr.indexOf(input.charAt(i++));
1064
- enc3 = keyStr.indexOf(input.charAt(i++));
1065
- enc4 = keyStr.indexOf(input.charAt(i++));
1066
-
1067
- chr1 = (enc1 << 2) | (enc2 >> 4);
1068
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
1069
- chr3 = ((enc3 & 3) << 6) | enc4;
1070
-
1071
- output = output + String.fromCharCode(chr1);
1072
-
1073
- if (enc3 != 64) {
1074
- output = output + String.fromCharCode(chr2);
1075
- }
1076
- if (enc4 != 64) {
1077
- output = output + String.fromCharCode(chr3);
1078
- }
1079
-
1080
- }
1081
-
1082
- return output;
1083
- };
1084
- }
1085
-
1086
-
1087
- function getImageSize(imageArray) {
1088
- var segments = slice2Segments(imageArray);
1089
- var seg,
1090
- width,
1091
- height,
1092
- SOF = [192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207];
1093
-
1094
- for (var x = 0; x < segments.length; x++) {
1095
- seg = segments[x];
1096
- if (SOF.indexOf(seg[1]) >= 0) {
1097
- height = seg[5] * 256 + seg[6];
1098
- width = seg[7] * 256 + seg[8];
1099
- break;
1100
- }
1101
- }
1102
- return [width, height];
1103
- }
1104
-
1105
-
1106
- function pack(mark, array) {
1107
- if (!(array instanceof Array)) {
1108
- throw new Error("'pack' error. Got invalid type argument.");
1109
- }
1110
- if ((mark.length - 1) != array.length) {
1111
- throw new Error("'pack' error. " + (mark.length - 1) + " marks, " + array.length + " elements.");
1112
- }
1113
-
1114
- var littleEndian;
1115
- if (mark[0] == "<") {
1116
- littleEndian = true;
1117
- } else if (mark[0] == ">") {
1118
- littleEndian = false;
1119
- } else {
1120
- throw new Error("");
1121
- }
1122
- var packed = "";
1123
- var p = 1;
1124
- var val = null;
1125
- var c = null;
1126
- var valStr = null;
1127
-
1128
- while (c = mark[p]) {
1129
- if (c.toLowerCase() == "b") {
1130
- val = array[p - 1];
1131
- if ((c == "b") && (val < 0)) {
1132
- val += 0x100;
1133
- }
1134
- if ((val > 0xff) || (val < 0)) {
1135
- throw new Error("'pack' error.");
1136
- } else {
1137
- valStr = String.fromCharCode(val);
1138
- }
1139
- } else if (c == "H") {
1140
- val = array[p - 1];
1141
- if ((val > 0xffff) || (val < 0)) {
1142
- throw new Error("'pack' error.");
1143
- } else {
1144
- valStr = String.fromCharCode(Math.floor((val % 0x10000) / 0x100)) +
1145
- String.fromCharCode(val % 0x100);
1146
- if (littleEndian) {
1147
- valStr = valStr.split("").reverse().join("");
1148
- }
1149
- }
1150
- } else if (c.toLowerCase() == "l") {
1151
- val = array[p - 1];
1152
- if ((c == "l") && (val < 0)) {
1153
- val += 0x100000000;
1154
- }
1155
- if ((val > 0xffffffff) || (val < 0)) {
1156
- throw new Error("'pack' error.");
1157
- } else {
1158
- valStr = String.fromCharCode(Math.floor(val / 0x1000000)) +
1159
- String.fromCharCode(Math.floor((val % 0x1000000) / 0x10000)) +
1160
- String.fromCharCode(Math.floor((val % 0x10000) / 0x100)) +
1161
- String.fromCharCode(val % 0x100);
1162
- if (littleEndian) {
1163
- valStr = valStr.split("").reverse().join("");
1164
- }
1165
- }
1166
- } else {
1167
- throw new Error("'pack' error.");
1168
- }
1169
-
1170
- packed += valStr;
1171
- p += 1;
1172
- }
1173
-
1174
- return packed;
1175
- }
1176
-
1177
- function unpack(mark, str) {
1178
- if (typeof (str) != "string") {
1179
- throw new Error("'unpack' error. Got invalid type argument.");
1180
- }
1181
- var l = 0;
1182
- for (var markPointer = 1; markPointer < mark.length; markPointer++) {
1183
- if (mark[markPointer].toLowerCase() == "b") {
1184
- l += 1;
1185
- } else if (mark[markPointer].toLowerCase() == "h") {
1186
- l += 2;
1187
- } else if (mark[markPointer].toLowerCase() == "l") {
1188
- l += 4;
1189
- } else {
1190
- throw new Error("'unpack' error. Got invalid mark.");
1191
- }
1192
- }
1193
-
1194
- if (l != str.length) {
1195
- throw new Error("'unpack' error. Mismatch between symbol and string length. " + l + ":" + str.length);
1196
- }
1197
-
1198
- var littleEndian;
1199
- if (mark[0] == "<") {
1200
- littleEndian = true;
1201
- } else if (mark[0] == ">") {
1202
- littleEndian = false;
1203
- } else {
1204
- throw new Error("'unpack' error.");
1205
- }
1206
- var unpacked = [];
1207
- var strPointer = 0;
1208
- var p = 1;
1209
- var val = null;
1210
- var c = null;
1211
- var length = null;
1212
- var sliced = "";
1213
-
1214
- while (c = mark[p]) {
1215
- if (c.toLowerCase() == "b") {
1216
- length = 1;
1217
- sliced = str.slice(strPointer, strPointer + length);
1218
- val = sliced.charCodeAt(0);
1219
- if ((c == "b") && (val >= 0x80)) {
1220
- val -= 0x100;
1221
- }
1222
- } else if (c == "H") {
1223
- length = 2;
1224
- sliced = str.slice(strPointer, strPointer + length);
1225
- if (littleEndian) {
1226
- sliced = sliced.split("").reverse().join("");
1227
- }
1228
- val = sliced.charCodeAt(0) * 0x100 +
1229
- sliced.charCodeAt(1);
1230
- } else if (c.toLowerCase() == "l") {
1231
- length = 4;
1232
- sliced = str.slice(strPointer, strPointer + length);
1233
- if (littleEndian) {
1234
- sliced = sliced.split("").reverse().join("");
1235
- }
1236
- val = sliced.charCodeAt(0) * 0x1000000 +
1237
- sliced.charCodeAt(1) * 0x10000 +
1238
- sliced.charCodeAt(2) * 0x100 +
1239
- sliced.charCodeAt(3);
1240
- if ((c == "l") && (val >= 0x80000000)) {
1241
- val -= 0x100000000;
1242
- }
1243
- } else {
1244
- throw new Error("'unpack' error. " + c);
1245
- }
1246
-
1247
- unpacked.push(val);
1248
- strPointer += length;
1249
- p += 1;
1250
- }
1251
-
1252
- return unpacked;
1253
- }
1254
-
1255
- function nStr(ch, num) {
1256
- var str = "";
1257
- for (var i = 0; i < num; i++) {
1258
- str += ch;
1259
- }
1260
- return str;
1261
- }
1262
-
1263
- function splitIntoSegments(data) {
1264
- if (data.slice(0, 2) != "\xff\xd8") {
1265
- throw new Error("Given data isn't JPEG.");
1266
- }
1267
-
1268
- var head = 2;
1269
- var segments = ["\xff\xd8"];
1270
- while (true) {
1271
- if (data.slice(head, head + 2) == "\xff\xda") {
1272
- segments.push(data.slice(head));
1273
- break;
1274
- } else {
1275
- var length = unpack(">H", data.slice(head + 2, head + 4))[0];
1276
- var endPoint = head + length + 2;
1277
- segments.push(data.slice(head, endPoint));
1278
- head = endPoint;
1279
- }
1280
-
1281
- if (head >= data.length) {
1282
- throw new Error("Wrong JPEG data.");
1283
- }
1284
- }
1285
- return segments;
1286
- }
1287
-
1288
-
1289
- function getExifSeg(segments) {
1290
- var seg;
1291
- for (var i = 0; i < segments.length; i++) {
1292
- seg = segments[i];
1293
- if (seg.slice(0, 2) == "\xff\xe1" &&
1294
- seg.slice(4, 10) == "Exif\x00\x00") {
1295
- return seg;
1296
- }
1297
- }
1298
- return null;
1299
- }
1300
-
1301
-
1302
- function mergeSegments(segments, exif) {
1303
- var hasExifSegment = false;
1304
- var additionalAPP1ExifSegments = [];
1305
-
1306
- segments.forEach(function(segment, i) {
1307
- // Replace first occurence of APP1:Exif segment
1308
- if (segment.slice(0, 2) == "\xff\xe1" &&
1309
- segment.slice(4, 10) == "Exif\x00\x00"
1310
- ) {
1311
- if (!hasExifSegment) {
1312
- segments[i] = exif;
1313
- hasExifSegment = true;
1314
- } else {
1315
- additionalAPP1ExifSegments.unshift(i);
1316
- }
1317
- }
1318
- });
1319
-
1320
- // Remove additional occurences of APP1:Exif segment
1321
- additionalAPP1ExifSegments.forEach(function(segmentIndex) {
1322
- segments.splice(segmentIndex, 1);
1323
- });
1324
-
1325
- if (!hasExifSegment && exif) {
1326
- segments = [segments[0], exif].concat(segments.slice(1));
1327
- }
1328
-
1329
- return segments.join("");
1330
- }
1331
-
1332
-
1333
- function toHex(str) {
1334
- var hexStr = "";
1335
- for (var i = 0; i < str.length; i++) {
1336
- var h = str.charCodeAt(i);
1337
- var hex = ((h < 10) ? "0" : "") + h.toString(16);
1338
- hexStr += hex + " ";
1339
- }
1340
- return hexStr;
1341
- }
1342
-
1343
-
1344
- var TYPES = {
1345
- "Byte": 1,
1346
- "Ascii": 2,
1347
- "Short": 3,
1348
- "Long": 4,
1349
- "Rational": 5,
1350
- "Undefined": 7,
1351
- "SLong": 9,
1352
- "SRational": 10
1353
- };
1354
-
1355
-
1356
- var TAGS = {
1357
- 'Image': {
1358
- 11: {
1359
- 'name': 'ProcessingSoftware',
1360
- 'type': 'Ascii'
1361
- },
1362
- 254: {
1363
- 'name': 'NewSubfileType',
1364
- 'type': 'Long'
1365
- },
1366
- 255: {
1367
- 'name': 'SubfileType',
1368
- 'type': 'Short'
1369
- },
1370
- 256: {
1371
- 'name': 'ImageWidth',
1372
- 'type': 'Long'
1373
- },
1374
- 257: {
1375
- 'name': 'ImageLength',
1376
- 'type': 'Long'
1377
- },
1378
- 258: {
1379
- 'name': 'BitsPerSample',
1380
- 'type': 'Short'
1381
- },
1382
- 259: {
1383
- 'name': 'Compression',
1384
- 'type': 'Short'
1385
- },
1386
- 262: {
1387
- 'name': 'PhotometricInterpretation',
1388
- 'type': 'Short'
1389
- },
1390
- 263: {
1391
- 'name': 'Threshholding',
1392
- 'type': 'Short'
1393
- },
1394
- 264: {
1395
- 'name': 'CellWidth',
1396
- 'type': 'Short'
1397
- },
1398
- 265: {
1399
- 'name': 'CellLength',
1400
- 'type': 'Short'
1401
- },
1402
- 266: {
1403
- 'name': 'FillOrder',
1404
- 'type': 'Short'
1405
- },
1406
- 269: {
1407
- 'name': 'DocumentName',
1408
- 'type': 'Ascii'
1409
- },
1410
- 270: {
1411
- 'name': 'ImageDescription',
1412
- 'type': 'Ascii'
1413
- },
1414
- 271: {
1415
- 'name': 'Make',
1416
- 'type': 'Ascii'
1417
- },
1418
- 272: {
1419
- 'name': 'Model',
1420
- 'type': 'Ascii'
1421
- },
1422
- 273: {
1423
- 'name': 'StripOffsets',
1424
- 'type': 'Long'
1425
- },
1426
- 274: {
1427
- 'name': 'Orientation',
1428
- 'type': 'Short'
1429
- },
1430
- 277: {
1431
- 'name': 'SamplesPerPixel',
1432
- 'type': 'Short'
1433
- },
1434
- 278: {
1435
- 'name': 'RowsPerStrip',
1436
- 'type': 'Long'
1437
- },
1438
- 279: {
1439
- 'name': 'StripByteCounts',
1440
- 'type': 'Long'
1441
- },
1442
- 282: {
1443
- 'name': 'XResolution',
1444
- 'type': 'Rational'
1445
- },
1446
- 283: {
1447
- 'name': 'YResolution',
1448
- 'type': 'Rational'
1449
- },
1450
- 284: {
1451
- 'name': 'PlanarConfiguration',
1452
- 'type': 'Short'
1453
- },
1454
- 290: {
1455
- 'name': 'GrayResponseUnit',
1456
- 'type': 'Short'
1457
- },
1458
- 291: {
1459
- 'name': 'GrayResponseCurve',
1460
- 'type': 'Short'
1461
- },
1462
- 292: {
1463
- 'name': 'T4Options',
1464
- 'type': 'Long'
1465
- },
1466
- 293: {
1467
- 'name': 'T6Options',
1468
- 'type': 'Long'
1469
- },
1470
- 296: {
1471
- 'name': 'ResolutionUnit',
1472
- 'type': 'Short'
1473
- },
1474
- 301: {
1475
- 'name': 'TransferFunction',
1476
- 'type': 'Short'
1477
- },
1478
- 305: {
1479
- 'name': 'Software',
1480
- 'type': 'Ascii'
1481
- },
1482
- 306: {
1483
- 'name': 'DateTime',
1484
- 'type': 'Ascii'
1485
- },
1486
- 315: {
1487
- 'name': 'Artist',
1488
- 'type': 'Ascii'
1489
- },
1490
- 316: {
1491
- 'name': 'HostComputer',
1492
- 'type': 'Ascii'
1493
- },
1494
- 317: {
1495
- 'name': 'Predictor',
1496
- 'type': 'Short'
1497
- },
1498
- 318: {
1499
- 'name': 'WhitePoint',
1500
- 'type': 'Rational'
1501
- },
1502
- 319: {
1503
- 'name': 'PrimaryChromaticities',
1504
- 'type': 'Rational'
1505
- },
1506
- 320: {
1507
- 'name': 'ColorMap',
1508
- 'type': 'Short'
1509
- },
1510
- 321: {
1511
- 'name': 'HalftoneHints',
1512
- 'type': 'Short'
1513
- },
1514
- 322: {
1515
- 'name': 'TileWidth',
1516
- 'type': 'Short'
1517
- },
1518
- 323: {
1519
- 'name': 'TileLength',
1520
- 'type': 'Short'
1521
- },
1522
- 324: {
1523
- 'name': 'TileOffsets',
1524
- 'type': 'Short'
1525
- },
1526
- 325: {
1527
- 'name': 'TileByteCounts',
1528
- 'type': 'Short'
1529
- },
1530
- 330: {
1531
- 'name': 'SubIFDs',
1532
- 'type': 'Long'
1533
- },
1534
- 332: {
1535
- 'name': 'InkSet',
1536
- 'type': 'Short'
1537
- },
1538
- 333: {
1539
- 'name': 'InkNames',
1540
- 'type': 'Ascii'
1541
- },
1542
- 334: {
1543
- 'name': 'NumberOfInks',
1544
- 'type': 'Short'
1545
- },
1546
- 336: {
1547
- 'name': 'DotRange',
1548
- 'type': 'Byte'
1549
- },
1550
- 337: {
1551
- 'name': 'TargetPrinter',
1552
- 'type': 'Ascii'
1553
- },
1554
- 338: {
1555
- 'name': 'ExtraSamples',
1556
- 'type': 'Short'
1557
- },
1558
- 339: {
1559
- 'name': 'SampleFormat',
1560
- 'type': 'Short'
1561
- },
1562
- 340: {
1563
- 'name': 'SMinSampleValue',
1564
- 'type': 'Short'
1565
- },
1566
- 341: {
1567
- 'name': 'SMaxSampleValue',
1568
- 'type': 'Short'
1569
- },
1570
- 342: {
1571
- 'name': 'TransferRange',
1572
- 'type': 'Short'
1573
- },
1574
- 343: {
1575
- 'name': 'ClipPath',
1576
- 'type': 'Byte'
1577
- },
1578
- 344: {
1579
- 'name': 'XClipPathUnits',
1580
- 'type': 'Long'
1581
- },
1582
- 345: {
1583
- 'name': 'YClipPathUnits',
1584
- 'type': 'Long'
1585
- },
1586
- 346: {
1587
- 'name': 'Indexed',
1588
- 'type': 'Short'
1589
- },
1590
- 347: {
1591
- 'name': 'JPEGTables',
1592
- 'type': 'Undefined'
1593
- },
1594
- 351: {
1595
- 'name': 'OPIProxy',
1596
- 'type': 'Short'
1597
- },
1598
- 512: {
1599
- 'name': 'JPEGProc',
1600
- 'type': 'Long'
1601
- },
1602
- 513: {
1603
- 'name': 'JPEGInterchangeFormat',
1604
- 'type': 'Long'
1605
- },
1606
- 514: {
1607
- 'name': 'JPEGInterchangeFormatLength',
1608
- 'type': 'Long'
1609
- },
1610
- 515: {
1611
- 'name': 'JPEGRestartInterval',
1612
- 'type': 'Short'
1613
- },
1614
- 517: {
1615
- 'name': 'JPEGLosslessPredictors',
1616
- 'type': 'Short'
1617
- },
1618
- 518: {
1619
- 'name': 'JPEGPointTransforms',
1620
- 'type': 'Short'
1621
- },
1622
- 519: {
1623
- 'name': 'JPEGQTables',
1624
- 'type': 'Long'
1625
- },
1626
- 520: {
1627
- 'name': 'JPEGDCTables',
1628
- 'type': 'Long'
1629
- },
1630
- 521: {
1631
- 'name': 'JPEGACTables',
1632
- 'type': 'Long'
1633
- },
1634
- 529: {
1635
- 'name': 'YCbCrCoefficients',
1636
- 'type': 'Rational'
1637
- },
1638
- 530: {
1639
- 'name': 'YCbCrSubSampling',
1640
- 'type': 'Short'
1641
- },
1642
- 531: {
1643
- 'name': 'YCbCrPositioning',
1644
- 'type': 'Short'
1645
- },
1646
- 532: {
1647
- 'name': 'ReferenceBlackWhite',
1648
- 'type': 'Rational'
1649
- },
1650
- 700: {
1651
- 'name': 'XMLPacket',
1652
- 'type': 'Byte'
1653
- },
1654
- 18246: {
1655
- 'name': 'Rating',
1656
- 'type': 'Short'
1657
- },
1658
- 18249: {
1659
- 'name': 'RatingPercent',
1660
- 'type': 'Short'
1661
- },
1662
- 32781: {
1663
- 'name': 'ImageID',
1664
- 'type': 'Ascii'
1665
- },
1666
- 33421: {
1667
- 'name': 'CFARepeatPatternDim',
1668
- 'type': 'Short'
1669
- },
1670
- 33422: {
1671
- 'name': 'CFAPattern',
1672
- 'type': 'Byte'
1673
- },
1674
- 33423: {
1675
- 'name': 'BatteryLevel',
1676
- 'type': 'Rational'
1677
- },
1678
- 33432: {
1679
- 'name': 'Copyright',
1680
- 'type': 'Ascii'
1681
- },
1682
- 33434: {
1683
- 'name': 'ExposureTime',
1684
- 'type': 'Rational'
1685
- },
1686
- 34377: {
1687
- 'name': 'ImageResources',
1688
- 'type': 'Byte'
1689
- },
1690
- 34665: {
1691
- 'name': 'ExifTag',
1692
- 'type': 'Long'
1693
- },
1694
- 34675: {
1695
- 'name': 'InterColorProfile',
1696
- 'type': 'Undefined'
1697
- },
1698
- 34853: {
1699
- 'name': 'GPSTag',
1700
- 'type': 'Long'
1701
- },
1702
- 34857: {
1703
- 'name': 'Interlace',
1704
- 'type': 'Short'
1705
- },
1706
- 34858: {
1707
- 'name': 'TimeZoneOffset',
1708
- 'type': 'Long'
1709
- },
1710
- 34859: {
1711
- 'name': 'SelfTimerMode',
1712
- 'type': 'Short'
1713
- },
1714
- 37387: {
1715
- 'name': 'FlashEnergy',
1716
- 'type': 'Rational'
1717
- },
1718
- 37388: {
1719
- 'name': 'SpatialFrequencyResponse',
1720
- 'type': 'Undefined'
1721
- },
1722
- 37389: {
1723
- 'name': 'Noise',
1724
- 'type': 'Undefined'
1725
- },
1726
- 37390: {
1727
- 'name': 'FocalPlaneXResolution',
1728
- 'type': 'Rational'
1729
- },
1730
- 37391: {
1731
- 'name': 'FocalPlaneYResolution',
1732
- 'type': 'Rational'
1733
- },
1734
- 37392: {
1735
- 'name': 'FocalPlaneResolutionUnit',
1736
- 'type': 'Short'
1737
- },
1738
- 37393: {
1739
- 'name': 'ImageNumber',
1740
- 'type': 'Long'
1741
- },
1742
- 37394: {
1743
- 'name': 'SecurityClassification',
1744
- 'type': 'Ascii'
1745
- },
1746
- 37395: {
1747
- 'name': 'ImageHistory',
1748
- 'type': 'Ascii'
1749
- },
1750
- 37397: {
1751
- 'name': 'ExposureIndex',
1752
- 'type': 'Rational'
1753
- },
1754
- 37398: {
1755
- 'name': 'TIFFEPStandardID',
1756
- 'type': 'Byte'
1757
- },
1758
- 37399: {
1759
- 'name': 'SensingMethod',
1760
- 'type': 'Short'
1761
- },
1762
- 40091: {
1763
- 'name': 'XPTitle',
1764
- 'type': 'Byte'
1765
- },
1766
- 40092: {
1767
- 'name': 'XPComment',
1768
- 'type': 'Byte'
1769
- },
1770
- 40093: {
1771
- 'name': 'XPAuthor',
1772
- 'type': 'Byte'
1773
- },
1774
- 40094: {
1775
- 'name': 'XPKeywords',
1776
- 'type': 'Byte'
1777
- },
1778
- 40095: {
1779
- 'name': 'XPSubject',
1780
- 'type': 'Byte'
1781
- },
1782
- 50341: {
1783
- 'name': 'PrintImageMatching',
1784
- 'type': 'Undefined'
1785
- },
1786
- 50706: {
1787
- 'name': 'DNGVersion',
1788
- 'type': 'Byte'
1789
- },
1790
- 50707: {
1791
- 'name': 'DNGBackwardVersion',
1792
- 'type': 'Byte'
1793
- },
1794
- 50708: {
1795
- 'name': 'UniqueCameraModel',
1796
- 'type': 'Ascii'
1797
- },
1798
- 50709: {
1799
- 'name': 'LocalizedCameraModel',
1800
- 'type': 'Byte'
1801
- },
1802
- 50710: {
1803
- 'name': 'CFAPlaneColor',
1804
- 'type': 'Byte'
1805
- },
1806
- 50711: {
1807
- 'name': 'CFALayout',
1808
- 'type': 'Short'
1809
- },
1810
- 50712: {
1811
- 'name': 'LinearizationTable',
1812
- 'type': 'Short'
1813
- },
1814
- 50713: {
1815
- 'name': 'BlackLevelRepeatDim',
1816
- 'type': 'Short'
1817
- },
1818
- 50714: {
1819
- 'name': 'BlackLevel',
1820
- 'type': 'Rational'
1821
- },
1822
- 50715: {
1823
- 'name': 'BlackLevelDeltaH',
1824
- 'type': 'SRational'
1825
- },
1826
- 50716: {
1827
- 'name': 'BlackLevelDeltaV',
1828
- 'type': 'SRational'
1829
- },
1830
- 50717: {
1831
- 'name': 'WhiteLevel',
1832
- 'type': 'Short'
1833
- },
1834
- 50718: {
1835
- 'name': 'DefaultScale',
1836
- 'type': 'Rational'
1837
- },
1838
- 50719: {
1839
- 'name': 'DefaultCropOrigin',
1840
- 'type': 'Short'
1841
- },
1842
- 50720: {
1843
- 'name': 'DefaultCropSize',
1844
- 'type': 'Short'
1845
- },
1846
- 50721: {
1847
- 'name': 'ColorMatrix1',
1848
- 'type': 'SRational'
1849
- },
1850
- 50722: {
1851
- 'name': 'ColorMatrix2',
1852
- 'type': 'SRational'
1853
- },
1854
- 50723: {
1855
- 'name': 'CameraCalibration1',
1856
- 'type': 'SRational'
1857
- },
1858
- 50724: {
1859
- 'name': 'CameraCalibration2',
1860
- 'type': 'SRational'
1861
- },
1862
- 50725: {
1863
- 'name': 'ReductionMatrix1',
1864
- 'type': 'SRational'
1865
- },
1866
- 50726: {
1867
- 'name': 'ReductionMatrix2',
1868
- 'type': 'SRational'
1869
- },
1870
- 50727: {
1871
- 'name': 'AnalogBalance',
1872
- 'type': 'Rational'
1873
- },
1874
- 50728: {
1875
- 'name': 'AsShotNeutral',
1876
- 'type': 'Short'
1877
- },
1878
- 50729: {
1879
- 'name': 'AsShotWhiteXY',
1880
- 'type': 'Rational'
1881
- },
1882
- 50730: {
1883
- 'name': 'BaselineExposure',
1884
- 'type': 'SRational'
1885
- },
1886
- 50731: {
1887
- 'name': 'BaselineNoise',
1888
- 'type': 'Rational'
1889
- },
1890
- 50732: {
1891
- 'name': 'BaselineSharpness',
1892
- 'type': 'Rational'
1893
- },
1894
- 50733: {
1895
- 'name': 'BayerGreenSplit',
1896
- 'type': 'Long'
1897
- },
1898
- 50734: {
1899
- 'name': 'LinearResponseLimit',
1900
- 'type': 'Rational'
1901
- },
1902
- 50735: {
1903
- 'name': 'CameraSerialNumber',
1904
- 'type': 'Ascii'
1905
- },
1906
- 50736: {
1907
- 'name': 'LensInfo',
1908
- 'type': 'Rational'
1909
- },
1910
- 50737: {
1911
- 'name': 'ChromaBlurRadius',
1912
- 'type': 'Rational'
1913
- },
1914
- 50738: {
1915
- 'name': 'AntiAliasStrength',
1916
- 'type': 'Rational'
1917
- },
1918
- 50739: {
1919
- 'name': 'ShadowScale',
1920
- 'type': 'SRational'
1921
- },
1922
- 50740: {
1923
- 'name': 'DNGPrivateData',
1924
- 'type': 'Byte'
1925
- },
1926
- 50741: {
1927
- 'name': 'MakerNoteSafety',
1928
- 'type': 'Short'
1929
- },
1930
- 50778: {
1931
- 'name': 'CalibrationIlluminant1',
1932
- 'type': 'Short'
1933
- },
1934
- 50779: {
1935
- 'name': 'CalibrationIlluminant2',
1936
- 'type': 'Short'
1937
- },
1938
- 50780: {
1939
- 'name': 'BestQualityScale',
1940
- 'type': 'Rational'
1941
- },
1942
- 50781: {
1943
- 'name': 'RawDataUniqueID',
1944
- 'type': 'Byte'
1945
- },
1946
- 50827: {
1947
- 'name': 'OriginalRawFileName',
1948
- 'type': 'Byte'
1949
- },
1950
- 50828: {
1951
- 'name': 'OriginalRawFileData',
1952
- 'type': 'Undefined'
1953
- },
1954
- 50829: {
1955
- 'name': 'ActiveArea',
1956
- 'type': 'Short'
1957
- },
1958
- 50830: {
1959
- 'name': 'MaskedAreas',
1960
- 'type': 'Short'
1961
- },
1962
- 50831: {
1963
- 'name': 'AsShotICCProfile',
1964
- 'type': 'Undefined'
1965
- },
1966
- 50832: {
1967
- 'name': 'AsShotPreProfileMatrix',
1968
- 'type': 'SRational'
1969
- },
1970
- 50833: {
1971
- 'name': 'CurrentICCProfile',
1972
- 'type': 'Undefined'
1973
- },
1974
- 50834: {
1975
- 'name': 'CurrentPreProfileMatrix',
1976
- 'type': 'SRational'
1977
- },
1978
- 50879: {
1979
- 'name': 'ColorimetricReference',
1980
- 'type': 'Short'
1981
- },
1982
- 50931: {
1983
- 'name': 'CameraCalibrationSignature',
1984
- 'type': 'Byte'
1985
- },
1986
- 50932: {
1987
- 'name': 'ProfileCalibrationSignature',
1988
- 'type': 'Byte'
1989
- },
1990
- 50934: {
1991
- 'name': 'AsShotProfileName',
1992
- 'type': 'Byte'
1993
- },
1994
- 50935: {
1995
- 'name': 'NoiseReductionApplied',
1996
- 'type': 'Rational'
1997
- },
1998
- 50936: {
1999
- 'name': 'ProfileName',
2000
- 'type': 'Byte'
2001
- },
2002
- 50937: {
2003
- 'name': 'ProfileHueSatMapDims',
2004
- 'type': 'Long'
2005
- },
2006
- 50938: {
2007
- 'name': 'ProfileHueSatMapData1',
2008
- 'type': 'Float'
2009
- },
2010
- 50939: {
2011
- 'name': 'ProfileHueSatMapData2',
2012
- 'type': 'Float'
2013
- },
2014
- 50940: {
2015
- 'name': 'ProfileToneCurve',
2016
- 'type': 'Float'
2017
- },
2018
- 50941: {
2019
- 'name': 'ProfileEmbedPolicy',
2020
- 'type': 'Long'
2021
- },
2022
- 50942: {
2023
- 'name': 'ProfileCopyright',
2024
- 'type': 'Byte'
2025
- },
2026
- 50964: {
2027
- 'name': 'ForwardMatrix1',
2028
- 'type': 'SRational'
2029
- },
2030
- 50965: {
2031
- 'name': 'ForwardMatrix2',
2032
- 'type': 'SRational'
2033
- },
2034
- 50966: {
2035
- 'name': 'PreviewApplicationName',
2036
- 'type': 'Byte'
2037
- },
2038
- 50967: {
2039
- 'name': 'PreviewApplicationVersion',
2040
- 'type': 'Byte'
2041
- },
2042
- 50968: {
2043
- 'name': 'PreviewSettingsName',
2044
- 'type': 'Byte'
2045
- },
2046
- 50969: {
2047
- 'name': 'PreviewSettingsDigest',
2048
- 'type': 'Byte'
2049
- },
2050
- 50970: {
2051
- 'name': 'PreviewColorSpace',
2052
- 'type': 'Long'
2053
- },
2054
- 50971: {
2055
- 'name': 'PreviewDateTime',
2056
- 'type': 'Ascii'
2057
- },
2058
- 50972: {
2059
- 'name': 'RawImageDigest',
2060
- 'type': 'Undefined'
2061
- },
2062
- 50973: {
2063
- 'name': 'OriginalRawFileDigest',
2064
- 'type': 'Undefined'
2065
- },
2066
- 50974: {
2067
- 'name': 'SubTileBlockSize',
2068
- 'type': 'Long'
2069
- },
2070
- 50975: {
2071
- 'name': 'RowInterleaveFactor',
2072
- 'type': 'Long'
2073
- },
2074
- 50981: {
2075
- 'name': 'ProfileLookTableDims',
2076
- 'type': 'Long'
2077
- },
2078
- 50982: {
2079
- 'name': 'ProfileLookTableData',
2080
- 'type': 'Float'
2081
- },
2082
- 51008: {
2083
- 'name': 'OpcodeList1',
2084
- 'type': 'Undefined'
2085
- },
2086
- 51009: {
2087
- 'name': 'OpcodeList2',
2088
- 'type': 'Undefined'
2089
- },
2090
- 51022: {
2091
- 'name': 'OpcodeList3',
2092
- 'type': 'Undefined'
2093
- }
2094
- },
2095
- 'Exif': {
2096
- 33434: {
2097
- 'name': 'ExposureTime',
2098
- 'type': 'Rational'
2099
- },
2100
- 33437: {
2101
- 'name': 'FNumber',
2102
- 'type': 'Rational'
2103
- },
2104
- 34850: {
2105
- 'name': 'ExposureProgram',
2106
- 'type': 'Short'
2107
- },
2108
- 34852: {
2109
- 'name': 'SpectralSensitivity',
2110
- 'type': 'Ascii'
2111
- },
2112
- 34855: {
2113
- 'name': 'ISOSpeedRatings',
2114
- 'type': 'Short'
2115
- },
2116
- 34856: {
2117
- 'name': 'OECF',
2118
- 'type': 'Undefined'
2119
- },
2120
- 34864: {
2121
- 'name': 'SensitivityType',
2122
- 'type': 'Short'
2123
- },
2124
- 34865: {
2125
- 'name': 'StandardOutputSensitivity',
2126
- 'type': 'Long'
2127
- },
2128
- 34866: {
2129
- 'name': 'RecommendedExposureIndex',
2130
- 'type': 'Long'
2131
- },
2132
- 34867: {
2133
- 'name': 'ISOSpeed',
2134
- 'type': 'Long'
2135
- },
2136
- 34868: {
2137
- 'name': 'ISOSpeedLatitudeyyy',
2138
- 'type': 'Long'
2139
- },
2140
- 34869: {
2141
- 'name': 'ISOSpeedLatitudezzz',
2142
- 'type': 'Long'
2143
- },
2144
- 36864: {
2145
- 'name': 'ExifVersion',
2146
- 'type': 'Undefined'
2147
- },
2148
- 36867: {
2149
- 'name': 'DateTimeOriginal',
2150
- 'type': 'Ascii'
2151
- },
2152
- 36868: {
2153
- 'name': 'DateTimeDigitized',
2154
- 'type': 'Ascii'
2155
- },
2156
- 37121: {
2157
- 'name': 'ComponentsConfiguration',
2158
- 'type': 'Undefined'
2159
- },
2160
- 37122: {
2161
- 'name': 'CompressedBitsPerPixel',
2162
- 'type': 'Rational'
2163
- },
2164
- 37377: {
2165
- 'name': 'ShutterSpeedValue',
2166
- 'type': 'SRational'
2167
- },
2168
- 37378: {
2169
- 'name': 'ApertureValue',
2170
- 'type': 'Rational'
2171
- },
2172
- 37379: {
2173
- 'name': 'BrightnessValue',
2174
- 'type': 'SRational'
2175
- },
2176
- 37380: {
2177
- 'name': 'ExposureBiasValue',
2178
- 'type': 'SRational'
2179
- },
2180
- 37381: {
2181
- 'name': 'MaxApertureValue',
2182
- 'type': 'Rational'
2183
- },
2184
- 37382: {
2185
- 'name': 'SubjectDistance',
2186
- 'type': 'Rational'
2187
- },
2188
- 37383: {
2189
- 'name': 'MeteringMode',
2190
- 'type': 'Short'
2191
- },
2192
- 37384: {
2193
- 'name': 'LightSource',
2194
- 'type': 'Short'
2195
- },
2196
- 37385: {
2197
- 'name': 'Flash',
2198
- 'type': 'Short'
2199
- },
2200
- 37386: {
2201
- 'name': 'FocalLength',
2202
- 'type': 'Rational'
2203
- },
2204
- 37396: {
2205
- 'name': 'SubjectArea',
2206
- 'type': 'Short'
2207
- },
2208
- 37500: {
2209
- 'name': 'MakerNote',
2210
- 'type': 'Undefined'
2211
- },
2212
- 37510: {
2213
- 'name': 'UserComment',
2214
- 'type': 'Ascii'
2215
- },
2216
- 37520: {
2217
- 'name': 'SubSecTime',
2218
- 'type': 'Ascii'
2219
- },
2220
- 37521: {
2221
- 'name': 'SubSecTimeOriginal',
2222
- 'type': 'Ascii'
2223
- },
2224
- 37522: {
2225
- 'name': 'SubSecTimeDigitized',
2226
- 'type': 'Ascii'
2227
- },
2228
- 40960: {
2229
- 'name': 'FlashpixVersion',
2230
- 'type': 'Undefined'
2231
- },
2232
- 40961: {
2233
- 'name': 'ColorSpace',
2234
- 'type': 'Short'
2235
- },
2236
- 40962: {
2237
- 'name': 'PixelXDimension',
2238
- 'type': 'Long'
2239
- },
2240
- 40963: {
2241
- 'name': 'PixelYDimension',
2242
- 'type': 'Long'
2243
- },
2244
- 40964: {
2245
- 'name': 'RelatedSoundFile',
2246
- 'type': 'Ascii'
2247
- },
2248
- 40965: {
2249
- 'name': 'InteroperabilityTag',
2250
- 'type': 'Long'
2251
- },
2252
- 41483: {
2253
- 'name': 'FlashEnergy',
2254
- 'type': 'Rational'
2255
- },
2256
- 41484: {
2257
- 'name': 'SpatialFrequencyResponse',
2258
- 'type': 'Undefined'
2259
- },
2260
- 41486: {
2261
- 'name': 'FocalPlaneXResolution',
2262
- 'type': 'Rational'
2263
- },
2264
- 41487: {
2265
- 'name': 'FocalPlaneYResolution',
2266
- 'type': 'Rational'
2267
- },
2268
- 41488: {
2269
- 'name': 'FocalPlaneResolutionUnit',
2270
- 'type': 'Short'
2271
- },
2272
- 41492: {
2273
- 'name': 'SubjectLocation',
2274
- 'type': 'Short'
2275
- },
2276
- 41493: {
2277
- 'name': 'ExposureIndex',
2278
- 'type': 'Rational'
2279
- },
2280
- 41495: {
2281
- 'name': 'SensingMethod',
2282
- 'type': 'Short'
2283
- },
2284
- 41728: {
2285
- 'name': 'FileSource',
2286
- 'type': 'Undefined'
2287
- },
2288
- 41729: {
2289
- 'name': 'SceneType',
2290
- 'type': 'Undefined'
2291
- },
2292
- 41730: {
2293
- 'name': 'CFAPattern',
2294
- 'type': 'Undefined'
2295
- },
2296
- 41985: {
2297
- 'name': 'CustomRendered',
2298
- 'type': 'Short'
2299
- },
2300
- 41986: {
2301
- 'name': 'ExposureMode',
2302
- 'type': 'Short'
2303
- },
2304
- 41987: {
2305
- 'name': 'WhiteBalance',
2306
- 'type': 'Short'
2307
- },
2308
- 41988: {
2309
- 'name': 'DigitalZoomRatio',
2310
- 'type': 'Rational'
2311
- },
2312
- 41989: {
2313
- 'name': 'FocalLengthIn35mmFilm',
2314
- 'type': 'Short'
2315
- },
2316
- 41990: {
2317
- 'name': 'SceneCaptureType',
2318
- 'type': 'Short'
2319
- },
2320
- 41991: {
2321
- 'name': 'GainControl',
2322
- 'type': 'Short'
2323
- },
2324
- 41992: {
2325
- 'name': 'Contrast',
2326
- 'type': 'Short'
2327
- },
2328
- 41993: {
2329
- 'name': 'Saturation',
2330
- 'type': 'Short'
2331
- },
2332
- 41994: {
2333
- 'name': 'Sharpness',
2334
- 'type': 'Short'
2335
- },
2336
- 41995: {
2337
- 'name': 'DeviceSettingDescription',
2338
- 'type': 'Undefined'
2339
- },
2340
- 41996: {
2341
- 'name': 'SubjectDistanceRange',
2342
- 'type': 'Short'
2343
- },
2344
- 42016: {
2345
- 'name': 'ImageUniqueID',
2346
- 'type': 'Ascii'
2347
- },
2348
- 42032: {
2349
- 'name': 'CameraOwnerName',
2350
- 'type': 'Ascii'
2351
- },
2352
- 42033: {
2353
- 'name': 'BodySerialNumber',
2354
- 'type': 'Ascii'
2355
- },
2356
- 42034: {
2357
- 'name': 'LensSpecification',
2358
- 'type': 'Rational'
2359
- },
2360
- 42035: {
2361
- 'name': 'LensMake',
2362
- 'type': 'Ascii'
2363
- },
2364
- 42036: {
2365
- 'name': 'LensModel',
2366
- 'type': 'Ascii'
2367
- },
2368
- 42037: {
2369
- 'name': 'LensSerialNumber',
2370
- 'type': 'Ascii'
2371
- },
2372
- 42240: {
2373
- 'name': 'Gamma',
2374
- 'type': 'Rational'
2375
- }
2376
- },
2377
- 'GPS': {
2378
- 0: {
2379
- 'name': 'GPSVersionID',
2380
- 'type': 'Byte'
2381
- },
2382
- 1: {
2383
- 'name': 'GPSLatitudeRef',
2384
- 'type': 'Ascii'
2385
- },
2386
- 2: {
2387
- 'name': 'GPSLatitude',
2388
- 'type': 'Rational'
2389
- },
2390
- 3: {
2391
- 'name': 'GPSLongitudeRef',
2392
- 'type': 'Ascii'
2393
- },
2394
- 4: {
2395
- 'name': 'GPSLongitude',
2396
- 'type': 'Rational'
2397
- },
2398
- 5: {
2399
- 'name': 'GPSAltitudeRef',
2400
- 'type': 'Byte'
2401
- },
2402
- 6: {
2403
- 'name': 'GPSAltitude',
2404
- 'type': 'Rational'
2405
- },
2406
- 7: {
2407
- 'name': 'GPSTimeStamp',
2408
- 'type': 'Rational'
2409
- },
2410
- 8: {
2411
- 'name': 'GPSSatellites',
2412
- 'type': 'Ascii'
2413
- },
2414
- 9: {
2415
- 'name': 'GPSStatus',
2416
- 'type': 'Ascii'
2417
- },
2418
- 10: {
2419
- 'name': 'GPSMeasureMode',
2420
- 'type': 'Ascii'
2421
- },
2422
- 11: {
2423
- 'name': 'GPSDOP',
2424
- 'type': 'Rational'
2425
- },
2426
- 12: {
2427
- 'name': 'GPSSpeedRef',
2428
- 'type': 'Ascii'
2429
- },
2430
- 13: {
2431
- 'name': 'GPSSpeed',
2432
- 'type': 'Rational'
2433
- },
2434
- 14: {
2435
- 'name': 'GPSTrackRef',
2436
- 'type': 'Ascii'
2437
- },
2438
- 15: {
2439
- 'name': 'GPSTrack',
2440
- 'type': 'Rational'
2441
- },
2442
- 16: {
2443
- 'name': 'GPSImgDirectionRef',
2444
- 'type': 'Ascii'
2445
- },
2446
- 17: {
2447
- 'name': 'GPSImgDirection',
2448
- 'type': 'Rational'
2449
- },
2450
- 18: {
2451
- 'name': 'GPSMapDatum',
2452
- 'type': 'Ascii'
2453
- },
2454
- 19: {
2455
- 'name': 'GPSDestLatitudeRef',
2456
- 'type': 'Ascii'
2457
- },
2458
- 20: {
2459
- 'name': 'GPSDestLatitude',
2460
- 'type': 'Rational'
2461
- },
2462
- 21: {
2463
- 'name': 'GPSDestLongitudeRef',
2464
- 'type': 'Ascii'
2465
- },
2466
- 22: {
2467
- 'name': 'GPSDestLongitude',
2468
- 'type': 'Rational'
2469
- },
2470
- 23: {
2471
- 'name': 'GPSDestBearingRef',
2472
- 'type': 'Ascii'
2473
- },
2474
- 24: {
2475
- 'name': 'GPSDestBearing',
2476
- 'type': 'Rational'
2477
- },
2478
- 25: {
2479
- 'name': 'GPSDestDistanceRef',
2480
- 'type': 'Ascii'
2481
- },
2482
- 26: {
2483
- 'name': 'GPSDestDistance',
2484
- 'type': 'Rational'
2485
- },
2486
- 27: {
2487
- 'name': 'GPSProcessingMethod',
2488
- 'type': 'Undefined'
2489
- },
2490
- 28: {
2491
- 'name': 'GPSAreaInformation',
2492
- 'type': 'Undefined'
2493
- },
2494
- 29: {
2495
- 'name': 'GPSDateStamp',
2496
- 'type': 'Ascii'
2497
- },
2498
- 30: {
2499
- 'name': 'GPSDifferential',
2500
- 'type': 'Short'
2501
- },
2502
- 31: {
2503
- 'name': 'GPSHPositioningError',
2504
- 'type': 'Rational'
2505
- }
2506
- },
2507
- 'Interop': {
2508
- 1: {
2509
- 'name': 'InteroperabilityIndex',
2510
- 'type': 'Ascii'
2511
- }
2512
- },
2513
- };
2514
- TAGS["0th"] = TAGS["Image"];
2515
- TAGS["1st"] = TAGS["Image"];
2516
- that.TAGS = TAGS;
2517
-
2518
-
2519
- that.ImageIFD = {
2520
- ProcessingSoftware:11,
2521
- NewSubfileType:254,
2522
- SubfileType:255,
2523
- ImageWidth:256,
2524
- ImageLength:257,
2525
- BitsPerSample:258,
2526
- Compression:259,
2527
- PhotometricInterpretation:262,
2528
- Threshholding:263,
2529
- CellWidth:264,
2530
- CellLength:265,
2531
- FillOrder:266,
2532
- DocumentName:269,
2533
- ImageDescription:270,
2534
- Make:271,
2535
- Model:272,
2536
- StripOffsets:273,
2537
- Orientation:274,
2538
- SamplesPerPixel:277,
2539
- RowsPerStrip:278,
2540
- StripByteCounts:279,
2541
- XResolution:282,
2542
- YResolution:283,
2543
- PlanarConfiguration:284,
2544
- GrayResponseUnit:290,
2545
- GrayResponseCurve:291,
2546
- T4Options:292,
2547
- T6Options:293,
2548
- ResolutionUnit:296,
2549
- TransferFunction:301,
2550
- Software:305,
2551
- DateTime:306,
2552
- Artist:315,
2553
- HostComputer:316,
2554
- Predictor:317,
2555
- WhitePoint:318,
2556
- PrimaryChromaticities:319,
2557
- ColorMap:320,
2558
- HalftoneHints:321,
2559
- TileWidth:322,
2560
- TileLength:323,
2561
- TileOffsets:324,
2562
- TileByteCounts:325,
2563
- SubIFDs:330,
2564
- InkSet:332,
2565
- InkNames:333,
2566
- NumberOfInks:334,
2567
- DotRange:336,
2568
- TargetPrinter:337,
2569
- ExtraSamples:338,
2570
- SampleFormat:339,
2571
- SMinSampleValue:340,
2572
- SMaxSampleValue:341,
2573
- TransferRange:342,
2574
- ClipPath:343,
2575
- XClipPathUnits:344,
2576
- YClipPathUnits:345,
2577
- Indexed:346,
2578
- JPEGTables:347,
2579
- OPIProxy:351,
2580
- JPEGProc:512,
2581
- JPEGInterchangeFormat:513,
2582
- JPEGInterchangeFormatLength:514,
2583
- JPEGRestartInterval:515,
2584
- JPEGLosslessPredictors:517,
2585
- JPEGPointTransforms:518,
2586
- JPEGQTables:519,
2587
- JPEGDCTables:520,
2588
- JPEGACTables:521,
2589
- YCbCrCoefficients:529,
2590
- YCbCrSubSampling:530,
2591
- YCbCrPositioning:531,
2592
- ReferenceBlackWhite:532,
2593
- XMLPacket:700,
2594
- Rating:18246,
2595
- RatingPercent:18249,
2596
- ImageID:32781,
2597
- CFARepeatPatternDim:33421,
2598
- CFAPattern:33422,
2599
- BatteryLevel:33423,
2600
- Copyright:33432,
2601
- ExposureTime:33434,
2602
- ImageResources:34377,
2603
- ExifTag:34665,
2604
- InterColorProfile:34675,
2605
- GPSTag:34853,
2606
- Interlace:34857,
2607
- TimeZoneOffset:34858,
2608
- SelfTimerMode:34859,
2609
- FlashEnergy:37387,
2610
- SpatialFrequencyResponse:37388,
2611
- Noise:37389,
2612
- FocalPlaneXResolution:37390,
2613
- FocalPlaneYResolution:37391,
2614
- FocalPlaneResolutionUnit:37392,
2615
- ImageNumber:37393,
2616
- SecurityClassification:37394,
2617
- ImageHistory:37395,
2618
- ExposureIndex:37397,
2619
- TIFFEPStandardID:37398,
2620
- SensingMethod:37399,
2621
- XPTitle:40091,
2622
- XPComment:40092,
2623
- XPAuthor:40093,
2624
- XPKeywords:40094,
2625
- XPSubject:40095,
2626
- PrintImageMatching:50341,
2627
- DNGVersion:50706,
2628
- DNGBackwardVersion:50707,
2629
- UniqueCameraModel:50708,
2630
- LocalizedCameraModel:50709,
2631
- CFAPlaneColor:50710,
2632
- CFALayout:50711,
2633
- LinearizationTable:50712,
2634
- BlackLevelRepeatDim:50713,
2635
- BlackLevel:50714,
2636
- BlackLevelDeltaH:50715,
2637
- BlackLevelDeltaV:50716,
2638
- WhiteLevel:50717,
2639
- DefaultScale:50718,
2640
- DefaultCropOrigin:50719,
2641
- DefaultCropSize:50720,
2642
- ColorMatrix1:50721,
2643
- ColorMatrix2:50722,
2644
- CameraCalibration1:50723,
2645
- CameraCalibration2:50724,
2646
- ReductionMatrix1:50725,
2647
- ReductionMatrix2:50726,
2648
- AnalogBalance:50727,
2649
- AsShotNeutral:50728,
2650
- AsShotWhiteXY:50729,
2651
- BaselineExposure:50730,
2652
- BaselineNoise:50731,
2653
- BaselineSharpness:50732,
2654
- BayerGreenSplit:50733,
2655
- LinearResponseLimit:50734,
2656
- CameraSerialNumber:50735,
2657
- LensInfo:50736,
2658
- ChromaBlurRadius:50737,
2659
- AntiAliasStrength:50738,
2660
- ShadowScale:50739,
2661
- DNGPrivateData:50740,
2662
- MakerNoteSafety:50741,
2663
- CalibrationIlluminant1:50778,
2664
- CalibrationIlluminant2:50779,
2665
- BestQualityScale:50780,
2666
- RawDataUniqueID:50781,
2667
- OriginalRawFileName:50827,
2668
- OriginalRawFileData:50828,
2669
- ActiveArea:50829,
2670
- MaskedAreas:50830,
2671
- AsShotICCProfile:50831,
2672
- AsShotPreProfileMatrix:50832,
2673
- CurrentICCProfile:50833,
2674
- CurrentPreProfileMatrix:50834,
2675
- ColorimetricReference:50879,
2676
- CameraCalibrationSignature:50931,
2677
- ProfileCalibrationSignature:50932,
2678
- AsShotProfileName:50934,
2679
- NoiseReductionApplied:50935,
2680
- ProfileName:50936,
2681
- ProfileHueSatMapDims:50937,
2682
- ProfileHueSatMapData1:50938,
2683
- ProfileHueSatMapData2:50939,
2684
- ProfileToneCurve:50940,
2685
- ProfileEmbedPolicy:50941,
2686
- ProfileCopyright:50942,
2687
- ForwardMatrix1:50964,
2688
- ForwardMatrix2:50965,
2689
- PreviewApplicationName:50966,
2690
- PreviewApplicationVersion:50967,
2691
- PreviewSettingsName:50968,
2692
- PreviewSettingsDigest:50969,
2693
- PreviewColorSpace:50970,
2694
- PreviewDateTime:50971,
2695
- RawImageDigest:50972,
2696
- OriginalRawFileDigest:50973,
2697
- SubTileBlockSize:50974,
2698
- RowInterleaveFactor:50975,
2699
- ProfileLookTableDims:50981,
2700
- ProfileLookTableData:50982,
2701
- OpcodeList1:51008,
2702
- OpcodeList2:51009,
2703
- OpcodeList3:51022,
2704
- NoiseProfile:51041,
2705
- };
2706
-
2707
-
2708
- that.ExifIFD = {
2709
- ExposureTime:33434,
2710
- FNumber:33437,
2711
- ExposureProgram:34850,
2712
- SpectralSensitivity:34852,
2713
- ISOSpeedRatings:34855,
2714
- OECF:34856,
2715
- SensitivityType:34864,
2716
- StandardOutputSensitivity:34865,
2717
- RecommendedExposureIndex:34866,
2718
- ISOSpeed:34867,
2719
- ISOSpeedLatitudeyyy:34868,
2720
- ISOSpeedLatitudezzz:34869,
2721
- ExifVersion:36864,
2722
- DateTimeOriginal:36867,
2723
- DateTimeDigitized:36868,
2724
- ComponentsConfiguration:37121,
2725
- CompressedBitsPerPixel:37122,
2726
- ShutterSpeedValue:37377,
2727
- ApertureValue:37378,
2728
- BrightnessValue:37379,
2729
- ExposureBiasValue:37380,
2730
- MaxApertureValue:37381,
2731
- SubjectDistance:37382,
2732
- MeteringMode:37383,
2733
- LightSource:37384,
2734
- Flash:37385,
2735
- FocalLength:37386,
2736
- SubjectArea:37396,
2737
- MakerNote:37500,
2738
- UserComment:37510,
2739
- SubSecTime:37520,
2740
- SubSecTimeOriginal:37521,
2741
- SubSecTimeDigitized:37522,
2742
- FlashpixVersion:40960,
2743
- ColorSpace:40961,
2744
- PixelXDimension:40962,
2745
- PixelYDimension:40963,
2746
- RelatedSoundFile:40964,
2747
- InteroperabilityTag:40965,
2748
- FlashEnergy:41483,
2749
- SpatialFrequencyResponse:41484,
2750
- FocalPlaneXResolution:41486,
2751
- FocalPlaneYResolution:41487,
2752
- FocalPlaneResolutionUnit:41488,
2753
- SubjectLocation:41492,
2754
- ExposureIndex:41493,
2755
- SensingMethod:41495,
2756
- FileSource:41728,
2757
- SceneType:41729,
2758
- CFAPattern:41730,
2759
- CustomRendered:41985,
2760
- ExposureMode:41986,
2761
- WhiteBalance:41987,
2762
- DigitalZoomRatio:41988,
2763
- FocalLengthIn35mmFilm:41989,
2764
- SceneCaptureType:41990,
2765
- GainControl:41991,
2766
- Contrast:41992,
2767
- Saturation:41993,
2768
- Sharpness:41994,
2769
- DeviceSettingDescription:41995,
2770
- SubjectDistanceRange:41996,
2771
- ImageUniqueID:42016,
2772
- CameraOwnerName:42032,
2773
- BodySerialNumber:42033,
2774
- LensSpecification:42034,
2775
- LensMake:42035,
2776
- LensModel:42036,
2777
- LensSerialNumber:42037,
2778
- Gamma:42240,
2779
- };
2780
-
2781
-
2782
- that.GPSIFD = {
2783
- GPSVersionID:0,
2784
- GPSLatitudeRef:1,
2785
- GPSLatitude:2,
2786
- GPSLongitudeRef:3,
2787
- GPSLongitude:4,
2788
- GPSAltitudeRef:5,
2789
- GPSAltitude:6,
2790
- GPSTimeStamp:7,
2791
- GPSSatellites:8,
2792
- GPSStatus:9,
2793
- GPSMeasureMode:10,
2794
- GPSDOP:11,
2795
- GPSSpeedRef:12,
2796
- GPSSpeed:13,
2797
- GPSTrackRef:14,
2798
- GPSTrack:15,
2799
- GPSImgDirectionRef:16,
2800
- GPSImgDirection:17,
2801
- GPSMapDatum:18,
2802
- GPSDestLatitudeRef:19,
2803
- GPSDestLatitude:20,
2804
- GPSDestLongitudeRef:21,
2805
- GPSDestLongitude:22,
2806
- GPSDestBearingRef:23,
2807
- GPSDestBearing:24,
2808
- GPSDestDistanceRef:25,
2809
- GPSDestDistance:26,
2810
- GPSProcessingMethod:27,
2811
- GPSAreaInformation:28,
2812
- GPSDateStamp:29,
2813
- GPSDifferential:30,
2814
- GPSHPositioningError:31,
2815
- };
2816
-
2817
-
2818
- that.InteropIFD = {
2819
- InteroperabilityIndex:1,
2820
- };
2821
-
2822
- that.GPSHelper = {
2823
- degToDmsRational:function (degFloat) {
2824
- var degAbs = Math.abs(degFloat);
2825
- var minFloat = degAbs % 1 * 60;
2826
- var secFloat = minFloat % 1 * 60;
2827
- var deg = Math.floor(degAbs);
2828
- var min = Math.floor(minFloat);
2829
- var sec = Math.round(secFloat * 100);
2830
-
2831
- return [[deg, 1], [min, 1], [sec, 100]];
2832
- },
2833
-
2834
- dmsRationalToDeg:function (dmsArray, ref) {
2835
- var sign = (ref === 'S' || ref === 'W') ? -1.0 : 1.0;
2836
- var deg = dmsArray[0][0] / dmsArray[0][1] +
2837
- dmsArray[1][0] / dmsArray[1][1] / 60.0 +
2838
- dmsArray[2][0] / dmsArray[2][1] / 3600.0;
2839
-
2840
- return deg * sign;
2841
- }
2842
- };
2843
-
2844
-
2845
- if ('object' !== 'undefined') {
2846
- if ('object' !== 'undefined' && module.exports) {
2847
- exports = module.exports = that;
2848
- }
2849
- exports.piexif = that;
2850
- } else {
2851
- window.piexif = that;
2852
- }
2853
-
2854
- })();
2855
- });
2856
-
2857
- const addExifInImg = async (blob, track, videoSize) => {
2858
- const base64 = await blobToBase64(blob);
2859
- const exif = piexif.load(base64);
2860
- const devices = await navigator.mediaDevices.enumerateDevices();
2861
- const cameraNames = devices.filter(device => device.kind === 'videoinput').map(device => device.label);
2862
- const json = {
2863
- width: videoSize.width,
2864
- height: videoSize.height,
2865
- usedCamera: track.label,
2866
- camerasOnDevice: cameraNames,
2867
- };
2868
- const newExif = {
2869
- '0th': Object.assign(Object.assign({}, exif['0th']), { [piexif.ImageIFD.Model]: json.usedCamera, [piexif.ImageIFD.ImageWidth]: json.width, [piexif.ImageIFD.ImageLength]: json.height }),
2870
- 'Exif': Object.assign(Object.assign({}, exif['Exif']), { [piexif.ExifIFD.UserComment]: JSON.stringify(json) }),
2871
- 'GPS': Object.assign({}, exif['GPS']),
2872
- 'Interop': Object.assign({}, exif['Interop']),
2873
- '1st': Object.assign({}, exif['1st']),
2874
- 'thumbnail': exif['thumbnail'],
2875
- };
2876
- const newExifBinary = piexif.dump(newExif);
2877
- const newPhotoData = piexif.insert(newExifBinary, base64);
2878
- return await fetch(newPhotoData).then(res => res.blob());
2879
- };
2880
-
2881
- var ImageFormat;
2882
- (function (ImageFormat) {
2883
- ImageFormat["JPEG"] = "image/jpeg";
2884
- ImageFormat["PNG"] = "image/png";
2885
- })(ImageFormat || (ImageFormat = {}));
2886
- class Stream {
2887
- setFaceDetection(val) {
2888
- this.faceDetection = val;
2889
- this.idDetection = !val;
2890
- }
2891
- setIdDetection(val) {
2892
- this.idDetection = val;
2893
- this.faceDetection = !val;
2894
- }
2895
- // public setProbabilityThreshold(val: number): void {
2896
- // Detector.getInstance().setProbabilityThreshold(val);
2897
- // }
2898
- setCallbackChangeTitle(fun) {
2899
- this.callbackChangeTitle = fun;
2900
- }
2901
- setCallbackVideoStarted(fun) {
2902
- this.callbackVideoStarted = fun;
2903
- }
2904
- setCallbackErrors(fun) {
2905
- this.callbackErrors = fun;
2906
- }
2907
- setCallbackAutoCapturing(fun) {
2908
- this.callbackAutoCapturing = fun;
2909
- }
2910
- // public setCallbackFaceDetectionErrors(fun: (e: PipelineResult) => void): void {
2911
- // this.callbackFaceDetectionErrors = fun;
2912
- // }
2913
- setCallbackRecordingReady(fun) {
2914
- this.callbackRecordingReady = fun;
2915
- }
2916
- setCallbackTimeElapsed(fun) {
2917
- this.callbackTimeElapsed = fun;
2918
- }
2919
- setVerificationFinished(fun) {
2920
- this.verificationFinished = fun;
2921
- }
2922
- constructor(mode) {
2923
- this.streamPaused = false;
2924
- this.recordedChunks = [];
2925
- this.videoSize = { width: 0, height: 0 };
2926
- this.pauseStream = () => {
2927
- this.streamPaused = true;
2928
- this.mediaRecorder.pause();
2929
- this.videoElement.pause();
2930
- // this.dropMask();
2931
- // if (this.faceDetection) Detector.getInstance().stopDetector();
2932
- };
2933
- this.initFacePose();
2934
- this.idML5Detector = IDML5Detector.getInstance(this, state.device.isMobile);
2935
- this.faceML5Detector = FaceML5Detector.getInstance(this, state.device.isMobile);
2936
- this.verificationMode = mode;
2937
- }
2938
- static getInstance(mode) {
2939
- if (!Stream.instance) {
2940
- Stream.instance = new Stream(mode);
2941
- }
2942
- return Stream.instance;
2943
- }
2944
- // public returnErrors(errors: PipelineResult) {
2945
- // this.callbackFaceDetectionErrors(errors);
2946
- // }
2947
- autoCapturing() {
2948
- this.callbackAutoCapturing();
2949
- }
2950
- timeElapsed() {
2951
- this.callbackTimeElapsed();
2952
- }
2953
- verificationReady() {
2954
- this.verificationFinished();
2955
- }
2956
- updateHtmlElements(videoElement, canvasElement, component) {
2957
- this.videoElement = videoElement;
2958
- this.canvasElement = canvasElement;
2959
- this.idML5Detector.updateHtmlElements(this.videoElement, this.canvasElement, component);
2960
- this.faceML5Detector.updateHtmlElements(this.videoElement, this.canvasElement, component);
2961
- }
2962
- static orientationChange() { }
2963
- startStream(stream) {
2964
- if (this.stream)
2965
- this.stream.getTracks().forEach((track) => track.stop());
2966
- this.stream = stream;
2967
- if (!this.videoElement || this.videoElement == null) {
2968
- return;
2969
- }
2970
- if ('srcObject' in this.videoElement) {
2971
- this.videoElement.srcObject = stream;
2972
- }
2973
- else {
2974
- // @ts-ignore
2975
- this.videoElement.src = window.URL.createObjectURL(stream);
2976
- }
2977
- this.videoElement.addEventListener('loadedmetadata', async (_e) => {
2978
- this.videoElement.play().then(() => {
2979
- this.streamPaused = false;
2980
- this.updateCanvasSize(this.canvasElement);
2981
- this.updateVideoSize(this.videoElement);
2982
- this.callbackVideoStarted();
2983
- if (this.idDetection)
2984
- this.startIdDetection();
2985
- if (this.faceDetection)
2986
- this.startFaceDetection();
2987
- });
2988
- }, false);
2989
- }
2990
- async initStream(stream) {
2991
- this.startStream(stream);
2992
- this.recordStream();
2993
- }
2994
- async resumeStream() {
2995
- this.streamPaused = false;
2996
- this.mediaRecorder.resume();
2997
- await this.videoElement.play();
2998
- // this.drawMask();
2999
- // if (this.faceDetection) await Detector.getInstance().startDetector();
3000
- }
3001
- recordStream() {
3002
- if (this.mediaRecorder && this.mediaRecorder.state == 'recording')
3003
- return;
3004
- var options = { mimeType: Stream.webmMimeType.mime, videoBitsPerSecond: 1500000 };
3005
- if (!MediaRecorder.isTypeSupported(options.mimeType)) {
3006
- if (state.device.mobileOS == MobileOS.iOS || state.device.browser == Browser.Safari)
3007
- options.mimeType = Stream.mp4MimeType.mime;
3008
- }
3009
- this.recordedChunks = [];
3010
- this.mediaRecorder = new MediaRecorder(this.stream, options);
3011
- this.mediaRecorder.ondataavailable = event => {
3012
- this.recordedChunks.push(event.data);
3013
- };
3014
- this.mediaRecorder.onstop = _e => {
3015
- var rec = new Blob(this.recordedChunks, {
3016
- type: options.mimeType.split(';')[0],
3017
- });
3018
- this.callbackRecordingReady(rec);
3019
- };
3020
- this.mediaRecorder.start(); // Start recording, and dump data every second
3021
- }
3022
- updateCanvasSize(canvas) {
3023
- this.videoSize = { width: this.videoElement.videoWidth, height: this.videoElement.videoHeight };
3024
- canvas.width = this.videoSize.width;
3025
- canvas.height = this.videoSize.height;
3026
- }
3027
- updateVideoSize(video) {
3028
- this.videoSize = { width: this.videoElement.videoWidth, height: this.videoElement.videoHeight };
3029
- video.width = this.videoSize.width;
3030
- video.height = this.videoSize.height;
3031
- }
3032
- dropStream() {
3033
- if (!this.streamStopped()) {
3034
- this.stream.getTracks().forEach((track) => track.stop());
3035
- this.videoElement.srcObject = null;
3036
- }
3037
- if (this.mediaRecorder && this.mediaRecorder.state != 'inactive') {
3038
- this.mediaRecorder.stop();
3039
- }
3040
- // if (this.faceDetection) Detector.getInstance().stopDetector();
3041
- }
3042
- streamStopped() {
3043
- return !(this.stream && this.stream.getTracks && this.stream.getTracks().length > 0);
3044
- }
3045
- async takePhoto() {
3046
- const canvas = document.createElement('canvas');
3047
- canvas.style.visibility = 'hidden';
3048
- canvas.width = this.videoElement.videoWidth;
3049
- canvas.height = this.videoElement.videoHeight;
3050
- return await this.getFrame(canvas);
3051
- }
3052
- getFrame(canvas) {
3053
- return new Promise(resolve => {
3054
- const context = canvas.getContext('2d');
3055
- context.drawImage(this.videoElement, 0, 0, canvas.width, canvas.height);
3056
- canvas.toBlob((frame) => {
3057
- if (frame.type === ImageFormat.JPEG && !state.device.isAppleDevice) {
3058
- try {
3059
- addExifInImg(frame, this.stream.getTracks()[0], this.videoSize).then(updatedFrame => resolve(updatedFrame));
3060
- }
3061
- catch (e) {
3062
- resolve(frame);
3063
- this.callbackErrors(e, false);
3064
- }
3065
- }
3066
- else {
3067
- resolve(frame);
3068
- }
3069
- }, ImageFormat.PNG, 1);
3070
- //let outCanvContext = this.canvasElement.getContext('2d');
3071
- //outCanvContext.drawImage(this.videoElement, 0, 0, this.canvasElement.width, this.canvasElement.height);
3072
- });
3073
- }
3074
- async startIdDetection() {
3075
- if (this.streamPaused)
3076
- return;
3077
- this.idML5Detector.initDetector(this.verificationMode);
3078
- }
3079
- async startFaceDetection() {
3080
- if (this.streamPaused)
3081
- return;
3082
- this.faceML5Detector.initDetector(this.verificationMode);
3083
- }
3084
- initFacePose() {
3085
- this.facePose = FacePosePick.randomEnum(FacePose);
3086
- }
3087
- requestFacePose() {
3088
- // var pose = FacePose.TiltLeft;
3089
- this.callbackChangeTitle(this.facePose);
3090
- return this.facePose;
3091
- }
3092
- changeFacePose() {
3093
- this.callbackChangeTitle(null);
3094
- }
3095
- changeIDPose(pose) {
3096
- this.callbackChangeTitle(pose);
3097
- }
3098
- }
3099
- Stream.mp4MimeType = { type: 'video/mp4', codec: 'codecs:h264', extension: 'mp4', mime: 'video/mp4;codecs:h264' };
3100
- Stream.webmMimeType = { type: 'video/webm', codec: 'codecs=vp8', extension: 'webm', mime: 'video/webm;codecs=vp8' };
3101
- window.addEventListener('resize', Stream.orientationChange, false);
3102
- window.addEventListener('orientationchange', Stream.orientationChange, false);
3103
-
3104
- export { FaceML5Detector as F, IDML5Detector as I, Stream as S, VerificationMode as V, FacePose as a };