Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@lunapaint/png-codec

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lunapaint/png-codec

Decode and encode png files in web or node

  • 0.2.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
1.5K
increased by49.14%
Maintainers
1
Weekly downloads
 
Created
Source

@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:

ChunkNameNotes
IHDRImage header
PLTEPalette
IDATImage dataFull filtering and interlacing support for all bit depths (1, 2, 4, 8, 16) are supported.
IENDImage trailer

Ancillary chunks:

ChunkNameNotes
bKGDBackground color
cHRMPrimary chromaticities and white point
eXIfExchangeable image file formatApproved 2017/7
gAMAImage gammaGamma values are provided, but are not applied to the resulting image (see #11)
hISTImage histogram
iCCPEmbedded ICC profileExposes the profile as a byte array
iTXtInternational textual data
oFFsImage offset🧪 Limited testing
Extension to the PNG 1.2 Specification v1.2.0
pCALCalibration of pixel values🧪 Limited testing
Extension to the PNG 1.2 Specification v1.2.0
pHYsPhysical pixel dimensions
sBITSignificant bitsSince the decoded buffer uses a minimum of uint8, this is only when the significant bits are in the range of 9-15
sCALPhysical scale of image subject🧪 Limited testing
Extension to the PNG 1.2 Specification v1.2.0
sPLTSuggested palette
sRGBStandard RGB colour space
sTERIndicator of stereo image🧪 Limited testing
Extension to the PNG 1.2 Specification v1.3.0
tEXtTextual data
tIMEImage last-modification time
tRNSTransparencySince this chunk modifies the resulting image, you cannot skip this chunk
zTXtCompressed 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

Keywords

FAQs

Package last updated on 07 Mar 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc