bcn-encdec-wasm
v1.0.1
Published
WebAssembly library for BCN (BC1-BC7, BC6H) texture compression and decompression
Maintainers
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-wasmQuick 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 bytesBC2 (DXT3)
Module._encode_bc2_image(level, pDst, pSrc, width, height)
// Block size: 16 bytesBC3 (DXT5)
Module._encode_bc3_image(level, pDst, pSrc, width, height)
// Block size: 16 bytesBC4 (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 bytesBC5 (Dual Channel)
Module._encode_bc5_image(pDst, pSrc, width, height, chan0, chan1)
// chan0, chan1: 0=R, 1=G, 2=B
// Block size: 16 bytesBC6H (HDR)
Module._encode_bc6h_image(pDst, pSrc, width, height)
// pSrc: Float32Array (RGB, 3 floats per pixel)
// Block size: 16 bytesBC7 (High Quality)
Module._encode_bc7_image(pDst, pSrc, width, height, quality)
// quality: 0-4 (0=fastest, 4=best quality)
// Block size: 16 bytesDecoding 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 viewCompressed 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
- Batch Processing: Use
_encode_*_image()functions instead of per-block encoding - Memory Reuse: Allocate buffers once and reuse for multiple compressions
- Quality vs Speed: Lower quality levels (0-5) are much faster
- 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]
