Преглед на файлове

Merge branch 'MikeKovarik-master'

Artur Paikin преди 5 години
родител
ревизия
7629854db5

+ 7 - 1
package-lock.json

@@ -8669,7 +8669,8 @@
     "@uppy/thumbnail-generator": {
       "version": "file:packages/@uppy/thumbnail-generator",
       "requires": {
-        "@uppy/utils": "file:packages/@uppy/utils"
+        "@uppy/utils": "file:packages/@uppy/utils",
+        "exifr": "^4.3.4"
       }
     },
     "@uppy/transloadit": {
@@ -18098,6 +18099,11 @@
         }
       }
     },
+	"exifr": {
+		"version": "4.3.4",
+		"resolved": "https://registry.npmjs.org/exifr/-/exifr-4.3.4.tgz",
+		"integrity": "sha512-1pS43SxlWUy3MGsL7pNaNO6OjStAH0tr/EnqT6BJOhft4xCNsN9QyXdhap71PEF4FIm2CPOyolls8L5h++wHyg=="
+	},
     "exit": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",

+ 0 - 12
packages/@uppy/thumbnail-generator/package-lock.json

@@ -1,12 +0,0 @@
-{
-	"requires": true,
-	"lockfileVersion": 1,
-	"dependencies": {
-		"namespace-emitter": {
-			"version": "2.0.1",
-			"resolved": "https://registry.npmjs.org/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
-			"integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g=="
-		}
-	},
-	"version": "1.5.6"
-}

+ 2 - 1
packages/@uppy/thumbnail-generator/package.json

