Language bindings, KDE thumbnails, yapf compare, in-memory encoding

- yapf_encode() / yapf_free_buffer(): encode to memory; yapf_save uses it
- yapf.c also compiles as C++
- `yapf compare`: size and decode speed of the original format vs YAPF,
  with a lossless check
- bindings with tested examples: C++ (header-only), C# (P/Invoke),
  Rust (crate, builds the C code), Go (cgo), Java (FFM API, Java 22+),
  Zig (@cImport), LuaJIT (FFI), TypeScript types for the JS port;
  Python now encodes in memory
- docs/LANGUAGES.md and examples/ with measured results
- KDE Dolphin thumbnail plugin (KF6, CMake)
- README: honest status for Photoshop / VS Code / Figma (not run in the
  apps yet) and macOS (cross-compiled only), platform table

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nexoniarz 2026-10-03 14:39:56 +02:00
commit d7f494a0c9
52 changed files with 1926 additions and 106 deletions

View file

@ -20,7 +20,9 @@ the .blend** and survive saving and reopening.
and pick the zip.
The zip contains the native YAPF library for Windows, macOS and Linux (x64
and ARM64). If no library matches your system, the extension still
and ARM64). Tested in Blender 5.1 on Linux; the Windows library is tested
outside Blender, and the macOS libraries are cross-compiled and **not yet run
on a Mac**. If no library matches your system, the extension still
**imports** using a pure-Python decoder (numpy, bundled with Blender), but
cannot export.

View file

