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 🙏

© 2025 – Pkg Stats / Ryan Hefner

bcn-encdec-wasm

v1.0.1

Published

WebAssembly library for BCN (BC1-BC7, BC6H) texture compression and decompression

Readme

BCN Texture Compression WASM

WebAssembly library for BCN (Block Compression) texture encoding and decoding. Supports BC1-BC7 and BC6H formats commonly used in GPU texture compression.

Features

  • BC1 (DXT1) - RGB/RGBA with 1-bit alpha, 6:1 or 8:1 compression
  • BC2 (DXT3) - RGBA with explicit alpha, 4:1 compression
  • BC3 (DXT5) - RGBA with interpolated alpha, 4:1 compression
  • BC4 - Single channel (grayscale), 2:1 compression
  • BC5 - Dual channel (normal maps), 2:1 compression
  • BC6H - HDR RGB (unsigned float), 6:1 compression
  • BC7 - High quality RGBA, 4:1 compression
  • 🚀 Batch image processing for optimal performance
  • 📦 Small bundle size (~400KB WASM)
  • 🎯 Full TypeScript support

Installation

npm install bcn-encdec-wasm

Quick Start

import BCNModule from 'bcn-encdec-wasm';

// Initialize the module
const Module = await BCNModule();

// Initialize encoders
const idealMode = Module._get_bc1_ideal_mode();
Module._init(idealMode);
Module._init_bc7(); // Required for BC7 encoding

// Example: Compress image to BC7
const width = 512;  // Must be multiple of 4
const height = 512; // Must be multiple of 4

// Prepare source RGBA data (Uint8Array)
const sourcePixels = new Uint8Array(width * height * 4);
// ... fill with your image data ...

// Calculate compressed size
const blocksX = width / 4;
const blocksY = height / 4;
const compressedSize = blocksX * blocksY * 16; // BC7 uses 16 bytes per block

// Allocate memory
const srcPtr = Module._malloc(sourcePixels.length);
const dstPtr = Module._malloc(compressedSize);

// Copy source data to WASM memory
Module.HEAPU8.set(sourcePixels, srcPtr);

// Compress to BC7 (quality 0-4)
Module._encode_bc7_image(dstPtr, srcPtr, width, height, 4);

// Get compressed data
const compressed = new Uint8Array(
  Module.HEAPU8.buffer,
  dstPtr,
  compressedSize
);
const result = new Uint8Array(compressed); // Copy before freeing

// Free memory
Module._free(srcPtr);
Module._free(dstPtr);

console.log('Compressed!', result);

API Reference

Initialization

Module._init(mode)          // Initialize rgbcx for BC1-BC5
Module._init_bc7()          // Initialize BC7 encoder (call once)

Encoding Functions

BC1 (DXT1)

Module._encode_bc1_image(level, pDst, pSrc, width, height, allow_3color, use_transparent)
// level: 0-18 (quality)
// Block size: 8 bytes

BC2 (DXT3)

Module._encode_bc2_image(level, pDst, pSrc, width, height)
// Block size: 16 bytes

BC3 (DXT5)

Module._encode_bc3_image(level, pDst, pSrc, width, height)
// Block size: 16 bytes

BC4 (Single Channel)

Module._encode_bc4_image(pDst, pSrc, width, height, channel)
// channel: 0=R, 1=G, 2=B (converts RGB to grayscale)
// Block size: 8 bytes

BC5 (Dual Channel)

Module._encode_bc5_image(pDst, pSrc, width, height, chan0, chan1)
// chan0, chan1: 0=R, 1=G, 2=B
// Block size: 16 bytes

BC6H (HDR)

Module._encode_bc6h_image(pDst, pSrc, width, height)
// pSrc: Float32Array (RGB, 3 floats per pixel)
// Block size: 16 bytes

BC7 (High Quality)

Module._encode_bc7_image(pDst, pSrc, width, height, quality)
// quality: 0-4 (0=fastest, 4=best quality)
// Block size: 16 bytes

