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