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

@lunapaint/png-codec

v0.2.0

Published

Decode and encode png files in web or node

Downloads

4,772

Readme

@lunapaint/png-codec

This is a PNG decoder and encoder library for JavaScript that runs in both the browser and in Node.js. It is used in Luna Paint (an image editor for VS Code) to work with PNG files.

You can try it out on vscode.dev by installing the Luna Paint extension and opening a png file.

Features

  • Performance: Just like Luna Paint, performance is a priority. This includes code splitting such that code that parses optional chunks are only loaded as needed.
  • Correctness: The library has > 97% code coverage via over 7500 tests, including full coverage of PngSuite—the "official" test suite for PNG.
  • Simple API: The API is a well documented TypeScript declaration file.
  • Metadata: All supported metadata is exposed on the API such as text, gamma, default background color, etc.
  • Readable Codebase: A big part of this was a learning exercise for me so I put some effort in to make the code as readable as possible to help others on the same journey.
  • Error tolerant: Images will still load with warnings unless a critical error is hit.

Install

The supported way of installing the project is through npm:

npm install @lunapaint/png-codec

Alternatively, you could add the repo as a git submodule, or download the source from the GitHub releases page.

API

Basic usage:

import { decodePng, encodePng } from '@lunapaint/png-codec';
import * as fs from 'fs/promises';

async function decode(filepath) {
  const data = await fs.readFile(filepath);
  const decoded = await decodePng(data);
  console.log('decoded image', decoded.image.data);
  // [r, g, b, a, ...]
}

async function encode(data, width, height, filepath) {
  const encoded = await encodePng({ data, width, height });
  await fs.writeFile(filepath, encoded.data);
  console.log('encoded image', encoded.data);
  // [...binary data]
}

The full API is documented as a TypeScript .d.ts declaration file. The view the API:

  • github.dev: View on the web in VS Code, which has symbol support out of the box. Try showing the Outline view and triggering the Go to Symbol in Editor command
  • github.com: View the raw file in github.com.

Decoder chunk support

PNGs are made up of a fixed signature followed by a series of chunks. The following chunks can be decoded supported, with some notes provided where applicable:

Critical chunks:

| Chunk | Name | Notes |---------|---------------|------- | IHDR | Image header | | PLTE | Palette | | IDAT | Image data | Full filtering and interlacing support for all bit depths (1, 2, 4, 8, 16) are supported. | IEND | Image trailer |

Ancillary chunks:

| Chunk | Name | Notes |---------|----------------------------------------|------- | bKGD | Background color | | cHRM | Primary chromaticities and white point | | eXIf | Exchangeable image file format | Approved 2017/7 | gAMA | Image gamma | Gamma values are provided, but are not applied to the resulting image (see #11) | hIST | Image histogram | | iCCP | Embedded ICC profile | Exposes the profile as a byte array | iTXt | International textual data | | oFFs | Image offset | 🧪 Limited testingExtension to the PNG 1.2 Specification v1.2.0 | pCAL | Calibration of pixel values | 🧪 Limited testingExtension to the PNG 1.2 Specification v1.2.0 | pHYs | Physical pixel dimensions | | sBIT | Significant bits | Since the decoded buffer uses a minimum of uint8, this is only when the significant bits are in the range of 9-15 | sCAL | Physical scale of image subject | 🧪 Limited testingExtension to the PNG 1.2 Specification v1.2.0 | sPLT | Suggested palette | | sRGB | Standard RGB colour space | | sTER | Indicator of stereo image | 🧪 Limited testingExtension to the PNG 1.2 Specification v1.3.0 | tEXt | Textual data | | tIME | Image last-modification time | | tRNS | Transparency | Since this chunk modifies the resulting image, you cannot skip this chunk | zTXt | Compressed textual data |

Why does this exist?

These are the main reasons:

  • To deeply understand the format.
  • To integrate better with Luna Paint and my other existing and future decoders that depend on the png format.
  • The scope is limited, this project will eventually be "done" and need minimal maintenance.
  • I didn't want to go the wasm route in Luna Paint (yet?).
  • To have full control over how the code is loaded, for example Luna Paint uses dynamic imports extensively to reduce the amount of code loaded to combat slow startup times.
  • As an educational resource.
  • To have some fun.

Dependencies

The library has the single runtime dependency pako which provides the compression/decompression capabilities needed to read various png chunks.

References

  • https://www.w3.org/TR/2003/REC-PNG-20031110
  • http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html
  • http://www.libpng.org/pub/png/spec/register/pngext-1.4.0-pdg.html
  • http://ftp-osl.osuosl.org/pub/libpng/documents/proposals/eXIf/png-proposed-eXIf-chunk-2017-06-15.html