@@ -22,7 +22,8 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "dependencies": {
-    "@uppy/utils": "file:../utils"
+    "@uppy/utils": "file:../utils",
+    "exifr": "^4.3.4"
   },
   "peerDependencies": {
     "@uppy/core": "^1.0.0"

+ 0 - 620
packages/@uppy/thumbnail-generator/src/exif.js

@@ -1,620 +0,0 @@
-// Adapted from https://github.com/exif-js/exif-js
-// Removed XMP and IPTC metadata parsing and EXIF thumbnail generation
-// MIT License (c) Jacob Seidelin https://github.com/exif-js/exif-js/blob/master/LICENSE.md
-
-const ExifTags = {
-  // version tags
-  0x9000: 'ExifVersion', // EXIF version
-  0xA000: 'FlashpixVersion', // Flashpix format version
-
-  // colorspace tags
-  0xA001: 'ColorSpace', // Color space information tag
-
-  // image configuration
-  0xA002: 'PixelXDimension', // Valid width of meaningful image
-  0xA003: 'PixelYDimension', // Valid height of meaningful image
-  0x9101: 'ComponentsConfiguration', // Information about channels
-  0x9102: 'CompressedBitsPerPixel', // Compressed bits per pixel
-
-  // user information
-  0x927C: 'MakerNote', // Any desired information written by the manufacturer
-  0x9286: 'UserComment', // Comments by user
-
-  // related file
-  0xA004: 'RelatedSoundFile', // Name of related sound file
-
-  // date and time
-  0x9003: 'DateTimeOriginal', // Date and time when the original image was generated
-  0x9004: 'DateTimeDigitized', // Date and time when the image was stored digitally
-  0x9290: 'SubsecTime', // Fractions of seconds for DateTime
-  0x9291: 'SubsecTimeOriginal', // Fractions of seconds for DateTimeOriginal
-  0x9292: 'SubsecTimeDigitized', // Fractions of seconds for DateTimeDigitized
-
-  // picture-taking conditions
-  0x829A: 'ExposureTime', // Exposure time (in seconds)
-  0x829D: 'FNumber', // F number
-  0x8822: 'ExposureProgram', // Exposure program
-  0x8824: 'SpectralSensitivity', // Spectral sensitivity
-  0x8827: 'ISOSpeedRatings', // ISO speed rating
-  0x8828: 'OECF', // Optoelectric conversion factor
-  0x9201: 'ShutterSpeedValue', // Shutter speed
-  0x9202: 'ApertureValue', // Lens aperture
-  0x9203: 'BrightnessValue', // Value of brightness
-  0x9204: 'ExposureBias', // Exposure bias
-  0x9205: 'MaxApertureValue', // Smallest F number of lens
-  0x9206: 'SubjectDistance', // Distance to subject in meters
-  0x9207: 'MeteringMode', // Metering mode
-  0x9208: 'LightSource', // Kind of light source
-  0x9209: 'Flash', // Flash status
-  0x9214: 'SubjectArea', // Location and area of main subject
-  0x920A: 'FocalLength', // Focal length of the lens in mm
-  0xA20B: 'FlashEnergy', // Strobe energy in BCPS
-  0xA20C: 'SpatialFrequencyResponse', //
-  0xA20E: 'FocalPlaneXResolution', // Number of pixels in width direction per FocalPlaneResolutionUnit
-  0xA20F: 'FocalPlaneYResolution', // Number of pixels in height direction per FocalPlaneResolutionUnit
-  0xA210: 'FocalPlaneResolutionUnit', // Unit for measuring FocalPlaneXResolution and FocalPlaneYResolution
-  0xA214: 'SubjectLocation', // Location of subject in image
-  0xA215: 'ExposureIndex', // Exposure index selected on camera
-  0xA217: 'SensingMethod', // Image sensor type
-  0xA300: 'FileSource', // Image source (3 === DSC)
-  0xA301: 'SceneType', // Scene type (1 === directly photographed)
-  0xA302: 'CFAPattern', // Color filter array geometric pattern
-  0xA401: 'CustomRendered', // Special processing
-  0xA402: 'ExposureMode', // Exposure mode
-  0xA403: 'WhiteBalance', // 1 = auto white balance, 2 = manual
-  0xA404: 'DigitalZoomRation', // Digital zoom ratio
-  0xA405: 'FocalLengthIn35mmFilm', // Equivalent foacl length assuming 35mm film camera (in mm)
-  0xA406: 'SceneCaptureType', // Type of scene
-  0xA407: 'GainControl', // Degree of overall image gain adjustment
-  0xA408: 'Contrast', // Direction of contrast processing applied by camera
-  0xA409: 'Saturation', // Direction of saturation processing applied by camera
-  0xA40A: 'Sharpness', // Direction of sharpness processing applied by camera
-  0xA40B: 'DeviceSettingDescription', //
-  0xA40C: 'SubjectDistanceRange', // Distance to subject
-
-  // other tags
-  0xA005: 'InteroperabilityIFDPointer',
-  0xA420: 'ImageUniqueID' // Identifier assigned uniquely to each image
-}
-
-const TiffTags = {
-  0x0100: 'ImageWidth',
-  0x0101: 'ImageHeight',
-  0x8769: 'ExifIFDPointer',
-  0x8825: 'GPSInfoIFDPointer',
-  0xA005: 'InteroperabilityIFDPointer',
-  0x0102: 'BitsPerSample',
-  0x0103: 'Compression',
-  0x0106: 'PhotometricInterpretation',
-  0x0112: 'Orientation',
-  0x0115: 'SamplesPerPixel',
-  0x011C: 'PlanarConfiguration',
-  0x0212: 'YCbCrSubSampling',
-  0x0213: 'YCbCrPositioning',
-  0x011A: 'XResolution',
-  0x011B: 'YResolution',
-  0x0128: 'ResolutionUnit',
-  0x0111: 'StripOffsets',
-  0x0116: 'RowsPerStrip',
-  0x0117: 'StripByteCounts',
-  0x0201: 'JPEGInterchangeFormat',
-  0x0202: 'JPEGInterchangeFormatLength',
-  0x012D: 'TransferFunction',
-  0x013E: 'WhitePoint',
-  0x013F: 'PrimaryChromaticities',
-  0x0211: 'YCbCrCoefficients',
-  0x0214: 'ReferenceBlackWhite',
-  0x0132: 'DateTime',
-  0x010E: 'ImageDescription',
-  0x010F: 'Make',
-  0x0110: 'Model',
-  0x0131: 'Software',
-  0x013B: 'Artist',
-  0x8298: 'Copyright'
-}
-
-const GPSTags = {
-  0x0000: 'GPSVersionID',
-  0x0001: 'GPSLatitudeRef',
-  0x0002: 'GPSLatitude',
-  0x0003: 'GPSLongitudeRef',
-  0x0004: 'GPSLongitude',
-  0x0005: 'GPSAltitudeRef',
-  0x0006: 'GPSAltitude',
-  0x0007: 'GPSTimeStamp',
-  0x0008: 'GPSSatellites',
-  0x0009: 'GPSStatus',
-  0x000A: 'GPSMeasureMode',
-  0x000B: 'GPSDOP',
-  0x000C: 'GPSSpeedRef',
-  0x000D: 'GPSSpeed',
-  0x000E: 'GPSTrackRef',
-  0x000F: 'GPSTrack',
-  0x0010: 'GPSImgDirectionRef',
-  0x0011: 'GPSImgDirection',
-  0x0012: 'GPSMapDatum',
-  0x0013: 'GPSDestLatitudeRef',
-  0x0014: 'GPSDestLatitude',
-  0x0015: 'GPSDestLongitudeRef',
-  0x0016: 'GPSDestLongitude',
-  0x0017: 'GPSDestBearingRef',
-  0x0018: 'GPSDestBearing',
-  0x0019: 'GPSDestDistanceRef',
-  0x001A: 'GPSDestDistance',
-  0x001B: 'GPSProcessingMethod',
-  0x001C: 'GPSAreaInformation',
-  0x001D: 'GPSDateStamp',
-  0x001E: 'GPSDifferential'
-}
-
-const StringValues = {
-  ExposureProgram: {
-    0: 'Not defined',
-    1: 'Manual',
-    2: 'Normal program',
-    3: 'Aperture priority',
-    4: 'Shutter priority',
-    5: 'Creative program',
-    6: 'Action program',
-    7: 'Portrait mode',
-    8: 'Landscape mode'
-  },
-  MeteringMode: {
-    0: 'Unknown',
-    1: 'Average',
-    2: 'CenterWeightedAverage',
-    3: 'Spot',
-    4: 'MultiSpot',
-    5: 'Pattern',
-    6: 'Partial',
-    255: 'Other'
-  },
-  LightSource: {
-    0: 'Unknown',
-    1: 'Daylight',
-    2: 'Fluorescent',
-    3: 'Tungsten (incandescent light)',
-    4: 'Flash',
-    9: 'Fine weather',
-    10: 'Cloudy weather',
-    11: 'Shade',
-    12: 'Daylight fluorescent (D 5700 - 7100K)',
-    13: 'Day white fluorescent (N 4600 - 5400K)',
-    14: 'Cool white fluorescent (W 3900 - 4500K)',
-    15: 'White fluorescent (WW 3200 - 3700K)',
-    17: 'Standard light A',
-    18: 'Standard light B',
-    19: 'Standard light C',
-    20: 'D55',
-    21: 'D65',
-    22: 'D75',
-    23: 'D50',
-    24: 'ISO studio tungsten',
-    255: 'Other'
-  },
-  Flash: {
-    0x0000: 'Flash did not fire',
-    0x0001: 'Flash fired',
-    0x0005: 'Strobe return light not detected',
-    0x0007: 'Strobe return light detected',
-    0x0009: 'Flash fired, compulsory flash mode',
-    0x000D: 'Flash fired, compulsory flash mode, return light not detected',
-    0x000F: 'Flash fired, compulsory flash mode, return light detected',
-    0x0010: 'Flash did not fire, compulsory flash mode',
-    0x0018: 'Flash did not fire, auto mode',
-    0x0019: 'Flash fired, auto mode',
-    0x001D: 'Flash fired, auto mode, return light not detected',
-    0x001F: 'Flash fired, auto mode, return light detected',
-    0x0020: 'No flash function',
-    0x0041: 'Flash fired, red-eye reduction mode',
-    0x0045: 'Flash fired, red-eye reduction mode, return light not detected',
-    0x0047: 'Flash fired, red-eye reduction mode, return light detected',
-    0x0049: 'Flash fired, compulsory flash mode, red-eye reduction mode',
-    0x004D: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected',
-    0x004F: 'Flash fired, compulsory flash mode, red-eye reduction mode, return light detected',
-    0x0059: 'Flash fired, auto mode, red-eye reduction mode',
-    0x005D: 'Flash fired, auto mode, return light not detected, red-eye reduction mode',
-    0x005F: 'Flash fired, auto mode, return light detected, red-eye reduction mode'
-  },
-  SensingMethod: {
-    1: 'Not defined',
-    2: 'One-chip color area sensor',
-    3: 'Two-chip color area sensor',
-    4: 'Three-chip color area sensor',
-    5: 'Color sequential area sensor',
-    7: 'Trilinear sensor',
-    8: 'Color sequential linear sensor'
-  },
-  SceneCaptureType: {
-    0: 'Standard',
-    1: 'Landscape',
-    2: 'Portrait',
-    3: 'Night scene'
-  },
-  SceneType: {
-    1: 'Directly photographed'
-  },
-  CustomRendered: {
-    0: 'Normal process',
-    1: 'Custom process'
-  },
-  WhiteBalance: {
-    0: 'Auto white balance',
-    1: 'Manual white balance'
-  },
-  GainControl: {
-    0: 'None',
-    1: 'Low gain up',
-    2: 'High gain up',
-    3: 'Low gain down',
-    4: 'High gain down'
-  },
-  Contrast: {
-    0: 'Normal',
-    1: 'Soft',
-    2: 'Hard'
-  },
-  Saturation: {
-    0: 'Normal',
-    1: 'Low saturation',
-    2: 'High saturation'
-  },
-  Sharpness: {
-    0: 'Normal',
-    1: 'Soft',
-    2: 'Hard'
-  },
-  SubjectDistanceRange: {
-    0: 'Unknown',
-    1: 'Macro',
-    2: 'Close view',
-    3: 'Distant view'
-  },
-  FileSource: {
-    3: 'DSC'
-  },
-
-  Components: {
-    0: '',
-    1: 'Y',
-    2: 'Cb',
-    3: 'Cr',
-    4: 'R',
-    5: 'G',
-    6: 'B'
-  }
-}
-
-function imageHasData (img) {
-  return !!(img.exifdata)
-}
-
-function base64ToArrayBuffer (base64, contentType) {
-  contentType = contentType || base64.match(/^data:([^;]+);base64,/mi)[1] || '' // e.g. 'data:image/jpeg;base64,...' => 'image/jpeg'
-  base64 = base64.replace(/^data:([^;]+);base64,/gmi, '')
-  var binary = atob(base64)
-  var len = binary.length
-  var buffer = new ArrayBuffer(len)
-  // eslint-disable-next-line compat/compat
-  var view = new Uint8Array(buffer)
-  for (var i = 0; i < len; i++) {
-    view[i] = binary.charCodeAt(i)
-  }
-  return buffer
-}
-
-function objectURLToBlob (url, callback) {
-  var http = new XMLHttpRequest()
-  http.open('GET', url, true)
-  http.responseType = 'blob'
-  http.onload = function (e) {
-    if (this.status === 200 || this.status === 0) {
-      callback(this.response)
-    }
-  }
-  http.send()
-}
-
-function getImageData (img, callback) {
-  function handleBinaryFile (binFile) {
-    var data = findEXIFinJPEG(binFile)
-    img.exifdata = data || {}
-    if (callback) {
-      callback.call(img)
-    }
-  }
-
-  if (img.src) {
-    if (/^data:/i.test(img.src)) { // Data URI
-      var arrayBuffer = base64ToArrayBuffer(img.src)
-      handleBinaryFile(arrayBuffer)
-    } else if (/^blob:/i.test(img.src)) { // Object URL
-      const fileReader = new FileReader()
-      fileReader.onload = function (e) {
-        handleBinaryFile(e.target.result)
-      }
-      objectURLToBlob(img.src, function (blob) {
-        fileReader.readAsArrayBuffer(blob)
-      })
-    } else {
-      var http = new XMLHttpRequest()
-      http.onload = function () {
-        if (this.status === 200 || this.status === 0) {
-          handleBinaryFile(http.response)
-        } else {
-          throw new Error('Could not load image')
-        }
-        http = null
-      }
-      http.open('GET', img.src, true)
-      http.responseType = 'arraybuffer'
-      http.send(null)
-    }
-  } else if (self.FileReader && (img instanceof self.Blob || img instanceof self.File)) {
-    const fileReader = new FileReader()
-    fileReader.onload = function (e) {
-      handleBinaryFile(e.target.result)
-    }
-
-    fileReader.readAsArrayBuffer(img)
-  }
-}
-
-function findEXIFinJPEG (file) {
-  var dataView = new DataView(file)
-
-  if ((dataView.getUint8(0) !== 0xFF) || (dataView.getUint8(1) !== 0xD8)) {
-    return false // not a valid jpeg
-  }
-
-  var offset = 2
-  var length = file.byteLength
-  var marker
-
-  while (offset < length) {
-    if (dataView.getUint8(offset) !== 0xFF) {
-      return false // not a valid marker, something is wrong
-    }
-
-    marker = dataView.getUint8(offset + 1)
-
-    // we could implement handling for other markers here,
-    // but we're only looking for 0xFFE1 for EXIF data
-
-    if (marker === 225) {
-      return readEXIFData(dataView, offset + 4, dataView.getUint16(offset + 2) - 2)
-    } else {
-      offset += 2 + dataView.getUint16(offset + 2)
-    }
-  }
-}
-
-function readTags (file, tiffStart, dirStart, strings, bigEnd) {
-  var entries = file.getUint16(dirStart, !bigEnd)
-  var tags = {}
-  var entryOffset; var tag
-  var i
-
-  for (i = 0; i < entries; i++) {
-    entryOffset = dirStart + i * 12 + 2
-    tag = strings[file.getUint16(entryOffset, !bigEnd)]
-    tags[tag] = readTagValue(file, entryOffset, tiffStart, dirStart, bigEnd)
-  }
-  return tags
-}
-
-function readTagValue (file, entryOffset, tiffStart, dirStart, bigEnd) {
-  var type = file.getUint16(entryOffset + 2, !bigEnd)
-  var numValues = file.getUint32(entryOffset + 4, !bigEnd)
-  var valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart
-  var offset
-  var vals; var val; var n
-  var numerator; var denominator
-
-  switch (type) {
-    case 1: // byte, 8-bit unsigned int
-    case 7: // undefined, 8-bit byte, value depending on field
-      if (numValues === 1) {
-        return file.getUint8(entryOffset + 8, !bigEnd)
-      } else {
-        offset = numValues > 4 ? valueOffset : (entryOffset + 8)
-        vals = []
-        for (n = 0; n < numValues; n++) {
-          vals[n] = file.getUint8(offset + n)
-        }
-        return vals
-      }
-
-    case 2: // ascii, 8-bit byte
-      offset = numValues > 4 ? valueOffset : (entryOffset + 8)
-      return getStringFromDB(file, offset, numValues - 1)
-
-    case 3: // short, 16 bit int
-      if (numValues === 1) {
-        return file.getUint16(entryOffset + 8, !bigEnd)
-      } else {
-        offset = numValues > 2 ? valueOffset : (entryOffset + 8)
-        vals = []
-        for (n = 0; n < numValues; n++) {
-          vals[n] = file.getUint16(offset + 2 * n, !bigEnd)
-        }
-        return vals
-      }
-
-    case 4: // long, 32 bit int
-      if (numValues === 1) {
-        return file.getUint32(entryOffset + 8, !bigEnd)
-      } else {
-        vals = []
-        for (n = 0; n < numValues; n++) {
-          vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd)
-        }
-        return vals
-      }
-
-    case 5: // rational = two long values, first is numerator, second is denominator
-      if (numValues === 1) {
-        numerator = file.getUint32(valueOffset, !bigEnd)
-        denominator = file.getUint32(valueOffset + 4, !bigEnd)
-        val = +(numerator / denominator)
-        return val
-      } else {
-        vals = []
-        for (n = 0; n < numValues; n++) {
-          numerator = file.getUint32(valueOffset + 8 * n, !bigEnd)
-          denominator = file.getUint32(valueOffset + 4 + 8 * n, !bigEnd)
-          vals[n] = +(numerator / denominator)
-        }
-        return vals
-      }
-
-    case 9: // slong, 32 bit signed int
-      if (numValues === 1) {
-        return file.getInt32(entryOffset + 8, !bigEnd)
-      } else {
-        vals = []
-        for (n = 0; n < numValues; n++) {
-          vals[n] = file.getInt32(valueOffset + 4 * n, !bigEnd)
-        }
-        return vals
-      }
-
-    case 10: // signed rational, two slongs, first is numerator, second is denominator
-      if (numValues === 1) {
-        return file.getInt32(valueOffset, !bigEnd) / file.getInt32(valueOffset + 4, !bigEnd)
-      } else {
-        vals = []
-        for (n = 0; n < numValues; n++) {
-          vals[n] = file.getInt32(valueOffset + 8 * n, !bigEnd) / file.getInt32(valueOffset + 4 + 8 * n, !bigEnd)
-        }
-        return vals
-      }
-  }
-}
-
-function getStringFromDB (buffer, start, length) {
-  var outstr = ''
-  for (let n = start; n < start + length; n++) {
-    outstr += String.fromCharCode(buffer.getUint8(n))
-  }
-  return outstr
-}
-
-function readEXIFData (file, start) {
-  if (getStringFromDB(file, start, 4) !== 'Exif') {
-    return false
-  }
-
-  var bigEnd
-  var tags; var tag
-  var exifData; var gpsData
-  var tiffOffset = start + 6
-
-  // test for TIFF validity and endianness
-  if (file.getUint16(tiffOffset) === 0x4949) {
-    bigEnd = false
-  } else if (file.getUint16(tiffOffset) === 0x4D4D) {
-    bigEnd = true
-  } else {
-    return false
-  }
-
-  if (file.getUint16(tiffOffset + 2, !bigEnd) !== 0x002A) {
-    return false
-  }
-
-  var firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd)
-
-  if (firstIFDOffset < 0x00000008) {
-    return false
-  }
-
-  tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd)
-
-  if (tags.ExifIFDPointer) {
-    exifData = readTags(file, tiffOffset, tiffOffset + tags.ExifIFDPointer, ExifTags, bigEnd)
-    for (tag in exifData) {
-      switch (tag) {
-        case 'LightSource' :
-        case 'Flash' :
-        case 'MeteringMode' :
-        case 'ExposureProgram' :
-        case 'SensingMethod' :
-        case 'SceneCaptureType' :
-        case 'SceneType' :
-        case 'CustomRendered' :
-        case 'WhiteBalance' :
-        case 'GainControl' :
-        case 'Contrast' :
-        case 'Saturation' :
-        case 'Sharpness' :
-        case 'SubjectDistanceRange' :
-        case 'FileSource' :
-          exifData[tag] = StringValues[tag][exifData[tag]]
-          break
-
-        case 'ExifVersion' :
-        case 'FlashpixVersion' :
-          exifData[tag] = String.fromCharCode(exifData[tag][0], exifData[tag][1], exifData[tag][2], exifData[tag][3])
-          break
-
-        case 'ComponentsConfiguration' :
-          exifData[tag] =
-                        StringValues.Components[exifData[tag][0]] +
-                        StringValues.Components[exifData[tag][1]] +
-                        StringValues.Components[exifData[tag][2]] +
-                        StringValues.Components[exifData[tag][3]]
-          break
-      }
-      tags[tag] = exifData[tag]
-    }
-  }
-
-  if (tags.GPSInfoIFDPointer) {
-    gpsData = readTags(file, tiffOffset, tiffOffset + tags.GPSInfoIFDPointer, GPSTags, bigEnd)
-    for (tag in gpsData) {
-      switch (tag) {
-        case 'GPSVersionID' :
-          gpsData[tag] = gpsData[tag][0] +
-                        '.' + gpsData[tag][1] +
-                        '.' + gpsData[tag][2] +
-                        '.' + gpsData[tag][3]
-          break
-      }
-      tags[tag] = gpsData[tag]
-    }
-  }
-
-  return tags
-}
-
-function getData (img, callback) {
-  if (((self.Image && img instanceof self.Image) ||
-        (self.HTMLImageElement && img instanceof self.HTMLImageElement)) &&
-        !img.complete) { return false }
-
-  if (!imageHasData(img)) {
-    getImageData(img, callback)
-  } else {
-    if (callback) {
-      callback.call(img)
-    }
-  }
-  return true
-}
-
-function getTag (img, tag) {
-  if (!imageHasData(img)) return
-  return img.exifdata[tag]
-}
-
-function getAllTags (img) {
-  if (!imageHasData(img)) return {}
-  return img.exifdata
-}
-
-module.exports = {
-  getAllTags,
-  getData,
-  getTag
-}

