GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Code Duplication    Length = 286-286 lines in 3 locations

third-party/angularjs-modules-plugins/ng-file-upload-12.2.12/demo/src/main/webapp/js/ng-file-upload-all.js 1 location

@@ 2618-2903 (lines=286) @@
2615
})();
2616
2617
// customized version of https://github.com/exif-js/exif-js
2618
ngFileUpload.service('UploadExif', ['UploadResize', '$q', function (UploadResize, $q) {
2619
  var upload = UploadResize;
2620
2621
  upload.isExifSupported = function () {
2622
    return window.FileReader && new FileReader().readAsArrayBuffer && upload.isResizeSupported();
2623
  };
2624
2625
  function applyTransform(ctx, orientation, width, height) {
2626
    switch (orientation) {
2627
      case 2:
2628
        return ctx.transform(-1, 0, 0, 1, width, 0);
2629
      case 3:
2630
        return ctx.transform(-1, 0, 0, -1, width, height);
2631
      case 4:
2632
        return ctx.transform(1, 0, 0, -1, 0, height);
2633
      case 5:
2634
        return ctx.transform(0, 1, 1, 0, 0, 0);
2635
      case 6:
2636
        return ctx.transform(0, 1, -1, 0, height, 0);
2637
      case 7:
2638
        return ctx.transform(0, -1, -1, 0, height, width);
2639
      case 8:
2640
        return ctx.transform(0, -1, 1, 0, 0, width);
2641
    }
2642
  }
2643
2644
  upload.readOrientation = function (file) {
2645
    var defer = $q.defer();
2646
    var reader = new FileReader();
2647
    var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file;
2648
    reader.readAsArrayBuffer(slicedFile);
2649
    reader.onerror = function (e) {
2650
      return defer.reject(e);
2651
    };
2652
    reader.onload = function (e) {
2653
      var result = {orientation: 1};
2654
      var view = new DataView(this.result);
2655
      if (view.getUint16(0, false) !== 0xFFD8) return defer.resolve(result);
2656
2657
      var length = view.byteLength,
2658
        offset = 2;
2659
      while (offset < length) {
2660
        var marker = view.getUint16(offset, false);
2661
        offset += 2;
2662
        if (marker === 0xFFE1) {
2663
          if (view.getUint32(offset += 2, false) !== 0x45786966) return defer.resolve(result);
2664
2665
          var little = view.getUint16(offset += 6, false) === 0x4949;
2666
          offset += view.getUint32(offset + 4, little);
2667
          var tags = view.getUint16(offset, little);
2668
          offset += 2;
2669
          for (var i = 0; i < tags; i++)
2670
            if (view.getUint16(offset + (i * 12), little) === 0x0112) {
2671
              var orientation = view.getUint16(offset + (i * 12) + 8, little);
2672
              if (orientation >= 2 && orientation <= 8) {
2673
                view.setUint16(offset + (i * 12) + 8, 1, little);
2674
                result.fixedArrayBuffer = e.target.result;
2675
              }
2676
              result.orientation = orientation;
2677
              return defer.resolve(result);
2678
            }
2679
        } else if ((marker & 0xFF00) !== 0xFF00) break;
2680
        else offset += view.getUint16(offset, false);
2681
      }
2682
      return defer.resolve(result);
2683
    };
2684
    return defer.promise;
2685
  };
2686
2687
  function arrayBufferToBase64(buffer) {
2688
    var binary = '';
2689
    var bytes = new Uint8Array(buffer);
2690
    var len = bytes.byteLength;
2691
    for (var i = 0; i < len; i++) {
2692
      binary += String.fromCharCode(bytes[i]);
2693
    }
2694
    return window.btoa(binary);
2695
  }
2696
2697
  upload.applyExifRotation = function (file) {
2698
    if (file.type.indexOf('image/jpeg') !== 0) {
2699
      return upload.emptyPromise(file);
2700
    }
2701
2702
    var deferred = $q.defer();
2703
    upload.readOrientation(file).then(function (result) {
2704
      if (result.orientation < 2 || result.orientation > 8) {
2705
        return deferred.resolve(file);
2706
      }
2707
      upload.dataUrl(file, true).then(function (url) {
2708
        var canvas = document.createElement('canvas');
2709
        var img = document.createElement('img');
2710
2711
        img.onload = function () {
2712
          try {
2713
            canvas.width = result.orientation > 4 ? img.height : img.width;
2714
            canvas.height = result.orientation > 4 ? img.width : img.height;
2715
            var ctx = canvas.getContext('2d');
2716
            applyTransform(ctx, result.orientation, img.width, img.height);
2717
            ctx.drawImage(img, 0, 0);
2718
            var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934);
2719
            dataUrl = upload.restoreExif(arrayBufferToBase64(result.fixedArrayBuffer), dataUrl);
2720
            var blob = upload.dataUrltoBlob(dataUrl, file.name);
2721
            deferred.resolve(blob);
2722
          } catch (e) {
2723
            return deferred.reject(e);
2724
          }
2725
        };
2726
        img.onerror = function () {
2727
          deferred.reject();
2728
        };
2729
        img.src = url;
2730
      }, function (e) {
2731
        deferred.reject(e);
2732
      });
2733
    }, function (e) {
2734
      deferred.reject(e);
2735
    });
2736
    return deferred.promise;
2737
  };
2738
2739
  upload.restoreExif = function (orig, resized) {
2740
    var ExifRestorer = {};
2741
2742
    ExifRestorer.KEY_STR = 'ABCDEFGHIJKLMNOP' +
2743
      'QRSTUVWXYZabcdef' +
2744
      'ghijklmnopqrstuv' +
2745
      'wxyz0123456789+/' +
2746
      '=';
2747
2748
    ExifRestorer.encode64 = function (input) {
2749
      var output = '',
2750
        chr1, chr2, chr3 = '',
2751
        enc1, enc2, enc3, enc4 = '',
2752
        i = 0;
2753
2754
      do {
2755
        chr1 = input[i++];
2756
        chr2 = input[i++];
2757
        chr3 = input[i++];
2758
2759
        enc1 = chr1 >> 2;
2760
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
2761
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
2762
        enc4 = chr3 & 63;
2763
2764
        if (isNaN(chr2)) {
2765
          enc3 = enc4 = 64;
2766
        } else if (isNaN(chr3)) {
2767
          enc4 = 64;
2768
        }
2769
2770
        output = output +
2771
          this.KEY_STR.charAt(enc1) +
2772
          this.KEY_STR.charAt(enc2) +
2773
          this.KEY_STR.charAt(enc3) +
2774
          this.KEY_STR.charAt(enc4);
2775
        chr1 = chr2 = chr3 = '';
2776
        enc1 = enc2 = enc3 = enc4 = '';
2777
      } while (i < input.length);
2778
2779
      return output;
2780
    };
2781
2782
    ExifRestorer.restore = function (origFileBase64, resizedFileBase64) {
2783
      if (origFileBase64.match('data:image/jpeg;base64,')) {
2784
        origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', '');
2785
      }
2786
2787
      var rawImage = this.decode64(origFileBase64);
2788
      var segments = this.slice2Segments(rawImage);
2789
2790
      var image = this.exifManipulation(resizedFileBase64, segments);
2791
2792
      return 'data:image/jpeg;base64,' + this.encode64(image);
2793
    };
2794
2795
2796
    ExifRestorer.exifManipulation = function (resizedFileBase64, segments) {
2797
      var exifArray = this.getExifArray(segments),
2798
        newImageArray = this.insertExif(resizedFileBase64, exifArray);
2799
      return new Uint8Array(newImageArray);
2800
    };
2801
2802
2803
    ExifRestorer.getExifArray = function (segments) {
2804
      var seg;
2805
      for (var x = 0; x < segments.length; x++) {
2806
        seg = segments[x];
2807
        if (seg[0] === 255 & seg[1] === 225) //(ff e1)
2808
        {
2809
          return seg;
2810
        }
2811
      }
2812
      return [];
2813
    };
2814
2815
2816
    ExifRestorer.insertExif = function (resizedFileBase64, exifArray) {
2817
      var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''),
2818
        buf = this.decode64(imageData),
2819
        separatePoint = buf.indexOf(255, 3),
2820
        mae = buf.slice(0, separatePoint),
2821
        ato = buf.slice(separatePoint),
2822
        array = mae;
2823
2824
      array = array.concat(exifArray);
2825
      array = array.concat(ato);
2826
      return array;
2827
    };
2828
2829
2830
    ExifRestorer.slice2Segments = function (rawImageArray) {
2831
      var head = 0,
2832
        segments = [];
2833
2834
      while (1) {
2835
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
2836
          break;
2837
        }
2838
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
2839
          head += 2;
2840
        }
2841
        else {
2842
          var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
2843
            endPoint = head + length + 2,
2844
            seg = rawImageArray.slice(head, endPoint);
2845
          segments.push(seg);
2846
          head = endPoint;
2847
        }
2848
        if (head > rawImageArray.length) {
2849
          break;
2850
        }
2851
      }
2852
2853
      return segments;
2854
    };
