⛵ The missing small and fast image decoding library for humans (not for machines).

Squirrel Abstract Image Library

The missing fast and easy-to-use image decoding library for humans (not for machines).

Travis Build Status Language grade: C/C++ Coverity Scan Build Status Latest release

Target AudienceFeaturesImage FormatsGetting StartedExamplesFAQ

SAIL is a format-agnostic cross-platform image decoding library providing rich APIs, from one-liners to complex use cases with custom I/O sources. It enables a client to read and write static, animated, multi-paged images along with their meta data and ICC profiles.

GIF Demo Screenshot

Target audience

  • Image viewers
  • Game developers
  • Anyone who needs to load or save images in different image formats and who needs a clean and comprehensive API for that

Features overview

  • Easy-to-use thread-safe C and C++ interfaces
  • Versatile APIs: junior, advanced, deep diver, and technical diver
  • Input/output: files, memory, custom I/O streams
  • Load by file suffixes, paths, and magic numbers
  • Output pixels as close as possible to the source
  • Meta data support: text comments, EXIF, ICC profiles
  • Access to the image properties w/o decoding pixels (probing)
  • Access to the source image properties
  • Adding or updating image codecs with ease demonstrated by Intel [*]
  • The best MIME icons in the computer industry 😄

* One day Intel demonstrated the advantages of their IPP technology in speeding up decoding JPEG and JPEG2000 images with the help of ksquirrel-libs, the predecessor of SAIL.

Features NOT provided

  • Image editing capabilities (filtering, distortion, scaling, etc.)
  • Color space conversion functions
  • Color management functions (applying ICC profiles etc.)
  • EXIF rotation

Supported image formats

N Image format Operations Dependencies
1 APNG R libpng+APNG patch
2 AVIF R libavif
3 BMP R
4 GIF R giflib
5 JPEG RW libjpeg-turbo
6 JPEG2000 R jasper
7 PNG RW libpng
8 SVG R resvg
9 TGA R
10 TIFF RW libtiff
.. ...
12 WEBP R libwebp

See the full list here. Work to add more image formats is ongoing.

Benchmarks

Benchmark

Time to load and output default pixels (without explicit conversion) was measured. See BENCHMARKS.

Preferred installation method

  • Windows: vcpkg
  • macOS: brew
  • Linux: native packages if available or vcpkg

See BUILDING.

APIs overview

SAIL provides four levels of APIs, depending on your needs. Let's have a quick look at the junior level.

C:

struct sail_image *image;

SAIL_TRY(sail_read_file(path, &image));

/*
 * Handle the image pixels here.
 * Use image->width, image->height, image->bytes_per_line,
 * image->pixel_format, and image->pixels for that.
 *
 * In particular, you can convert it to a different pixel format with functions
 * from libsail-manip. With sail_convert_image(), for example.
 */

sail_destroy_image(image);

C++:

sail::image image(path);

// Handle the image and its pixels here.
// Use image.width(), image.height(), image.bytes_per_line(),
// image.pixel_format(), and image.pixels() for that.
//
// In particular, you can convert it to a different pixel format with image::convert().

It's pretty easy, isn't it? 😄 See EXAMPLES and FAQ for more.

Programming languages

Programming language: C11
Bindings: C++17

Competitors

Differences from other image decoding libraries

  • Easily extensible with new image format plugins
  • Easy-to-use API providing expected business entities - images, palettes, pixels etc.
  • Access to source pixel data (supported by the most codecs)
  • Access to the image properties w/o decoding pixel data (probing)

Development status

SAIL is ready for every day use. However, it's still under heavy development. The API can be changed at any time breaking binary and source compatibility. Consider opening a GitHub issue if you have any feature requests or issue reports. Your help (pull requests etc.) is highly welcomed.

Have questions or issues?

Opening a GitHub issue is the preferred way of communicating and solving problems.

See FAQ for more.

Architecture overview

SAIL is written in pure C11 w/o using any third-party libraries (except for codecs). It also provides bindings to C++.

SAIL codecs

SAIL codecs is the deepest level. This is a set of standalone, dynamically loaded codecs (SO on Linux and DLL on Windows). They implement actual decoding and encoding capabilities. End-users never work with codecs directly. They always use abstract, high-level APIs in libsail for that.

