1
0
Fork 0
stb libraries I use
  • C 62.2%
  • C++ 37.7%
Find a file
2026-02-10 13:49:22 -06:00
c Reorganize C++ implementations into subfolders 2026-02-09 21:55:04 -06:00
easyfont Reorganize C++ implementations into subfolders 2026-02-09 21:55:04 -06:00
img Reorganize C++ implementations into subfolders 2026-02-09 21:55:04 -06:00
rectpacker Benchmark, test, ensure 0 warning/error output from compilers 2026-02-10 13:49:22 -06:00
scripts Reorganize C++ implementations into subfolders 2026-02-09 21:55:04 -06:00
truetype Benchmark, test, ensure 0 warning/error output from compilers 2026-02-10 13:49:22 -06:00
.gitignore Implement rectpacker and truetype benchmarks 2026-02-10 10:16:05 -06:00
README.md Promote modern API as primary interface for sel::img 2026-02-09 12:40:39 -06:00
STYLE.md scaffold truetype.hpp 2025-10-29 11:12:21 -05:00

STB Libraries

Just the stb header files I use in my projects. They're copied in their entirety, copyright notices included. The GitHub repo for them is here.

The c files are in c/, but cpp/ contains refactored versions for C++17 and beyond. These include the author name and date but all are assumed to be MIT/Public Domain by default.

C++

The C++ conversions are as faithful API-wise as is possible. However, I am making internal changes to improve these libraries to fit more use cases and be as efficient as can be. They retain their original spirit and the credit goes entirely to Sean Barrett for their creation.

Benchmarking

A comprehensive benchmark system is available in bench/ to compare SEL C++ decoders against the original STB C library. The system measures:

  • Execution speed: High-precision timing with statistical analysis
  • Memory usage: Peak memory, allocations (requires hooks)
  • Correctness: Pixel-perfect verification

Quick Start

# Build and run quick benchmark
g++ -std=c++17 -O2 -I. bench/benchmark_runner.cpp -o bench/benchmark_runner.exe
./bench/benchmark_runner.exe --quick

# Single image with detailed output
./bench/benchmark_runner.exe --image tests/images/jpeg.jpg --verbose

Results

Initial benchmarks show SEL C++ decoders are 3-12% faster than STB with 100% pixel-perfect correctness:

  • JPEG: 1.06x-1.12x faster
  • PNG: 1.03x-1.09x faster

See bench_data/results/INITIAL_RESULTS.md for detailed analysis and bench/README.md for full documentation.

Image Processing

The image processing library takes from stb_image.h directly. It uses all the same techniques and technical implementations, just converted to C++17 and namespaced; this way we have opt-in formats rather than opt-out. This also splits helpers and image formats, which can help with compilation speed. The image library is under the sel::img namespace.

img::util

The util namespace contains helper functions that are shared among the image processing formats. Context management, memory management, byte utilities, error handling, etc. The util.hpp file is a prerequisite for including any of the image formats.

img::bmp

The bmp namespace provides functions for handling bitmap images; this is primarily bit manipulation and mask handling.

img::tga

The tga namespace is for TGA format images. For the most part this is just RLE decoding and 16-bit RGB conversion.

img::hdr

The hdr namespace handles Radiance RGBE HDR format images. This format stores high dynamic range data using a compact 32-bit-per-pixel encoding with shared exponent.

img::jpeg

The jpeg namespace provides JPEG decoding with progressive support, IDCT optimizations, and SSE2 acceleration. Supports baseline and progressive JPEG with 12-bit Huffman lookup tables for improved performance.

img::png

The png namespace handles PNG format with support for all bit depths, color types, interlacing, and filtering methods. Uses optimized Huffman decoding with 12-bit lookup tables and SSE2 for defiltering.

img::gif

The gif namespace decodes GIF images with support for transparency and interlacing. Note: animation support is limited to first frame by default.

img::pic

The pic namespace handles Softimage PIC format, a format primarily used in 3D graphics applications.

img::psd

The psd namespace provides Adobe Photoshop PSD file decoding with support for basic layer compositing and various color modes.

img::pnm

The pnm namespace handles the Portable aNyMap family of formats (PBM, PGM, PPM) in both ASCII and binary variants.

The img/image.hpp header provides a modern C++ interface with RAII, std::optional, and type safety:

#include "img/image.hpp"