2855
2856
2857
    ExifRestorer.decode64 = function (input) {
2858
      var chr1, chr2, chr3 = '',
2859
        enc1, enc2, enc3, enc4 = '',
2860
        i = 0,
2861
        buf = [];
2862
2863
      // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
2864
      var base64test = /[^A-Za-z0-9\+\/\=]/g;
2865
      if (base64test.exec(input)) {
2866
        console.log('There were invalid base64 characters in the input text.\n' +
2867
          'Valid base64 characters are A-Z, a-z, 0-9, ' + ', ' / ',and "="\n' +
2868
          'Expect errors in decoding.');
2869
      }
2870
      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
2871
2872
      do {
2873
        enc1 = this.KEY_STR.indexOf(input.charAt(i++));
2874
        enc2 = this.KEY_STR.indexOf(input.charAt(i++));
2875
        enc3 = this.KEY_STR.indexOf(input.charAt(i++));
2876
        enc4 = this.KEY_STR.indexOf(input.charAt(i++));
2877
2878
        chr1 = (enc1 << 2) | (enc2 >> 4);
2879
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
2880
        chr3 = ((enc3 & 3) << 6) | enc4;
2881
2882
        buf.push(chr1);
2883
2884
        if (enc3 !== 64) {
2885
          buf.push(chr2);
2886
        }
2887
        if (enc4 !== 64) {
2888
          buf.push(chr3);
2889
        }
2890
2891
        chr1 = chr2 = chr3 = '';
2892
        enc1 = enc2 = enc3 = enc4 = '';
2893
2894
      } while (i < input.length);
2895
2896
      return buf;
2897
    };
