BlobInfo
Lightweight JavaScript library designed for inspecting blobs, mostly for getting image properties.
Introduction
BlobInfo allows to get useful information about binary data (blob). The library is specialized for getting image properties, but it can be extended in the future to get properties of other media files as well. BlobInfo doesn't depend on any other library and should run in node.js and browser environments without any modifications.
BlobInfo has been designed in a portable way. It doesn't use filesystem or any other APIs to read files directly from a storage. It expects that you have already the content of a file or at least some part of it. It accepts a node.js Buffer
or just String
with binary data that is to be inspected.
BlobInfo can be considered as a high-performance library. It doesn't create any temporary objects while inspecting, it doesn't use Buffer.slice()
or String.substr()
to get a part of inspected buffer and it tries to bail out as fast as possible to not waste time on inspecting something that will fail at later phase.
Usage
BlobInfo has a very simple API, basically all you need to start is to import the library and use inspect()
function that returns an object of recognized properties of a given blob on success; on failure null
would be returned.
var blobinfo = require("blobinfo");
var buffer = new Buffer([
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x08,0x08,0x02,0x00,0x00,0x00,0x17,0xe7,0x6a,
0xf8,0x00,0x00,0x00,0x04,0x67,0x41,0x4d,0x41,0x00,0x01,0x86,0xa0,0x31,0xe8,0x96,
0x5f,0x00,0x00,0x00,0x03,0x73,0x42,0x49,0x54,0x04,0x04,0x04,0x77,0xf8,0xb5,0xa3,
0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,
0x00,0x1f,0xe8,0x55,0x65,0x00,0x00,0x00,0xeb,0x49,0x44,0x41,0x54,0x78,0x9c,0x7d,
0x92,0x6b,0xb1,0xc3,0x20,0x14,0x84,0xbf,0xcc,0xd4,0xc0,0x5a,0xc0,0x42,0x2c,0xc4,
0x42,0x2c,0xc4,0x42,0x2c,0xdc,0x58,0xa8,0x85,0x58,0xc0,0x02,0x16,0x8e,0x85,0x23,
0x21,0xf7,0x07,0x8f,0x42,0xdb,0x74,0x87,0x01,0x06,0xe6,0xbc,0x76,0x77,0xba,0xf8,
0x40,0x00,0xd5,0xc5,0xb8,0x37,0x78,0xdd,0xf3,0xc5,0xba,0xfb,0x88,0x47,0x39,0x05,
0x33,0xac,0xb0,0x96,0x87,0x16,0xd2,0x07,0x7a,0x57,0xa8,0xf5,0x10,0xda,0xa3,0xc1,
0x01,0x09,0xac,0x2f,0x20,0x58,0x20,0x94,0xde,0x5d,0x44,0x88,0xf0,0x2c,0xb3,0x6c,
0xb8,0x70,0x61,0xdd,0x14,0x72,0xe4,0x04,0x20,0xc1,0x29,0xfc,0x0f,0x66,0x98,0x03,
0xe4,0xe5,0x10,0x4b,0x99,0x07,0xeb,0x2b,0xd0,0x4a,0x5e,0x1c,0x91,0x3f,0xce,0x5d,
0x4f,0xb6,0xc8,0x46,0xac,0xc3,0xc8,0x08,0x07,0x73,0xdc,0x61,0x4d,0xcc,0x82,0x68,
0x24,0x03,0x6b,0xf3,0xe7,0xe8,0x13,0xac,0x51,0x74,0x07,0x81,0x30,0x91,0x90,0xaa,
0x14,0x86,0x9c,0x4e,0xa4,0x3b,0x38,0xc0,0x74,0xf5,0x14,0x2d,0xf8,0xf2,0x46,0xd1,
0x02,0x01,0x07,0xd7,0x20,0x42,0x66,0x09,0x83,0x18,0xf0,0x3d,0x53,0xe4,0x70,0xd4,
0xd4,0x95,0xa2,0xe9,0x6a,0x9d,0x86,0x41,0x64,0x1f,0xad,0xf1,0x66,0x10,0x8d,0x22,
0xbf,0x28,0x3e,0xc0,0x06,0x91,0xa7,0x2f,0x36,0xed,0x9d,0xf1,0x83,0x87,0xde,0xa9,
0x7e,0x6b,0xd3,0x7f,0x08,0xcd,0x5c,0xaa,0x68,0xbe,0xfb,0xa4,0x00,0x00,0x00,0x00,
0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
]);
console.log(blobinfo.inspect(buffer));
The code above should output something like:
{
"type" : "image",
"mime" : ["image/png"],
"extension": [".png"],
"width" : 32,
"height" : 8
}
There is also a second and purely optional parameter, which can be used to specify file types that will be accepted:
console.log(blobinfo.inspect(buffer, ["images/png", "image/jpeg"]));
console.log(blobinfo.inspect(buffer, ["images/bmp", "image/jpeg"]));
The first call to inspect
in the code above returns exactly the same object as in the first example, however, the second call returns null
, because PNG
data doesn't match BMP
or JPEG
signature.
Supported File Types
- BMP (
image/bmp
or image/x-bmp
) - GIF (
image/gif
) - JPEG (
image/jpeg
) - PNG (
image/png
)
Implementation Details
BlobInfo has been designed for future extensions and adding more file types is welcome. The core of the library itself is very small and uses inspectors that are specialized for a particular file formats. Mandatory properties of the inspector are:
var Inspector = {
inspect: function(reader, data) {
...
},
type: "string",
mime: ["string"],
extension: [".string"],
lead: 0x00
};
The most interesting part is the inspect()
function. It accepts reader
and data
parameters. The reader
is an instance of BufferReader
or StringReader
, both private objects not accessible outside of BlobInfo
, which is used to access bytes stored in data
. Reader is basically an interface to access String
or Buffer
without having to worry about the data type.
The reader
object provides the following methods:
// Methods to read BYTE, WORD, or DWORD.
function read8(data, offset)
function read16LE(data, offset);
function read16BE(data, offset);
function read32LE(data, offset);
function read32BE(data, offset);
// Comparison.
function equals(data, offset, pattern);
Methods, which starts with read
are used to read BYTE, WORD or DWORD depending on suffix and endianness. Function equals
is used to compare bytes in data
starting from offset
against pattern
(pattern can be Array
of bytes or Buffer
, but not String
).
Adding a new, global, inspector is possible through addInspector()
function. The following example shows how to create a new inspector for inspecting a PCX
file and to how add it dynamically to the global inspectors list:
blobinfo.addInspector({
inspect: function(reader, data) {
var len = data.length;
var fileSize;
// We need at least 12 bytes to determine image width and height.
if (len < 12)
return null;
// Check the file signature, see `fileSig` (0A 05).
if (!reader.equals(data, 0, this.fileSig))
return null;
// Read the most interesting information stored in the header.
var xMin = reader.read16LE(data, 4);
var yMin = reader.read16LE(data, 6);
var xMax = reader.read16LE(data, 8);
var yMax = reader.read16LE(data, 10);
// Broken or no PCX.
if (xMin >= xMax || yMin >= yMax)
return null;
// Probably PCX.
return {
type : this.type,
mime : this.mime,
extension : this.extension,
width : xMax - xMin + 1,
height : yMax - yMin + 1,
bitsPerPixel: reader.read8(data, 3)
};
},
type: "image",
mime: ["application/pcx"],
extension: [".pcx"],
// Leading byte, not required, but helps to determine the file type faster
// without calling `inspect()`.
lead: 0x0A,
// This is not required, but fileSig is used by nearly all inspectors.
fileSig: [0x0A, 0x05]
});
Please note that PCX is not part of files recognized by BlobInfo. It's just an example, which tries to explain the concept on something that is working.