@ -30,3 +30,10 @@ node build.js
```
Figma limits images to 4096 × 4096; larger `.yapf` files report an error.
## Status
The plugin UI was tested in a browser engine (headless Chromium) with a
simulated Figma main thread: import hands Figma a pixel-exact PNG, and
export downloads a pixel-exact `.yapf`. `code.js` is syntax-checked.
**It has not yet been run inside Figma itself.**

View file

@ -0,0 +1,26 @@
# YAPF thumbnails for KDE Dolphin (KF6 KIO thumbnail plugin).
# cmake -B build -DCMAKE_BUILD_TYPE=Release
# cmake --build build
# sudo cmake --install build (or see README.md for a per-user install)
cmake_minimum_required(VERSION 3.16)
project(yapfthumbnail LANGUAGES C CXX)
find_package(ECM 6.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
find_package(Qt6 6.5 REQUIRED COMPONENTS Core Gui)
find_package(KF6 6.0 REQUIRED COMPONENTS KIO)
find_package(Threads REQUIRED)
kcoreaddons_add_plugin(yapfthumbnail
SOURCES yapfthumbnail.cpp ../../yapf.c
INSTALL_NAMESPACE "kf6/thumbcreator")
set_source_files_properties(../../yapf.c PROPERTIES LANGUAGE C)
target_include_directories(yapfthumbnail PRIVATE ../..)
target_link_libraries(yapfthumbnail PRIVATE KF6::KIOGui Qt6::Gui Threads::Threads)
# Register the image/x-yapf file type so Dolphin recognises .yapf files.
install(FILES ../linux/yapf-mime.xml DESTINATION ${KDE_INSTALL_MIMEDIR} RENAME yapf.xml)

50
extensions/kde/README.md Normal file
View file

@ -0,0 +1,50 @@
# YAPF thumbnails for KDE (Dolphin)
Shows previews of `.yapf` files in **Dolphin**, the KDE file dialogs and
anything else that uses KIO thumbnails. KDE Frameworks 6 / Plasma 6.
Files with mipmaps are thumbnailed from the nearest mip level, so even huge
textures preview instantly.
## Build and install
You need CMake, a C/C++ compiler and the KDE development packages:
| System | Packages |
| :-------------- | :------- |
| Arch / Manjaro | `sudo pacman -S cmake extra-cmake-modules kio` |
| Debian / Ubuntu | `sudo apt install cmake extra-cmake-modules libkf6kio-dev qt6-base-dev` |
| Fedora | `sudo dnf install cmake extra-cmake-modules kf6-kio-devel qt6-qtbase-devel` |
| openSUSE | `sudo zypper install cmake kf6-extra-cmake-modules kf6-kio-devel qt6-base-devel` |
| NixOS | `nix-shell kde-shell.nix` (in this folder) |
```sh
cd extensions/kde
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
cmake --build build
sudo cmake --install build
update-mime-database /usr/share/mime
```
This installs the plugin (`kf6/thumbcreator/yapfthumbnail.so`) and the
`image/x-yapf` file type. Then in Dolphin: **Settings → Configure Dolphin →
Interface → Previews**, tick **YAPF Images**, and turn previews on.
### Without root (per user, also NixOS)
```sh
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$HOME/.local
cmake --build build && cmake --install build
update-mime-database ~/.local/share/mime
mkdir -p ~/.config/plasma-workspace/env
echo 'export QT_PLUGIN_PATH="$HOME/.local/lib/plugins:$QT_PLUGIN_PATH"' > ~/.config/plasma-workspace/env/yapf.sh
```
Log out and back in, then enable **YAPF Images** in Dolphin's preview settings.
(Some distributions use `lib64/plugins` or `lib/qt6/plugins`; `cmake
--install` prints the exact folder.)
## Status
Built against KF6 / Qt 6 and tested by loading the plugin through KDE's
plugin factory and creating thumbnails (RGBA, RGB, mipmapped, wide images;
corrupt files are rejected). Not yet tried inside a running Dolphin.

View file

@ -0,0 +1,6 @@
# Development shell for building the plugin on NixOS: nix-shell kde-shell.nix
with import <nixpkgs> {};
mkShell {
nativeBuildInputs = [ cmake kdePackages.extra-cmake-modules pkg-config ];
buildInputs = [ kdePackages.kio kdePackages.qtbase kdePackages.kcoreaddons ];
}

View file

@ -0,0 +1,79 @@
// YAPF thumbnails for KDE Dolphin and other KIO file dialogs.
// Copyright 2026 Nexoniarz — Apache License 2.0.
#include <KIO/ThumbnailCreator>
#include <KPluginFactory>
#include <QImage>
extern "C" {
#include "yapf.h"
}
class YapfThumbnailCreator : public KIO::ThumbnailCreator
{
Q_OBJECT
public:
YapfThumbnailCreator(QObject *parent, const QVariantList &args)
: KIO::ThumbnailCreator(parent, args)
{
}
KIO::ThumbnailResult create(const KIO::ThumbnailRequest &request) override
{
const QByteArray path = request.url().toLocalFile().toLocal8Bit();
yapf_image_t *img = yapf_load(path.constData());
if (!img) {
return KIO::ThumbnailResult::fail();
}
// Start from the smallest stored mip level that still covers the
// requested size; Qt scales the rest.
const QSize want = request.targetSize();
int m = 0;
while (m + 1 < img->mip_levels &&
int(img->width >> (m + 1)) >= want.width() &&
int(img->height >> (m + 1)) >= want.height()) {
++m;
}
const int w = qMax(1, int(img->width >> m));
const int h = qMax(1, int(img->height >> m));
const uchar *px = img->mips[m];
QImage image;
switch (img->channels) {
case 1:
image = QImage(px, w, h, w, QImage::Format_Grayscale8).copy();
break;
case 2: { // gray + alpha → RGBA
image = QImage(w, h, QImage::Format_RGBA8888);
for (int y = 0; y < h; ++y) {
const uchar *s = px + size_t(y) * w * 2;
uchar *d = image.scanLine(y);
for (int x = 0; x < w; ++x, s += 2, d += 4) {
d[0] = d[1] = d[2] = s[0];
d[3] = s[1];
}
}
break;
}
case 3:
image = QImage(px, w, h, w * 3, QImage::Format_RGB888).copy();
break;
default:
image = QImage(px, w, h, w * 4,
(img->flags & YAPF_FLAG_PREMULT_ALPHA) ? QImage::Format_RGBA8888_Premultiplied
: QImage::Format_RGBA8888).copy();
break;
}
yapf_free(img);
if (image.width() > want.width() || image.height() > want.height()) {
image = image.scaled(want, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
return KIO::ThumbnailResult::pass(image);
}
};
K_PLUGIN_CLASS_WITH_JSON(YapfThumbnailCreator, "yapfthumbnail.json")
#include "yapfthumbnail.moc"

View file

@ -0,0 +1,7 @@
{
"CacheThumbnail": true,
"KPlugin": {
"MimeTypes": ["image/x-yapf"],
"Name": "YAPF Images"
}
}

View file

@ -24,4 +24,11 @@ Decoding runs in plain JavaScript inside the preview; no native code.
code --install-extension yapf-preview-1.0.0.vsix
```
Works in VS Code, VSCodium and other VS Code–based editors (1.75+).
Should work in VS Code 1.75+ and VS Code–based editors such as VSCodium.
## Status
The `.vsix` packages cleanly, and the preview code was tested in a browser
engine (headless Chromium) with real files: correct pixels, mip picker,
error message for corrupt files. **It has not yet been run inside VS Code
itself.**