2898
2899
    return ExifRestorer.restore(orig, resized);  //<= EXIF
2900
  };
2901
2902
  return upload;
2903
}]);
2904
2905

third-party/angularjs-modules-plugins/ng-file-upload-12.2.12/demo/src/main/webapp/js/ng-file-upload.js 1 location

@@ 2196-2481 (lines=286) @@
2193
})();
2194
2195
// customized version of https://github.com/exif-js/exif-js
2196
ngFileUpload.service('UploadExif', ['UploadResize', '$q', function (UploadResize, $q) {
2197
  var upload = UploadResize;
2198
2199
  upload.isExifSupported = function () {
2200
    return window.FileReader && new FileReader().readAsArrayBuffer && upload.isResizeSupported();
2201
  };
2202
2203
  function applyTransform(ctx, orientation, width, height) {
2204
    switch (orientation) {
2205
      case 2:
2206
        return ctx.transform(-1, 0, 0, 1, width, 0);
2207
      case 3:
2208
        return ctx.transform(-1, 0, 0, -1, width, height);
2209
      case 4:
2210
        return ctx.transform(1, 0, 0, -1, 0, height);
2211
      case 5:
2212
        return ctx.transform(0, 1, 1, 0, 0, 0);
2213
      case 6:
2214
        return ctx.transform(0, 1, -1, 0, height, 0);
2215
      case 7:
2216
        return ctx.transform(0, -1, -1, 0, height, width);
2217
      case 8:
2218
        return ctx.transform(0, -1, 1, 0, 0, width);
2219
    }
2220
  }
2221
2222
  upload.readOrientation = function (file) {
2223
    var defer = $q.defer();
2224
    var reader = new FileReader();
2225
    var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file;
2226
    reader.readAsArrayBuffer(slicedFile);
2227
    reader.onerror = function (e) {
2228
      return defer.reject(e);
2229
    };
2230
    reader.onload = function (e) {
2231
      var result = {orientation: 1};
2232
      var view = new DataView(this.result);
2233
      if (view.getUint16(0, false) !== 0xFFD8) return defer.resolve(result);
2234
2235
      var length = view.byteLength,
2236
        offset = 2;
2237
      while (offset < length) {
2238
        var marker = view.getUint16(offset, false);
2239
        offset += 2;
2240
        if (marker === 0xFFE1) {
2241
          if (view.getUint32(offset += 2, false) !== 0x45786966) return defer.resolve(result);
2242
2243
          var little = view.getUint16(offset += 6, false) === 0x4949;
2244
          offset += view.getUint32(offset + 4, little);
2245
          var tags = view.getUint16(offset, little);
2246
          offset += 2;
2247
          for (var i = 0; i < tags; i++)
2248
            if (view.getUint16(offset + (i * 12), little) === 0x0112) {
2249
              var orientation = view.getUint16(offset + (i * 12) + 8, little);
2250
              if (orientation >= 2 && orientation <= 8) {
2251
                view.setUint16(offset + (i * 12) + 8, 1, little);
2252
                result.fixedArrayBuffer = e.target.result;
2253
              }
2254
              result.orientation = orientation;
2255
              return defer.resolve(result);
2256
            }
2257
        } else if ((marker & 0xFF00) !== 0xFF00) break;
2258
        else offset += view.getUint16(offset, false);
2259
      }
2260
      return defer.resolve(result);
2261
    };
2262
    return defer.promise;
2263
  };
2264
2265
  function arrayBufferToBase64(buffer) {
2266
    var binary = '';
2267
    var bytes = new Uint8Array(buffer);
2268
    var len = bytes.byteLength;
2269
    for (var i = 0; i < len; i++) {
2270
      binary += String.fromCharCode(bytes[i]);
2271
    }
2272
    return window.btoa(binary);
2273
  }
2274
2275
  upload.applyExifRotation = function (file) {
2276
    if (file.type.indexOf('image/jpeg') !== 0) {
2277
      return upload.emptyPromise(file);
2278
    }
2279
2280
    var deferred = $q.defer();
2281
    upload.readOrientation(file).then(function (result) {
2282
      if (result.orientation < 2 || result.orientation > 8) {
2283
        return deferred.resolve(file);
2284
      }
2285
      upload.dataUrl(file, true).then(function (url) {
2286
        var canvas = document.createElement('canvas');
2287
        var img = document.createElement('img');
2288
2289
        img.onload = function () {
2290
          try {
2291
            canvas.width = result.orientation > 4 ? img.height : img.width;
2292
            canvas.height = result.orientation > 4 ? img.width : img.height;
2293
            var ctx = canvas.getContext('2d');
2294
            applyTransform(ctx, result.orientation, img.width, img.height);
2295
            ctx.drawImage(img, 0, 0);
2296
            var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934);
2297
            dataUrl = upload.restoreExif(arrayBufferToBase64(result.fixedArrayBuffer), dataUrl);
2298
            var blob = upload.dataUrltoBlob(dataUrl, file.name);
2299
            deferred.resolve(blob);
2300
          } catch (e) {
2301
            return deferred.reject(e);
2302
          }
2303
        };
2304
        img.onerror = function () {
2305
          deferred.reject();
2306
        };
2307
        img.src = url;
2308
      }, function (e) {
2309
        deferred.reject(e);
2310
      });
2311
    }, function (e) {
2312
      deferred.reject(e);
2313
    });
2314
    return deferred.promise;
2315
  };
2316
2317
  upload.restoreExif = function (orig, resized) {
2318
    var ExifRestorer = {};
2319
2320
    ExifRestorer.KEY_STR = 'ABCDEFGHIJKLMNOP' +
2321
      'QRSTUVWXYZabcdef' +
2322
      'ghijklmnopqrstuv' +
2323
      'wxyz0123456789+/' +
2324
      '=';
2325
2326
    ExifRestorer.encode64 = function (input) {
2327
      var output = '',
2328
        chr1, chr2, chr3 = '',
2329
        enc1, enc2, enc3, enc4 = '',
2330
        i = 0;
2331
2332
      do {
2333
        chr1 = input[i++];
2334
        chr2 = input[i++];
2335
        chr3 = input[i++];
2336
2337
        enc1 = chr1 >> 2;
2338
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
2339
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
2340
        enc4 = chr3 & 63;
2341
2342
        if (isNaN(chr2)) {
2343
          enc3 = enc4 = 64;
2344
        } else if (isNaN(chr3)) {
2345
          enc4 = 64;
2346
        }
2347
2348
        output = output +
2349
          this.KEY_STR.charAt(enc1) +
2350
          this.KEY_STR.charAt(enc2) +
2351
          this.KEY_STR.charAt(enc3) +
2352
          this.KEY_STR.charAt(enc4);
2353
        chr1 = chr2 = chr3 = '';
2354
        enc1 = enc2 = enc3 = enc4 = '';
2355
      } while (i < input.length);
2356
2357
      return output;
2358
    };
2359
2360
    ExifRestorer.restore = function (origFileBase64, resizedFileBase64) {
2361
      if (origFileBase64.match('data:image/jpeg;base64,')) {
2362
        origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', '');
2363
      }
2364
2365
      var rawImage = this.decode64(origFileBase64);
2366
      var segments = this.slice2Segments(rawImage);
2367
2368
      var image = this.exifManipulation(resizedFileBase64, segments);
2369
2370
      return 'data:image/jpeg;base64,' + this.encode64(image);
2371
    };
2372
2373
2374
    ExifRestorer.exifManipulation = function (resizedFileBase64, segments) {
2375
      var exifArray = this.getExifArray(segments),
2376
        newImageArray = this.insertExif(resizedFileBase64, exifArray);
2377
      return new Uint8Array(newImageArray);
2378
    };
2379
2380
2381
    ExifRestorer.getExifArray = function (segments) {
2382
      var seg;
2383
      for (var x = 0; x < segments.length; x++) {
2384
        seg = segments[x];
2385
        if (seg[0] === 255 & seg[1] === 225) //(ff e1)
2386
        {
2387
          return seg;
2388
        }
2389
      }
2390
      return [];
2391
    };
2392
2393
2394
    ExifRestorer.insertExif = function (resizedFileBase64, exifArray) {
2395
      var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''),
2396
        buf = this.decode64(imageData),
2397
        separatePoint = buf.indexOf(255, 3),
2398
        mae = buf.slice(0, separatePoint),
2399
        ato = buf.slice(separatePoint),
2400
        array = mae;
2401
2402
      array = array.concat(exifArray);
2403
      array = array.concat(ato);
2404
      return array;
2405
    };
2406
2407
2408
    ExifRestorer.slice2Segments = function (rawImageArray) {
2409
      var head = 0,
2410
        segments = [];
2411
2412
      while (1) {
2413
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
2414
          break;
2415
        }
2416
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
2417
          head += 2;
2418
        }
2419
        else {
2420
          var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
2421
            endPoint = head + length + 2,
2422
            seg = rawImageArray.slice(head, endPoint);
2423
          segments.push(seg);
2424
          head = endPoint;
2425
        }
2426
        if (head > rawImageArray.length) {
2427
          break;
2428
        }
2429
      }
2430
2431
      return segments;
2432
    };
2433
2434
2435
    ExifRestorer.decode64 = function (input) {
2436
      var chr1, chr2, chr3 = '',
2437
        enc1, enc2, enc3, enc4 = '',
2438
        i = 0,
2439
        buf = [];
2440
2441
      // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
2442
      var base64test = /[^A-Za-z0-9\+\/\=]/g;
2443
      if (base64test.exec(input)) {
2444
        console.log('There were invalid base64 characters in the input text.\n' +
2445
          'Valid base64 characters are A-Z, a-z, 0-9, ' + ', ' / ',and "="\n' +
2446
          'Expect errors in decoding.');
2447
      }
2448
      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
2449
2450
      do {
2451
        enc1 = this.KEY_STR.indexOf(input.charAt(i++));
2452
        enc2 = this.KEY_STR.indexOf(input.charAt(i++));
2453
        enc3 = this.KEY_STR.indexOf(input.charAt(i++));
2454
        enc4 = this.KEY_STR.indexOf(input.charAt(i++));
2455
2456
        chr1 = (enc1 << 2) | (enc2 >> 4);
2457
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
2458
        chr3 = ((enc3 & 3) << 6) | enc4;
2459
2460
        buf.push(chr1);
2461
2462
        if (enc3 !== 64) {
2463
          buf.push(chr2);
2464
        }
2465
        if (enc4 !== 64) {
2466
          buf.push(chr3);
2467
        }
2468
2469
        chr1 = chr2 = chr3 = '';
2470
        enc1 = enc2 = enc3 = enc4 = '';
2471
2472
      } while (i < input.length);
2473
2474
      return buf;
2475
    };
