'use strict'; // NOTE: we only support baseline and progressive JPGs here // due to the structure of the loader class, we only get a buffer // with a maximum size of 4096 bytes. so if the SOF marker is outside // if this range we can't detect the file size correctly. function isJPG (buffer) { //, filepath var SOIMarker = buffer.toString('hex', 0, 2); return ('ffd8' === SOIMarker); } function extractSize (buffer, i) { return { 'height' : buffer.readUInt16BE(i), 'width' : buffer.readUInt16BE(i + 2) }; } function validateBuffer (buffer, i) { // index should be within buffer limits if (i > buffer.length) { throw new TypeError('Corrupt JPG, exceeded buffer limits'); } // Every JPEG block must begin with a 0xFF if (buffer[i] !== 0xFF) { throw new TypeError('Invalid JPG, marker table corrupted'); } } function calculate (buffer) { // Skip 4 chars, they are for signature buffer = buffer.slice(4); var i, next; while (buffer.length) { // read length of the next block i = buffer.readUInt16BE(0); // ensure correct format validateBuffer(buffer, i); // 0xFFC0 is baseline standard(SOF) // 0xFFC1 is baseline optimized(SOF) // 0xFFC2 is progressive(SOF2) next = buffer[i + 1]; if (next === 0xC0 || next === 0xC1 || next === 0xC2) { return extractSize(buffer, i + 5); } // move to the next block buffer = buffer.slice(i + 2); } throw new TypeError('Invalid JPG, no size found'); } module.exports = { 'detect': isJPG, 'calculate': calculate };