filepond-plugin-image-exif-orientation.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*!
  2. * FilePondPluginImageExifOrientation 1.0.11
  3. * Licensed under MIT, https://opensource.org/licenses/MIT/
  4. * Please visit https://pqina.nl/filepond/ for details.
  5. */
  6. /* eslint-disable */
  7. (function(global, factory) {
  8. typeof exports === 'object' && typeof module !== 'undefined'
  9. ? (module.exports = factory())
  10. : typeof define === 'function' && define.amd
  11. ? define(factory)
  12. : ((global = global || self),
  13. (global.FilePondPluginImageExifOrientation = factory()));
  14. })(this, function() {
  15. 'use strict';
  16. // test if file is of type image
  17. var isJPEG = function isJPEG(file) {
  18. return /^image\/jpeg/.test(file.type);
  19. };
  20. var Marker = {
  21. JPEG: 0xffd8,
  22. APP1: 0xffe1,
  23. EXIF: 0x45786966,
  24. TIFF: 0x4949,
  25. Orientation: 0x0112,
  26. Unknown: 0xff00
  27. };
  28. var getUint16 = function getUint16(view, offset) {
  29. var little =
  30. arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  31. return view.getUint16(offset, little);
  32. };
  33. var getUint32 = function getUint32(view, offset) {
  34. var little =
  35. arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  36. return view.getUint32(offset, little);
  37. };
  38. var getImageOrientation = function getImageOrientation(file) {
  39. return new Promise(function(resolve, reject) {
  40. var reader = new FileReader();
  41. reader.onload = function(e) {
  42. var view = new DataView(e.target.result);
  43. // Every JPEG file starts from binary value '0xFFD8'
  44. if (getUint16(view, 0) !== Marker.JPEG) {
  45. // This aint no JPEG
  46. resolve(-1);
  47. return;
  48. }
  49. var length = view.byteLength;
  50. var offset = 2;
  51. while (offset < length) {
  52. var marker = getUint16(view, offset);
  53. offset += 2;
  54. // There's our APP1 Marker
  55. if (marker === Marker.APP1) {
  56. if (getUint32(view, (offset += 2)) !== Marker.EXIF) {
  57. // no EXIF info defined
  58. break;
  59. }
  60. // Get TIFF Header
  61. var little = getUint16(view, (offset += 6)) === Marker.TIFF;
  62. offset += getUint32(view, offset + 4, little);
  63. var tags = getUint16(view, offset, little);
  64. offset += 2;
  65. for (var i = 0; i < tags; i++) {
  66. // found the orientation tag
  67. if (
  68. getUint16(view, offset + i * 12, little) === Marker.Orientation
  69. ) {
  70. resolve(getUint16(view, offset + i * 12 + 8, little));
  71. return;
  72. }
  73. }
  74. } else if ((marker & Marker.Unknown) !== Marker.Unknown) {
  75. // Invalid
  76. break;
  77. } else {
  78. offset += getUint16(view, offset);
  79. }
  80. }
  81. // Nothing found
  82. resolve(-1);
  83. };
  84. // we don't need to read the entire file to get the orientation
  85. reader.readAsArrayBuffer(file.slice(0, 64 * 1024));
  86. });
  87. };
  88. var IS_BROWSER = (function() {
  89. return (
  90. typeof window !== 'undefined' && typeof window.document !== 'undefined'
  91. );
  92. })();
  93. var isBrowser = function isBrowser() {
  94. return IS_BROWSER;
  95. };
  96. // 2x1 pixel image 90CW rotated with orientation header
  97. var testSrc =
  98. 'data:image/jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4QA6RXhpZgAATU0AKgAAAAgAAwESAAMAAAABAAYAAAEoAAMAAAABAAIAAAITAAMAAAABAAEAAAAAAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////wAALCAABAAIBASIA/8QAJgABAAAAAAAAAAAAAAAAAAAAAxABAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQAAPwBH/9k=';
  99. // should correct orientation if is presented in landscape, in which case the browser doesn't autocorrect
  100. var shouldCorrect = undefined;
  101. var testImage = isBrowser() ? new Image() : {};
  102. testImage.onload = function() {
  103. return (shouldCorrect = testImage.naturalWidth > testImage.naturalHeight);
  104. };
  105. testImage.src = testSrc;
  106. var shouldCorrectImageExifOrientation = function shouldCorrectImageExifOrientation() {
  107. return shouldCorrect;
  108. };
  109. /**
  110. * Read Image Orientation Plugin
  111. */
  112. var plugin = function plugin(_ref) {
  113. var addFilter = _ref.addFilter,
  114. utils = _ref.utils;
  115. var Type = utils.Type,
  116. isFile = utils.isFile;
  117. // subscribe to file load and append required info
  118. addFilter('DID_LOAD_ITEM', function(item, _ref2) {
  119. var query = _ref2.query;
  120. return new Promise(function(resolve, reject) {
  121. // get file reference
  122. var file = item.file;
  123. // if this is not a jpeg image we are not interested
  124. if (
  125. !isFile(file) ||
  126. !isJPEG(file) ||
  127. !query('GET_ALLOW_IMAGE_EXIF_ORIENTATION') ||
  128. !shouldCorrectImageExifOrientation()
  129. ) {
  130. // continue with the unaltered dataset
  131. return resolve(item);
  132. }
  133. // get orientation from exif data
  134. getImageOrientation(file).then(function(orientation) {
  135. item.setMetadata('exif', { orientation: orientation });
  136. resolve(item);
  137. });
  138. });
  139. });
  140. // Expose plugin options
  141. return {
  142. options: {
  143. // Enable or disable image orientation reading
  144. allowImageExifOrientation: [true, Type.BOOLEAN]
  145. }
  146. };
  147. };
  148. // fire pluginloaded event if running in browser, this allows registering the plugin when using async script tags
  149. var isBrowser$1 =
  150. typeof window !== 'undefined' && typeof window.document !== 'undefined';
  151. if (isBrowser$1) {
  152. document.dispatchEvent(
  153. new CustomEvent('FilePond:pluginloaded', { detail: plugin })
  154. );
  155. }
  156. return plugin;
  157. });