Decoding Functions

Module._decode_bc1_image(pSrc, pDst, width, height, set_alpha, mode)
Module._decode_bc4_image(pSrc, pDst, width, height)
Module._decode_bc6h_image(pSrc, pDst, width, height) // Output: Float32Array RGB
Module._decode_bc7_image(pSrc, pDst, width, height)

Memory Management

const ptr = Module._malloc(size)  // Allocate memory
Module._free(ptr)                 // Free memory

// Access memory
Module.HEAPU8   // Uint8Array view
Module.HEAPF32  // Float32Array view

Compressed Size Calculation

function getCompressedSize(width, height, format) {
  const blocksX = width / 4;
  const blocksY = height / 4;
  const totalBlocks = blocksX * blocksY;

  const blockSizes = {
    'BC1': 8,   // BC1, BC4
    'BC2': 16,  // BC2, BC3, BC5, BC6H, BC7
  };

  return totalBlocks * blockSizes[format];
}

Complete Example: BC7 Encoding & Decoding

import BCNModule from 'bcn-encdec-wasm';

async function compressImage(imageData, width, height) {
  const Module = await BCNModule();

  Module._init(Module._get_bc1_ideal_mode());
  Module._init_bc7();

  // Encode
  const compressedSize = (width / 4) * (height / 4) * 16;
  const srcPtr = Module._malloc(imageData.length);
  const dstPtr = Module._malloc(compressedSize);

  Module.HEAPU8.set(imageData, srcPtr);
  Module._encode_bc7_image(dstPtr, srcPtr, width, height, 4);

  const compressed = new Uint8Array(
    Module.HEAPU8.buffer,
    dstPtr,
    compressedSize
  );
  const compressedCopy = new Uint8Array(compressed);

  // Decode
  const decodedPtr = Module._malloc(width * height * 4);
  Module.HEAPU8.set(compressedCopy, dstPtr);
  Module._decode_bc7_image(dstPtr, decodedPtr, width, height);

  const decoded = new Uint8Array(
    Module.HEAPU8.buffer,
    decodedPtr,
    width * height * 4
  );
  const decodedCopy = new Uint8Array(decoded);

  // Cleanup
  Module._free(srcPtr);
  Module._free(dstPtr);
  Module._free(decodedPtr);

  return {
    compressed: compressedCopy,
    decoded: decodedCopy
  };
}

Browser Usage

<script type="module">
  import BCNModule from './bcn.js';

  const Module = await BCNModule();
  Module._init(Module._get_bc1_ideal_mode());
  Module._init_bc7();

  // Your compression code here...
</script>

DDS Export

The compressed data can be exported as DDS files:

function createDDSFile(compressed, width, height, format) {
  // DDS header is 128 bytes (or 148 for DX10 extended)
  // For BC7, use DX10 extended header with DXGI_FORMAT_BC7_UNORM (98)
  // See examples/index.html for complete DDS export implementation
}

Performance Tips

  1. Batch Processing: Use _encode_*_image() functions instead of per-block encoding
  2. Memory Reuse: Allocate buffers once and reuse for multiple compressions
  3. Quality vs Speed: Lower quality levels (0-5) are much faster
  4. Image Size: Ensure width/height are multiples of 4

Format Selection Guide

| Format | Use Case | Alpha | Quality | Speed | |--------|----------|-------|---------|-------| | BC1 | Diffuse maps, no alpha | 1-bit | Good | Fast | | BC2 | Sharp alpha transitions | Explicit | Medium | Fast | | BC3 | Smooth alpha gradients | Interpolated | Good | Fast | | BC4 | Heightmaps, grayscale | No | Good | Fast | | BC5 | Normal maps | No | Good | Fast | | BC6H | HDR images | No | Excellent | Medium | | BC7 | High quality diffuse+alpha | Full | Excellent | Slow |

Credits

Built with:

License

MIT

Contributing

Issues and pull requests welcome at [GitHub repository URL]