2476
2477
    return ExifRestorer.restore(orig, resized);  //<= EXIF
2478
  };
2479
2480
  return upload;
2481
}]);
2482
2483

third-party/angularjs-modules-plugins/ng-file-upload-12.2.12/src/exif.js 1 location

@@ 2-287 (lines=286) @@
1
// customized version of https://github.com/exif-js/exif-js
2
ngFileUpload.service('UploadExif', ['UploadResize', '$q', function (UploadResize, $q) {
3
  var upload = UploadResize;
4
5
  upload.isExifSupported = function () {
6
    return window.FileReader && new FileReader().readAsArrayBuffer && upload.isResizeSupported();
7
  };
8
9
  function applyTransform(ctx, orientation, width, height) {
10
    switch (orientation) {
11
      case 2:
12
        return ctx.transform(-1, 0, 0, 1, width, 0);
13
      case 3:
14
        return ctx.transform(-1, 0, 0, -1, width, height);
15
      case 4:
16
        return ctx.transform(1, 0, 0, -1, 0, height);
17
      case 5:
18
        return ctx.transform(0, 1, 1, 0, 0, 0);
19
      case 6:
20
        return ctx.transform(0, 1, -1, 0, height, 0);
21
      case 7:
22
        return ctx.transform(0, -1, -1, 0, height, width);
23
      case 8:
24
        return ctx.transform(0, -1, 1, 0, 0, width);
25
    }
26
  }
27
28
  upload.readOrientation = function (file) {
29
    var defer = $q.defer();
30
    var reader = new FileReader();
31
    var slicedFile = file.slice ? file.slice(0, 64 * 1024) : file;
32
    reader.readAsArrayBuffer(slicedFile);
33
    reader.onerror = function (e) {
34
      return defer.reject(e);
35
    };
36
    reader.onload = function (e) {
37
      var result = {orientation: 1};
38
      var view = new DataView(this.result);
39
      if (view.getUint16(0, false) !== 0xFFD8) return defer.resolve(result);
40
41
      var length = view.byteLength,
42
        offset = 2;
43
      while (offset < length) {
44
        var marker = view.getUint16(offset, false);
45
        offset += 2;
46
        if (marker === 0xFFE1) {
47
          if (view.getUint32(offset += 2, false) !== 0x45786966) return defer.resolve(result);
48
49
          var little = view.getUint16(offset += 6, false) === 0x4949;
50
          offset += view.getUint32(offset + 4, little);
51
          var tags = view.getUint16(offset, little);
52
          offset += 2;
53
          for (var i = 0; i < tags; i++)
54
            if (view.getUint16(offset + (i * 12), little) === 0x0112) {
55
              var orientation = view.getUint16(offset + (i * 12) + 8, little);
56
              if (orientation >= 2 && orientation <= 8) {
57
                view.setUint16(offset + (i * 12) + 8, 1, little);
58
                result.fixedArrayBuffer = e.target.result;
59
              }
60
              result.orientation = orientation;
61
              return defer.resolve(result);
62
            }
63
        } else if ((marker & 0xFF00) !== 0xFF00) break;
64
        else offset += view.getUint16(offset, false);
65
      }
66
      return defer.resolve(result);
67
    };
68
    return defer.promise;
69
  };
70
71
  function arrayBufferToBase64(buffer) {
72
    var binary = '';
73
    var bytes = new Uint8Array(buffer);
74
    var len = bytes.byteLength;
75
    for (var i = 0; i < len; i++) {
76
      binary += String.fromCharCode(bytes[i]);
77
    }
78
    return window.btoa(binary);
79
  }
80
81
  upload.applyExifRotation = function (file) {
82
    if (file.type.indexOf('image/jpeg') !== 0) {
83
      return upload.emptyPromise(file);
84
    }
85
86
    var deferred = $q.defer();
87
    upload.readOrientation(file).then(function (result) {
88
      if (result.orientation < 2 || result.orientation > 8) {
89
        return deferred.resolve(file);
90
      }
91
      upload.dataUrl(file, true).then(function (url) {
92
        var canvas = document.createElement('canvas');
93
        var img = document.createElement('img');
94
95
        img.onload = function () {
96
          try {
97
            canvas.width = result.orientation > 4 ? img.height : img.width;
98
            canvas.height = result.orientation > 4 ? img.width : img.height;
99
            var ctx = canvas.getContext('2d');
100
            applyTransform(ctx, result.orientation, img.width, img.height);
101
            ctx.drawImage(img, 0, 0);
102
            var dataUrl = canvas.toDataURL(file.type || 'image/WebP', 0.934);
103
            dataUrl = upload.restoreExif(arrayBufferToBase64(result.fixedArrayBuffer), dataUrl);
104
            var blob = upload.dataUrltoBlob(dataUrl, file.name);
105
            deferred.resolve(blob);
106
          } catch (e) {
107
            return deferred.reject(e);
108
          }
109
        };
110
        img.onerror = function () {
111
          deferred.reject();
112
        };
113
        img.src = url;
114
      }, function (e) {
115
        deferred.reject(e);
116
      });
117
    }, function (e) {
118
      deferred.reject(e);
119
    });
120
    return deferred.promise;
121
  };
122
123
  upload.restoreExif = function (orig, resized) {
124
    var ExifRestorer = {};
125
126
    ExifRestorer.KEY_STR = 'ABCDEFGHIJKLMNOP' +
127
      'QRSTUVWXYZabcdef' +
128
      'ghijklmnopqrstuv' +
129
      'wxyz0123456789+/' +
130
      '=';
131
132
    ExifRestorer.encode64 = function (input) {
133
      var output = '',
134
        chr1, chr2, chr3 = '',
135
        enc1, enc2, enc3, enc4 = '',
136
        i = 0;
137
138
      do {
139
        chr1 = input[i++];
140
        chr2 = input[i++];
141
        chr3 = input[i++];
142
143
        enc1 = chr1 >> 2;
144
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
145
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
146
        enc4 = chr3 & 63;
147
148
        if (isNaN(chr2)) {
149
          enc3 = enc4 = 64;
150
        } else if (isNaN(chr3)) {
151
          enc4 = 64;
152
        }
153
154
        output = output +
155
          this.KEY_STR.charAt(enc1) +
156
          this.KEY_STR.charAt(enc2) +
157
          this.KEY_STR.charAt(enc3) +
158
          this.KEY_STR.charAt(enc4);
159
        chr1 = chr2 = chr3 = '';
160
        enc1 = enc2 = enc3 = enc4 = '';
161
      } while (i < input.length);
162
163
      return output;
164
    };
165
166
    ExifRestorer.restore = function (origFileBase64, resizedFileBase64) {
167
      if (origFileBase64.match('data:image/jpeg;base64,')) {
168
        origFileBase64 = origFileBase64.replace('data:image/jpeg;base64,', '');
169
      }
170
171
      var rawImage = this.decode64(origFileBase64);
172
      var segments = this.slice2Segments(rawImage);
173
174
      var image = this.exifManipulation(resizedFileBase64, segments);
175
176
      return 'data:image/jpeg;base64,' + this.encode64(image);
177
    };
178
179
180
    ExifRestorer.exifManipulation = function (resizedFileBase64, segments) {
181
      var exifArray = this.getExifArray(segments),
182
        newImageArray = this.insertExif(resizedFileBase64, exifArray);
183
      return new Uint8Array(newImageArray);
184
    };
185
186
187
    ExifRestorer.getExifArray = function (segments) {
188
      var seg;
189
      for (var x = 0; x < segments.length; x++) {
190
        seg = segments[x];
191
        if (seg[0] === 255 & seg[1] === 225) //(ff e1)
192
        {
193
          return seg;
194
        }
195
      }
196
      return [];
197
    };
198
199
200
    ExifRestorer.insertExif = function (resizedFileBase64, exifArray) {
201
      var imageData = resizedFileBase64.replace('data:image/jpeg;base64,', ''),
202
        buf = this.decode64(imageData),
203
        separatePoint = buf.indexOf(255, 3),
204
        mae = buf.slice(0, separatePoint),
205
        ato = buf.slice(separatePoint),
206
        array = mae;
207
208
      array = array.concat(exifArray);
209
      array = array.concat(ato);
210
      return array;
211
    };
212
213
214
    ExifRestorer.slice2Segments = function (rawImageArray) {
215
      var head = 0,
216
        segments = [];
217
218
      while (1) {
219
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 218) {
220
          break;
221
        }
222
        if (rawImageArray[head] === 255 & rawImageArray[head + 1] === 216) {
223
          head += 2;
224
        }
225
        else {
226
          var length = rawImageArray[head + 2] * 256 + rawImageArray[head + 3],
227
            endPoint = head + length + 2,
228
            seg = rawImageArray.slice(head, endPoint);
229
          segments.push(seg);
230
          head = endPoint;
231
        }
232
        if (head > rawImageArray.length) {
233
          break;
234
        }
235
      }
236
237
      return segments;
238
    };
239
240
241
    ExifRestorer.decode64 = function (input) {
242
      var chr1, chr2, chr3 = '',
243
        enc1, enc2, enc3, enc4 = '',
244
        i = 0,
245
        buf = [];
246
247
      // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
248
      var base64test = /[^A-Za-z0-9\+\/\=]/g;
249
      if (base64test.exec(input)) {
250
        console.log('There were invalid base64 characters in the input text.\n' +
251
          'Valid base64 characters are A-Z, a-z, 0-9, ' + ', ' / ',and "="\n' +
252
          'Expect errors in decoding.');
253
      }
254
      input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
255
256
      do {
257
        enc1 = this.KEY_STR.indexOf(input.charAt(i++));
258
        enc2 = this.KEY_STR.indexOf(input.charAt(i++));
259
        enc3 = this.KEY_STR.indexOf(input.charAt(i++));
260
        enc4 = this.KEY_STR.indexOf(input.charAt(i++));
261
262
        chr1 = (enc1 << 2) | (enc2 >> 4);
263
        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
264
        chr3 = ((enc3 & 3) << 6) | enc4;
265
266
        buf.push(chr1);
267
268
        if (enc3 !== 64) {
269
          buf.push(chr2);
270
        }
271
        if (enc4 !== 64) {
272
          buf.push(chr3);
273
        }
274
275
        chr1 = chr2 = chr3 = '';
276
        enc1 = enc2 = enc3 = enc4 = '';
277
278
      } while (i < input.length);
279
280
      return buf;
281
    };
282
283
    return ExifRestorer.restore(orig, resized);  //<= EXIF
284
  };
285
286
  return upload;
287
}]);
288
289