npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

blobinfo

v0.1.2

Published

Lightweight library designed for inspecting blobs, mostly for getting image properties.

Downloads

44

Readme

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");

// This is a PNG image from PNG test suite, also part of BlobInfo's unit test.
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"])); // Success.
console.log(blobinfo.inspect(buffer, ["images/bmp", "image/jpeg"])); // Failure.

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 = {
  // Function that is called to inspect a data buffer.
  inspect: function(reader, data) {
    ...
  },

  type: "string",         // Optional  - file-type.
  mime: ["string"],       // Mandatory - list of mime types.
  extension: [".string"], // Optional  - list of file extensions.
  lead: 0x00              // Optional  - magic byte.
};

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.