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

2d-bit-array

v0.0.3

Published

Efficient 2D Bit Array with Serialization

Downloads

20

Readme

2d-bit-array

A package for afficiently managing a 2D bit-array (also known as a bit-mask, bit-map, bit-string, or bit-vector). It can be used for any 2D array of flags but is especially suitable for working with images where the flags could be mapped to pixel transparencies.

Installation

Install using your package manager of choice:

pnpm i 2d-bit-array

Usage

BitArray

Create an instance of the BitArray class with the desired width and height:

import { BitArray } from '2d-bit-array'

const bv = new BitArray(320, 240)

The flag for each x, and y coordinate is stored as a single bit inside a Uint8Array which will always be the minimum size necssary to store all the possible flags. Use get(x, y) to check the flag value, set(x, y) to set it to true, clear(x, y) to set it to false, and toggle(x, y) to invert the current value.

The BitArray instance has an empty and length property to indicate if any flags are set, and how many are set. The set flags can be iterated:

for (const [x, y] of bv) {
  // do something with x & y
}

The .trim() method returns the smallest instance that bounds the set flags, with the x and y offsets of the BitArray itself set. So given a bit vector:

import { BitArray } from '2d-bit-array'

const bv = new BitArray(8, 8)
bv.set(2, 4)
bv.set(5, 6)

const trimmed = bv.trim()

// trimmed will be width = 4, height = 3, offset x = 2 and y =4
// the same flags can still be checked:

expect(trimmed.get(2, 4)).true
expect(trimmed.get(5, 6)).true

// iterating the flags will still return the same [2, 4] and [5, 6] coordinates

The reason this is desirable is for serialization, when the minimal amount of data can be stored or transmitted. When .toJSON() is used, the a trimmed version is returned automatically and the Uint8Array data encoded to a bas64 string. Use BitArray.fromJSON(value) to decode a JSON serialized version.

The flags from one BitArray can be added to another. So the previous trimmed values could be added to another instance to get back to the original state:

const bv2 = new BitArray(8, 8)
bv2.add(trimmed)

// bv2 now matches the original bv instance

Use .reset() to clear all the flags in an instance.

ChangeSet

Sometimes you need to track not just what has been set, but also what has been cleared. i.e. to store the difference between one set of flags and another. For this you can use the ChangeSet class. It's effectively just two BitArray instances, one to store added flags and one to store removed flags. Reversing an operation is slightly different - if you set a flag on a ChangeSet (which would set the added BitArray coordinate to true) and then clear it, it would simply delete the flag from the added BitArray. Likewise, clearing a flag would set the removed BitArray coordinate, and then setting it would clear the flag.

Only if the next result is to set or clear a flag will a flag be set in the added or removed BitArray layers.

The same empty and length properties indicate if any, and how many, flags are set.

Checking a flag using get(x, y) returns either the Added, Removed, or Unchanged state of the coordinate.

Iterating the flags returns an object containing the x and y properties plus the changed property (Added or Removed).

The ChangeSet can be applied to a BitArray to update it using the .applyTo(bv: BitArray) method, with any Added or Removed coordinated being applied as appropriate to set or clear the existing flags.

Any use of .toJSON will return a compact representation with empty layers marked as null for maximum space saving. Use ChangeSet.fromJSON to decode a JSON serialized version.

Image

The applyToImage method allows a BitArray to be applied to an ImageData instance. The transparency for a pixel will be set based on whether the matching flag coordinate is true (opaque) or false (transparent).