+ 6 - 16
packages/@uppy/thumbnail-generator/src/index.js

@@ -4,7 +4,7 @@ const dataURItoBlob = require('@uppy/utils/lib/dataURItoBlob')
 const isObjectURL = require('@uppy/utils/lib/isObjectURL')
 const isPreviewSupported = require('@uppy/utils/lib/isPreviewSupported')
 const ORIENTATIONS = require('./image-orientations')
-const Exif = require('./exif')
+const exifr = require('exifr/dist/mini.legacy.umd.cjs')
 
 /**
  * The Thumbnail Generator plugin
@@ -74,10 +74,11 @@ module.exports = class ThumbnailGenerator extends Plugin {
       })
     })
 
-    return Promise.all([onload, this.getOrientation(file)])
-      .then(values => {
-        const image = values[0]
-        const orientation = values[1]
+    const orientationPromise = exifr.orientation(file.data).catch(_err => 1)
+
+    return Promise.all([onload, orientationPromise])
+      .then(([image, rawOrientation]) => {
+        const orientation = ORIENTATIONS[rawOrientation || 1]
         const dimensions = this.getProportionalDimensions(image, targetWidth, targetHeight, orientation.rotation)
         const rotatedImage = this.rotateImage(image, orientation)
         const resizedImage = this.resizeImage(rotatedImage, dimensions.width, dimensions.height)
@@ -120,17 +121,6 @@ module.exports = class ThumbnailGenerator extends Plugin {
     }
   }
 
-  getOrientation (file) {
-    return new Promise((resolve) => {
-      const uppy = this.uppy
-      Exif.getData(file.data, function exifGetDataCallback () {
-        uppy.setFileMeta(file.id, { exifdata: Exif.getAllTags(this) })
-        const orientation = Exif.getTag(this, 'Orientation') || 1
-        resolve(ORIENTATIONS[orientation])
-      })
-    })
-  }
-
   /**
    * Make sure the image doesn’t exceed browser/device canvas limits.
    * For ios with 256 RAM and ie