compressorjs 1.1.1 → 1.2.0

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.
@@ -1,103 +1,25 @@
1
1
  /*!
2
- * Compressor.js v1.1.1
2
+ * Compressor.js v1.2.0
3
3
  * https://fengyuanchen.github.io/compressorjs
4
4
  *
5
5
  * Copyright 2018-present Chen Fengyuan
6
6
  * Released under the MIT license
7
7
  *
8
- * Date: 2021-10-05T02:32:40.212Z
8
+ * Date: 2023-02-25T11:35:56.625Z
9
9
  */
10
10
 
11
- function ownKeys(object, enumerableOnly) {
12
- var keys = Object.keys(object);
13
-
14
- if (Object.getOwnPropertySymbols) {
15
- var symbols = Object.getOwnPropertySymbols(object);
16
-
17
- if (enumerableOnly) {
18
- symbols = symbols.filter(function (sym) {
19
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
20
- });
21
- }
22
-
23
- keys.push.apply(keys, symbols);
24
- }
25
-
26
- return keys;
27
- }
28
-
29
- function _objectSpread2(target) {
30
- for (var i = 1; i < arguments.length; i++) {
31
- var source = arguments[i] != null ? arguments[i] : {};
32
-
33
- if (i % 2) {
34
- ownKeys(Object(source), true).forEach(function (key) {
35
- _defineProperty(target, key, source[key]);
36
- });
37
- } else if (Object.getOwnPropertyDescriptors) {
38
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
39
- } else {
40
- ownKeys(Object(source)).forEach(function (key) {
41
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
42
- });
43
- }
44
- }
45
-
46
- return target;
47
- }
48
-
49
- function _classCallCheck(instance, Constructor) {
50
- if (!(instance instanceof Constructor)) {
51
- throw new TypeError("Cannot call a class as a function");
52
- }
53
- }
54
-
55
- function _defineProperties(target, props) {
56
- for (var i = 0; i < props.length; i++) {
57
- var descriptor = props[i];
58
- descriptor.enumerable = descriptor.enumerable || false;
59
- descriptor.configurable = true;
60
- if ("value" in descriptor) descriptor.writable = true;
61
- Object.defineProperty(target, descriptor.key, descriptor);
62
- }
63
- }
64
-
65
- function _createClass(Constructor, protoProps, staticProps) {
66
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
67
- if (staticProps) _defineProperties(Constructor, staticProps);
68
- return Constructor;
69
- }
70
-
71
- function _defineProperty(obj, key, value) {
72
- if (key in obj) {
73
- Object.defineProperty(obj, key, {
74
- value: value,
75
- enumerable: true,
76
- configurable: true,
77
- writable: true
78
- });
79
- } else {
80
- obj[key] = value;
81
- }
82
-
83
- return obj;
84
- }
85
-
86
11
  function _extends() {
87
- _extends = Object.assign || function (target) {
12
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
88
13
  for (var i = 1; i < arguments.length; i++) {
89
14
  var source = arguments[i];
90
-
91
15
  for (var key in source) {
92
16
  if (Object.prototype.hasOwnProperty.call(source, key)) {
93
17
  target[key] = source[key];
94
18
  }
95
19
  }
96
20
  }
97
-
98
21
  return target;
99
22
  };
100
-
101
23
  return _extends.apply(this, arguments);
102
24
  }
103
25
 
@@ -116,16 +38,13 @@ var canvasToBlob = {exports: {}};
116
38
  * Based on stackoverflow user Stoive's code snippet:
117
39
  * http://stackoverflow.com/q/4998908
118
40
  */
119
-
120
41
  (function (module) {
121
42
  if (typeof window === 'undefined') {
122
43
  return;
123
44
  }
124
-
125
45
  (function (window) {
126
46
 
127
47
  var CanvasPrototype = window.HTMLCanvasElement && window.HTMLCanvasElement.prototype;
128
-
129
48
  var hasBlobConstructor = window.Blob && function () {
130
49
  try {
131
50
  return Boolean(new Blob());
@@ -133,7 +52,6 @@ var canvasToBlob = {exports: {}};
133
52
  return false;
134
53
  }
135
54
  }();
136
-
137
55
  var hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array && function () {
138
56
  try {
139
57
  return new Blob([new Uint8Array(100)]).size === 100;
@@ -141,52 +59,42 @@ var canvasToBlob = {exports: {}};
141
59
  return false;
142
60
  }
143
61
  }();
144
-
145
62
  var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
146
63
  var dataURIPattern = /^data:((.*?)(;charset=.*?)?)(;base64)?,/;
147
-
148
64
  var dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob && window.ArrayBuffer && window.Uint8Array && function (dataURI) {
149
- var matches, mediaType, isBase64, dataString, byteString, arrayBuffer, intArray, i, bb; // Parse the dataURI components as per RFC 2397
150
-
65
+ var matches, mediaType, isBase64, dataString, byteString, arrayBuffer, intArray, i, bb;
66
+ // Parse the dataURI components as per RFC 2397
151
67
  matches = dataURI.match(dataURIPattern);
152
-
153
68
  if (!matches) {
154
69
  throw new Error('invalid data URI');
155
- } // Default to text/plain;charset=US-ASCII
156
-
157
-
70
+ }
71
+ // Default to text/plain;charset=US-ASCII
158
72
  mediaType = matches[2] ? matches[1] : 'text/plain' + (matches[3] || ';charset=US-ASCII');
159
73
  isBase64 = !!matches[4];
160
74
  dataString = dataURI.slice(matches[0].length);
161
-
162
75
  if (isBase64) {
163
76
  // Convert base64 to raw binary data held in a string:
164
77
  byteString = atob(dataString);
165
78
  } else {
166
79
  // Convert base64/URLEncoded data component to raw binary:
167
80
  byteString = decodeURIComponent(dataString);
168
- } // Write the bytes of the string to an ArrayBuffer:
169
-
170
-
81
+ }
82
+ // Write the bytes of the string to an ArrayBuffer:
171
83
  arrayBuffer = new ArrayBuffer(byteString.length);
172
84
  intArray = new Uint8Array(arrayBuffer);
173
-
174
85
  for (i = 0; i < byteString.length; i += 1) {
175
86
  intArray[i] = byteString.charCodeAt(i);
176
- } // Write the ArrayBuffer (or ArrayBufferView) to a blob:
177
-
178
-
87
+ }
88
+ // Write the ArrayBuffer (or ArrayBufferView) to a blob:
179
89
  if (hasBlobConstructor) {
180
90
  return new Blob([hasArrayBufferViewSupport ? intArray : arrayBuffer], {
181
91
  type: mediaType
182
92
  });
183
93
  }
184
-
185
94
  bb = new BlobBuilder();
186
95
  bb.append(arrayBuffer);
187
96
  return bb.getBlob(mediaType);
188
97
  };
189
-
190
98
  if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {
191
99
  if (CanvasPrototype.mozGetAsFile) {
192
100
  CanvasPrototype.toBlob = function (callback, type, quality) {
@@ -221,7 +129,6 @@ var canvasToBlob = {exports: {}};
221
129
  }
222
130
  }
223
131
  }
224
-
225
132
  if (module.exports) {
226
133
  module.exports = dataURLtoBlob;
227
134
  } else {
@@ -229,14 +136,12 @@ var canvasToBlob = {exports: {}};
229
136
  }
230
137
  })(window);
