9cfdaa8ce518e054486cc355f4f0da907c4a9ae2787892db7e3185fb18dc8a8d8e7c2a04c621a5ffe12c9ec545f38a04466800f79bb062a9a3772abbfaf3ac 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. 'use strict';
  2. // NOTE: we only support baseline and progressive JPGs here
  3. // due to the structure of the loader class, we only get a buffer
  4. // with a maximum size of 4096 bytes. so if the SOF marker is outside
  5. // if this range we can't detect the file size correctly.
  6. function isJPG (buffer) { //, filepath
  7. var SOIMarker = buffer.toString('hex', 0, 2);
  8. return ('ffd8' === SOIMarker);
  9. }
  10. function extractSize (buffer, i) {
  11. return {
  12. 'height' : buffer.readUInt16BE(i),
  13. 'width' : buffer.readUInt16BE(i + 2)
  14. };
  15. }
  16. function validateBuffer (buffer, i) {
  17. // index should be within buffer limits
  18. if (i > buffer.length) {
  19. throw new TypeError('Corrupt JPG, exceeded buffer limits');
  20. }
  21. // Every JPEG block must begin with a 0xFF
  22. if (buffer[i] !== 0xFF) {
  23. throw new TypeError('Invalid JPG, marker table corrupted');
  24. }
  25. }
  26. function calculate (buffer) {
  27. // Skip 4 chars, they are for signature
  28. buffer = buffer.slice(4);
  29. var i, next;
  30. while (buffer.length) {
  31. // read length of the next block
  32. i = buffer.readUInt16BE(0);
  33. // ensure correct format
  34. validateBuffer(buffer, i);
  35. // 0xFFC0 is baseline standard(SOF)
  36. // 0xFFC1 is baseline optimized(SOF)
  37. // 0xFFC2 is progressive(SOF2)
  38. next = buffer[i + 1];
  39. if (next === 0xC0 || next === 0xC1 || next === 0xC2) {
  40. return extractSize(buffer, i + 5);
  41. }
  42. // move to the next block
  43. buffer = buffer.slice(i + 2);
  44. }
  45. throw new TypeError('Invalid JPG, no size found');
  46. }
  47. module.exports = {
  48. 'detect': isJPG,
  49. 'calculate': calculate
  50. };