Small header-only C library to decompress any BC compressed image

Overview

bcdec

Small header-only C library to decompress any BC compressed image inspired by incredible stb libaries (http://nothings.org/stb)

Written by Sergii "iOrange" Kudlai in 2022.

This library provides functions to decompress blocks of BC compressed images.

This library does not allocate memory and is trying to use as less stack as possible.

The library was never optimized specifically for speed but for the overall size.
It has zero external dependencies and is not using any runtime functions.

Supported BC formats:

  • BC1 (also known as DXT1) + it's "binary alpha" variant BC1A (DXT1A)
  • BC2 (also known as DXT3)
  • BC3 (also known as DXT5)
  • BC4 (also known as ATI1N)
  • BC5 (also known as ATI2N)
  • BC6H (HDR format)
  • BC7

BC1/BC2/BC3/BC7 are expected to decompress into 4*4 RGBA blocks 8bit per component (32bit pixel)
BC4/BC5 are expected to decompress into 4*4 R/RG blocks 8bit per component (8bit and 16bit pixel)
BC6H is expected to decompress into 4*4 RGB blocks 32bit float per component (96bit pixel)


You will also find included test program that converts compressed DDS files into TGA/HDR.
It is a good start to learn on how to use the bcdec library.
It comes with some test images in the test_images folder and a batch script test_bcdec.bat to run over them.


Used HDRI image "Lythwood Room" from https://polyhaven.com/a/lythwood_room licensed under CC0 license.

Comments
  • Fix portability of test.c

    Fix portability of test.c

    This test file would only compile in C11 mode on a libc which implements annex K, which is none of the ones I have access to. Thankfully, that was used only for strcpy_s(), which can be replaced with strncpy() with no issue.

    I also made it reflect argv[0] because my bcdec doesn’t have a .exe suffix.

    opened by linkmauve 5
  • Potentially uninitialized local variable used `partition`

    Potentially uninitialized local variable used `partition`

    Hello! Your library is excellent and I wanted to report this warning we got from integrating bcdec into our engine.

    Warning C4701 potentially uninitialized local variable 'partition' https://github.com/iOrange/bcdec/blob/main/bcdec.h#L870

    It seems like there's a very rare case that could happen where partition is uninitialized. I noticed the if-else block above on L829 sets it to 0 but only in the if, not the else. I'm not too knowledgeable on BC formats so I wouldn't know what the proper value to set it here would be, hence me reporting this warning we get in an issue rather than submitting a PR. 😅

    opened by Gocnak 4
  • Mark helper functions static inline

    Mark helper functions static inline

    When built into a shared library, this prevents them from getting their own symbol, duplicating code that would otherwise get inlined into the actual entrypoints.

    The gain is of about 4 KiB when built using gcc 12 on Linux.

    opened by linkmauve 2
  • Source code license terms

    Source code license terms

    I am the team lead for Compressonator Tool, and would like to consider adding your single header decoder code into the repo. In order to do this can your license terms be updated to the same as Compressonator source code which is MIT licensed.?

    opened by NPCompress 2
  • Optimize BC6 by moving endpoint unquant out of pixel loop

    Optimize BC6 by moving endpoint unquant out of pixel loop

    The endpoint unquantize work does not depent on actual pixel index values, so it can be moved outside of the final pixel loop.

    On my machine this makes BC6HU decoding go 82 -> 115 Mpix/s.

    opened by aras-p 1
  • Buffer Overflow for tiny images

    Buffer Overflow for tiny images

    Disclaimer: my C++ experience is limited in comparison to my C# experience.

    Thank you for making this! I ported your code to C#.

    As part of porting your code, I replaced most uses of pointers with Span, which enables automatic bounds checking. I found a bug whilst testing on files with mipmaps. It overruns the output buffer when the decompressed image would be 2x2 or 1x1 pixels.

    Example images which exhibit this issue can be found here. Each file contains an image and its mipmaps. The original is 256x256, and each mip is half the size of the previous image, ie 9 images in total. The 2x2 and 1x1 images each take up one block (8 bytes for BC 1 and 16 bytes for BC 2/3) at the end of the file.

    opened by ds5678 1
  • BC6H can be decoded into either

    BC6H can be decoded into either "float" or "half"

    Previously was always into a "float". Some use cases might need half precision as destination, e.g. decoding a texture on a GPU that can't do BC6H, but can do FP16 just fine. So now it has two functions bcdec_bc6h_float and bcdec_bc6h_half.

    Curiously enough, even when using the "float", the new code is a bit faster in my tests -- it first decodes the block into half's, and then converts all of them into full floats. My guess is that the previous code was either harder on the branch predictor or on the code cache due to many expanded inlines -- the new one has all the half->float conversions in one place, outside of all the BC6H decoding logic.

    On my Apple M1 Max, decoding BC6H unsigned into floats goes from ~79 Mpix/s up to ~85 Mpix/s.

    opened by aras-p 1
  • Optimize the decoders a bit

    Optimize the decoders a bit

    The actual changes are fairly simple, and most of them are like "instead of doing work at byte level, do it at integer level".

    In my tests, on windows (vs2022, ryzen 5950x):

    • BC1 821->1327 Mpix/s
    • BC3 516->694
    • BC6H 65->85
    • BC7 91->143

    On mac (clang 13, M1 Max):

    • BC1 804->2037
    • BC3 585->1062
    • BC6H 63->76
    • BC7 113->212

    With the speed bump, this makes it one of the fastest BCn decoders out there, actually (with some exceptions in some formats). I plan to write about this more somewhere, but here's a sneak peek (higher numbers are better; bcdec is upstream repo, bcdec_opt is with this PR) Clipboard01

    opened by aras-p 1
  • Version define

    Version define

    Hi iOrange. I'm thinking of using bcdec over at https://github.com/bluescan/tacentview. Would it be possible to put the version number at the top of the header as a define after the include guards... maybe same for etcdec too?

    opened by bluescan 2
Owner
null
The CImg Library is a small and open-source C++ toolkit for image processing

http://cimg.eu The CImg Library is a small and open-source C++ toolkit for image processing, designed with these properties in mind: CImg defines clas

David Tschumperlé 1.2k Jan 3, 2023
PoC black/white image sequence to dumpy gif image sequence converter

PoC black/white image sequence to dumpy gif image sequence converter

null 69 Dec 9, 2022
The “Quite OK Image” format for fast, lossless image compression

The “Quite OK Image” format for fast, lossless image compression

Dominic Szablewski 6k Dec 30, 2022
This library provides a cross-platform image loading library in C11 for projects based on our foundation library

Image Library - Public Domain This library provides a cross-platform image loading library in C11 for projects based on our foundation library.

Mattias Jansson 1 Jan 29, 2022
A header-only C++11 library for colors; color space converters for RGB, HSL, XYZ, Lab, etc. and perceptual color difference calculators such as CIEDE2000

color-util A header-only C++11 library for handling colors, including color space converters between RGB, XYZ, Lab, etc. and color difference calculat

Yuki Koyama 79 Oct 6, 2022
NanoPM, single header only PatchMatch

NanoPM, single header only PatchMatch NanoPM is a single header-only implementation of PatchMatch algorithm written in C++. Could be used for variety

null 67 Sep 27, 2022
A slim, fast and header-only GIF loader written in C

gif_load This is an ANSI C compatible animated GIF loader in a single header file of less than 300 lines of code (less than 200 without empty lines an

Andrey Guskov 68 Dec 10, 2022
A fast image processing library with low memory needs.

libvips : an image processing library Introduction libvips is a demand-driven, horizontally threaded image processing library. Compared to similar lib

libvips 26 Nov 10, 2022
C++ image processing and machine learning library with using of SIMD: SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX-512, VMX(Altivec) and VSX(Power7), NEON for ARM.

Introduction The Simd Library is a free open source image processing and machine learning library, designed for C and C++ programmers. It provides man

Ihar Yermalayeu 1.7k Jan 5, 2023
Video++, a C++14 high performance video and image processing library.

Video++ Video++ is a video and image processing library taking advantage of the C++14 standard to ease the writing of fast video and image processing

Matthieu Garrigues 692 Dec 28, 2022
a generic C++ library for image analysis

VIGRA Computer Vision Library Copyright 1998-2013 by Ullrich Koethe This file is part of the VIGRA computer vision library. You may use,

Ullrich Koethe 378 Dec 30, 2022
Intel® Open Image Denoise library

Intel Open Image Denoise is an open source library of high-performance, high-quality denoising filters for images rendered with ray tracing

Intel® Open Image Denoise 1.3k Dec 28, 2022
Arduino PNG image decoder library

An 'embedded-friendly' (aka Arduino) PNG image decoding library

Larry Bank 102 Jan 6, 2023
libvot - A C++11 multi-thread library for image retrieval

libvot is a fast implementation of vocabulary tree, which is an algorithm widely used in image retrieval and computer vision. It usually comprises three components to build a image retrieval system using vocabulary tree: build a k-means tree using sift descriptors from images, register images into the database, query images against the database. I

Tianwei Shen 174 Dec 22, 2022
ppl.cv is a high-performance image processing library of openPPL supporting x86 and cuda platforms.

ppl.cv is a high-performance image processing library of openPPL supporting x86 and cuda platforms.

null 366 Dec 30, 2022
An 'embedded-friendly' (aka Arduino) JPEG image encoding library

Starting in the late 80's I wrote my own imaging codecs for the existing standards (CCITT G3/G4 was the first). I soon added GIF, JPEG and not long after that, the PNG specification was ratified. All of this code was "clean room" - written just from the specification. I used my imaging library in many projects and products over the years and recently decided that some of my codecs could get a new lease on life as open source, embedded-friendly libraries for microcontrollers.

Larry Bank 38 Dec 30, 2022
A simple API wrapper that generates images & facts of any animal

animality.h A simple API wrapper that generates images & facts of any animal Required dependencies: libcurl for sending HTTPS requests. pthreads for t

animality 5 Nov 10, 2022
GLSL Image Processing System

GIPS: The GLSL Image Processing System An image processing application that applies filters written in the OpenGL Shading Language (GLSL). This means

Martin Fiedler 57 Nov 29, 2022
Video, Image and GIF upscale/enlarge(Super-Resolution) and Video frame interpolation. Achieved with Waifu2x, SRMD, RealSR, Anime4K, RIFE, CAIN, DAIN and ACNet.

Video, Image and GIF upscale/enlarge(Super-Resolution) and Video frame interpolation. Achieved with Waifu2x, SRMD, RealSR, Anime4K, RIFE, CAIN, DAIN and ACNet.

Aaron Feng 8.7k Jan 7, 2023