// Load image - returns std::optional<image> with RAII
std::vector<uint8_t> file_data = read_file("image.png");
if (auto img = sel::img::load(file_data)) {
    printf("Loaded %dx%d image\n", img->width(), img->height());
    // Memory automatically freed when img goes out of scope
}

// Load with specific channel count using type-safe enum
if (auto img = sel::img::load(file_data, sel::img::channels::rgba)) {
    // Always 4 channels
    auto pixel = img->at(x, y);  // Access pixel at (x, y)
}

// Query info without decoding
if (auto info = sel::img::info(file_data)) {
    printf("Image is %dx%d\n", info->width, info->height);
}

Legacy C-Style API

For performance-critical code or backward compatibility, use img/legacy.hpp:

#include "img/legacy.hpp"

int width, height, channels;
void* pixels = sel::img::legacy::load_from_memory(buffer, buffer_size,
                                                   &width, &height, &channels, 4);
// Use pixels...
sel::img::legacy::image_free(pixels);

Format detection follows stb_image.h order: formats with magic bytes first, TGA last as fallback.

Supported Image Formats

Format Extension Features
JPEG .jpg, .jpeg Baseline, progressive, 12-bit Huffman, SSE2
PNG .png All bit depths, interlacing, 12-bit Huffman, SSE2
BMP .bmp Uncompressed, RLE
TGA .tga Uncompressed, RLE, colormapped
GIF .gif Transparency, interlacing (first frame)
PSD .psd Basic layer compositing
HDR .hdr, .rgbe Radiance RGBE format
PIC .pic Softimage PIC
PNM .ppm, .pgm, .pbm ASCII and binary variants

Building

Compile Check

g++ -std=c++17 -fsyntax-only img/image.hpp -I.

Example Test Program

# Visual comparison test
g++ -std=c++17 -O2 tests/test_image.cpp -I. -lopengl32 -lgdi32 -o tests/test_image.exe

# Performance benchmarks
g++ -std=c++17 -O2 -static tests/test_optimizations.cpp -I. -o test.exe

Usage in Your Project

Simply include the headers you need:

// Modern API (recommended) - RAII, std::optional, type-safe
#include "img/image.hpp"

if (auto img = sel::img::load(data)) {
    // Use img->data(), img->width(), img->height(), etc.
    // Memory automatically freed on scope exit
}

// Legacy C-style API - for backward compatibility or max control
#include "img/legacy.hpp"

int w, h, c;
void* pixels = sel::img::legacy::load_from_memory(buf, size, &w, &h, &c, 4);
sel::img::legacy::image_free(pixels);

Performance Optimizations

The SEL C++ decoders include several optimizations over the original STB:

  • 12-bit Huffman lookup tables: Faster symbol decoding in JPEG and PNG
  • SSE2 SIMD: Block zeroing and defiltering operations
  • Arithmetic right shift: Efficient sign-extension without bit manipulation
  • Branch hints: [[likely]]/[[unlikely]] annotations on hot paths

Current benchmarks show 3-12% speed improvement with 100% pixel-perfect output matching STB.

Other Libraries

TrueType Font Rendering

Font rasterization library in truetype.hpp - refactored to modern C++ with OOP design. Handles TrueType and OpenType font parsing, glyph rasterization, and text layout.

Verification Status: PRODUCTION READY - The C++ implementation produces output matching or exceeding the C reference quality.

Byte-for-Byte Tests (tests/test_truetype_verification.cpp):

  • Font loading and metrics (100% byte-perfect)
  • Shape extraction (100% byte-perfect)
  • SDF generation (100% byte-perfect) - All 3248 pixels match exactly
  • Bitmap rasterization (100% byte-perfect)
  • Subpixel rendering (100% byte-perfect)
  • ✗ Texture baking (minor pixel differences in atlas packing)

Visual Comparison Tests (tests/test_truetype_visual.cpp):

  • Character rendering at all sizes (16-64px) - pixel-perfect
  • SDF generation - pixel-perfect with smooth, artifact-free edges
  • Subpixel rendering - pixel-perfect
  • Texture atlas baking - visually identical (different packing algorithm)

Conclusion: The implementation is byte-for-byte identical for all core rendering operations (bitmap, SDF, subpixel). Texture baking uses a different packing algorithm but produces visually equivalent results. Approved for production use.

See tests/TRUETYPE_VERIFICATION_RESULTS.md and tests/TRUETYPE_VISUAL_RESULTS.md for detailed analysis.

Rectangle Packing

Rectangle packing utilities in rectpacker.hpp for texture atlas generation and other 2D bin packing tasks.