Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BPG API SDK 1.0.0 for Windows x64

bpg_api.dll is a stable C ABI for in-memory BPG processing on Windows:

  • convert JPEG, PNG, or BMP bytes to a still BPG;
  • encode packed RGB frames as an animated BPG;
  • decode still or animated BPG bytes frame by frame to BGRA8;
  • keep all codec input, intermediate data, and output callbacks in memory.

The DLL itself opens no files and performs no disk I/O. Your application decides whether bytes are kept in RAM, sent over a network, or written to storage.

New integrations should use the size-versioned *_v1 API. The legacy API remains exported for binary compatibility.

Platform and current limits

Item SDK 1.0.0
Operating system Windows 10/11 x64
ABI C, __cdecl, undecorated export names
Still input JPEG, PNG, uncompressed 24/32-bit BMP
Animated encoder input RGB24 and RGB48
Decoder output BGRA32 (8 bits per channel)
Still alpha Supported for suitable PNG/BMP input
Animated alpha encoding Not supported by this build; RGBA input returns BPG_ERR_UNSUPPORTED
Animated alpha decoding Supported
Per-frame timing Rational duration in seconds
File I/O inside DLL None

Animated alpha encoding is deliberately rejected. The bundled x265 revision is unsafe while flushing delayed monochrome frames used by the BPG alpha layer. Returning BPG_ERR_UNSUPPORTED prevents a process crash. Do not strip this guard unless replacing and fully testing the encoder backend.

Package layout

A release archive contains:

bin/
  bpg_api.dll
  libjpeg-8.dll
  libpng16-16.dll
  libwinpthread-1.dll
  libgcc_s_seh-1.dll
  zlib1.dll
include/
  bpg_api.h
lib/
  libbpg_api.a       # MinGW/GNU import library
  bpg_api.lib        # MSVC x64 COFF import library
examples/
licenses/
README_BPG_API.md
DISTRIBUTION.md
THIRD_PARTY_NOTICES.md
RELEASE_CHECKLIST.md
SHA256SUMS.txt

Keep the DLL and all five non-system runtime DLLs beside the application executable, or place them in another directory selected by a secure DLL-loading policy. Do not rely on the current working directory or a globally modified PATH in production.

Five-minute C quick start

This example converts an already-loaded image buffer to BPG. It performs no file I/O.

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "bpg_api.h"

int encode_image(const uint8_t *source, uint64_t source_len)
{
    BPGConvertConfigV1 config;
    uint8_t *bpg = NULL;
    uint64_t bpg_len = 0;
    int32_t result;

    memset(&config, 0, sizeof(config));
    config.struct_size = sizeof(config);
    config.qp = 28;
    config.bit_depth = 8;
    config.compress_level = 6;

    result = bpg_convert_v1(source, source_len, &config, &bpg, &bpg_len);
    if (result != BPG_OK) {
        fprintf(stderr, "BPG encode failed: %s (%d)\n",
                bpg_error_string(result), (int)result);
        return 0;
    }

    /* Use bpg[0..bpg_len): retain in RAM, send, or write it yourself. */
    printf("encoded %llu bytes\n", (unsigned long long)bpg_len);

    bpg_free(bpg);
    return 1;
}

Link with MSVC

cl /nologo /W4 /Iinclude your_app.c /link /LIBPATH:lib bpg_api.lib

Link with MinGW

gcc -O2 -Wall -Wextra -Iinclude -o your_app.exe your_app.c -Llib -lbpg_api

At runtime, place the contents of bin/ next to your_app.exe.

Choosing an API

Goal Recommended API
Convert one JPEG/PNG/BMP buffer bpg_convert_v1
Encode a sequence of raw RGB frames bpg_anim_open_v1bpg_anim_add_frame_v1bpg_anim_finish_v1
Cancel an animation bpg_anim_abort_v1
Inspect/decode BPG frames bpg_decode_open_v1bpg_decode_next_frame_v1bpg_decode_close_v1
Check runtime compatibility bpg_api_version and bpg_api_capabilities
Maintain an existing integration Legacy exports remain available; migrate when practical

ABI initialization rule

Every v1 structure starts with struct_size.

  1. Zero the entire structure.
  2. Set struct_size = sizeof(structure).
  3. Set only documented fields.
  4. Leave all reserved fields zero.

Example:

BPGAnimEncoderConfigV1 config;
memset(&config, 0, sizeof(config));
config.struct_size = sizeof(config);

The DLL accepts a structure at least as large as the v1 definition and ignores unknown tail fields. A smaller structure returns BPG_ERR_INVALID_PARAM.

Still-image conversion