231
138
  })(canvasToBlob);
232
-
233
139
  var toBlob = canvasToBlob.exports;
234
140
 
235
- var isBlob = function isBlob(value) {
141
+ var isBlob = value => {
236
142
  if (typeof Blob === 'undefined') {
237
143
  return false;
238
144
  }
239
-
240
145
  return value instanceof Blob || Object.prototype.toString.call(value) === '[object Blob]';
241
146
  };
242
147
 
@@ -247,59 +152,55 @@ var DEFAULTS = {
247
152
  * @type {boolean}
248
153
  */
249
154
  strict: true,
250
-
251
155
  /**
252
156
  * Indicates if read the image's Exif Orientation information,
253
157
  * and then rotate or flip the image automatically.
254
158
  * @type {boolean}
255
159
  */
256
160
  checkOrientation: true,
257
-
161
+ /**
162
+ * Indicates if retain the image's Exif information after compressed.
163
+ * @type {boolean}
164
+ */
165
+ retainExif: false,
258
166
  /**
259
167
  * The max width of the output image.
260
168
  * @type {number}
261
169
  */
262
170
  maxWidth: Infinity,
263
-
264
171
  /**
265
172
  * The max height of the output image.
266
173
  * @type {number}
267
174
  */
268
175
  maxHeight: Infinity,
269
-
270
176
  /**
271
177
  * The min width of the output image.
272
178
  * @type {number}
273
179
  */
274
180
  minWidth: 0,
275
-
276
181
  /**
277
182
  * The min height of the output image.
278
183
  * @type {number}
279
184
  */
280
185
  minHeight: 0,
281
-
282
186
  /**
283
187
  * The width of the output image.
284
188
  * If not specified, the natural width of the source image will be used.
285
189
  * @type {number}
286
190
  */
287
191
  width: undefined,
288
-
289
192
  /**
290
193
  * The height of the output image.
291
194
  * If not specified, the natural height of the source image will be used.
292
195
  * @type {number}
293
196
  */
294
197
  height: undefined,
295
-
296
198
  /**
297
199
  * Sets how the size of the image should be resized to the container
298
200
  * specified by the `width` and `height` options.
299
201
  * @type {string}
300
202
  */
301
203
  resize: 'none',
302
-
303
204
  /**
304
205
  * The quality of the output image.
305
206
  * It must be a number between `0` and `1`,
@@ -308,28 +209,24 @@ var DEFAULTS = {
308
209
  * @type {number}
309
210
  */
310
211
  quality: 0.8,
311
-
312
212
  /**
313
213
  * The mime type of the output image.
314
214
  * By default, the original mime type of the source image file will be used.
315
215
  * @type {string}
316
216
  */
317
217
  mimeType: 'auto',
318
-
319
218
  /**
320
219
  * Files whose file type is included in this list,
321
220
  * and whose file size exceeds the `convertSize` value will be converted to JPEGs.
322
221
  * @type {string|Array}
323
222
  */
324
223
  convertTypes: ['image/png'],
325
-
326
224
  /**
327
225
  * PNG files over this size (5 MB by default) will be converted to JPEGs.
328
226
  * To disable this, just set the value to `Infinity`.
329
227
  * @type {number}
330
228
  */
331
229
  convertSize: 5000000,
332
-
333
230
  /**
334
231
  * The hook function to execute before draw the image into the canvas for compression.
335
232
  * @type {Function}
@@ -341,7 +238,6 @@ var DEFAULTS = {
341
238
  * }
342
239
  */
343
240
  beforeDraw: null,
344
-
345
241
  /**
346
242
  * The hook function to execute after drew the image into the canvas for compression.
347
243
  * @type {Function}
@@ -353,7 +249,6 @@ var DEFAULTS = {
353
249
  * }
354
250
  */
355
251
  drew: null,
356
-
357
252
  /**
358
253
  * The hook function to execute when success to compress the image.
359
254
  * @type {Function}
@@ -364,7 +259,6 @@ var DEFAULTS = {
364
259
  * }
365
260
  */
366
261
  success: null,
367
-
368
262
  /**
369
263
  * The hook function to execute when fail to compress the image.
370
264
  * @type {Function}
@@ -377,54 +271,54 @@ var DEFAULTS = {
377
271
  error: null
378
272
  };
379
273
 
380
- var IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
381
- var WINDOW = IS_BROWSER ? window : {};
274
+ const IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined';
275
+ const WINDOW = IS_BROWSER ? window : {};
382
276
 
383
277
  /**
384
278
  * Check if the given value is a positive number.
385
279
  * @param {*} value - The value to check.
386
280
  * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
387
281
  */
282
+ const isPositiveNumber = value => value > 0 && value < Infinity;
283
+ const {
284
+ slice
285
+ } = Array.prototype;
388
286
 
389
- var isPositiveNumber = function isPositiveNumber(value) {
390
- return value > 0 && value < Infinity;
391
- };
392
- var slice = Array.prototype.slice;
393
287
  /**
394
288
  * Convert array-like or iterable object to an array.
395
289
  * @param {*} value - The value to convert.
396
290
  * @returns {Array} Returns a new array.
397
291
  */
398
-
399
292
  function toArray(value) {
400
293
  return Array.from ? Array.from(value) : slice.call(value);
401
294
  }
402
- var REGEXP_IMAGE_TYPE = /^image\/.+$/;
295
+ const REGEXP_IMAGE_TYPE = /^image\/.+$/;
296
+
403
297
  /**
404
298
  * Check if the given value is a mime type of image.
405
299
  * @param {*} value - The value to check.
406
300
  * @returns {boolean} Returns `true` if the given is a mime type of image, else `false`.
407
301
  */
408
-
409
302
  function isImageType(value) {
410
303
  return REGEXP_IMAGE_TYPE.test(value);
411
304
  }
305
+
412
306
  /**
413
307
  * Convert image type to extension.
414
308
  * @param {string} value - The image type to convert.
415
309
  * @returns {boolean} Returns the image extension.
416
310
  */
417
-
418
311
  function imageTypeToExtension(value) {
419
- var extension = isImageType(value) ? value.substr(6) : '';
420
-
312
+ let extension = isImageType(value) ? value.substr(6) : '';
421
313
  if (extension === 'jpeg') {
422
314
  extension = 'jpg';
423
315
  }
424
-
425
- return ".".concat(extension);
316
+ return `.${extension}`;
426
317
  }
427
- var fromCharCode = String.fromCharCode;
318
+ const {
319
+ fromCharCode
320
+ } = String;
321
+
428
322
  /**
429
323
  * Get string from char code in data view.
430
324
  * @param {DataView} dataView - The data view for read.
@@ -432,83 +326,74 @@ var fromCharCode = String.fromCharCode;
432
326
  * @param {number} length - The read length.
433
327
  * @returns {string} The read result.
434
328
  */
435
-
436
329
  function getStringFromCharCode(dataView, start, length) {
437
- var str = '';
438
- var i;
330
+ let str = '';
331
+ let i;
439
332
  length += start;
440
-
441
333
  for (i = start; i < length; i += 1) {
442
334
  str += fromCharCode(dataView.getUint8(i));
443
335
  }
444
-
445
336
  return str;
446
337
  }
447
- var btoa = WINDOW.btoa;
338
+ const {
339
+ btoa
340
+ } = WINDOW;
341
+
448
342
  /**
449
343
  * Transform array buffer to Data URL.
450
344
  * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
451
345
  * @param {string} mimeType - The mime type of the Data URL.
452
346
  * @returns {string} The result Data URL.
453
347
  */
454
-
455
348
  function arrayBufferToDataURL(arrayBuffer, mimeType) {
456
- var chunks = [];
457
- var chunkSize = 8192;
458
- var uint8 = new Uint8Array(arrayBuffer);
459
-
349
+ const chunks = [];
350
+ const chunkSize = 8192;
351
+ let uint8 = new Uint8Array(arrayBuffer);
460
352
  while (uint8.length > 0) {
461
353
  // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
462
354
  // eslint-disable-next-line prefer-spread
463
355
  chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
464
356
  uint8 = uint8.subarray(chunkSize);
465
357
  }
466
-
467
- return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
358
+ return `data:${mimeType};base64,${btoa(chunks.join(''))}`;
468
359
  }
360
+
469
361
  /**
470
362
  * Get orientation value from given array buffer.
471
363
  * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
472
364
  * @returns {number} The read orientation value.
473
365
  */
474
-
475
366
  function resetAndGetOrientation(arrayBuffer) {
476
- var dataView = new DataView(arrayBuffer);
477
- var orientation; // Ignores range error when the image does not have correct Exif information
367
+ const dataView = new DataView(arrayBuffer);
368
+ let orientation;
478
369
 
370
+ // Ignores range error when the image does not have correct Exif information
479
371
  try {
480
- var littleEndian;
481
- var app1Start;
482
- var ifdStart; // Only handle JPEG image (start by 0xFFD8)
372
+ let littleEndian;
373
+ let app1Start;
374
+ let ifdStart;
483
375
 
376
+ // Only handle JPEG image (start by 0xFFD8)
484
377
  if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
485
- var length = dataView.byteLength;
486
- var offset = 2;
487
-
378
+ const length = dataView.byteLength;
379
+ let offset = 2;
488
380
  while (offset + 1 < length) {
489
381
  if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
490
382
  app1Start = offset;
491
383
  break;
492
384
  }
493
-
494
385
  offset += 1;
495
386
  }
496
387
  }
497
-
498
388
  if (app1Start) {
499
- var exifIDCode = app1Start + 4;
500
- var tiffOffset = app1Start + 10;
501
-
389
+ const exifIDCode = app1Start + 4;
390
+ const tiffOffset = app1Start + 10;
502
391
  if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
503
- var endianness = dataView.getUint16(tiffOffset);
392
+ const endianness = dataView.getUint16(tiffOffset);
504
393
  littleEndian = endianness === 0x4949;
505
-
506
- if (littleEndian || endianness === 0x4D4D
507
- /* bigEndian */
508
- ) {
394
+ if (littleEndian || endianness === 0x4D4D /* bigEndian */) {
509
395
  if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
510
- var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
511
-
396
+ const firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
512
397
  if (firstIFDOffset >= 0x00000008) {
513
398
  ifdStart = tiffOffset + firstIFDOffset;
514
399
  }
@@ -516,26 +401,21 @@ function resetAndGetOrientation(arrayBuffer) {
516
401
  }
517
402
  }
518
403
  }
519
-
520
404
  if (ifdStart) {
521
- var _length = dataView.getUint16(ifdStart, littleEndian);
522
-
523
- var _offset;
524
-
525
- var i;
526
-
527
- for (i = 0; i < _length; i += 1) {
528
- _offset = ifdStart + i * 12 + 2;
529
-
530
- if (dataView.getUint16(_offset, littleEndian) === 0x0112
531
- /* Orientation */
532
- ) {
405
+ const length = dataView.getUint16(ifdStart, littleEndian);
406
+ let offset;
407
+ let i;
408
+ for (i = 0; i < length; i += 1) {
409
+ offset = ifdStart + i * 12 + 2;
410
+ if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) {
533
411
  // 8 is the offset of the current tag's value
534
- _offset += 8; // Get the original orientation value
412
+ offset += 8;
535
413
 
536
- orientation = dataView.getUint16(_offset, littleEndian); // Override the orientation with its default value
414
+ // Get the original orientation value
415
+ orientation = dataView.getUint16(offset, littleEndian);
537
416
 
538
- dataView.setUint16(_offset, 1, littleEndian);
417
+ // Override the orientation with its default value
418
+ dataView.setUint16(offset, 1, littleEndian);
539
419
  break;
540
420
  }
541
421
  }
@@ -543,66 +423,64 @@ function resetAndGetOrientation(arrayBuffer) {
543
423
  } catch (e) {
544
424
  orientation = 1;
545
425
  }
546
-
547
426
  return orientation;
548
427
  }
428
+
549
429
  /**
550
430
  * Parse Exif Orientation value.
551
431
  * @param {number} orientation - The orientation to parse.
552
432
  * @returns {Object} The parsed result.
553
433
  */
554
-
555
434
  function parseOrientation(orientation) {
556
- var rotate = 0;
557
- var scaleX = 1;
558
- var scaleY = 1;
559
-
435
+ let rotate = 0;
436
+ let scaleX = 1;
437
+ let scaleY = 1;
560
438
  switch (orientation) {
561
439
  // Flip horizontal
562
440
  case 2:
563
441
  scaleX = -1;
564
442
  break;
565
- // Rotate left 180°
566
443
 
444
+ // Rotate left 180°
567
445
  case 3:
568
446
  rotate = -180;
569
447
  break;
570
- // Flip vertical
571
448
 
449
+ // Flip vertical
572
450
  case 4:
573
451
  scaleY = -1;
574
452
  break;
575
- // Flip vertical and rotate right 90°
576
453
 
454
+ // Flip vertical and rotate right 90°
577
455
  case 5:
578
456
  rotate = 90;
579
457
  scaleY = -1;
580
458
  break;
581
- // Rotate right 90°
582
459
 
460
+ // Rotate right 90°
583
461
  case 6:
584
462
  rotate = 90;
585
463
  break;
586
- // Flip horizontal and rotate right 90°
587
464
 
465
+ // Flip horizontal and rotate right 90°
588
466
  case 7:
589
467
  rotate = 90;
590
468
  scaleX = -1;
591
469
  break;
592
- // Rotate left 90°
593
470
 
471
+ // Rotate left 90°
594
472
  case 8:
595
473
  rotate = -90;
596
474
  break;
597
475
  }
598
-
599
476
  return {
600
- rotate: rotate,
601
- scaleX: scaleX,
602
- scaleY: scaleY
477
+ rotate,
478
+ scaleX,
479
+ scaleY
603
480
  };
604
481
  }
605
- var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
482
+ const REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
483
+
606
484
  /**
607
485
  * Normalize decimal number.
608
486
  * Check out {@link https://0.30000000000000004.com/}
@@ -610,29 +488,28 @@ var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
610
488
  * @param {number} [times=100000000000] - The times for normalizing.
611
489
  * @returns {number} Returns the normalized number.
612
490
  */
613
-
614
491
  function normalizeDecimalNumber(value) {
615
- var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
492
+ let times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
616
493
  return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
617
494
  }
495
+
618
496
  /**
619
497
  * Get the max sizes in a rectangle under the given aspect ratio.
620
498
  * @param {Object} data - The original sizes.
621
499
  * @param {string} [type='contain'] - The adjust type.
622
500
  * @returns {Object} The result sizes.
623
501
  */
624
-
625
502
  function getAdjustedSizes(_ref) {
626
- var aspectRatio = _ref.aspectRatio,
627
- height = _ref.height,
628
- width = _ref.width;
629
- var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
630
- var isValidWidth = isPositiveNumber(width);
631
- var isValidHeight = isPositiveNumber(height);
632
-
503
+ let {
504
+ aspectRatio,
505
+ height,
506
+ width
507
+ } = _ref;
508
+ let type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'none';
509
+ const isValidWidth = isPositiveNumber(width);
510
+ const isValidHeight = isPositiveNumber(height);
633
511
  if (isValidWidth && isValidHeight) {
634
- var adjustedWidth = height * aspectRatio;
635
-
512
+ const adjustedWidth = height * aspectRatio;
636
513
  if ((type === 'contain' || type === 'none') && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
637
514
  height = width / aspectRatio;
638
515
  } else {
@@ -643,429 +520,467 @@ function getAdjustedSizes(_ref) {
643
520
  } else if (isValidHeight) {
644
521
  width = height * aspectRatio;
645
522
  }
646
-
647
523
  return {
648
- width: width,
649
- height: height
524
+ width,
525
+ height
650
526
  };
651
527
  }
652
528
 
653
- var ArrayBuffer$1 = WINDOW.ArrayBuffer,
654
- FileReader = WINDOW.FileReader;
655
- var URL = WINDOW.URL || WINDOW.webkitURL;
656
- var REGEXP_EXTENSION = /\.\w+$/;
657
- var AnotherCompressor = WINDOW.Compressor;
529
+ /**
530
+ * Get Exif information from the given array buffer.
531
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
532
+ * @returns {Array} The read Exif information.
533
+ */
534
+ function getExif(arrayBuffer) {
535
+ const array = toArray(new Uint8Array(arrayBuffer));
536
+ const {
537
+ length
538
+ } = array;
539
+ const segments = [];
540
+ let start = 0;
541
+ while (start + 3 < length) {
542
+ const value = array[start];
543
+ const next = array[start + 1];
544
+
545
+ // SOS (Start of Scan)
546
+ if (value === 0xFF && next === 0xDA) {
547
+ break;
548
+ }
549
+
550
+ // SOI (Start of Image)
551
+ if (value === 0xFF && next === 0xD8) {
552
+ start += 2;
553
+ } else {
554
+ const offset = array[start + 2] * 256 + array[start + 3];
555
+ const end = start + offset + 2;
556
+ const segment = array.slice(start, end);
557
+ segments.push(segment);
558
+ start = end;
559
+ }
560
+ }
561
+ return segments.reduce((exifArray, current) => {
562
+ if (current[0] === 0xFF && current[1] === 0xE1) {
563
+ return exifArray.concat(current);
564
+ }
565
+ return exifArray;
566
+ }, []);
567
+ }
568
+
569
+ /**
570
+ * Insert Exif information into the given array buffer.
571
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
572
+ * @param {Array} exifArray - The Exif information to insert.
573
+ * @returns {ArrayBuffer} The transformed array buffer.
574
+ */
575
+ function insertExif(arrayBuffer, exifArray) {
576
+ const array = toArray(new Uint8Array(arrayBuffer));
577
+ if (array[2] !== 0xFF || array[3] !== 0xE0) {
578
+ return arrayBuffer;
579
+ }
580
+ const app0Length = array[4] * 256 + array[5];
581
+ const newArrayBuffer = [0xFF, 0xD8].concat(exifArray, array.slice(4 + app0Length));
582
+ return new Uint8Array(newArrayBuffer);
583
+ }
584
+
585
+ const {
586
+ ArrayBuffer: ArrayBuffer$1,
587
+ FileReader
588
+ } = WINDOW;
589
+ const URL = WINDOW.URL || WINDOW.webkitURL;
590
+ const REGEXP_EXTENSION = /\.\w+$/;
591
+ const AnotherCompressor = WINDOW.Compressor;
592
+
658
593
  /**
659
594
  * Creates a new image compressor.
660
595
  * @class
661
596
  */
662
-
663
- var Compressor = /*#__PURE__*/function () {
597
+ class Compressor {
664
598
  /**
665
599
  * The constructor of Compressor.
666
600
  * @param {File|Blob} file - The target image file for compressing.
667
601
  * @param {Object} [options] - The options for compressing.
668
602
  */
669
- function Compressor(file, options) {
670
- _classCallCheck(this, Compressor);
671
-
603
+ constructor(file, options) {
672
604
  this.file = file;
605
+ this.exif = [];
673
606
  this.image = new Image();
674
- this.options = _objectSpread2(_objectSpread2({}, DEFAULTS), options);
607
+ this.options = {
608
+ ...DEFAULTS,
609
+ ...options
610
+ };
675
611
  this.aborted = false;
676
612
  this.result = null;
677
613
  this.init();
678
614
  }
615
+ init() {
616
+ const {
617
+ file,
618
+ options
619
+ } = this;
620
+ if (!isBlob(file)) {
621
+ this.fail(new Error('The first argument must be a File or Blob object.'));
622
+ return;
623
+ }
624
+ const mimeType = file.type;
625
+ if (!isImageType(mimeType)) {
626
+ this.fail(new Error('The first argument must be an image File or Blob object.'));
627
+ return;
628
+ }
629
+ if (!URL || !FileReader) {
630
+ this.fail(new Error('The current browser does not support image compression.'));
631
+ return;
632
+ }
633
+ if (!ArrayBuffer$1) {
634
+ options.checkOrientation = false;
635
+ options.retainExif = false;
636
+ }
637
+ const isJPEGImage = mimeType === 'image/jpeg';
638
+ const checkOrientation = isJPEGImage && options.checkOrientation;
639
+ const retainExif = isJPEGImage && options.retainExif;
640
+ if (URL && !checkOrientation && !retainExif) {
641
+ this.load({
642
+ url: URL.createObjectURL(file)
643
+ });
644
+ } else {
645
+ const reader = new FileReader();
646
+ this.reader = reader;
647
+ reader.onload = _ref => {
648
+ let {
649
+ target
650
+ } = _ref;
651
+ const {
652
+ result
653
+ } = target;
654
+ const data = {};
655
+ let orientation = 1;
656
+ if (checkOrientation) {
657
+ // Reset the orientation value to its default value 1
658
+ // as some iOS browsers will render image with its orientation
659
+ orientation = resetAndGetOrientation(result);
660
+ if (orientation > 1) {
661
+ _extends(data, parseOrientation(orientation));
662
+ }
663
+ }
664
+ if (retainExif) {
665
+ this.exif = getExif(result);
666
+ }
667
+ if (checkOrientation || retainExif) {
668
+ if (!URL
679
669
 
680
- _createClass(Compressor, [{
681
- key: "init",
682
- value: function init() {
683
- var _this = this;
684
-
685
- var file = this.file,
686
- options = this.options;
687
-
688
- if (!isBlob(file)) {
689
- this.fail(new Error('The first argument must be a File or Blob object.'));
690
- return;
691
- }
692
-
693
- var mimeType = file.type;
694
-
695
- if (!isImageType(mimeType)) {
696
- this.fail(new Error('The first argument must be an image File or Blob object.'));
697
- return;
698
- }
699
-
700
- if (!URL || !FileReader) {
701
- this.fail(new Error('The current browser does not support image compression.'));
702
- return;
703
- }
704
-
705
- if (!ArrayBuffer$1) {
706
- options.checkOrientation = false;
707
- }
708
-
709
- if (URL && !options.checkOrientation) {
710
- this.load({
711
- url: URL.createObjectURL(file)
712
- });
713
- } else {
714
- var reader = new FileReader();
715
- var checkOrientation = options.checkOrientation && mimeType === 'image/jpeg';
716
- this.reader = reader;
717
-
718
- reader.onload = function (_ref) {
719
- var target = _ref.target;
720
- var result = target.result;
721
- var data = {};
722
-
723
- if (checkOrientation) {
724
- // Reset the orientation value to its default value 1
725
- // as some iOS browsers will render image with its orientation
726
- var orientation = resetAndGetOrientation(result);
727
-
728
- if (orientation > 1 || !URL) {
729
- // Generate a new URL which has the default orientation value
730
- data.url = arrayBufferToDataURL(result, mimeType);
731
-
732
- if (orientation > 1) {
733
- _extends(data, parseOrientation(orientation));
734
- }
735
- } else {
736
- data.url = URL.createObjectURL(file);
737
- }
670
+ // Generate a new URL with the default orientation value 1.
671
+ || orientation > 1) {
672
+ data.url = arrayBufferToDataURL(result, mimeType);
738
673
  } else {
739
- data.url = result;
674
+ data.url = URL.createObjectURL(file);
740
675
  }
741
-
742
- _this.load(data);
743
- };
744
-
745
- reader.onabort = function () {
746
- _this.fail(new Error('Aborted to read the image with FileReader.'));
747
- };
748
-
749
- reader.onerror = function () {
750
- _this.fail(new Error('Failed to read the image with FileReader.'));
751
- };
752
-
753
- reader.onloadend = function () {
754
- _this.reader = null;
755
- };
756
-
757
- if (checkOrientation) {
758
- reader.readAsArrayBuffer(file);
759
676
  } else {
760
- reader.readAsDataURL(file);
677
+ data.url = result;
761
678
  }
762
- }
763
- }
764
- }, {
765
- key: "load",
766
- value: function load(data) {
767
- var _this2 = this;
768
-
769
- var file = this.file,
770
- image = this.image;
771
-
772
- image.onload = function () {
773
- _this2.draw(_objectSpread2(_objectSpread2({}, data), {}, {
774
- naturalWidth: image.naturalWidth,
775
- naturalHeight: image.naturalHeight
776
- }));
679
+ this.load(data);
777
680
  };
778
-
779
- image.onabort = function () {
780
- _this2.fail(new Error('Aborted to load the image.'));
681
+ reader.onabort = () => {
682
+ this.fail(new Error('Aborted to read the image with FileReader.'));
781
683
  };
782
-
783
- image.onerror = function () {
784
- _this2.fail(new Error('Failed to load the image.'));
785
- }; // Match all browsers that use WebKit as the layout engine in iOS devices,
786
- // such as Safari for iOS, Chrome for iOS, and in-app browsers.
787
-
788
-
789
- if (WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent)) {
790
- // Fix the `The operation is insecure` error (#57)
791
- image.crossOrigin = 'anonymous';
792
- }
793
-
794
- image.alt = file.name;
795
- image.src = data.url;
796
- }
797
- }, {
798
- key: "draw",
799
- value: function draw(_ref2) {
800
- var _this3 = this;
801
-
802
- var naturalWidth = _ref2.naturalWidth,
803
- naturalHeight = _ref2.naturalHeight,
804
- _ref2$rotate = _ref2.rotate,
805
- rotate = _ref2$rotate === void 0 ? 0 : _ref2$rotate,
806
- _ref2$scaleX = _ref2.scaleX,
807
- scaleX = _ref2$scaleX === void 0 ? 1 : _ref2$scaleX,
808
- _ref2$scaleY = _ref2.scaleY,
809
- scaleY = _ref2$scaleY === void 0 ? 1 : _ref2$scaleY;
810
- var file = this.file,
811
- image = this.image,
812
- options = this.options;
813
- var canvas = document.createElement('canvas');
814
- var context = canvas.getContext('2d');
815
- var is90DegreesRotated = Math.abs(rotate) % 180 === 90;
816
- var resizable = (options.resize === 'contain' || options.resize === 'cover') && isPositiveNumber(options.width) && isPositiveNumber(options.height);
817
- var maxWidth = Math.max(options.maxWidth, 0) || Infinity;
818
- var maxHeight = Math.max(options.maxHeight, 0) || Infinity;
819
- var minWidth = Math.max(options.minWidth, 0) || 0;
820
- var minHeight = Math.max(options.minHeight, 0) || 0;
821
- var aspectRatio = naturalWidth / naturalHeight;
822
- var width = options.width,
823
- height = options.height;
824
-
825
- if (is90DegreesRotated) {
826
- var _ref3 = [maxHeight, maxWidth];
827
- maxWidth = _ref3[0];
828
- maxHeight = _ref3[1];
829
- var _ref4 = [minHeight, minWidth];
830
- minWidth = _ref4[0];
831
- minHeight = _ref4[1];
832
- var _ref5 = [height, width];
833
- width = _ref5[0];
834
- height = _ref5[1];
835
- }
836
-
837
- if (resizable) {
838
- aspectRatio = width / height;
839
- }
840
-
841
- var _getAdjustedSizes = getAdjustedSizes({
842
- aspectRatio: aspectRatio,
843
- width: maxWidth,
844
- height: maxHeight
845
- }, 'contain');
846
-
847
- maxWidth = _getAdjustedSizes.width;
848
- maxHeight = _getAdjustedSizes.height;
849
-
850
- var _getAdjustedSizes2 = getAdjustedSizes({
851
- aspectRatio: aspectRatio,
852
- width: minWidth,
853
- height: minHeight
854
- }, 'cover');
855
-
856
- minWidth = _getAdjustedSizes2.width;
857
- minHeight = _getAdjustedSizes2.height;
858
-
859
- if (resizable) {
860
- var _getAdjustedSizes3 = getAdjustedSizes({
861
- aspectRatio: aspectRatio,
862
- width: width,
863
- height: height
864
- }, options.resize);
865
-
866
- width = _getAdjustedSizes3.width;
867
- height = _getAdjustedSizes3.height;
868
- } else {
869
- var _getAdjustedSizes4 = getAdjustedSizes({
870
- aspectRatio: aspectRatio,
871
- width: width,
872
- height: height
873
- });
874
-
875
- var _getAdjustedSizes4$wi = _getAdjustedSizes4.width;
876
- width = _getAdjustedSizes4$wi === void 0 ? naturalWidth : _getAdjustedSizes4$wi;
877
- var _getAdjustedSizes4$he = _getAdjustedSizes4.height;
878
- height = _getAdjustedSizes4$he === void 0 ? naturalHeight : _getAdjustedSizes4$he;
879
- }
880
-
881
- width = Math.floor(normalizeDecimalNumber(Math.min(Math.max(width, minWidth), maxWidth)));
882
- height = Math.floor(normalizeDecimalNumber(Math.min(Math.max(height, minHeight), maxHeight)));
883
- var destX = -width / 2;
884
- var destY = -height / 2;
885
- var destWidth = width;
886
- var destHeight = height;
887
- var params = [];
888
-
889
- if (resizable) {
890
- var srcX = 0;
891
- var srcY = 0;
892
- var srcWidth = naturalWidth;
893
- var srcHeight = naturalHeight;
894
-
895
- var _getAdjustedSizes5 = getAdjustedSizes({
896
- aspectRatio: aspectRatio,
897
- width: naturalWidth,
898
- height: naturalHeight
899
- }, {
900
- contain: 'cover',
901
- cover: 'contain'
902
- }[options.resize]);
903
-
904
- srcWidth = _getAdjustedSizes5.width;
905
- srcHeight = _getAdjustedSizes5.height;
906
- srcX = (naturalWidth - srcWidth) / 2;
907
- srcY = (naturalHeight - srcHeight) / 2;
908
- params.push(srcX, srcY, srcWidth, srcHeight);
909
- }
910
-
911
- params.push(destX, destY, destWidth, destHeight);
912
-
913
- if (is90DegreesRotated) {
914
- var _ref6 = [height, width];
915
- width = _ref6[0];
916
- height = _ref6[1];
917
- }
918
-
919
- canvas.width = width;
920
- canvas.height = height;
921
-
922
- if (!isImageType(options.mimeType)) {
923
- options.mimeType = file.type;
924
- }
925
-
926
- var fillStyle = 'transparent'; // Converts PNG files over the `convertSize` to JPEGs.
927
-
928
- if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
929
- options.mimeType = 'image/jpeg';
930
- }
931
-
932
- if (options.mimeType === 'image/jpeg') {
933
- fillStyle = '#fff';
934
- } // Override the default fill color (#000, black)
935
-
936
-
937
- context.fillStyle = fillStyle;
938
- context.fillRect(0, 0, width, height);
939
-
940
- if (options.beforeDraw) {
941
- options.beforeDraw.call(this, context, canvas);
942
- }
943
-
944
- if (this.aborted) {
945
- return;
946
- }
947
-
948
- context.save();
949
- context.translate(width / 2, height / 2);
950
- context.rotate(rotate * Math.PI / 180);
951
- context.scale(scaleX, scaleY);
952
- context.drawImage.apply(context, [image].concat(params));
953
- context.restore();
954
-
955
- if (options.drew) {
956
- options.drew.call(this, context, canvas);
957
- }
958
-
959
- if (this.aborted) {
960
- return;
961
- }
962
-
963
- var done = function done(result) {
964
- if (!_this3.aborted) {
965
- _this3.done({
966
- naturalWidth: naturalWidth,
967
- naturalHeight: naturalHeight,
968
- result: result
969
- });
970
- }
684
+ reader.onerror = () => {
685
+ this.fail(new Error('Failed to read the image with FileReader.'));
971
686
  };
972
-
973
- if (canvas.toBlob) {
974
- canvas.toBlob(done, options.mimeType, options.quality);
687
+ reader.onloadend = () => {
688
+ this.reader = null;
689
+ };
690
+ if (checkOrientation || retainExif) {
691
+ reader.readAsArrayBuffer(file);
975
692
  } else {
976
- done(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
693
+ reader.readAsDataURL(file);
977
694
  }
978
695
  }
979
- }, {
980
- key: "done",
981
- value: function done(_ref7) {
982
- var naturalWidth = _ref7.naturalWidth,
983
- naturalHeight = _ref7.naturalHeight,
984
- result = _ref7.result;
985
- var file = this.file,
986
- image = this.image,
987
- options = this.options;
696
+ }
697
+ load(data) {
698
+ const {
699
+ file,
700
+ image
701
+ } = this;
702
+ image.onload = () => {
703
+ this.draw({
704
+ ...data,
705
+ naturalWidth: image.naturalWidth,
706
+ naturalHeight: image.naturalHeight
707
+ });
708
+ };
709
+ image.onabort = () => {
710
+ this.fail(new Error('Aborted to load the image.'));
711
+ };
712
+ image.onerror = () => {
713
+ this.fail(new Error('Failed to load the image.'));
714
+ };
988
715
 
989
- if (URL && !options.checkOrientation) {
990
- URL.revokeObjectURL(image.src);
991
- }
716
+ // Match all browsers that use WebKit as the layout engine in iOS devices,
717
+ // such as Safari for iOS, Chrome for iOS, and in-app browsers.
718
+ if (WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent)) {
719
+ // Fix the `The operation is insecure` error (#57)
720
+ image.crossOrigin = 'anonymous';
721
+ }
722
+ image.alt = file.name;
723
+ image.src = data.url;
724
+ }
725
+ draw(_ref2) {
726
+ let {
727
+ naturalWidth,
728
+ naturalHeight,
729
+ rotate = 0,
730
+ scaleX = 1,
731
+ scaleY = 1
732
+ } = _ref2;
733
+ const {
734
+ file,
735
+ image,
736
+ options
737
+ } = this;
738
+ const canvas = document.createElement('canvas');
739
+ const context = canvas.getContext('2d');
740
+ const is90DegreesRotated = Math.abs(rotate) % 180 === 90;
741
+ const resizable = (options.resize === 'contain' || options.resize === 'cover') && isPositiveNumber(options.width) && isPositiveNumber(options.height);
742
+ let maxWidth = Math.max(options.maxWidth, 0) || Infinity;
743
+ let maxHeight = Math.max(options.maxHeight, 0) || Infinity;
744
+ let minWidth = Math.max(options.minWidth, 0) || 0;
745
+ let minHeight = Math.max(options.minHeight, 0) || 0;
746
+ let aspectRatio = naturalWidth / naturalHeight;
747
+ let {
748
+ width,
749
+ height
750
+ } = options;
751
+ if (is90DegreesRotated) {
752
+ [maxWidth, maxHeight] = [maxHeight, maxWidth];
753
+ [minWidth, minHeight] = [minHeight, minWidth];
754
+ [width, height] = [height, width];
755
+ }
756
+ if (resizable) {
757
+ aspectRatio = width / height;
758
+ }
759
+ ({
760
+ width: maxWidth,
761
+ height: maxHeight
762
+ } = getAdjustedSizes({
763
+ aspectRatio,
764
+ width: maxWidth,
765
+ height: maxHeight
766
+ }, 'contain'));
767
+ ({
768
+ width: minWidth,
769
+ height: minHeight
770
+ } = getAdjustedSizes({
771
+ aspectRatio,
772
+ width: minWidth,
773
+ height: minHeight
774
+ }, 'cover'));
775
+ if (resizable) {
776
+ ({
777
+ width,
778
+ height
779
+ } = getAdjustedSizes({
780
+ aspectRatio,
781
+ width,
782
+ height
783
+ }, options.resize));
784
+ } else {
785
+ ({
786
+ width = naturalWidth,
787
+ height = naturalHeight
788
+ } = getAdjustedSizes({
789
+ aspectRatio,
790
+ width,
791
+ height
792
+ }));
793
+ }
794
+ width = Math.floor(normalizeDecimalNumber(Math.min(Math.max(width, minWidth), maxWidth)));
795
+ height = Math.floor(normalizeDecimalNumber(Math.min(Math.max(height, minHeight), maxHeight)));
796
+ const destX = -width / 2;
797
+ const destY = -height / 2;
798
+ const destWidth = width;
799
+ const destHeight = height;
800
+ const params = [];
801
+ if (resizable) {
802
+ let srcX = 0;
803
+ let srcY = 0;
804
+ let srcWidth = naturalWidth;
805
+ let srcHeight = naturalHeight;
806
+ ({
807
+ width: srcWidth,
808
+ height: srcHeight
809
+ } = getAdjustedSizes({
810
+ aspectRatio,
811
+ width: naturalWidth,
812
+ height: naturalHeight
813
+ }, {
814
+ contain: 'cover',
815
+ cover: 'contain'
816
+ }[options.resize]));
817
+ srcX = (naturalWidth - srcWidth) / 2;
818
+ srcY = (naturalHeight - srcHeight) / 2;
819
+ params.push(srcX, srcY, srcWidth, srcHeight);
820
+ }
821
+ params.push(destX, destY, destWidth, destHeight);
822
+ if (is90DegreesRotated) {
823
+ [width, height] = [height, width];
824
+ }
825
+ canvas.width = width;
826
+ canvas.height = height;
827
+ if (!isImageType(options.mimeType)) {
828
+ options.mimeType = file.type;
829
+ }
830
+ let fillStyle = 'transparent';
992
831
 
993
- if (result) {
994
- // Returns original file if the result is greater than it and without size related options
995
- if (options.strict && result.size > file.size && options.mimeType === file.type && !(options.width > naturalWidth || options.height > naturalHeight || options.minWidth > naturalWidth || options.minHeight > naturalHeight || options.maxWidth < naturalWidth || options.maxHeight < naturalHeight)) {
996
- result = file;
997
- } else {
998
- var date = new Date();
999
- result.lastModified = date.getTime();
1000
- result.lastModifiedDate = date;
1001
- result.name = file.name; // Convert the extension to match its type
832
+ // Converts PNG files over the `convertSize` to JPEGs.
833
+ if (file.size > options.convertSize && options.convertTypes.indexOf(options.mimeType) >= 0) {
834
+ options.mimeType = 'image/jpeg';
835
+ }
836
+ const isJPEGImage = options.mimeType === 'image/jpeg';
837
+ if (isJPEGImage) {
838
+ fillStyle = '#fff';
839
+ }
1002
840
 
1003
- if (result.name && result.type !== file.type) {
1004
- result.name = result.name.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
841
+ // Override the default fill color (#000, black)
842
+ context.fillStyle = fillStyle;
843
+ context.fillRect(0, 0, width, height);
844
+ if (options.beforeDraw) {
845
+ options.beforeDraw.call(this, context, canvas);
846
+ }
847
+ if (this.aborted) {
848
+ return;
849
+ }
850
+ context.save();
851
+ context.translate(width / 2, height / 2);
852
+ context.rotate(rotate * Math.PI / 180);
853
+ context.scale(scaleX, scaleY);
854
+ context.drawImage(image, ...params);
855
+ context.restore();
856
+ if (options.drew) {
857
+ options.drew.call(this, context, canvas);
858
+ }
859
+ if (this.aborted) {
860
+ return;
861
+ }
862
+ const callback = blob => {
863
+ if (!this.aborted) {
864
+ const done = result => this.done({
865
+ naturalWidth,
866
+ naturalHeight,
867
+ result
868
+ });
869
+ if (blob && isJPEGImage && options.retainExif && this.exif && this.exif.length > 0) {
870
+ const next = arrayBuffer => done(toBlob(arrayBufferToDataURL(insertExif(arrayBuffer, this.exif), options.mimeType)));
871
+ if (blob.arrayBuffer) {
872
+ blob.arrayBuffer().then(next).catch(() => {
873
+ this.fail(new Error('Failed to read the compressed image with Blob.arrayBuffer().'));
874
+ });
875
+ } else {
876
+ const reader = new FileReader();
877
+ this.reader = reader;
878
+ reader.onload = _ref3 => {
879
+ let {
880
+ target
881
+ } = _ref3;
882
+ next(target.result);
883
+ };
884
+ reader.onabort = () => {
885
+ this.fail(new Error('Aborted to read the compressed image with FileReader.'));
886
+ };
887
+ reader.onerror = () => {
888
+ this.fail(new Error('Failed to read the compressed image with FileReader.'));
889
+ };
890
+ reader.onloadend = () => {
891
+ this.reader = null;
892
+ };
893
+ reader.readAsArrayBuffer(blob);
1005
894
  }
895
+ } else {
896
+ done(blob);
1006
897
  }
1007
- } else {
1008
- // Returns original file if the result is null in some cases.
1009
- result = file;
1010
- }
1011
-
1012
- this.result = result;
1013
-
1014
- if (options.success) {
1015
- options.success.call(this, result);
1016
898
  }
899
+ };
900
+ if (canvas.toBlob) {
901
+ canvas.toBlob(callback, options.mimeType, options.quality);
902
+ } else {
903
+ callback(toBlob(canvas.toDataURL(options.mimeType, options.quality)));
1017
904
  }
1018
- }, {
1019
- key: "fail",
1020
- value: function fail(err) {
1021
- var options = this.options;
1022
-
1023
- if (options.error) {
1024
- options.error.call(this, err);
1025
- } else {
1026
- throw err;
1027
- }
905
+ }
906
+ done(_ref4) {
907
+ let {
908
+ naturalWidth,
909
+ naturalHeight,
910
+ result
911
+ } = _ref4;
912
+ const {
913
+ file,
914
+ image,
915
+ options
916
+ } = this;
917
+ if (URL && image.src.indexOf('blob:') === 0) {
918
+ URL.revokeObjectURL(image.src);
1028
919
  }
1029
- }, {
1030
- key: "abort",
1031
- value: function abort() {
1032
- if (!this.aborted) {
1033
- this.aborted = true;
1034
-
1035
- if (this.reader) {
1036
- this.reader.abort();
1037
- } else if (!this.image.complete) {
1038
- this.image.onload = null;
1039
- this.image.onabort();
1040
- } else {
1041
- this.fail(new Error('The compression process has been aborted.'));
920
+ if (result) {
921
+ // Returns original file if the result is greater than it and without size related options
922
+ if (options.strict && !options.retainExif && result.size > file.size && options.mimeType === file.type && !(options.width > naturalWidth || options.height > naturalHeight || options.minWidth > naturalWidth || options.minHeight > naturalHeight || options.maxWidth < naturalWidth || options.maxHeight < naturalHeight)) {
923
+ result = file;
924
+ } else {
925
+ const date = new Date();
926
+ result.lastModified = date.getTime();
927
+ result.lastModifiedDate = date;
928
+ result.name = file.name;
929
+
930
+ // Convert the extension to match its type
931
+ if (result.name && result.type !== file.type) {
932
+ result.name = result.name.replace(REGEXP_EXTENSION, imageTypeToExtension(result.type));
1042
933
  }
1043
934
  }
935
+ } else {
936
+ // Returns original file if the result is null in some cases.
937
+ result = file;
1044
938
  }
1045
- /**
1046
- * Get the no conflict compressor class.
1047
- * @returns {Compressor} The compressor class.
1048
- */
1049
-
1050
- }], [{
1051
- key: "noConflict",
1052
- value: function noConflict() {
1053
- window.Compressor = AnotherCompressor;
1054
- return Compressor;
939
+ this.result = result;
940
+ if (options.success) {
941
+ options.success.call(this, result);
1055
942
  }
1056
- /**
1057
- * Change the default options.
1058
- * @param {Object} options - The new default options.
1059
- */
1060
-
1061
- }, {
1062
- key: "setDefaults",
1063
- value: function setDefaults(options) {
1064
- _extends(DEFAULTS, options);
943
+ }
944
+ fail(err) {
945
+ const {
946
+ options
947
+ } = this;
948
+ if (options.error) {
949
+ options.error.call(this, err);
950
+ } else {
951
+ throw err;
952
+ }
953
+ }
954
+ abort() {
955
+ if (!this.aborted) {
956
+ this.aborted = true;
957
+ if (this.reader) {
958
+ this.reader.abort();
959
+ } else if (!this.image.complete) {
960
+ this.image.onload = null;
961
+ this.image.onabort();
962
+ } else {
963
+ this.fail(new Error('The compression process has been aborted.'));
964
+ }
1065
965
  }
1066
- }]);
966
+ }
967
+
968
+ /**
969
+ * Get the no conflict compressor class.
970
+ * @returns {Compressor} The compressor class.
971
+ */
972
+ static noConflict() {
973
+ window.Compressor = AnotherCompressor;
974
+ return Compressor;
975
+ }
1067
976
 
1068
- return Compressor;
1069
- }();
977
+ /**
978
+ * Change the default options.
979
+ * @param {Object} options - The new default options.
980
+ */
981
+ static setDefaults(options) {
982
+ _extends(DEFAULTS, options);
983
+ }
984
+ }
1070
985
 
1071
986
  export { Compressor as default };