FPNG Java

FPNG-Java provides Java wrappers around two native, SIMD-optimised PNG encoders — FPNG (SSE2) and FPNGE (AVX2). Both produce fully compliant PNG files at significantly higher throughput than javax.imageio.

The JDK23+ version of the encoders uses Foreign Function & Memory API and is the fastest. Otherwise JNI is used via JNA, which comes with some overhead.

Latest stable release: fpng-java-1.4.1.jar

GitHub Repository: https://github.com/manticore-projects/fpng-java

Features

  • Two encoders with automatic runtime selection
    • FPNG — SSE2/SSE4.1/PCLMUL, works on any x86-64 CPU

    • FPNGE — AVX2, used automatically when the CPU supports it

  • FFM for JDK22+, JNI/JNA for older JDKs

  • Runtime hasAVX2() CPUID probe — no AVX2 library is loaded on unsupported hardware

  • Encodes BufferedImage directly — 3-channel (RGB) and 4-channel (RGBA)

  • Handles Java’s native TYPE_3BYTE_BGR / TYPE_4BYTE_ABGR channel order in C via SIMD byte shuffles

  • Interleaved Adler32 checksum — no redundant full-image pass

  • PCLMUL-accelerated CRC32

  • Supports Java 8, Java 11, Java 17 and Java 21

  • Platforms: Linux x86-64, Windows x86/x86-64, macOS x86-64

Benchmarks

Run the JMH benchmarks with:

./gradlew jmh

Results are written to benchmark/build/results/jmh/results.json.

JMH PNG Encoder Benchmark Report

PNG Encoder Benchmark Report

Generated by Manticore Projects · JMH ms/op · lower is better

3 ch example.png

Encoder Score (ms/op) Error vs Winner
FPNGE (Java 23 FFM) 2.706 ±0.143 baseline
FPNGE (JNI) 3.261 ±0.691 +20.5%
FPNG Encoder (JNI) 3.987 ±0.818 +47.3%
FPNG Encoder (Java 23) 5.002 ±1.122 +84.9%
PNGEncoder (fastest) 20.986 ±12.699 +675.7%
ObjectPlanet PNG 41.352 ±2.925 +1428.4%
PNGEncoder 44.550 ±23.990 +1546.6%
ImageIO 50.375 ±4.578 +1761.9%

3 ch looklet-look-scale6.png

Encoder Score (ms/op) Error vs Winner
FPNGE (Java 23 FFM) 139.807 ±33.887 baseline
FPNGE (JNI) 166.635 ±126.279 +19.2%
FPNG Encoder (JNI) 302.257 ±141.186 +116.2%
FPNG Encoder (Java 23) 337.719 ±28.268 +141.6%
PNGEncoder (fastest) 346.707 ±111.700 +148.0%
PNGEncoder 1176.420 ±115.739 +741.5%
ImageIO 1238.361 ±568.947 +785.8%
ObjectPlanet PNG 1756.963 ±427.382 +1156.7%

4 ch example.png

Encoder Score (ms/op) Error vs Winner
FPNGE (Java 23 FFM) 4.223 ±0.587 baseline
FPNGE (JNI) 4.625 ±1.513 +9.5%
FPNG Encoder (Java 23) 6.605 ±1.217 +56.4%
FPNG Encoder (JNI) 8.457 ±2.726 +100.3%
PNGEncoder (fastest) 24.527 ±21.807 +480.9%
PNGEncoder 50.895 ±4.062 +1105.3%
ObjectPlanet PNG 51.795 ±24.218 +1126.6%
ImageIO 63.420 ±37.017 +1401.9%

4 ch looklet-look-scale6.png

Encoder Score (ms/op) Error vs Winner
FPNGE (Java 23 FFM) 197.625 ±39.119 baseline
FPNGE (JNI) 271.884 ±56.459 +37.6%
PNGEncoder (fastest) 423.605 ±168.635 +114.3%
FPNG Encoder (Java 23) 440.591 ±53.450 +122.9%
FPNG Encoder (JNI) 476.420 ±445.912 +141.1%
ImageIO 1484.558 ±1000.757 +651.2%
PNGEncoder 1511.124 ±147.042 +664.6%
ObjectPlanet PNG 2145.475 ±202.674 +985.6%
Manticore Projects © 2026 · JMH benchmark report · JDK 23 · Serial GC · 1×3 fork/iteration