int32_t bpg_convert_v1(
    const uint8_t *input_data,
    uint64_t input_len,
    const BPGConvertConfigV1 *config,
    uint8_t **out_buf,
    uint64_t *out_len);

Configuration

Field Values Default
qp 0..51; lower usually means higher quality/larger output -1 selects 29
lossless 0 or 1 0
bit_depth 8, 10, or 12 0 selects 8
compress_level 1..9; higher is slower 0 selects 8
prefer_444 0 for 4:2:0, 1 for 4:4:4 0

On success, the DLL allocates *out_buf and sets *out_len. Release the buffer only with bpg_free(). On failure, outputs are reset to NULL and zero.

Do not pass a still-owned output pointer back as out_buf for another call: because outputs are reset on entry, doing so would lose your original pointer. Free the previous result first.

Input detection

Format Detection and support
JPEG FF D8; grayscale, YCbCr, RGB, YCCK, and CMYK paths supported by the bundled decoder
PNG PNG signature; 8/16-bit grayscale, palette, RGB, and alpha variants
BMP BM; uncompressed 24-bit and 32-bit BMP

Unknown signatures return BPG_ERR_UNKNOWN_FORMAT. Recognized but malformed data returns BPG_ERR_DECODE_FAILED.

Animated encoder

Lifecycle

void *encoder = NULL;
int32_t result;

result = bpg_anim_open_v1(&config, write_callback, opaque, &encoder);
if (result != BPG_OK)
    return result;

/* Submit one or more RGB frames. */

result = bpg_anim_finish_v1(&encoder);
/* encoder is NULL after finish, including on failure. */

If any operation fails and the handle is still non-null, call:

bpg_anim_abort_v1(&encoder);

bpg_anim_abort_v1 consumes the session, releases retained codec output, and sets the caller's handle to NULL. Calling it with a valid pointer whose contained handle is already NULL succeeds.

Finishing a zero-frame session returns BPG_ERR_BAD_STATE, still releases the session, and still nulls the handle.

Encoder configuration

Field Meaning
width, height Fixed dimensions for every frame; nonzero
qp -1 for 29 or 0..51
fps_num / fps_den Frame rate, for example 30/1 or 30000/1001; each component must fit 1..65535
loop_count 0 means infinite; maximum 65535
compress_level 0 for 8 or 1..9
prefer_444 0 for 4:2:0, 1 for 4:4:4
lossless 0 or 1; lossless forces RGB 4:4:4 internally

The frame duration reported by the decoder is the inverse frame rate. A 30/1 FPS configuration normally decodes as duration 1/30 second.

Contiguous frame contract

int32_t bpg_anim_add_frame_v1(
    void *handle,
    const uint8_t *pixels,
    uint64_t pixels_len,
    uint32_t stride,
    uint32_t pixel_format,
    uint32_t limited_range);

Supported encoder formats:

Constant Layout Bytes/pixel
BPG_PIXFMT_RGB24 R8 G8 B8 3
BPG_PIXFMT_RGB48 native-endian R16 G16 B16 6

BPG_PIXFMT_RGBA32 and BPG_PIXFMT_RGBA64 are defined for ABI stability but animated alpha encoding returns BPG_ERR_UNSUPPORTED in SDK 1.0.0.

The packed row size is:

row_bytes = width * bytes_per_pixel

Requirements:

stride >= row_bytes
pixels_len >= stride * (height - 1) + row_bytes

For 16-bit input, the base pointer and stride must be 2-byte aligned. The pixel buffer remains caller-owned and needs to stay valid only until bpg_anim_add_frame_v1 returns. The DLL converts/copies frame pixels during the call.

Output callback contract

typedef int32_t (__cdecl *BPGAnimWriteFuncV1)(
    void *opaque,
    const uint8_t *buf,
    uint32_t buf_len);
  • Return 0 after consuming/copying all bytes.
  • Return nonzero to abort output.
  • buf is borrowed and valid only until the callback returns.
  • Do not retain buf; copy it if asynchronous use is required.
  • The callback may be invoked while adding the first frame and/or while finishing.
  • A callback rejection is reported as BPG_ERR_CALLBACK_FAILED.
  • Do not call encoder functions recursively from its own callback.

For long recordings, stream callback chunks directly to a bounded application pipeline or final destination. Accumulating every callback chunk in one growable memory buffer increases peak RAM use.

Decoder

Open

BPGDecodeInfoV1 info;
void *decoder = NULL;

memset(&info, 0, sizeof(info));
info.struct_size = sizeof(info);
result = bpg_decode_open_v1(bpg_data, bpg_len, &info, &decoder);

