| '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 | 
| }; |