Every codec is accompanied with a so called codec info (description) file which is just a plain text file. It describes what the codec can actually do: what pixel formats it can read and output, what compression types it supports, and more.

By default, SAIL loads codecs on demand. To preload them, use sail_init_with_flags(SAIL_FLAG_PRELOAD_CODECS).

libsail-common

libsail-common holds common data types (images, pixel formats, I/O abstractions etc.) and a small set of functions shared between SAIL codecs and the high-level APIs in libsail.

libsail

libsail is a feature-rich, high-level API. It provides comprehensive and lightweight interfaces to decode and encode images. End-users implementing C applications always work with libsail.

libsail-manip

libsail-manip is a collection of image manipulation functions. For example, conversion functions from one pixel format to another.

libsail-c++

libsail-c++ is a C++ binding to libsail. End-users implementing C++ applications may choose between libsail and libsail-c++. Using libsail-c++ is always recommended, as it's much more simple to use in C++ applications.

Building

See BUILDING.

Philosophy

Philosophy of SAIL is modularization and simplicity.

Image codecs are architectured to be standalone dynamically loaded files. Any future hypothetical improvements will be implemented as separate client libraries. So a user is always able to choose what to use (i.e. to link against) and what not to use.

Support

If you like the project, please consider starring the repository.

Author

Dmitry Baryshev

License

Released under the MIT license.

Copyright (c) 2020 Dmitry Baryshev

The MIT License

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Comments
  • Fix cmake object libraries in static build

    Fix cmake object libraries in static build

    Hi again,

    SAIL's static build was sadly broken for me since commit ce0e3d2824936013083fdc8219a1f3916cc3ebbc. SAIL could still be built statically but the sail-codecs-objects archive produced by the build didn't contain the private bmp-common library that's shared by the BMP and ICO codecs. That meant linking with SAIL failed because the symbols from bmp-common were missing.

    I've tried to fix this by making common libraries like bmp-common build as object libraries as well, just like the codecs themselves. This fixes the static build for me.

    I'm not sure if I broke other things in the process though so I'd be quite happy if you could review my changes when you have time!

  • Bug: Copying a default-constructed sail::palette raises SAIL_ERROR_UNSUPPORTED_PIXEL_FORMAT

    Bug: Copying a default-constructed sail::palette raises SAIL_ERROR_UNSUPPORTED_PIXEL_FORMAT

    Hi,

    I've found a bug in the following function:

    // palette-c++.cpp
    palette& palette::with_data(SailPixelFormat pixel_format, const arbitrary_data &data)
    {
        unsigned bits_per_pixel;
        SAIL_TRY_OR_SUPPRESS(sail_bits_per_pixel(pixel_format, &bits_per_pixel));
    
        const unsigned bytes_per_pixel = (bits_per_pixel + 7) / 8;
    
        return with_data(pixel_format, data.data(), static_cast<unsigned>(data.size() / bytes_per_pixel));
    }
    

    It attempts to get the bits per pixel for the given pixel format; however, an empty palette has SAIL_PIXEL_FORMAT_UNKNOWN. This causes sail_bits_per_pixel to raise an error. Additionally, bits_per_pixel doesn't get initialized, causing undefined behavior (I encountered a SIGFPE crash when the uninitialized variable happened to be zero). Given that the result of this operation isn't used anyway in case of an unknown format, I'd suggest to simply wrap the entire thing in an if condition.

    Here's a fixed version of the function:

    palette& palette::with_data(SailPixelFormat pixel_format, const arbitrary_data &data)
    {
        unsigned color_count = 0;
        
        if (pixel_format != SAIL_PIXEL_FORMAT_UNKNOWN) {
            unsigned bits_per_pixel = 0;
            
            SAIL_TRY_OR_SUPPRESS(sail_bits_per_pixel(pixel_format, &bits_per_pixel));
            
            const unsigned bytes_per_pixel = (bits_per_pixel + 7) / 8;
            color_count = static_cast<unsigned>(data.size() / bytes_per_pixel);
        }
        
        return with_data(pixel_format, data.data(), color_count);
    }
    

    It might also be a good idea to check the other uses of SAIL_TRY_OR_SUPPRESS for similar bugs (especially regarding undefined behavior stemming from uninitialized result variables). I can grep over the code tomorrow if you like, just let me know.

    Thanks a lot! Jonathan

  • vcpkg include directories incorrect

    vcpkg include directories incorrect

    It seems that when installing using vcpkg, the headers expect that the include root is in the sail directory, but vcpkg places the includes under sail. To include something in your own project, you need

    #include <sail/sail-c++/sail-c++.h>
    

    but the sail headers includes other sail headers as

    #include <sail-c++/...>
    

    Am I missing something here? Was this project updated since it was set up for vcpkg that caused this?

  • png codec doesn't support non indexed grayscale

    png codec doesn't support non indexed grayscale

    basically if I just check formats with sail::codec_info::from_extension("png").write_features().output_pixel_formats() it just gives me this list: 13,14,15,16,31,32,33,34,47,48,49,50,55,56,57,58

    I've tried to write png image from grayscale buffer but didn't actually find an obvious way to do that (apart from converting it to rgb which I'd like to avoid)

    is that intended? or it's something with my build (I just installed it from vcpkg)

  • Lua style custom allocators

    Lua style custom allocators

    Tried a search for alloc but that brought up a lot of junk results that didn't match what I was looking for, when lua is first initialised in C it provides the option of setting a custom allocator and user data where the allocator is of the form void * Alloc( void *ud, void *ptr, size_t size, size_t want ) where ud is ignored by the default allocator and only used by a user supplied allocator, this is helpful when multi-threading as I can pass the threads object to the ud parameter which can then communicate the desire for memory to the main thread which handles the allocations instead, avoiding potential collisions when 2 or more threads try to re-allocate memory as they can just all have the same pointer & size reported to them after each re-allocation request is processed, also makes garbage collection easier.

    Does SAIL have something similar? If not I'll have to write my own custom image loading functions, I'd prefer to not do that though as I'm trying to keep my graphic studies to just the graphics and not the formats (only recently learned how to use index buffers and am now trying to learn how to use textures).

  • Copying of library contents with GCC's --whole-archive doesn't work, breaks non-shared build

    Copying of library contents with GCC's --whole-archive doesn't work, breaks non-shared build

    Hi again,

    the static build woes on Linux aren't quite over yet, sadly... :cry:

    I just switched to using BUILD_SHARED_LIBS=OFF when I noticed that my build was still using the old (no longer functional) SAIL_STATIC=ON flag. As soon as I did that, my project broke with the following linker errors:

    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x8): undefined reference to `sail_codec_read_seek_next_frame_v6_bmp'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x10): undefined reference to `sail_codec_read_frame_v6_bmp'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x18): undefined reference to `sail_codec_read_finish_v6_bmp'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x20): undefined reference to `sail_codec_write_init_v6_bmp'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x28): undefined reference to `sail_codec_write_seek_next_frame_v6_bmp'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x30): undefined reference to `sail_codec_write_frame_v6_bmp'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x38): undefined reference to `sail_codec_write_finish_v6_bmp'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x40): undefined reference to `sail_codec_read_init_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x48): undefined reference to `sail_codec_read_seek_next_frame_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x50): undefined reference to `sail_codec_read_frame_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x58): undefined reference to `sail_codec_read_finish_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x60): undefined reference to `sail_codec_write_init_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x68): undefined reference to `sail_codec_write_seek_next_frame_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x70): undefined reference to `sail_codec_write_frame_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x78): undefined reference to `sail_codec_write_finish_v6_jpeg'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x80): undefined reference to `sail_codec_read_init_v6_png'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x88): undefined reference to `sail_codec_read_seek_next_frame_v6_png'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x90): undefined reference to `sail_codec_read_frame_v6_png'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0x98): undefined reference to `sail_codec_read_finish_v6_png'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0xa0): undefined reference to `sail_codec_write_init_v6_png'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0xa8): undefined reference to `sail_codec_write_seek_next_frame_v6_png'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0xb0): undefined reference to `sail_codec_write_frame_v6_png'
    /usr/bin/ld: /home/jonathan/CLionProjects/vlktest/cmake-build-optimizeddebug/thirdparty/sail/install/lib/libsail-codecs.a(enabled_codecs.c.o):(.data.rel.ro+0xb8): undefined reference to `sail_codec_write_finish_v6_png'
    

    I then tried to do another clean build of SAIL with the following CMake command-line: cmake -DBUILD_SHARED_LIBS=OFF -DSAIL_THIRD_PARTY_CODECS_PATH=OFF -DSAIL_ONLY_CODECS="png;jpeg;bmp" ..

    The build of SAIL itself worked; however, the libsail-codecs.a archive doesn't contain any of the codecs' symbols, it just references them:

    [email protected]:~/bigdisk/sail-repo/sail/build/src/sail-codecs-archive$ nm -g libsail-codecs.a 
    
    enabled_codecs.c.o:
                     U sail_codec_read_finish_v6_bmp
                     U sail_codec_read_finish_v6_jpeg
                     U sail_codec_read_finish_v6_png
                     U sail_codec_read_frame_v6_bmp
                     U sail_codec_read_frame_v6_jpeg
                     U sail_codec_read_frame_v6_png
                     U sail_codec_read_init_v6_bmp
                     U sail_codec_read_init_v6_jpeg
                     U sail_codec_read_init_v6_png
                     U sail_codec_read_seek_next_frame_v6_bmp
                     U sail_codec_read_seek_next_frame_v6_jpeg
                     U sail_codec_read_seek_next_frame_v6_png
                     U sail_codec_write_finish_v6_bmp
                     U sail_codec_write_finish_v6_jpeg
                     U sail_codec_write_finish_v6_png
                     U sail_codec_write_frame_v6_bmp
                     U sail_codec_write_frame_v6_jpeg
                     U sail_codec_write_frame_v6_png
                     U sail_codec_write_init_v6_bmp
                     U sail_codec_write_init_v6_jpeg
                     U sail_codec_write_init_v6_png
                     U sail_codec_write_seek_next_frame_v6_bmp
                     U sail_codec_write_seek_next_frame_v6_jpeg
                     U sail_codec_write_seek_next_frame_v6_png
    0000000000000000 D sail_enabled_codecs
    0000000000000020 D sail_enabled_codecs_info
    0000000000000000 D sail_enabled_codecs_layouts
    

    On the other hand, libsail-codecs-objects.a does contain the codecs' symbols.

    Apparently, the GNU linker's --whole-archive option only adds dependencies on all public symbols of the libraries that are being linked against, it does not copy them into the new archive. (It only does the copying when building an executable or shared object, not when building an archive.)

    On the other hand, if I build with BUILD_SHARED_LIBS=ON, the libsail-codecs.a that is produced does contain all the required symbols and works fine with static linking.

    As far as I can tell, it should be possible to just remove the library copying step and always build the combined archive like in the shared library case (by compiling everything directly into sail-codecs). There should be no reason to build the static library in two different ways depending on whether the shared library is built as well or not.

    I did this change on my fork of the repo and it works just fine on Linux (and fixes the problem): https://github.com/JoniSt/sail/tree/remove-library-copying

    Do you think this would break anything? (Or is it intentional that sail-codecs doesn't contain the codecs themselves in a non-shared build? Should I instead link against sail-codecs-objects?)

    Jonathan

  • Notify user code about contexts created in the background

    Notify user code about contexts created in the background

    I'm currently using SAIL in a heavily multithreaded project where I don't know exactly what threads my code (and therefore SAIL) is potentially running on. This means that SAIL will often create new thread-local contexts in the background that my code isn't aware of (and therefore can't clean up with sail_finish).

    I'd really appreciate it if you could add a feature that allows user code to get notified of new contexts created by SAIL. Here's a patch that implements this functionality with a user-settable callback function which gets called by init_context just before context initialization. That way, the user can manipulate the flags of the context and keep track of it so it can be properly cleaned up when it's not needed anymore (i.e. when the thread exits).

    Thanks!

  • No rule to make target '/lib/libavif.a'

    No rule to make target '/lib/libavif.a'

    Hi,

    I'm trying to use sail + vcpkg + cmake + Ubuntu 20.10 in my application. When I try to build the project I can see this error:

    gmake[2]: *** No rule to make target '/lib/libavif.a', needed by

    and this file is not in the /lib folder. Not sure why it is being searched in this location because this file is in the /build/vcpkg_installed/x64-linux/lib folder.

    When I manually edit this path in "build.make" and "link.txt" I see errors:

    error.txt

    I also tried to add this to my cmake file: set(SAIL_EXCEPT_CODECS "av1;avif" CACHE STRING "Disable the codecs specified in this ';'-separated list.
    A codec specified in this setting remains disabled even if it's also specified in SAIL_ONLY_CODECS.") but it did nothing.

  • SAIL_ERROR_CODEC_NOT_FOUND when installing via vckpkg on windows

    SAIL_ERROR_CODEC_NOT_FOUND when installing via vckpkg on windows

    config.h shows that the codecs should be stored in path "...\vcpkg\packages\sail_x64-windows-static\lib\sail\codecs" However no such folder or file named sail\codecs exists in path "...\vcpkg\packages\sail_x64-windows-static\lib\"

    I am just trying to read a jpg or png file, but I keep getting the codec not found error. I have only tried x64-windows-static and x64-windows versions however.

  • CMake build error

    CMake build error

    Hi. I'm want to build SAIL on Arch Linux, but I get this error:

       CMake Error at examples/c/sail-sdl-viewer/CMakeLists.txt:30 (string):
       string sub-command STRIP requires two arguments.
    

    all dependencies are installed

  • Call to image.with_shallow_pixels will free pixels used in previous call to with_shallow_pixels

    Call to image.with_shallow_pixels will free pixels used in previous call to with_shallow_pixels

    The notes in image-c++.h indicate that, with this function, shallow data is not deleted upon image destruction.

    It's a natural assumption that this would include reuse of the image object.

    (SHA 6250cceea79b7e7218224cb30ffc04ea7c9e4cd9)

  • Sail fails to decode some APNGs

    Sail fails to decode some APNGs

    Sail fails to decode Animated PNG files which use a Color Type other than 6 and APNG_BLEND_OP_OVER. This is because png_private_blend_over only supports RGBA, and doesn't check the tRNS chunk. Even if the PNG doesn't have any transparency information, blend_source should be used instead (equivalent to blend_over assuming all pixels are opaque).

    Examples from https://philip.html5.org/tests/apng/tests.html: 8-bit greyscale and alpha, with blending 1-bit palette and alpha, with blending

    const char* filename = "038.png";
    sail_image* image = NULL;
    const sail_codec_info* codec_info = NULL;
    void* state = NULL;
    sail_codec_info_from_extension("png", &codec_info); // SAIL_OK
    sail_start_loading_from_file(filename, codec_info, &state); // SAIL_OK
    sail_load_next_frame(state, &image); // SAIL_OK
    sail_load_next_frame(state, &image); // SAIL_ERROR_UNSUPPORTED_BIT_DEPTH
    

    And here's a 16-bit grayscale+alpha APNG that will incorrectly be blended as if it's 8-bit RGBA: grayanim16

  • Inspect libjxl for JPEG XL plugin

    Inspect libjxl for JPEG XL plugin

    Many (most?) distros link libaom against libjxl for butteraugli tuning, and libavif is typically linked against libaom. This means that libjxl is likely already available when building sail.

  • Implement more tests

    Implement more tests

    Ideas:

    • check all codecs have the same layout version
    • check all codecs could be loaded
    • decode/encode with reference data
    • all codecs have RGB and RGBA output
    • mem and file I/O sources output the same data
A demonstration of various different techniques for implementing 'threaded code,' a technique used in Forth and in virtual machines like the JVM.

Threaded code is a technique used in the implementation of virtual machines (VMs). It avoids the overhead of calling subroutines repeatedly by 'thread

Nov 4, 2022
Text utilities, including beam search decoding, tokenizing, and more, built for use in Flashlight.

Flashlight Text: Fast, Lightweight Utilities for Text Quickstart | Installation | Python Documentation | Citing Flashlight Text is a fast, minimal lib

Dec 15, 2022
PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions.
PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions.

PetitPotam PoC tool to coerce Windows hosts to authenticate to other machines via MS-EFSRPC EfsRpcOpenFileRaw or other functions :) The tools use the

Jan 4, 2023
rdtsc x86 instruction to detect virtual machines
rdtsc x86 instruction to detect virtual machines

rdtsc_detector rdtsc x86 instruction to detect virtual machines What is rdtsc? The Time Stamp Counter (TSC) is a 64-bit register present on all x86 pr

Apr 29, 2022
A guide that teach you build a custom version of Chrome / Electron on macOS / Windows / Linux that supports hardware / software HEVC decoding.

enable-chromium-hevc-hardware-decoding A guide that teach you build a custom version of Chrome / Electron on macOS / Windows / Linux that supports har

Jan 1, 2023
C++11 header-only library that offers small vector, small flat map/set/multimap/multiset.

sfl library This is header-only C++11 library that offers several new containers: small_vector small_flat_set small_flat_map small_flat_multiset small

Dec 14, 2022
Second life for famous JPEGView - fast and tiny viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF and TIFF images with a minimalist GUI and base image processing.
Second life for famous JPEGView - fast and tiny viewer/editor for JPEG, BMP, PNG, WEBP, TGA, GIF and TIFF images with a minimalist GUI and base image processing.

JPEGView-Image-Viewer-and-Editor Updated Dec 07 2021. Version 1.1.1.0 has been released. Download link1, link2 added. Second life for famous JPEGView

Dec 27, 2022
A fast and small port of Zstandard to WASM.

Zstandard WASM A fast and small port of Zstandard to WASM. (Decompress-only for now). Features Fast: Zstandard has been compiled with the -03 flag, so

Nov 9, 2022
dwm is an extremely fast, small, and dynamic window manager for X.

dwm - dynamic window manager dwm is an extremely fast, small, and dynamic window manager for X. My Patches This is in the order that I patched everyth

Dec 23, 2022
A small and fast programming language.
A small and fast programming language.

Pocketlang is a small (~3000 semicolons) and fast functional language written in C. It's syntactically similar to Ruby and it can be learned within 15

Dec 28, 2022
ArkScript is a small, fast, functional and scripting language for C++ projects
ArkScript is a small, fast, functional and scripting language for C++ projects

ArkScript Documentation Discord server: invite link, to discuss the specification of the language and receive help Modules Nota bene: the project is r

Jan 1, 2023
A family of small, fast, and simple bitmap fonts in single-file C headers
A family of small, fast, and simple bitmap fonts in single-file C headers

Blit A family of small, fast, and simple bitmap fonts in single-file C headers [go to repository] These are not intended as a replacement for fancy us

Dec 22, 2022
TinyGL: a Small, Free and Fast Subset of OpenGL
TinyGL: a Small, Free and Fast Subset of OpenGL

TinyGL A major overhaul of Fabrice Bellard's TinyGL to be more useful as a software rasterizer. Now with limited multithreading support Tightly tweake

Dec 30, 2022
A small, fast, vectorizeable libm

jodiemath a small, fast, vectorizeable libm goals: all functions have absolute or relative error ~= 0.000010 or less, this isn't a fast math library,

Mar 29, 2022
A small, fast codeforces command line tool for competitive programming.
A small, fast codeforces command line tool for competitive programming.

chainsaw: A Codeforces Commandline Tool chainsaw is a small and faster drop-in replacement for your copy and paste while attending Codeforces contests

Dec 8, 2022
The Wren Programming Language. Wren is a small, fast, class-based concurrent scripting language.

Wren is a small, fast, class-based concurrent scripting language Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a fami

Dec 30, 2022
The purpose of these streams is to be educational and entertaining for viewers to learn about systems architecture, reverse engineering, software security, etc., and NOT to encourage nor endorse malicious game hacking.
The purpose of these streams is to be educational and entertaining for viewers to learn about systems architecture, reverse engineering, software security, etc., and NOT to encourage nor endorse malicious game hacking.

Memestream This repository holds the code that I develop during my live game "modding" ?? sessions. When I stream, I like to speedrun making a success

Jul 6, 2022
The movements of your RC vehicles are jerky and not smooth? This Arduino device will solve this issue by adding acceleration and deceleration ramps to the PWM signals!
The movements of your RC vehicles are jerky and not smooth? This Arduino device will solve this issue by adding acceleration and deceleration ramps to the PWM signals!

This is an Arduino Pro Mini 3.3V / 8MHz based RC servo ramp / delay generator Features: 4 RC servo PWM inputs and outputs (can be enhanced) Reads the

Apr 15, 2022
Not related to software bugs and exploits; this repo contains snippets of code that demonstrate some interesting functionality or a handy trick.

Proof-of-Concept Not related to software bugs and exploits; this repo contains snippets of code that demonstrate some interesting functionality or a h

Nov 19, 2022