On success, info reports dimensions, alpha/animation flags, loop count, and BPG_PIXFMT_BGRA32. The decoder copies/retains the encoded payload it needs, so the caller may release the source BPG buffer after open returns.

Decode frames

BPGDecodedFrameV1 frame;
memset(&frame, 0, sizeof(frame));
frame.struct_size = sizeof(frame);

result = bpg_decode_next_frame_v1(
    decoder, bgra, bgra_len, bgra_stride, &frame);

Return values:

  • 1: one frame was written;
  • 0: end of stream;
  • negative: BPG_ERR_* failure.

The BGRA capacity rule is:

row_bytes = width * 4
bgra_stride >= row_bytes
bgra_len >= bgra_stride * (height - 1) + row_bytes

Reuse one caller-owned output buffer for all frames. frame.frame_index starts at zero. frame.delay_num / frame.delay_den is the current frame duration in seconds, with a nonzero denominator.

Upstream libbpg does not distinguish normal animation end from malformed trailing animation payload after earlier frames have decoded. The wrapper preserves legacy behavior and reports that condition as EOS. A malformed header or initial frame is rejected by bpg_decode_open_v1.

Close

bpg_decode_close_v1(&decoder);

The function releases the decoder and sets the handle to NULL. A valid pointer containing a null handle is accepted.

Ownership summary

Object Owner Valid until / release
Still input bytes Caller Until bpg_convert_v1 returns
Still BPG output DLL transfers to caller bpg_free
Encoder config Caller Until bpg_anim_open_v1 returns
Submitted frame pixels Caller Until bpg_anim_add_frame_v1 returns
Callback buf DLL Callback return only
Encoder handle DLL, referenced by caller bpg_anim_finish_v1 or bpg_anim_abort_v1
BPG bytes passed to decoder open Caller May release after successful open
BGRA output buffer Caller Caller-controlled and reusable
Decoder handle DLL, referenced by caller bpg_decode_close_v1
Error/version strings DLL static storage Do not free or modify

Never use C free(), C++ delete, or another runtime allocator for memory returned by the DLL. Use bpg_free().

Error codes

Value Constant Meaning
0 BPG_OK Success
-1 BPG_ERR_INVALID_PARAM Null pointer, invalid range, stride, alignment, or structure size
-2 BPG_ERR_UNKNOWN_FORMAT Still input signature is unsupported
-3 BPG_ERR_DECODE_FAILED Recognized input could not be decoded
-4 BPG_ERR_ENCODE_FAILED Codec or BPG construction failure
-5 BPG_ERR_OUT_OF_MEMORY Allocation failed
-6 BPG_ERR_BUFFER_TOO_SMALL Declared input/output capacity is insufficient
-7 BPG_ERR_CALLBACK_FAILED Output callback returned nonzero
-8 BPG_ERR_BAD_STATE Invalid lifecycle state, including finishing zero frames
-9 BPG_ERR_UNSUPPORTED Valid but unsupported format/option in this build

bpg_error_string(code) returns a static English diagnostic. Log both the numeric code and text; do not parse the text programmatically.

Version and capabilities

uint32_t packed = bpg_api_version();       /* 0xMMmmpp */
const char *text = bpg_api_version_string();
uint64_t caps = bpg_api_capabilities();

SDK 1.0.0 returns packed version 0x010000. Check the major version before relying on ABI compatibility and use capability bits when features are optional.

The Windows file resource reports file version 1.0.0.0 and product version 1.0.0.

Thread safety

Verified behavior:

  • independent encoder/decoder sessions can run concurrently on separate threads;
  • release tests run four threads, each creating three independent encode/decode sessions;
  • each handle, callback state, and input/output buffer is owned by one thread at a time.

Unsupported behavior:

  • concurrent calls using the same encoder or decoder handle;
  • closing/aborting a handle while another thread is using it;
  • sharing mutable callback state without application synchronization;
  • recursive API calls on the same session from its output callback.

Use one session per worker or externally serialize each handle.

Performance and memory guidance

  • Reuse capture and BGRA decode buffers.
  • Submit contiguous frames directly; the v1 wrapper allocates its row-pointer table once per encoder session.
  • Keep the output callback short. Copy or enqueue bytes and return.
  • Prefer a bounded queue when the final sink can stall.
  • Avoid an extra full-file accumulation buffer for long recordings.
  • compress_level trades CPU time for compression; benchmark representative screen content.
  • 4:2:0 usually reduces output size; 4:4:4 preserves sharp colored text better at higher cost.
  • Encoder sessions retain x265 output until delayed frames are flushed, so peak memory is not strictly constant with recording duration.
  • The DLL performs no file I/O, but x265/libpng/libjpeg allocate internal memory.

