Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
name: Build libdither

env:
QT_VERSION_WIN: "6.9.2"

on:
workflow_dispatch:
push:
tags:
- '*-*-*'

permissions:
contents: write

jobs:
build:
name: Build (${{ matrix.project }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
project: win64_msvc
- os: windows-latest
project: win64_mingw
- os: ubuntu-22.04
project: linux_x86_64
- os: macos-latest
project: macos_universal
qt_arch: clang_64

steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up msbuild (Windows MSVC)
if: matrix.project == 'win64_msvc'
uses: microsoft/setup-msbuild@v2
with:
msbuild-architecture: x64

- name: Build libdither (Windows MSVC)
if: matrix.project == 'win64_msvc'
run: |
msbuild libdither.vcxproj /p:Configuration=Release /property:Platform=x64
shell: cmd

- name: Build demo (Windows MSVC)
if: matrix.project == 'win64_msvc'
run: |
msbuild libdither_static.vcxproj /p:Configuration=Release /property:Platform=x64
msbuild demo.vcxproj /p:Configuration=Release /property:Platform=x64
shell: cmd

- name: Run demo (Windows MSVC)
if: matrix.project == 'win64_msvc'
run: |
make demo_run_msvc
shell: cmd

- name: Set up Make and Chocolatey (Windows MinGW)
if: matrix.project == 'win64_mingw'
uses: crazy-max/ghaction-chocolatey@v3
with:
args: 'install make'

- name: Set up Qt (Windows MinGW)
if: matrix.project == 'win64_mingw'
uses: jurplel/install-qt-action@v4
with:
target: 'desktop'
arch: ${{ matrix.qt_arch }}
version: ${{ env.QT_VERSION_WIN }}
archives: 'qtbase MinGW'
setup-python: true
cache: true
add-tools-to-path: true
set-env: true

- name: Build libdither (Windows MinGW)
if: matrix.project == 'win64_mingw'
run: |
make WIN_MINGW_BIN_PATH=%GITHUB_WORKSPACE%\Qt\${{ env.QT_VERSION_WIN }}\mingw_64\bin libdither
shell: cmd

- name: Build demo (Windows MinGW)
if: matrix.project == 'win64_mingw'
run: |
make WIN_MINGW_BIN_PATH=%GITHUB_WORKSPACE%\Qt\${{ env.QT_VERSION_WIN }}\mingw_64\bin demo
shell: cmd

- name: Run demo (Windows MinGW)
if: matrix.project == 'win64_mingw'
run: |
make demo_run
shell: cmd

- name: Install prerequisites (Linux)
if: matrix.project == 'linux_x86_64'
run: |
sudo apt-get update
sudo apt-get install -y build-essential

- name: Build libdither (Linux)
if: matrix.project == 'linux_x86_64'
run: |
make libdither
shell: bash -l {0}

- name: Build demo (Linux)
if: matrix.project == 'linux_x86_64'
run: |
make demo
shell: bash -l {0}

- name: Run demo (Linux)
if: matrix.project == 'linux_x86_64'
run: |
make demo_run
shell: bash -l {0}

- name: Build libdither (macOS)
if: matrix.project == 'macos_universal'
run: |
make libdither_universal
shell: bash

- name: Build demo (macOS)
if: matrix.project == 'macos_universal'
run: |
make demo
shell: bash

- name: Run demo (macOS)
if: matrix.project == 'macos_universal'
run: |
make demo_run
shell: bash

- name: Cleanup (Windows MSVC)
if: matrix.project == 'win64_msvc'
run: |
ls -la $GITHUB_WORKSPACE/dist/Release
rm dist/Release/*.bmp
rm dist/Release/*.png
rm dist/Release/demo.*
shell: bash

- name: Cleanup (General)
if: matrix.project != 'win64_msvc'
run: |
ls -la $GITHUB_WORKSPACE/dist
rm dist/*.bmp
rm dist/*.png
rm dist/demo*
shell: bash

- name: Package artifacts
id: pkg
run: |
ls -la $GITHUB_WORKSPACE/dist
echo "dist_path=$GITHUB_WORKSPACE/dist" >> $GITHUB_OUTPUT
shell: bash

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ditherista-${{ matrix.project }}
path: ${{ steps.pkg.outputs.dist_path }}
if-no-files-found: warn
retention-days: 14











2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ dist/
.idea/
.DS_Store
.vscode
.vs/
*.vcxproj.*

# Prerequisites
*.d
Expand Down
50 changes: 30 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# default MingW path for Qt 6.3.x:
WIN_MINGW_BIN_PATH=C:\\Qt\\Tools\\mingw1310_64\\bin

LIB_VERSION=2025.07.07a
LIB_VERSION=2025.10.04a

LIBNAME=libdither
SRCDIR=src/$(LIBNAME)
Expand All @@ -23,20 +23,23 @@ CFLAGS=-std=c11 -Wall -Wextra -Wconversion -Wshadow -Wstrict-overflow -Wformat=2

ifdef OS # Windows:
define fn_mkdir
if not exist "$(1)" mkdir "$(1)"
@if not exist "$(1)" mkdir "$(1)"
endef
SHELL=cmd
CP=copy
DELTREE=rd /s /q
CC=SET PATH=$(WIN_MINGW_BIN_PATH);%PATH% && gcc
LIBEXT=dll
SEP=\\
DEMOCMD=cd dist && demo
else # Unix based platforms
define fn_mkdir
@mkdir -p "$(1)"
endef
CP=cp
DELTREE=rm -Rf
SEP=/
DEMOCMD=cd dist && ./demo
ifeq ($(shell uname), Darwin) # macOS
CC=clang
LIBEXT=dylib
Expand All @@ -59,7 +62,7 @@ all:
@echo "* libdither_x64 - build macOS x86 library"
@echo "* libdither_arm64 - build macOS apple silicon library"
@echo "* libdither_universal - build universal macOS library"
@echo "* libdither_msvc - build using MSVC on Windows"
@echo "* libdither_msvc - build using MSVC on Windows (run vcvar64.bat first!)"
@echo "* demo - builds a small executable for the current platform to demo libdither's capabilities"
@echo "* clean"

Expand All @@ -80,37 +83,44 @@ $(LIBNAME)_arm64: $(LIBNAME)_build
$(LIBNAME): $(LIBNAME)_build

$(LIBNAME)_build: $(OBJDIR)/$(LIBNAME).$(LIBEXT)
$(call fn_mkdir,$(DISTDIR))
-$(call fn_mkdir,$(DISTDIR))
$(CP) $(OBJDIR)$(SEP)$(LIBNAME).$(LIBEXT) $(DISTDIR)$(SEP)$(LIBNAME).$(LIBEXT)
@echo "$(LIBNAME) build successfully $(TARGETARCH)"

$(OBJDIR)/$(LIBNAME).$(LIBEXT): $(OBJ)
cd $(OBJDIR) && $(CC) $(TARGETARCH) -shared $(OBJFILES) -fPIC -o $(LIBNAME).$(LIBEXT)

$(OBJDIR)/%.o: $(addprefix $(SRCDIR)/, %.c)
$(call fn_mkdir,$(OBJDIR))
$(call fn_mkdir,$(OBJDIR)/tetrapal)
$(call fn_mkdir,$(OBJDIR)/kdtree)
-$(call fn_mkdir,$(OBJDIR))
-$(call fn_mkdir,$(OBJDIR)/tetrapal)
-$(call fn_mkdir,$(OBJDIR)/kdtree)
$(CC) $(CFLAGS) $(TARGETARCH) -c -fPIC -c $< -o $@

.PHONY: libdither_msvc
libdither_msvc:
@echo Make sure to run vcvars64.bat or this target will fail...
$(call fn_mkdir,$(OBJDIR))
cd build && cl.exe ..\\src\\libdither\\*.c /LD /DLL /Fe: libdither.dll
cd build && cl.exe ..\\src\\demo\\demo.c ..\src\demo\spng.c libdither.lib /I..\\src\\libdither /L. /Fe: demo.exe
$(call fn_mkdir,$(DISTDIR))
copy src\\demo\\*.bmp $(DISTDIR)
copy build\\demo.exe $(DISTDIR)
copy build\\libdither.dll $(DISTDIR)

demo: libdither
@echo Make sure to run vcvars64.bat (for Visual Studio 2022) or this target will fail...
msbuild libdither.vcxproj /p:Configuration=Release
# building without msbuild:
# cd build && cl.exe ..\\src\\libdither\\*.c ..\\src\\libdither\\tetrapal\\*.c ..\\src\\libdither\\kdtree\\*.c /LD /DLL /Fe: libdither.dll
# cd build && cl.exe ..\\src\\demo\\demo.c ..\src\demo\lodepng.c libdither.lib /I..\\src\\libdither /Fe: demo.exe

.PHONY: demo_msvc
demo_msvc:
msbuild demo.vcxproj /p:Configuration=Release

.PHONY: demo
demo:
cd dist && $(CC) $(UNIXFLAGS) -I../src/libdither -L. ../src/demo/demo.c ../src/demo/lodepng.c -ldither -lm -o demo
$(CP) src$(SEP)demo$(SEP)*.png $(DISTDIR)
$(CP) src$(SEP)demo$(SEP)blue_noise.bmp $(DISTDIR)

demo_run: demo
@cd dist && ./demo
#open -a Preview dist/david_OUT.png
.PHONY: demo_run
demo_run:
$(DEMOCMD)

.PHONY: demo_run_msvc
demo_run_msvc:
cd dist\Release && demo

.PHONY: clean
clean:
Expand Down
25 changes: 19 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -467,17 +467,30 @@ Once compiled, you can find the finished library in the ```dist``` directory.
*MacOS notes*:

* Installing the XCode command line tools is all you need for building libdither
* You can choose if you want to build a x64, arm64 or universal library. The demo, however, only builds against the current machine's architecture.
* You can choose if you want to build a x64, arm64 or universal library. The demo, however, only builds against the
current machine's architecture.

*Linux notes*:

* ```gcc``` and ```make``` is all you need to build libdither. E.g. on Ubuntu you should install build-essential via ```apt``` to get these tools.
* ```gcc``` and ```make``` is all you need to build libdither. E.g. on Ubuntu you should install ```build-essential```
via ```apt``` to get these tools.

*Windows notes*:
*Windows notes - MinGW*:

* You can build both MingW and MSVC targets from the Makefile (sorry, no .sln)
* For MingW, open the Makefile and ensure the path (on top of the file) points to your MingW installation directory
* Install make via Chocolatey package manager from chocolatey.org (https://chocolatey.org/, https://chocolatey.org/packages/make)
* Install ```make``` via Chocolatey package manager from chocolatey.org (https://chocolatey.org/, https://chocolatey.org/packages/make)
* Open the Makefile and ensure the path (on top of the file) points to your MingW installation directory.
* Run ```make libdither``` to build using MinGW.

*Windows notes - Microsoft Visual Studio Solution*:

* Open the solution file (```.sln``) in Visual Studio 2022 or newer.
* There are 3 projects you can build: libdither (dynamic ```.dll`` library) and the demo.

*Windows notes - Microsoft Visual Studio (make)*:

* To build using make, install ```make``` via Chocolatey package manager from chocolatey.org (https://chocolatey.org/, https://chocolatey.org/packages/make)
* Run ```make libdither_msvc``` to build (make sure to run Visual Studio's ```vcvars64.bat``` first!)
* OR use the solution file (`.sln`) to build libdither from the Visual Studio IDE (2022 or newer).

Usage
-----
Expand Down
Loading