Legacy ABI compatibility

The following original names remain exported unchanged:

bpg_convert
bpg_convert_ex
bpg_free
bpg_error_string
bpg_anim_begin
bpg_anim_add_frame
bpg_anim_end
bpg_decode_open
bpg_decode_next_frame
bpg_decode_close

Existing binaries can continue to load these symbols. New code should prefer v1 because it adds:

  • fixed-width ABI fields;
  • size-versioned structures;
  • explicit open errors;
  • total buffer-length checks;
  • contiguous frame input;
  • distinct finish and abort operations;
  • caller-handle nulling;
  • version and capability queries.

The legacy animated-alpha path now also returns BPG_ERR_UNSUPPORTED to prevent the bundled x265 crash.

Building from source

Prerequisites

Install MSYS2, then from an MSYS2 MinGW x64 shell:

pacman -S mingw-w64-x86_64-gcc \
          mingw-w64-x86_64-libpng \
          mingw-w64-x86_64-libjpeg-turbo \
          make cmake

Windows command prompt

build.bat clean
build.bat
build.bat test
build.bat verify

build.bat test is the release gate for native behavior. It runs:

  1. legacy still-image self-tests;
  2. v1 contract tests;
  3. independent-session concurrency stress;
  4. exact export-set comparison against expected_exports_v1.txt.

Direct make targets

make -f Makefile.win
make -f Makefile.win test
make -f Makefile.win verify-exports
make -f Makefile.win clean

Build products:

File Purpose
bpg_api.dll Versioned Windows x64 DLL
libbpg_api.a MinGW/GNU import library
bpg_api.lib MSVC-compatible x64 COFF import library
bpg_api.h Public ABI header

The .def file is the authoritative public export list.

Troubleshooting

Application cannot start: DLL not found (0xC0000135)

Copy all release bin/ DLLs next to the executable. A source-tree build directly imports:

libjpeg-8.dll
libpng16-16.dll
libwinpthread-1.dll

Their transitive non-system imports require:

libgcc_s_seh-1.dll
zlib1.dll

Use dumpbin /dependents bpg_api.dll or objdump -p bpg_api.dll to inspect the exact binary being deployed.

Wrong architecture or 0xC000007B

SDK 1.0.0 is x64 only. The application and every dependency must also be x64.

BPG_ERR_BUFFER_TOO_SMALL

Use the last-row formulas documented above. stride * height is safe but may be larger than required; stride * (height - 1) + row_bytes is exact.

BPG_ERR_CALLBACK_FAILED

The callback returned nonzero. Preserve the original sink error in callback-owned state, then abort the still-live encoder handle if necessary.

BPG_ERR_UNSUPPORTED for RGBA animation

This is expected in SDK 1.0.0. Composite to RGB before submission or replace and qualify the encoder backend.

Decoder opens but a later damaged animation ends early

This is an upstream libbpg limitation: normal EOS and malformed trailing animation data share one return path. Validate transport length/checksums outside the decoder when truncation detection is required.

Output is too large or encoding is too slow

Benchmark qp, compress_level, and chroma mode with representative content. Lower QP and 4:4:4 usually increase size. Higher compression levels usually increase CPU time.

Security notes

  • Treat all image/BPG input as untrusted.
  • Enforce application-level size, duration, and frame-count limits before allocating large buffers.
  • Do not load dependency DLLs from writable or ambiguous search paths.
  • Keep the DLL and dependency set together and verify release checksums/signatures.
  • Run malformed-input tests and dependency inspection for every release.

Licensing and distribution

The project combines components under multiple licenses. The encoder build statically links x265. Community distribution of that combined encoder DLL is intended for the GPL-2.0-or-later path and must satisfy the corresponding source/notice obligations. Organizations that cannot use that path should obtain appropriate commercial x265 licensing and perform their own legal review.

libbpg wrapper/core files, decoder-derived files, libpng, libjpeg-turbo, zlib, MinGW runtimes, and other bundled components have separate notices and conditions. HEVC may also be subject to patent licensing requirements depending on product, use, and jurisdiction.

Read DISTRIBUTION.md, THIRD_PARTY_NOTICES.md, and the packaged licenses/ directory before redistribution. These documents provide engineering guidance, not legal advice.

Further material

  • bpg_api.h: authoritative declarations and constants.
  • examples/: complete C/C++, Rust, Python, and C# integrations.
  • RELEASE_CHECKLIST.md: publication gate.
  • DISTRIBUTION.md: distribution and source-offer guidance.
  • THIRD_PARTY_NOTICES.md: component inventory and notices.

About

libbpg for windows https://bellard.org/bpg/

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages