Compare commits
146
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70111c4272 | ||
|
|
f837314f5c | ||
|
|
851c7eece3 | ||
|
|
b67c7ca318 | ||
|
|
7744518b87 | ||
|
|
18c6a4c89d | ||
|
|
c4cc3de0ec | ||
|
|
16eb647b1a | ||
|
|
20bce9dff4 | ||
|
|
cb5e740688 | ||
|
|
5392458515 | ||
|
|
39cad74c43 | ||
|
|
d1bf83928d | ||
|
|
e194514264 | ||
|
|
2261ebd331 | ||
|
|
de3065f4cc | ||
|
|
9c3982354d | ||
|
|
86e692ecda | ||
|
|
f30d16816f | ||
|
|
cf93305fdd | ||
|
|
1eb72e865b | ||
|
|
e0f86eec29 | ||
|
|
c196912bed | ||
|
|
ebbc675297 | ||
|
|
21d59d891c | ||
|
|
7b3ebf4c87 | ||
|
|
cc61e2aa4c | ||
|
|
a07a5d638d | ||
|
|
5b75dd4284 | ||
|
|
fb6b37bade | ||
|
|
b02df94744 | ||
|
|
429c772e4a | ||
|
|
d843716e8b | ||
|
|
b763dd78d1 | ||
|
|
c88187b200 | ||
|
|
fe0230b3d5 | ||
|
|
4ddeb0158c | ||
|
|
885fa3fee8 | ||
|
|
68defb1de7 | ||
|
|
f252f0093a | ||
|
|
b13aef999a | ||
|
|
a45a9ac130 | ||
|
|
a1f4471fd1 | ||
|
|
f62f41fdd2 | ||
|
|
dab1103269 | ||
|
|
ce9fa3bfdf | ||
|
|
8e4484d553 | ||
|
|
624bd2ed15 | ||
|
|
c4aa78acde | ||
|
|
1320cab8bf | ||
|
|
f4e030c0f8 | ||
|
|
b0d8a965a6 | ||
|
|
a9056b54b9 | ||
|
|
0388185da5 | ||
|
|
8d540e09f3 | ||
|
|
8a9b7d345b | ||
|
|
d22fe8682c | ||
|
|
2bc03b73a8 | ||
|
|
37c30ad344 | ||
|
|
77318550b2 | ||
|
|
1a995b7624 | ||
|
|
85f077433a | ||
|
|
f0b86786cf | ||
|
|
9712e4e604 | ||
|
|
0a60d7bafd | ||
|
|
54b70c105e | ||
|
|
4ee496e068 | ||
|
|
19b777013f | ||
|
|
684e7aca1a | ||
|
|
31faa87423 | ||
|
|
425410beee | ||
|
|
68ec429a6e | ||
|
|
002af6dfee | ||
|
|
a6f6e36bca | ||
|
|
b63d9cc1bd | ||
|
|
05527b4e21 | ||
|
|
8be75421cb | ||
|
|
19eb62502b | ||
|
|
cc135217f3 | ||
|
|
9b42f1c1bc | ||
|
|
1918aed278 | ||
|
|
3b55a5c345 | ||
|
|
05b30502b3 | ||
|
|
0052dc0aa8 | ||
|
|
f276312f71 | ||
|
|
793f264dcb | ||
|
|
219c6f8c1c | ||
|
|
6bede95351 | ||
|
|
6d1886f1d2 | ||
|
|
249dc9dac2 | ||
|
|
8c0ebb1872 | ||
|
|
2a993d9e23 | ||
|
|
60969b40bd | ||
|
|
55471fb1cf | ||
|
|
9d43f4de2d | ||
|
|
c62f3cba8a | ||
|
|
7f73dfef85 | ||
|
|
5ed13ae372 | ||
|
|
a58008e40a | ||
|
|
3685af99d0 | ||
|
|
682c0ceeda | ||
|
|
1f9499e747 | ||
|
|
5561dc2d25 | ||
|
|
8ce0e77fdb | ||
|
|
fef8585187 | ||
|
|
d45677a02c | ||
|
|
08edcc33af | ||
|
|
27c6944fdb | ||
|
|
bc3cbdca49 | ||
|
|
95c05100d2 | ||
|
|
b94487108a | ||
|
|
d0209ec246 | ||
|
|
28b9d96f7a | ||
|
|
c1da09b662 | ||
|
|
c7147771d7 | ||
|
|
68a67f5ec3 | ||
|
|
7afd91bba9 | ||
|
|
19739981b5 | ||
|
|
c2a000a98a | ||
|
|
2ff3f0cf43 | ||
|
|
2bdef41460 | ||
|
|
c5fcea8923 | ||
|
|
8e39e44027 | ||
|
|
e49979bf4d | ||
|
|
67d868fb94 | ||
|
|
bd1f7ff0ef | ||
|
|
a5272ccc7d | ||
|
|
4d6ce64afd | ||
|
|
2a40c823f6 | ||
|
|
b41d5e88ec | ||
|
|
c84b78734f | ||
|
|
cbfc9cc7da | ||
|
|
29edebe2ea | ||
|
|
c1267eecca | ||
|
|
1f28e57714 | ||
|
|
c0993d71a9 | ||
|
|
cf04489993 | ||
|
|
50032acc88 | ||
|
|
eba183807a | ||
|
|
8cb92ca3a6 | ||
|
|
22801925b4 | ||
|
|
b2435a88b3 | ||
|
|
a8fc9202a4 | ||
|
|
103f7cb5fe | ||
|
|
f6153b0751 | ||
|
|
6cda572b93 |
@@ -0,0 +1,64 @@
|
||||
name: Linux x86_64 Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential gcc make jam \
|
||||
libx11-dev libxext-dev libxxf86vm-dev libxinerama-dev \
|
||||
libxrandr-dev libxau-dev libxdmcp-dev libxss-dev \
|
||||
libssl-dev libpng-dev libjpeg-dev libtiff-dev zlib1g-dev \
|
||||
tar gzip zip
|
||||
|
||||
- name: Build ArgyllCMS
|
||||
run: |
|
||||
export OSTYPE=linux-gnu
|
||||
export MACHTYPE=x86_64-pc-linux-gnu
|
||||
export HOSTTYPE=x86_64
|
||||
jam -q -fJambase -j$(nproc) -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
|
||||
|
||||
- name: Smoke Tests
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
./bin/dispcal -? || true
|
||||
./bin/chartread -? || true
|
||||
./bin/colprof -? || true
|
||||
./bin/targen -? || true
|
||||
|
||||
- name: Package Release
|
||||
run: |
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_linux_x86_64_bin.tgz "Argyll_${TAG}_${SHORT_SHA}_linux_x86_64_bin.tgz"
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_linux_x86_64_bin
|
||||
path: Argyll_*_linux_x86_64_bin.tgz
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_linux_x86_64_bin.tgz
|
||||
@@ -0,0 +1,198 @@
|
||||
name: macOS Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- arch: x86_64
|
||||
machtype: x86_64-apple-darwin
|
||||
artifact: macOS_x86_64_bin
|
||||
- arch: arm64
|
||||
machtype: arm64-apple-darwin
|
||||
artifact: macOS_arm64_bin
|
||||
runs-on: macos
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install ftjam
|
||||
run: |
|
||||
curl -fsSL -o ftjam.tar.gz https://sourceforge.net/projects/freetype/files/ftjam/2.5.2/ftjam-2.5.2.tar.gz/download || wget --no-check-certificate -q -O ftjam.tar.gz https://sourceforge.net/projects/freetype/files/ftjam/2.5.2/ftjam-2.5.2.tar.gz/download
|
||||
tar -xzf ftjam.tar.gz
|
||||
cd ftjam-2.5.2
|
||||
make jam0 CC="cc -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -Wno-int-conversion -Wno-implicit-int"
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
cp jam0 "$HOME/.local/bin/jam"
|
||||
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
||||
cp jam0 /usr/local/bin/jam 2>/dev/null || true
|
||||
|
||||
- name: Build ArgyllCMS
|
||||
run: |
|
||||
export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"
|
||||
export OSTYPE=darwin
|
||||
export MACHTYPE=${{ matrix.machtype }}
|
||||
export HOSTTYPE=${{ matrix.arch }}
|
||||
export CCOPTFLAG="-O0 -Wno-error=implicit-function-declaration -Wno-error=incompatible-pointer-types -Wno-error=int-conversion -Wno-error=implicit-int"
|
||||
jam -q -d2 -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
|
||||
|
||||
- name: Ad-hoc Sign & Verify Binaries
|
||||
run: |
|
||||
for f in bin/*; do
|
||||
if [ -f "$f" ] && file "$f" | grep -q "Mach-O"; then
|
||||
echo "Ad-hoc signing $f"
|
||||
codesign -f -s - "$f"
|
||||
codesign -dvv "$f"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Smoke Tests
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
./bin/dispcal -? || true
|
||||
./bin/chartread -? || true
|
||||
./bin/colprof -? || true
|
||||
./bin/targen -? || true
|
||||
|
||||
- name: Package Release
|
||||
run: |
|
||||
export PATH="$HOME/.local/bin:/usr/local/bin:$PATH"
|
||||
export OSTYPE=darwin
|
||||
export MACHTYPE=${{ matrix.machtype }}
|
||||
export HOSTTYPE=${{ matrix.arch }}
|
||||
export CCOPTFLAG="-O0 -Wno-error=implicit-function-declaration -Wno-error=incompatible-pointer-types -Wno-error=int-conversion -Wno-error=implicit-int"
|
||||
export NO_BUILD=1
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_${{ matrix.artifact }}.tgz "Argyll_${TAG}_${SHORT_SHA}_${{ matrix.artifact }}.tgz"
|
||||
|
||||
- name: Upload Raw Binaries
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: raw-bin-${{ matrix.arch }}
|
||||
path: bin/
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_${{ matrix.artifact }}
|
||||
path: Argyll_*_${{ matrix.artifact }}.tgz
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_${{ matrix.artifact }}.tgz
|
||||
|
||||
universal:
|
||||
needs: build
|
||||
runs-on: macos
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download x86_64 binaries
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: raw-bin-x86_64
|
||||
path: raw-bin-x86_64
|
||||
|
||||
- name: Download arm64 binaries
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: raw-bin-arm64
|
||||
path: raw-bin-arm64
|
||||
|
||||
- name: Create Universal Binaries
|
||||
run: |
|
||||
mkdir -p bin
|
||||
for file in raw-bin-arm64/*; do
|
||||
bin_name=$(basename "$file")
|
||||
if [ -f "raw-bin-x86_64/$bin_name" ]; then
|
||||
if file "raw-bin-arm64/$bin_name" | grep -q "Mach-O" && file "raw-bin-x86_64/$bin_name" | grep -q "Mach-O"; then
|
||||
echo "Creating universal binary with lipo: $bin_name"
|
||||
lipo -create "raw-bin-x86_64/$bin_name" "raw-bin-arm64/$bin_name" -output "bin/$bin_name"
|
||||
chmod +x "bin/$bin_name"
|
||||
codesign -f -s - "bin/$bin_name"
|
||||
else
|
||||
echo "Non Mach-O file, copying directly: $bin_name"
|
||||
cp "$file" "bin/$bin_name"
|
||||
fi
|
||||
else
|
||||
echo "Warning: $bin_name not found in raw-bin-x86_64, copying arm64 version"
|
||||
cp "$file" "bin/$bin_name"
|
||||
if file "bin/$bin_name" | grep -q "Mach-O"; then
|
||||
codesign -f -s - "bin/$bin_name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
for file in raw-bin-x86_64/*; do
|
||||
bin_name=$(basename "$file")
|
||||
if [ ! -f "bin/$bin_name" ]; then
|
||||
echo "Warning: $bin_name only found in raw-bin-x86_64, copying x86_64 version"
|
||||
cp "$file" "bin/$bin_name"
|
||||
if file "bin/$bin_name" | grep -q "Mach-O"; then
|
||||
codesign -f -s - "bin/$bin_name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Verify Architecture & Code Signatures
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
echo "=== Binary Architecture & Signature Verification ==="
|
||||
for file in bin/*; do
|
||||
if [ -f "$file" ] && file "$file" | grep -q "Mach-O"; then
|
||||
file "$file"
|
||||
codesign -dvv "$file"
|
||||
fi
|
||||
done
|
||||
echo "=== Smoke Tests ==="
|
||||
./bin/dispcal -? || true
|
||||
./bin/chartread -? || true
|
||||
./bin/colprof -? || true
|
||||
./bin/targen -? || true
|
||||
|
||||
- name: Package Universal Release
|
||||
run: |
|
||||
export OSTYPE=darwin
|
||||
export MACHTYPE=universal-apple-darwin
|
||||
export HOSTTYPE=universal
|
||||
export NO_BUILD=1
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_macOS_universal_bin.tgz "Argyll_${TAG}_${SHORT_SHA}_macOS_universal_bin.tgz"
|
||||
|
||||
- name: Upload Universal Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_macOS_universal_bin
|
||||
path: Argyll_*_macOS_universal_bin.tgz
|
||||
|
||||
- name: Upload Universal Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_macOS_universal_bin.tgz
|
||||
@@ -0,0 +1,88 @@
|
||||
name: Windows x86_64 Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
install: >-
|
||||
git
|
||||
make
|
||||
mingw-w64-x86_64-gcc
|
||||
unzip
|
||||
zip
|
||||
bison
|
||||
|
||||
- name: Install ftjam
|
||||
run: |
|
||||
wget -q -O ftjam-win32.zip https://sourceforge.net/projects/freetype/files/ftjam/2.5.2/ftjam-2.5.2-win32.zip/download
|
||||
unzip ftjam-win32.zip
|
||||
cp jam.exe /usr/bin/jam.exe
|
||||
|
||||
- name: Build ArgyllCMS
|
||||
run: |
|
||||
export MINGW=$(cygpath -m /mingw64)
|
||||
jam -q -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
|
||||
|
||||
- name: Smoke Tests
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
./bin/dispcal.exe -? || true
|
||||
./bin/chartread.exe -? || true
|
||||
./bin/colprof.exe -? || true
|
||||
./bin/targen.exe -? || true
|
||||
|
||||
- name: Package Release
|
||||
env:
|
||||
COMPILER: MINGW64
|
||||
run: |
|
||||
export MINGW=$(cygpath -m /mingw64)
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip"
|
||||
|
||||
- name: Verify Package Contents
|
||||
run: |
|
||||
ZIP_FILE=$(ls Argyll_*_win64_exe.zip)
|
||||
echo "Verifying contents of ${ZIP_FILE}..."
|
||||
unzip -l "${ZIP_FILE}" | grep "usb/ArgyllCMS.inf"
|
||||
unzip -l "${ZIP_FILE}" | grep "usb/bin/amd64/libusb0.sys"
|
||||
unzip -l "${ZIP_FILE}" | grep "doc/ArgyllDoc.html"
|
||||
unzip -l "${ZIP_FILE}" | grep "ReadMe.txt"
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_win64_exe
|
||||
path: Argyll_*_win64_exe.zip
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: akkuman/gitea-release-action@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_win64_exe.zip
|
||||
@@ -0,0 +1,65 @@
|
||||
name: Linux x86_64 Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential gcc make jam \
|
||||
libx11-dev libxext-dev libxxf86vm-dev libxinerama-dev \
|
||||
libxrandr-dev libxau-dev libxdmcp-dev libxss-dev \
|
||||
libssl-dev libpng-dev libjpeg-dev libtiff-dev zlib1g-dev \
|
||||
tar gzip zip
|
||||
|
||||
- name: Build ArgyllCMS
|
||||
run: |
|
||||
export OSTYPE=linux-gnu
|
||||
export MACHTYPE=x86_64-pc-linux-gnu
|
||||
export HOSTTYPE=x86_64
|
||||
jam -q -fJambase -j$(nproc) -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
|
||||
|
||||
- name: Smoke Tests
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
./bin/dispcal -? || true
|
||||
./bin/chartread -? || true
|
||||
./bin/colprof -? || true
|
||||
./bin/targen -? || true
|
||||
|
||||
- name: Package Release
|
||||
run: |
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_linux_x86_64_bin.tgz "Argyll_${TAG}_${SHORT_SHA}_linux_x86_64_bin.tgz"
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_linux_x86_64_bin
|
||||
path: Argyll_*_linux_x86_64_bin.tgz
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_linux_x86_64_bin.tgz
|
||||
@@ -0,0 +1,195 @@
|
||||
name: macOS Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-26-intel
|
||||
arch: x86_64
|
||||
machtype: x86_64-apple-darwin
|
||||
artifact: macOS_x86_64_bin
|
||||
- os: macos-latest
|
||||
arch: arm64
|
||||
machtype: arm64-apple-darwin
|
||||
artifact: macOS_arm64_bin
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install ftjam
|
||||
run: |
|
||||
wget -q -O ftjam.tar.gz https://sourceforge.net/projects/freetype/files/ftjam/2.5.2/ftjam-2.5.2.tar.gz/download
|
||||
tar -xzf ftjam.tar.gz
|
||||
cd ftjam-2.5.2
|
||||
make CC="cc -Wno-implicit-function-declaration -Wno-incompatible-pointer-types -Wno-int-conversion -Wno-implicit-int"
|
||||
sudo cp bin.*/jam /usr/local/bin/jam
|
||||
|
||||
- name: Build ArgyllCMS
|
||||
run: |
|
||||
export OSTYPE=darwin
|
||||
export MACHTYPE=${{ matrix.machtype }}
|
||||
export HOSTTYPE=${{ matrix.arch }}
|
||||
export CCOPTFLAG="-O0"
|
||||
jam -q -d2 -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
|
||||
|
||||
- name: Ad-hoc Sign & Verify Binaries
|
||||
run: |
|
||||
for f in bin/*; do
|
||||
if [ -f "$f" ] && file "$f" | grep -q "Mach-O"; then
|
||||
echo "Ad-hoc signing $f"
|
||||
codesign -f -s - "$f"
|
||||
codesign -dvv "$f"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Smoke Tests
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
./bin/dispcal -? || true
|
||||
./bin/chartread -? || true
|
||||
./bin/colprof -? || true
|
||||
./bin/targen -? || true
|
||||
|
||||
- name: Package Release
|
||||
run: |
|
||||
export OSTYPE=darwin
|
||||
export MACHTYPE=${{ matrix.machtype }}
|
||||
export HOSTTYPE=${{ matrix.arch }}
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_${{ matrix.artifact }}.tgz "Argyll_${TAG}_${SHORT_SHA}_${{ matrix.artifact }}.tgz"
|
||||
|
||||
- name: Upload Raw Binaries
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: raw-bin-${{ matrix.arch }}
|
||||
path: bin/
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_${{ matrix.artifact }}
|
||||
path: Argyll_*_${{ matrix.artifact }}.tgz
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_${{ matrix.artifact }}.tgz
|
||||
|
||||
universal:
|
||||
needs: build
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download x86_64 binaries
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: raw-bin-x86_64
|
||||
path: raw-bin-x86_64
|
||||
|
||||
- name: Download arm64 binaries
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: raw-bin-arm64
|
||||
path: raw-bin-arm64
|
||||
|
||||
- name: Create Universal Binaries
|
||||
run: |
|
||||
mkdir -p bin
|
||||
for file in raw-bin-arm64/*; do
|
||||
bin_name=$(basename "$file")
|
||||
if [ -f "raw-bin-x86_64/$bin_name" ]; then
|
||||
if file "raw-bin-arm64/$bin_name" | grep -q "Mach-O" && file "raw-bin-x86_64/$bin_name" | grep -q "Mach-O"; then
|
||||
echo "Creating universal binary with lipo: $bin_name"
|
||||
lipo -create "raw-bin-x86_64/$bin_name" "raw-bin-arm64/$bin_name" -output "bin/$bin_name"
|
||||
chmod +x "bin/$bin_name"
|
||||
codesign -f -s - "bin/$bin_name"
|
||||
else
|
||||
echo "Non Mach-O file, copying directly: $bin_name"
|
||||
cp "$file" "bin/$bin_name"
|
||||
fi
|
||||
else
|
||||
echo "Warning: $bin_name not found in raw-bin-x86_64, copying arm64 version"
|
||||
cp "$file" "bin/$bin_name"
|
||||
if file "bin/$bin_name" | grep -q "Mach-O"; then
|
||||
codesign -f -s - "bin/$bin_name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
for file in raw-bin-x86_64/*; do
|
||||
bin_name=$(basename "$file")
|
||||
if [ ! -f "bin/$bin_name" ]; then
|
||||
echo "Warning: $bin_name only found in raw-bin-x86_64, copying x86_64 version"
|
||||
cp "$file" "bin/$bin_name"
|
||||
if file "bin/$bin_name" | grep -q "Mach-O"; then
|
||||
codesign -f -s - "bin/$bin_name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Verify Architecture & Code Signatures
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
echo "=== Binary Architecture & Signature Verification ==="
|
||||
for file in bin/*; do
|
||||
if [ -f "$file" ] && file "$file" | grep -q "Mach-O"; then
|
||||
file "$file"
|
||||
codesign -dvv "$file"
|
||||
fi
|
||||
done
|
||||
echo "=== Smoke Tests ==="
|
||||
./bin/dispcal -? || true
|
||||
./bin/chartread -? || true
|
||||
./bin/colprof -? || true
|
||||
./bin/targen -? || true
|
||||
|
||||
- name: Package Universal Release
|
||||
run: |
|
||||
export OSTYPE=darwin
|
||||
export MACHTYPE=universal-apple-darwin
|
||||
export HOSTTYPE=universal
|
||||
export NO_BUILD=1
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_macOS_universal_bin.tgz "Argyll_${TAG}_${SHORT_SHA}_macOS_universal_bin.tgz"
|
||||
|
||||
- name: Upload Universal Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_macOS_universal_bin
|
||||
path: Argyll_*_macOS_universal_bin.tgz
|
||||
|
||||
- name: Upload Universal Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_macOS_universal_bin.tgz
|
||||
@@ -0,0 +1,89 @@
|
||||
name: Windows x86_64 Release Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: true
|
||||
install: >-
|
||||
git
|
||||
make
|
||||
mingw-w64-x86_64-gcc
|
||||
unzip
|
||||
zip
|
||||
bison
|
||||
|
||||
- name: Install ftjam
|
||||
run: |
|
||||
wget -q -O ftjam-win32.zip https://sourceforge.net/projects/freetype/files/ftjam/2.5.2/ftjam-2.5.2-win32.zip/download
|
||||
unzip ftjam-win32.zip
|
||||
cp jam.exe /usr/bin/jam.exe
|
||||
|
||||
- name: Build ArgyllCMS
|
||||
run: |
|
||||
export MINGW=$(cygpath -m /mingw64)
|
||||
jam -q -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
|
||||
|
||||
- name: Smoke Tests
|
||||
env:
|
||||
ARGYLL_NOT_INTERACTIVE: "1"
|
||||
ARGYLL_EXCLUDE_SERIAL_SCAN: "1"
|
||||
run: |
|
||||
./bin/dispcal.exe -? || true
|
||||
./bin/chartread.exe -? || true
|
||||
./bin/colprof.exe -? || true
|
||||
./bin/targen.exe -? || true
|
||||
|
||||
- name: Package Release
|
||||
env:
|
||||
COMPILER: MINGW64
|
||||
run: |
|
||||
export MINGW=$(cygpath -m /mingw64)
|
||||
./makepackagebin.sh
|
||||
TAG="${{ github.ref_name }}"
|
||||
SHORT_SHA="$(git rev-parse --short HEAD)"
|
||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||
mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip"
|
||||
|
||||
- name: Verify Package Contents
|
||||
run: |
|
||||
ZIP_FILE=$(ls Argyll_*_win64_exe.zip)
|
||||
echo "Verifying contents of ${ZIP_FILE}..."
|
||||
unzip -l "${ZIP_FILE}" | grep "usb/ArgyllCMS.inf"
|
||||
unzip -l "${ZIP_FILE}" | grep "usb/bin/amd64/libusb0.sys"
|
||||
unzip -l "${ZIP_FILE}" | grep "doc/ArgyllDoc.html"
|
||||
unzip -l "${ZIP_FILE}" | grep "ReadMe.txt"
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Argyll_${{ github.ref_name }}_${{ env.SHORT_SHA }}_win64_exe
|
||||
path: Argyll_*_win64_exe.zip
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: Release ${{ github.ref_name }}
|
||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||
files: Argyll_*_win64_exe.zip
|
||||
Executable → Regular
+49
-8
@@ -1,9 +1,9 @@
|
||||
|
||||
Argyll CMS README file - Version 3.5.0
|
||||
--------------------------------------
|
||||
|
||||
Date: 4th February 2026
|
||||
Author: Graeme Gill
|
||||
Date: 21st August 2026
|
||||
Original Author: Graeme W. Gill
|
||||
Fork Maintainer: Gordon Bolton (gronod) <gordon@i3omb.com>
|
||||
|
||||
Introduction
|
||||
|
||||
@@ -30,17 +30,58 @@ This is Version 3.5.0, a bug fix update to the release V3.4.1.
|
||||
The first public release of icclib was in November 1998,
|
||||
and of Argyll was in October 2000. Code development commenced in 1995. See
|
||||
Changes Summary for an overview of changes since the last release. Changes
|
||||
between revisions is detailed in the log.txt file that accompanies the source code.
|
||||
between revisions is detailed in the log.txt file that accompanies the source code.
|
||||
|
||||
It is licensed under the Affero GNU Version 3 license.
|
||||
Modifications in this fork:
|
||||
--------------------------
|
||||
Based on the upstream ArgyllCMS V3.5.0 release, this fork adds structured
|
||||
JSON output capabilities (via a common `-u` switch) to several tools so they
|
||||
can be driven as isolated subprocesses by external UIs while preserving
|
||||
AGPLv3 licence isolation (no library linking; communication over stdin /
|
||||
stdout / stderr only).
|
||||
|
||||
Changes merged into main:
|
||||
|
||||
- **chartread** (`-u`): Real-time row-level and patch-level colour
|
||||
measurement events (`ROW_COLORS_JSON: ...`) containing device values,
|
||||
measured / expected XYZ & D50 Lab, and optional spectral data.
|
||||
|
||||
- **instlist**: New utility that enumerates connected instruments and emits
|
||||
the result as structured JSON.
|
||||
|
||||
- **printtarg** (`-u`): Emits a structured JSON target manifest describing
|
||||
the generated chart.
|
||||
|
||||
- **targen** (`-u`): Structured JSON progress output while generating test
|
||||
chart values.
|
||||
|
||||
- **profcheck** (`-u`): Structured JSON Delta E report.
|
||||
|
||||
- **colprof** (`-u`): Structured JSON calculation / progress reporting
|
||||
during profile creation.
|
||||
|
||||
Supporting documentation for the chartread JSON stream protocol, payload
|
||||
schema, process lifecycle, and AGPL isolation guidelines is also included.
|
||||
|
||||
Modified source code repository: https://git.i3omb.com/gronod/argyllcms
|
||||
|
||||
License:
|
||||
--------
|
||||
ArgyllCMS is licensed under the GNU Affero General Public License (AGPL) Version 3.
|
||||
In compliance with the AGPLv3, the complete corresponding source code for all
|
||||
modifications is publicly available at https://git.i3omb.com/gronod/argyllcms.
|
||||
|
||||
For more detailed information, please consult the HTML documentation in
|
||||
<doc/ArgyllDoc.html>, or <http://www.argyllcms.com/doc/ArgyllDoc.html>.
|
||||
|
||||
For the most recent source code start at <http://www.argyllcms.com/index.html>.
|
||||
|
||||
Contact me in regards to Argyll, icclib or cgatslib at:
|
||||
For the upstream source code start at <http://www.argyllcms.com/index.html>.
|
||||
|
||||
Contact:
|
||||
--------
|
||||
Original Argyll, icclib or cgatslib:
|
||||
Graeme at argyllcms dot com
|
||||
|
||||
This fork and the JSON streaming (`-u`) modifications:
|
||||
Gordon Bolton <gordon@i3omb.com>
|
||||
|
||||
Enjoy!
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
<h1>[V3.4.1 -> V3.5.0] 4th February 2026<br>
|
||||
</h1>
|
||||
<ul>
|
||||
<li>Added macOS Universal Binary release archive (Intel x86_64 + Apple Silicon arm64).</li>
|
||||
<li>Fixed non-blocking stdin polling deadlock on MSWindows anonymous pipes when running interactive measurement tools in subprocess mode.</li>
|
||||
<li>Added -d switch to printtarg to allow custom chart label strings or omit labelling entirely.</li>
|
||||
<li>Added MSWindows ARM release.</li>
|
||||
<li>Added Mac ARM release.</li>
|
||||
<li>Removed Mac PowerPC build from release.</li>
|
||||
|
||||
@@ -52,6 +52,7 @@ Test 1D Brent solver
|
||||
<br>xicc/xcolorantslu.exe
|
||||
<br>xicc/xfbview.exe
|
||||
<br>spectro/dispwin.exe
|
||||
<br>spectro/instlist.exe
|
||||
<br>target/ifarp.exe
|
||||
<br>target/ppoint.exe
|
||||
<br>target/qrand.exe
|
||||
|
||||
@@ -49,6 +49,7 @@ Verbose
|
||||
|
||||
|
||||
mode</tt><tt><br>
|
||||
</tt> <tt> </tt><tt><a href="#u">-u</a></tt><tt> Emit real-time JSON stream of row patch data to stdout</tt><tt><br>
|
||||
</tt><tt> </tt><tt><a href="#c">-c listno</a></tt><tt>
|
||||
Set communication port from the
|
||||
following list (default 1)</tt><tt><br>
|
||||
@@ -656,6 +657,8 @@ Override
|
||||
<a name="v"></a>The <b>-v</b> flag causes extra information to be
|
||||
printed out during chartread operation.<br>
|
||||
<br>
|
||||
<a name="u"></a>The <b>-u</b> flag enables real-time JSON streaming of row patch data to stdout. Each time a row is completed (either forward or reverse), a JSON object containing the expected and measured patch data, along with padding indicators, is emitted prefixed by <code>ROW_COLORS_JSON:</code>. This is designed for GUI applications wrapping chartread to display live swatches and calculate color differences during reading.<br>
|
||||
<br>
|
||||
<a name="c"></a>Normally instruments are connected via a serial
|
||||
communication port, and the port used should be selected by
|
||||
supplying the correct parameter to the <b>-c</b> flag. If you
|
||||
|
||||
@@ -0,0 +1,331 @@
|
||||
# ArgyllCMS `chartread -u` Subprocess Integration Specification & License Isolation Guide
|
||||
|
||||
This document specifies the communication protocol, JSON payload schema, process lifecycle, and licensing isolation architecture for integrating `chartread -u` into external user interfaces and control software.
|
||||
|
||||
---
|
||||
|
||||
## 1. Architectural & Licensing Boundary (AGPLv3 Isolation)
|
||||
|
||||
ArgyllCMS is licensed under the **GNU Affero General Public License (AGPL) Version 3**. To ensure a separate host project (proprietary, MIT, Apache, etc.) is **not tainted** by the AGPLv3 copyleft terms, the integration must maintain a strict, arm's-length inter-process communication (IPC) boundary:
|
||||
|
||||
### Core Isolation Rules
|
||||
1. **No Library Linking**: The host application **must never** statically or dynamically link (`#include`, `.so`, `.dylib`, `.dll`, `.a`) against any ArgyllCMS C libraries (`libinst`, `libicc`, `libcgats`, `libyajl`, etc.).
|
||||
2. **Subprocess Isolation via Standard OS Pipes**: `chartread` must run strictly as a standalone, decoupled child process.
|
||||
3. **Standard IPC Only**: Communication is conducted exclusively over standard POSIX / Win32 file descriptors (`stdin`, `stdout`, `stderr`).
|
||||
4. **Independent Binary Distribution**: The `chartread` binary should be treated as an external utility tool invoked by the OS shell or process manager.
|
||||
|
||||
```
|
||||
+-------------------------------------------------------------+
|
||||
| Host Application |
|
||||
| (Electron, Web App, Qt, Python, Rust, etc.) |
|
||||
| |
|
||||
| +-----------------------------------------------------+ |
|
||||
| | Line-by-Line Subprocess Stream Reader | |
|
||||
| +-----------------------------------------------------+ |
|
||||
+------------------------------|------------------------------+
|
||||
|
|
||||
Standard Pipes | (stdin / stdout / stderr)
|
||||
|
|
||||
+------------------------------v------------------------------+
|
||||
| Isolated Child Process |
|
||||
| `chartread -u ...` |
|
||||
| (AGPLv3 Licensed Binary) |
|
||||
+-------------------------------------------------------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Command Invocation
|
||||
|
||||
### Command Syntax
|
||||
```bash
|
||||
chartread [options] -u <target_basename>
|
||||
```
|
||||
|
||||
* **`-u` Flag**: Enables real-time emission of JSON records to `stdout`.
|
||||
* `<target_basename>`: The base name of the input `.ti2` target file and output `.ti3` measurement file (without extension).
|
||||
|
||||
### Key Command Options
|
||||
| Flag | Description |
|
||||
| :--- | :--- |
|
||||
| `-u` | **Required for streaming**: Emits `ROW_COLORS_JSON: ...` payloads on `stdout`. |
|
||||
| `-p` | Patch-by-patch spot mode (emits JSON after each individual patch). |
|
||||
| `-n` | Disable spectral readings (omits `spectral` field from JSON). |
|
||||
| `-c <port>` | Select communication port / instrument index. |
|
||||
| `-d` | Display measurement mode. |
|
||||
| `-t` | Transmission measurement mode. |
|
||||
| `-e` | Emissive measurement mode. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Stream Protocol & Framing Specification
|
||||
|
||||
When `-u` is provided, `chartread` outputs two types of lines to `stdout`:
|
||||
|
||||
1. **Human-Readable Status / Prompt Lines**: Unprefixed text intended for user prompts or diagnostics (e.g. `Hit [Space] to read strip A`).
|
||||
2. **Structured JSON Events**: Single-line JSON objects strictly prefixed by the marker:
|
||||
```
|
||||
ROW_COLORS_JSON: <json_object>\n
|
||||
```
|
||||
|
||||
### Stream Guarantees
|
||||
* **Line-Delimited**: Every JSON event is serialized as a single, uninterrupted line terminated with `\n`.
|
||||
* **Immediate Flush**: `chartread` explicitly invokes `fflush(stdout)` immediately after emitting each JSON line, guaranteeing low latency without OS-level output buffering.
|
||||
* **Deterministic Ordering**: Patches within a row are always indexed in canonical left-to-right strip order (bi-directional scan reversals are normalized internally before emission).
|
||||
|
||||
---
|
||||
|
||||
## 4. JSON Payload Schema
|
||||
|
||||
### Top-Level Object Schema
|
||||
|
||||
```json
|
||||
ROW_COLORS_JSON: {
|
||||
"event": "row_complete",
|
||||
"row_id": "A",
|
||||
"row_index": 0,
|
||||
"total_rows": 12,
|
||||
"patch_count": 21,
|
||||
"patches": [
|
||||
/* Array of Patch Objects */
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `event` | `string` | Event identifier. Currently always `"row_complete"`. |
|
||||
| `row_id` | `string` | Human-readable label of the row/strip (e.g. `"A"`, `"B"`, `"1"`). |
|
||||
| `row_index` | `integer` | 0-based index of the row within the target chart (`0 ... total_rows - 1`). |
|
||||
| `total_rows` | `integer` | Total number of rows/passes defined in the target chart. |
|
||||
| `patch_count`| `integer` | Number of patch elements contained in this row payload. |
|
||||
| `patches` | `array` | List of individual patch data objects. |
|
||||
|
||||
---
|
||||
|
||||
### Patch Object Schema
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "1",
|
||||
"loc": "A1",
|
||||
"is_pad": false,
|
||||
"device": [0.0, 50.0, 100.0, 0.0],
|
||||
"expected": {
|
||||
"XYZ": [18.4210, 20.1234, 15.6789],
|
||||
"Lab": [51.98, -8.45, 12.32]
|
||||
},
|
||||
"measured": {
|
||||
"XYZ": [18.5120, 20.0451, 15.7100],
|
||||
"Lab": [51.89, -8.31, 12.15],
|
||||
"spectral": {
|
||||
"bands": 36,
|
||||
"start_nm": 380.0,
|
||||
"end_nm": 730.0,
|
||||
"norm": 100.0,
|
||||
"values": [0.0120, 0.0135, 0.0180, 0.0245]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `id` | `string` | Patch ID string from `.ti2` file. If `"0"`, indicates a spacer/padding patch. |
|
||||
| `loc` | `string` | Physical location coordinate string (e.g. `"A1"`, `"B12"`). |
|
||||
| `is_pad` | `boolean` | `true` if patch is an alignment/lead-in spacer patch (`id == "0"`). UIs should typically render these distinctly or skip them in analysis. |
|
||||
| `device` | `array[float]` | Device colorant drive values scaled to percentage `0.0 ... 100.0%` (e.g. `[C, M, Y, K]` or `[R, G, B]`). |
|
||||
| `expected` | `object` *(optional)* | Expected reference values from `.ti2` (omitted if no reference data is present). |
|
||||
| `expected.XYZ` | `array[float][3]` | Reference CIE XYZ values on reference scale `0.0 ... 100.0`. |
|
||||
| `expected.Lab` | `array[float][3]` | Reference D50 $L^*a^*b^*$ computed via standard CIE transformation. |
|
||||
| `measured` | `object` | Actual instrument readings. |
|
||||
| `measured.XYZ` | `array[float][3]` | Measured CIE XYZ values on reference scale `0.0 ... 100.0`. |
|
||||
| `measured.Lab` | `array[float][3]` | Measured D50 $L^*a^*b^*$ ($L^* \in [0, 100]$, $a^*, b^* \in [-128, 127]$). |
|
||||
| `measured.spectral` | `object` *(optional)* | Spectral reflection/emission data (omitted if instrument is colorimeter-only or `-n` passed). |
|
||||
| `measured.spectral.bands` | `integer` | Number of spectral sample bands. |
|
||||
| `measured.spectral.start_nm` | `float` | Starting wavelength in nanometres (e.g. `380.0` or `400.0`). |
|
||||
| `measured.spectral.end_nm` | `float` | Ending wavelength in nanometres (e.g. `700.0` or `730.0`). |
|
||||
| `measured.spectral.norm` | `float` | Normalization scale factor (typically `100.0`). |
|
||||
| `measured.spectral.values` | `array[float]` | Array of spectral reflectance / radiance values per band. |
|
||||
|
||||
---
|
||||
|
||||
## 5. Integration Implementation Examples
|
||||
|
||||
### Node.js / Electron / TypeScript Integration
|
||||
|
||||
```typescript
|
||||
import { spawn, ChildProcessWithoutNullStreams } from 'child_process';
|
||||
import * as readline from 'readline';
|
||||
|
||||
export interface PatchColorEvent {
|
||||
event: string;
|
||||
row_id: string;
|
||||
row_index: number;
|
||||
total_rows: number;
|
||||
patch_count: number;
|
||||
patches: Array<{
|
||||
id: string;
|
||||
loc: string;
|
||||
is_pad: boolean;
|
||||
device: number[];
|
||||
expected?: {
|
||||
XYZ: [number, number, number];
|
||||
Lab: [number, number, number];
|
||||
};
|
||||
measured: {
|
||||
XYZ: [number, number, number];
|
||||
Lab: [number, number, number];
|
||||
spectral?: {
|
||||
bands: number;
|
||||
start_nm: number;
|
||||
end_nm: number;
|
||||
norm: number;
|
||||
values: number[];
|
||||
};
|
||||
};
|
||||
}>;
|
||||
}
|
||||
|
||||
export class ChartreadRunner {
|
||||
private process: ChildProcessWithoutNullStreams | null = null;
|
||||
private readonly JSON_PREFIX = 'ROW_COLORS_JSON: ';
|
||||
|
||||
public startSession(
|
||||
targetBasename: string,
|
||||
onRowData: (data: PatchColorEvent) => void,
|
||||
onConsoleMessage: (msg: string) => void,
|
||||
onError: (err: string) => void
|
||||
): void {
|
||||
// Spawn isolated process over standard pipes (No library linking)
|
||||
this.process = spawn('chartread', ['-u', targetBasename]);
|
||||
|
||||
// Parse stdout line by line
|
||||
const rlOut = readline.createInterface({ input: this.process.stdout });
|
||||
rlOut.on('line', (line: string) => {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.startsWith(this.JSON_PREFIX)) {
|
||||
try {
|
||||
const jsonStr = trimmed.substring(this.JSON_PREFIX.length);
|
||||
const payload: PatchColorEvent = JSON.parse(jsonStr);
|
||||
onRowData(payload);
|
||||
} catch (err) {
|
||||
onError(`Failed to parse JSON row payload: ${err}`);
|
||||
}
|
||||
} else if (trimmed.length > 0) {
|
||||
onConsoleMessage(trimmed);
|
||||
}
|
||||
});
|
||||
|
||||
// Capture stderr for warnings / errors
|
||||
const rlErr = readline.createInterface({ input: this.process.stderr });
|
||||
rlErr.on('line', (errLine: string) => {
|
||||
onError(errLine);
|
||||
});
|
||||
|
||||
this.process.on('close', (code) => {
|
||||
onConsoleMessage(`chartread exited with code ${code}`);
|
||||
this.process = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send user keyboard triggers or confirmations to chartread (e.g. Spacebar or Enter)
|
||||
*/
|
||||
public sendInput(input: string): void {
|
||||
if (this.process && this.process.stdin.writable) {
|
||||
this.process.stdin.write(input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abort measurement session
|
||||
*/
|
||||
public abort(): void {
|
||||
if (this.process) {
|
||||
this.sendInput('q\n'); // Send standard quit character
|
||||
setTimeout(() => {
|
||||
if (this.process) {
|
||||
this.process.kill('SIGTERM');
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Python Subprocess Integration
|
||||
|
||||
```python
|
||||
import subprocess
|
||||
import json
|
||||
import threading
|
||||
|
||||
class ChartreadClient:
|
||||
JSON_PREFIX = "ROW_COLORS_JSON: "
|
||||
|
||||
def __init__(self, target_basename: str, on_row_callback, on_status_callback):
|
||||
self.target_basename = target_basename
|
||||
self.on_row_callback = on_row_callback
|
||||
self.on_status_callback = on_status_callback
|
||||
self.process = None
|
||||
|
||||
def start(self):
|
||||
# Arms-length subprocess invocation maintaining AGPL isolation
|
||||
self.process = subprocess.Popen(
|
||||
["chartread", "-u", self.target_basename],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
bufsize=1 # Line buffered
|
||||
)
|
||||
|
||||
threading.Thread(target=self._read_stdout, daemon=True).start()
|
||||
threading.Thread(target=self._read_stderr, daemon=True).start()
|
||||
|
||||
def _read_stdout(self):
|
||||
for line in iter(self.process.stdout.readline, ''):
|
||||
line_str = line.strip()
|
||||
if line_str.startswith(self.JSON_PREFIX):
|
||||
payload_str = line_str[len(self.JSON_PREFIX):]
|
||||
try:
|
||||
data = json.loads(payload_str)
|
||||
self.on_row_callback(data)
|
||||
except json.JSONDecodeError as ex:
|
||||
print(f"JSON decode error: {ex}")
|
||||
elif line_str:
|
||||
self.on_status_callback(line_str)
|
||||
|
||||
def _read_stderr(self):
|
||||
for line in iter(self.process.stderr.readline, ''):
|
||||
if line.strip():
|
||||
print(f"[chartread stderr] {line.strip()}")
|
||||
|
||||
def send_key(self, key: str):
|
||||
if self.process and self.process.stdin:
|
||||
self.process.stdin.write(f"{key}\n")
|
||||
self.process.stdin.flush()
|
||||
|
||||
def terminate(self):
|
||||
if self.process:
|
||||
self.process.terminate()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Real-Time UI Visualisation Best Practices
|
||||
|
||||
1. **Rendering Device Colors**:
|
||||
* For RGB targets: scale `device[0..2]` from $0..100$ to $0..255$ (`rgb(r%, g%, b%)`).
|
||||
* For CMYK targets: use device simulation or convert `measured.Lab` / `expected.Lab` to sRGB for color swatch display.
|
||||
2. **Delta E Calculation ($\Delta E_{00}$ or $\Delta E_{ab}$)**:
|
||||
* When `expected.Lab` and `measured.Lab` are both present, calculate the color difference $\Delta E$.
|
||||
* The basic Euclidean distance ($\Delta E_{ab}$) is simple to implement directly:
|
||||
$$\Delta E_{ab} = \sqrt{(L_m^* - L_e^*)^2 + (a_m^* - a_e^*)^2 + (b_m^* - b_e^*)^2}$$
|
||||
* **Recommendation**: For professional color work, use the modern $\Delta E_{00}$ (CIEDE2000) formula. Due to its complexity, it is highly recommended to use an established color math library (e.g., `colorjs.io` in JavaScript, or `colormath` in Python) rather than implementing it from scratch.
|
||||
* Display green/amber/red indicator lights next to each patch in real-time based on your accepted $\Delta E$ tolerance.
|
||||
3. **Handling Alignment / Spacer Patches (`is_pad == true`)**:
|
||||
* Omit `is_pad == true` patches from quality score computations, or render them with dashed neutral borders to maintain layout grid accuracy without skewing statistics.
|
||||
@@ -2700,6 +2700,10 @@ White &nb
|
||||
useful in creating a profile for a device that is known to have a
|
||||
perfectly linear response, such as a camera in RAW mode.<br>
|
||||
<br>
|
||||
<a name="u_progress"></a> <span style="font-weight: bold;">-u:</span>
|
||||
Emit structured JSON progress events to <tt>stdout</tt> during profile
|
||||
calculation (e.g. <tt>{"event": "progress", "stage": "gamut_mapping", "percent": 75}</tt>).<br>
|
||||
<br>
|
||||
<a name="u"></a> <span style="font-weight: bold;">-u:</span> Input
|
||||
profiles will normally be created such that the white patch of the
|
||||
test chart will be mapped to perfect white when used with any of the
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>instlist</title>
|
||||
<meta http-equiv="content-type" content="text/html;
|
||||
charset=windows-1252">
|
||||
<meta name="author" content="Graeme Gill">
|
||||
</head>
|
||||
<body>
|
||||
<h2><b>spectro/instlist</b></h2>
|
||||
<br>
|
||||
Enumerate connected instrument communication ports (USB and Serial) and output the list in JSON format.<br>
|
||||
<h3>Usage</h3>
|
||||
<small><span style="font-family: monospace;"> instlist [-options]</span><br style="font-family: monospace;">
|
||||
<span style="font-family: monospace;"> -h, -?, --help Show help information</span><br style="font-family: monospace;">
|
||||
<span style="font-family: monospace;"> -v Verbose diagnostics to stderr</span><br style="font-family: monospace;">
|
||||
<span style="font-family: monospace;"> -D [level] Print debug diagnostics to stderr</span><br style="font-family: monospace;">
|
||||
</small><br>
|
||||
<h3><b>Output</b></h3>
|
||||
The output is emitted to <code>stdout</code> as a JSON object containing an array of discovered device objects:<br>
|
||||
<pre>
|
||||
{
|
||||
"event": "instruments",
|
||||
"devices": [
|
||||
{
|
||||
"port": 1,
|
||||
"name": "usb:/bus0/dev1 (X-Rite i1Pro)",
|
||||
"type": "i1Pro"
|
||||
}
|
||||
]
|
||||
}
|
||||
</pre>
|
||||
<h3>Comments</h3>
|
||||
This tool is designed to allow graphical user interfaces and external automation scripts to discover available spectrophotometers and colorimeters across Windows, macOS, and Linux without needing to parse interactive usage output.<br>
|
||||
<br>
|
||||
The <code>port</code> number directly corresponds to the <code>-c</code> parameter accepted by tools such as <a href="chartread.html">chartread</a>, <a href="spotread.html">spotread</a>, and <a href="dispread.html">dispread</a>.<br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
|
||||
Verbose mode<br>
|
||||
<a href="#u">-u</a> Emit JSON manifest of generated target pages on stdout<br>
|
||||
<a href="#i">-i 20 | 22 | 41 | 51 | SS | i1 | p3 | CM</a> Select
|
||||
target instrument (default i1)<br>
|
||||
|
||||
@@ -263,6 +264,7 @@ channels
|
||||
|
||||
|
||||
Dither 8 bit TIFF values down from 16 bit<br>
|
||||
<a href="#d">-d "string"</a> Custom target label string, or "" to omit labelling<br>
|
||||
<a href="#Q">-Q nbits</a>
|
||||
Quantize
|
||||
test
|
||||
@@ -447,6 +449,10 @@ A3
|
||||
set, and how many pages will be generated. Good for figuring out what
|
||||
the magic number of patches should be for a particular page size.<br>
|
||||
<br>
|
||||
<a name="u"></a> The <b>-u</b> flag emits a structured JSON manifest upon
|
||||
completion to <code>stdout</code> detailing the generated files, physical dimensions,
|
||||
and patch counts per page.<br>
|
||||
<br>
|
||||
<a name="i"></a> The <b>-i</b> parameter should be used to tell printtarg
|
||||
which instrument it should lay the patches out for. Each instrument has a
|
||||
slightly different requirement, and will lead to a different number of
|
||||
@@ -753,6 +759,12 @@ A3
|
||||
to use it to verify the overall operation of the printing system), then you
|
||||
can use the <b>-U</b> flag to disable this.<br>
|
||||
<br>
|
||||
<a name="d"></a> The <b>-d</b> parameter allows specifying a custom
|
||||
chart description/label string to be printed along the page/strip borders on
|
||||
generated test target files (TIFF, PostScript, EPS), replacing the default
|
||||
generated chart identifier. If an empty string is provided (<b>-d ""</b>),
|
||||
chart labelling along the page borders is suppressed entirely.<br>
|
||||
<br>
|
||||
<a name="p"></a> The <b>-p</b> parameter specifies the paper size. The size
|
||||
can either be one of the default sizes, <a name="pp"></a>or can be
|
||||
specified in millimeters. Limitations of the instrument may limit the
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
1), 2 to print each DE</span></small><small><span
|
||||
style="font-family: monospace;"></span><br style="font-family:
|
||||
monospace;">
|
||||
<span style="font-family: monospace;"> -u Emit
|
||||
structured JSON Delta E report to stdout</span><br style="font-family: monospace;">
|
||||
<span style="font-family: monospace;"> -c
|
||||
|
||||
Show
|
||||
@@ -233,6 +235,12 @@ Sort
|
||||
|
||||
be</b><i> .ti3 PCS values</i><br>
|
||||
<br>
|
||||
The <b>-u</b> flag causes the final delta E check report to be
|
||||
emitted to <tt>stdout</tt> in structured JSON format (e.g.,
|
||||
<tt>{"event": "report", "peak_de2000": 2.34, "avg_de2000": 0.51, "rms": 0.61}</tt>).
|
||||
This facilitates subprocess integration and mathematical extraction of error
|
||||
metrics without parsing human-readable text.<br>
|
||||
<br>
|
||||
The <b>-c</b> option causes the differences between the test values
|
||||
and the profile prediction of the color for each device value to be
|
||||
displayed in CIE94 delta E, rather than plain L*a*b* delta E. CIE94
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
<p><span style="font-family: monospace;">targen [options] <i>outfile</i><br>
|
||||
<a href="#v">-v [level]</a> Verbose mode [optional
|
||||
verbose level, 1..n]<br>
|
||||
<a href="#u">-u</a> Emit
|
||||
structured JSON progress events to stdout<br>
|
||||
<a href="#d">-d col_comb</a> choose colorant combination
|
||||
from the following:<br>
|
||||
0:
|
||||
@@ -528,6 +530,12 @@ incremental
|
||||
generating patch values. Extra diagnostics and verbosity may be available if
|
||||
a parameter is provided with a value greater than 1.<br>
|
||||
<br>
|
||||
<a name="u"></a> The <b>-u</b> flag causes structured JSON progress events
|
||||
to be emitted to <tt>stdout</tt> in real-time during patch generation (such
|
||||
as during OFPS point seeding and iterative optimization). This facilitates
|
||||
subprocess integration with graphical host applications without requiring
|
||||
text regex parsing.<br>
|
||||
<br>
|
||||
<a name="d"></a> The <b>-d</b> parameter sets the colorspace the test
|
||||
values will be generated in. Video gray space is assumed to be an additive
|
||||
space, where a zero device value will be black, and a maximum device value
|
||||
|
||||
@@ -747,6 +747,8 @@ void usage(char *diag) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa, nfa; /* argument we're looking at */
|
||||
|
||||
@@ -86,6 +86,8 @@ double sl[65][4] = {
|
||||
|
||||
#define GAMRES 5.0 /* Default surface resolution */
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int i, j, e;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,6 +55,8 @@ void usage(char *diag) {
|
||||
}
|
||||
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa,nfa; /* argument we're looking at */
|
||||
|
||||
+36
-18
@@ -3531,7 +3531,7 @@ double *in /* input point (absolute)*/
|
||||
) {
|
||||
gtri *tp;
|
||||
int j;
|
||||
double ss, rv;
|
||||
double ss, rv = -1.0;
|
||||
double nin[3]; /* Normalised input vector */
|
||||
|
||||
//printf("~1 radial called with %f %f %f\n", in[0], in[1], in[2]);
|
||||
@@ -3541,9 +3541,15 @@ double *in /* input point (absolute)*/
|
||||
/* Compute vector length to center point */
|
||||
for (ss = 0.0, j = 0; j < 3; j++)
|
||||
ss += (in[j] - s->cent[j]) * (in[j] - s->cent[j]);
|
||||
ss = 1.0/sqrt(ss); /* Normalising factor */
|
||||
for (ss = 0.0, j = 0; j < 3; j++)
|
||||
nin[j] = s->cent[j] + (in[j] - s->cent[j]) * ss;
|
||||
ss = sqrt(ss);
|
||||
if (ss > 1e-9) { /* Normalise to 1.0 */
|
||||
for (j = 0; j < 3; j++)
|
||||
nin[j] = s->cent[j] + (in[j] - s->cent[j]) / ss;
|
||||
} else {
|
||||
nin[0] = s->cent[0] + 1.0;
|
||||
nin[1] = s->cent[1];
|
||||
nin[2] = s->cent[2];
|
||||
}
|
||||
|
||||
tp = s->tris;
|
||||
FOR_ALL_ITEMS(gtri, tp) {
|
||||
@@ -3600,8 +3606,15 @@ double *in /* input point (absolute)*/
|
||||
//if (trace) printf("~1 Normalised in = %f %f %f\n", nin[0], nin[1], nin[2]);
|
||||
rv = radial_point(s, s->lutree, nin);
|
||||
|
||||
if (rv < 0.0) {
|
||||
error("gamut: radial internal error - failed to find triangle (rv %f)\n",rv);
|
||||
if (rv < -1e-4 || rv > 1e6 || rv != rv) {
|
||||
/* Failed to find a valid triangle via BSP (likely floating point fuzz
|
||||
on parallel planes). Fall back to robust brute force search. */
|
||||
double dummy_out[3];
|
||||
rv = radial_bf(s, out ? out : dummy_out, in);
|
||||
if (rv < 0.0 || rv != rv)
|
||||
rv = 0.0;
|
||||
} else if (rv < 0.0 || rv != rv) {
|
||||
rv = 0.0;
|
||||
}
|
||||
|
||||
if (out != NULL) {
|
||||
@@ -3943,6 +3956,8 @@ double *nin /* Normalised center relative point */
|
||||
) {
|
||||
gtri *rv;
|
||||
//if (trace) printf("~1 rad_pnt_tri: BSP 0x%x tag = %d, point %f %f %f\n", np,np->tag,nin[0],nin[1],nin[2]);
|
||||
if (np == NULL)
|
||||
return NULL;
|
||||
if (np->tag == 1) { /* It's a BSP node */
|
||||
gbspn *n = (gbspn *)np;
|
||||
double ds;
|
||||
@@ -3965,12 +3980,14 @@ double *nin /* Normalised center relative point */
|
||||
return NULL; /* Hmm */
|
||||
|
||||
} else { /* It's a triangle or list of triangles */
|
||||
int nt; /* Number of triangles in list */
|
||||
gtri **tpp; /* Pointer to list of triangles */
|
||||
int nt = 0; /* Number of triangles in list */
|
||||
gtri **tpp = NULL; /* Pointer to list of triangles */
|
||||
gtri *t_single;
|
||||
int i, j;
|
||||
|
||||
if (np->tag == 2) { /* It's a triangle */
|
||||
tpp = (gtri **)&np;
|
||||
t_single = (gtri *)np;
|
||||
tpp = &t_single;
|
||||
nt = 1;
|
||||
} else if (np->tag == 3) { /* It's a triangle list */
|
||||
gbspl *n = (gbspl *)np;
|
||||
@@ -4024,7 +4041,7 @@ double *nin /* Normalised center relative point */
|
||||
/* If we failed to find a triangle, or the result was incorrect, do a */
|
||||
/* brute force search to be sure of the result. */
|
||||
if (t == NULL) {
|
||||
error("rspl.radial: failed to find radial triangle\n");
|
||||
return -1.0; /* Signal failure to caller for fallback */
|
||||
}
|
||||
|
||||
/* Compute the intersection of the input vector with the triangle plane */
|
||||
@@ -4032,10 +4049,7 @@ double *nin /* Normalised center relative point */
|
||||
num = -(t->pe[0] * s->cent[0] + t->pe[1] * s->cent[1] + t->pe[2] * s->cent[2] + t->pe[3]);
|
||||
denom = (t->pe[0] * nin[0] + t->pe[1] * nin[1] + t->pe[2] * nin[2]);
|
||||
|
||||
if (fabs(denom) < 1e-9) {
|
||||
/* Hmm. The ray is paralell to the triangle ? */
|
||||
error("radial_point: failed to intersect radial triangle, num %e, denom %e\n",num,denom);
|
||||
}
|
||||
|
||||
rv = num/denom;
|
||||
|
||||
#ifdef ASSERTS
|
||||
@@ -5064,6 +5078,8 @@ int *lu /* Number used in list */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (np == NULL)
|
||||
return;
|
||||
if (np->tag == 1) { /* It's a BSP node */
|
||||
int j;
|
||||
gbspn *n = (gbspn *)np;
|
||||
@@ -5208,13 +5224,15 @@ int *lu /* Number used in list */
|
||||
return;
|
||||
|
||||
/* It's a list of triangles */
|
||||
} else {
|
||||
int nt; /* Number of triangles in list */
|
||||
gtri **tpp; /* Pointer to list of triangles */
|
||||
} else { /* It's a triangle or list of triangles */
|
||||
int nt = 0; /* Number of triangles in list */
|
||||
gtri **tpp = NULL; /* Pointer to list of triangles */
|
||||
gtri *t_single;
|
||||
int i, j;
|
||||
|
||||
if (np->tag == 2) { /* It's a triangle */
|
||||
tpp = (gtri **)&np;
|
||||
t_single = (gtri *)np;
|
||||
tpp = &t_single;
|
||||
nt = 1;
|
||||
} else if (np->tag == 3) { /* It's a triangle list */
|
||||
gbspl *n = (gbspl *)np;
|
||||
|
||||
@@ -169,6 +169,8 @@ static void set_default(gamdisp *gds, int n) {
|
||||
|
||||
static int g_vect_isect(gamut *s, double *p, double *p1, double *p2);
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa, nfa, mfa; /* argument we're looking at */
|
||||
|
||||
@@ -42,6 +42,7 @@ LINKLIBS = ../numlib/libnum ;
|
||||
# GenFile source.c : program args ; make custom file
|
||||
# Generate all the kernel files
|
||||
GenFileND imdi_k.h : imdi_make $(IMDI_MAKE_OPT) -d [ NormPaths $(DOT) ] ;
|
||||
Clean clean : imdi_k.c ;
|
||||
|
||||
# imdi library
|
||||
Library libimdi : imdi.c imdi_tab.c ;
|
||||
|
||||
@@ -975,6 +975,8 @@ J_COLOR_SPACE cspace
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa, nfa; /* argument we're looking at */
|
||||
|
||||
@@ -429,6 +429,8 @@ static void output_curves(
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa,nfa; /* argument we're looking at */
|
||||
|
||||
@@ -186,6 +186,8 @@ void output_curve(
|
||||
out_vals[e] = in_vals[e];
|
||||
}
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa,nfa; /* argument we're looking at */
|
||||
|
||||
@@ -136,6 +136,7 @@ void usage(void) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa,nfa; /* argument we're looking at */
|
||||
|
||||
+55
-27
@@ -7,7 +7,7 @@ echo "Script to invoke Jam and then package the binary release."
|
||||
PRODUCT=Argyll
|
||||
|
||||
# Set the environment string VERSION from the #define, ie 1.0.0
|
||||
VERSION=`grep ARGYLL_VERSION_STR h/aconfig.h | head -1 | sed 's/# define ARGYLL_VERSION_STR //' | sed 's/"//g'`
|
||||
VERSION=`grep ARGYLL_VERSION_STR h/aconfig.h | head -1 | sed 's/# define ARGYLL_VERSION_STR //' | sed 's/\"//g'`
|
||||
|
||||
# Typical environment variables:
|
||||
# (NOTE some systems don't export these ENV vars. by default !!!)
|
||||
@@ -106,12 +106,20 @@ else if [ "${OSTYPE#*darwin*}" != "$OSTYPE" ] ; then
|
||||
PACKAGE=${PRODUCT}_V${VERSION}_osx10.4_i86_bin.tgz
|
||||
else if [ X$HOSTTYPE = "Xx86_64" \
|
||||
-o X$COMPILER = "XOSX10_6_X86_64BIT" ] ; then
|
||||
echo "We're on OSX 10 x86_64!"
|
||||
PACKAGE=${PRODUCT}_V${VERSION}_osx10.6_x86_64_bin.tgz
|
||||
echo "We're on MacOS x86_64!"
|
||||
PACKAGE=${PRODUCT}_V${VERSION}_macOS_x86_64_bin.tgz
|
||||
export MACOSX_DEPLOYMENT_TARGET="10.15" # Minimum target platform version
|
||||
else if [ X$HOSTTYPE = "Xarm64" ] ; then
|
||||
echo "We're on MacOS arm64!"
|
||||
PACKAGE=${PRODUCT}_V${VERSION}_macOS_arm64_bin.tgz
|
||||
export MACOSX_DEPLOYMENT_TARGET="11.0" # Minimum target platform version
|
||||
else if [ X$HOSTTYPE = "Xuniversal" \
|
||||
-o X$MACHTYPE = "Xuniversal-apple-darwin" \
|
||||
-o X$COMPILER = "XUNIVERSAL" ] ; then
|
||||
echo "We're on MacOS Universal!"
|
||||
PACKAGE=${PRODUCT}_V${VERSION}_macOS_universal_bin.tgz
|
||||
export MACOSX_DEPLOYMENT_TARGET="10.15" # Minimum target platform version
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -144,35 +152,56 @@ fi
|
||||
|
||||
echo "Making GNU $PRODUCT binary distribution $PACKAGE for Version $VERSION"
|
||||
|
||||
# Clean up so we get a solid build
|
||||
# .sp come from profile, .cht from scanin and .ti3 from spectro
|
||||
rm -f bin/*.exe bin/*.dll
|
||||
rm -f ref/*.sp ref/*.cht ref/*.ti2
|
||||
if [ X$NO_BUILD = "X" ] ; then
|
||||
# Clean up so we get a solid build
|
||||
# .sp come from profile, .cht from scanin and .ti3 from spectro
|
||||
rm -f bin/*.exe bin/*.dll
|
||||
rm -f ref/*.sp ref/*.cht ref/*.ti2
|
||||
|
||||
if [ X$CROSS_COMPILE = "X" ] ; then # If not cross compiling
|
||||
echo "Cleaning before build ..."
|
||||
if ! jam -fJambase -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true clean ; then
|
||||
echo "Clean failed!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ X$CROSS_COMPILE = "X" ] ; then # If not cross compiling
|
||||
echo "Cleaning before build ..."
|
||||
if ! jam -fJambase -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true clean ; then
|
||||
echo "Clean failed!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make sure it's built and installed
|
||||
if ! jam -q -fJambase -j${NUMBER_OF_PROCESSORS:-1} -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install ; then
|
||||
echo "Build failed!"
|
||||
exit 1
|
||||
# Make sure it's built and installed
|
||||
if ! jam -q -fJambase -j${NUMBER_OF_PROCESSORS:-1} -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install ; then
|
||||
echo "Build failed!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Apply ad-hoc code signatures to macOS Mach-O binaries before staging
|
||||
if [ "${OSTYPE#*darwin*}" != "$OSTYPE" ] ; then
|
||||
echo "=== Applying ad-hoc code signatures to macOS Mach-O binaries ==="
|
||||
for f in bin/* ; do
|
||||
if [ -f "$f" ] && file "$f" | grep -q "Mach-O" ; then
|
||||
echo "Signing $f..."
|
||||
codesign -f -s - "$f" || true
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
rm -rf $TOPDIR
|
||||
mkdir $TOPDIR
|
||||
|
||||
# Ensure catalog copies exist if needed for Windows packaging
|
||||
if [ -d usb ] ; then
|
||||
if [ -f usb/ArgyllCMS.cat ] ; then
|
||||
[ ! -f usb/ArgyllCMS_x64.cat ] && cp usb/ArgyllCMS.cat usb/ArgyllCMS_x64.cat
|
||||
[ ! -f usb/ArgyllCMS_arm64.cat ] && cp usb/ArgyllCMS.cat usb/ArgyllCMS_arm64.cat
|
||||
fi
|
||||
fi
|
||||
|
||||
# Collect the names of all the files that we're going to package
|
||||
unset topfiles; for i in `cat binfiles`; do topfiles="$topfiles ${i}"; done
|
||||
unset docfiles; for i in `cat doc/afiles`; do docfiles="$docfiles doc/${i}"; done
|
||||
unset topfiles; for i in `tr -d '\r' < binfiles`; do topfiles="$topfiles ${i}"; done
|
||||
unset docfiles; for i in `tr -d '\r' < doc/afiles`; do docfiles="$docfiles doc/${i}"; done
|
||||
unset usbfiles;
|
||||
for j in ${USBDIRS}; do
|
||||
if [ ${j} ]; then
|
||||
for i in `cat ${j}/${USBBINFILES}`; do usbfiles="$usbfiles ${j}/${i}"; done
|
||||
for i in `tr -d '\r' < ${j}/${USBBINFILES}`; do usbfiles="$usbfiles ${j}/${i}"; done
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -182,16 +211,16 @@ allfiles="${topfiles} bin/* ref/* ${docfiles} ${usbfiles}"
|
||||
for i in ${allfiles}; do
|
||||
path=${i%/*} # extract path without filename
|
||||
file=${i##*/} # extract filename
|
||||
if [ $path = $i ] ; then
|
||||
if [ "$path" = "$i" ] ; then
|
||||
path=
|
||||
fi
|
||||
if [ X$path != "X" ] ; then
|
||||
mkdir -p $TOPDIR/${path}
|
||||
if [ X"$path" != "X" ] ; then
|
||||
mkdir -p "$TOPDIR/${path}"
|
||||
fi
|
||||
if [ X${file} = "Xafiles" ] ; then
|
||||
if [ X"${file}" = "Xafiles" ] ; then
|
||||
continue
|
||||
fi
|
||||
cp $i $TOPDIR/$i
|
||||
cp "$i" "$TOPDIR/$i" || { echo "Failed to copy $i to $TOPDIR/$i"; exit 1; }
|
||||
done
|
||||
|
||||
# Create the package
|
||||
@@ -229,4 +258,3 @@ else
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ struct _tagsigpair {
|
||||
int dir; /* 0 = none or out, 1 = in */
|
||||
}; typedef struct _tagsigpair tagsigpair;
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa,nfa; /* argument we're looking at */
|
||||
|
||||
@@ -47,6 +47,8 @@ usage(void) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
+14
-4
@@ -75,6 +75,14 @@
|
||||
|
||||
#define DEMPH_DEFAULT 1.0 /* Default dark region emphasis == none */
|
||||
|
||||
int json_progress = 0;
|
||||
|
||||
void emit_json_progress(const char *stage, int percent) {
|
||||
if (!json_progress) return;
|
||||
printf("{\"event\": \"progress\", \"stage\": \"%s\", \"percent\": %d}\n", stage, percent);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Flags used:
|
||||
@@ -129,6 +137,7 @@ void usage(char *diag, ...) {
|
||||
fprintf(stderr," X = display XYZ cLUT + matrix, Y = display XYZ cLUT + debug matrix\n");
|
||||
fprintf(stderr," g = gamma+matrix, s = shaper+matrix, m = matrix only,\n");
|
||||
fprintf(stderr," G = single gamma+matrix, S = single shaper+matrix\n");
|
||||
fprintf(stderr," -u Emit structured JSON calculation progress to stdout\n");
|
||||
fprintf(stderr," -u If input profile, auto scale WP to allow extrapolation\n");
|
||||
fprintf(stderr," -ua If input profile, force absolute intent\n");
|
||||
fprintf(stderr," -uc If input profile, clip cLUT values above WP\n");
|
||||
@@ -492,8 +501,6 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
else if (argv[fa][1] == 'u') {
|
||||
autowpsc = 1;
|
||||
clipovwp = 0;
|
||||
if (argv[fa][2] == 'a') {
|
||||
autowpsc = 2;
|
||||
clipovwp = 0;
|
||||
@@ -502,12 +509,15 @@ int main(int argc, char *argv[]) {
|
||||
clipovwp = 1;
|
||||
} else if (argv[fa][2] != '\000') {
|
||||
usage("Unknown flag '%c' after -u",argv[fa][2]);
|
||||
|
||||
} else if (na != NULL) {
|
||||
} else if (na != NULL && (isdigit(na[0]) || (na[0] == '.' && isdigit(na[1])))) {
|
||||
fa = nfa;
|
||||
iwpscale = atof(na);
|
||||
if (iwpscale < 0.0 || iwpscale > 200.0)
|
||||
usage("Argument '%s' to flag -u out of range",na);
|
||||
autowpsc = 1;
|
||||
clipovwp = 0;
|
||||
} else {
|
||||
json_progress = 1;
|
||||
}
|
||||
}
|
||||
/* Clip primaries */
|
||||
|
||||
@@ -52,6 +52,8 @@ void usage(char *diag, ...) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
int fa,nfa,mfa; /* argument we're looking at */
|
||||
|
||||
@@ -107,6 +107,8 @@ void usage(void) {
|
||||
|
||||
static void DE2RGB(double *out, double in);
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int
|
||||
main(
|
||||
int argc,
|
||||
|
||||
@@ -58,6 +58,8 @@ FILE *open_pat(char *filename);
|
||||
int next_pat(FILE *fp, double *Lab);
|
||||
void close_pat(FILE *fp);
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -32,6 +32,9 @@ typedef enum {
|
||||
prof_matonly = 7 /* XYZ matrix, linear */
|
||||
} prof_atype;
|
||||
|
||||
extern int json_progress;
|
||||
void emit_json_progress(const char *stage, int percent);
|
||||
|
||||
/* Output or Display device */
|
||||
void make_output_icc(
|
||||
prof_atype ptype, /* Profile output type */
|
||||
|
||||
+24
-2
@@ -55,6 +55,7 @@ usage(void) {
|
||||
fprintf(stderr,"Author: Graeme W. Gill, licensed under the AGPL Version 3\n");
|
||||
fprintf(stderr,"usage: profcheck [-options] data.ti3 iccprofile.icm\n");
|
||||
fprintf(stderr," -v [level] Verbosity level (default 1), 2 to print each DE\n");
|
||||
fprintf(stderr," -u Emit structured JSON Delta E report to stdout\n");
|
||||
fprintf(stderr," -c Show CIE94 delta E values\n");
|
||||
fprintf(stderr," -k Show CIEDE2000 delta E values\n");
|
||||
fprintf(stderr," -w create %s visualisation (iccprofile%s)\n",vrml_format(),vrml_ext());
|
||||
@@ -105,6 +106,7 @@ typedef struct {
|
||||
int main(int argc, char *argv[]) {
|
||||
int fa,nfa; /* current argument we're looking at */
|
||||
int verb = 0;
|
||||
int json_report = 0;
|
||||
int cie94 = 0;
|
||||
int cie2k = 0;
|
||||
int dovrml = 0;
|
||||
@@ -187,6 +189,11 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
/* JSON Delta E report */
|
||||
else if (argv[fa][1] == 'u') {
|
||||
json_report = 1;
|
||||
}
|
||||
|
||||
/* VRML/X3D */
|
||||
else if (argv[fa][1] == 'w')
|
||||
dovrml = 1;
|
||||
@@ -1246,8 +1253,23 @@ int main(int argc, char *argv[]) {
|
||||
wrl->make_lines_vc(wrl, 0, 0.0);
|
||||
wrl->del(wrl);
|
||||
}
|
||||
printf("Profile check complete, errors%s: max. = %f, avg. = %f, RMS = %f\n",
|
||||
cie2k ? "(CIEDE2000)" : cie94 ? " (CIE94)" : "", merr, aerr/nsamps, sqrt(rerr/nsamps));
|
||||
if (json_report) {
|
||||
if (cie2k) {
|
||||
printf("{\"event\": \"report\", \"peak_de2000\": %.2f, \"avg_de2000\": %.2f, \"rms\": %.2f}\n",
|
||||
merr, aerr/nsamps, sqrt(rerr/nsamps));
|
||||
} else if (cie94) {
|
||||
printf("{\"event\": \"report\", \"peak_de94\": %.2f, \"avg_de94\": %.2f, \"rms\": %.2f}\n",
|
||||
merr, aerr/nsamps, sqrt(rerr/nsamps));
|
||||
} else {
|
||||
printf("{\"event\": \"report\", \"peak_de\": %.2f, \"avg_de\": %.2f, \"rms\": %.2f}\n",
|
||||
merr, aerr/nsamps, sqrt(rerr/nsamps));
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
if (verb || !json_report) {
|
||||
printf("Profile check complete, errors%s: max. = %f, avg. = %f, RMS = %f\n",
|
||||
cie2k ? "(CIEDE2000)" : cie94 ? " (CIE94)" : "", merr, aerr/nsamps, sqrt(rerr/nsamps));
|
||||
}
|
||||
|
||||
/* ------------------------------- */
|
||||
/* If we want sort by target value */
|
||||
|
||||
+15
-5
@@ -229,14 +229,19 @@ void in_b2a_clut(void *cntx, double *out, double in[3]
|
||||
DBG(("convert PCS' to DEV' got %f %f %f %f\n",out[0],out[1],out[2],out[3]))
|
||||
DBG(("in_b2a_clut returning DEV' %f %f %f\n",out[0],out[1],out[2]))
|
||||
|
||||
if (p->verb
|
||||
if ((p->verb || json_progress)
|
||||
&& tn == 0
|
||||
) { /* Output percent intervals */
|
||||
int pc;
|
||||
p->count++;
|
||||
pc = (int)(p->count * 100.0/p->total + 0.5);
|
||||
if (pc != p->last) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
if (p->verb) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("b2a_table", pc);
|
||||
}
|
||||
p->last = pc;
|
||||
}
|
||||
}
|
||||
@@ -1171,7 +1176,7 @@ make_input_icc(
|
||||
|
||||
/* We now setup an exact inverse, colorimetric style */
|
||||
/* Use helper function to do the hard work. */
|
||||
if (cx.verb) {
|
||||
if (cx.verb || json_progress) {
|
||||
unsigned int ui;
|
||||
int extra;
|
||||
cx.count = 0;
|
||||
@@ -1182,8 +1187,13 @@ make_input_icc(
|
||||
for (extra = 1, ui = 0; ui < 3; extra *= (blut_clutPoints[ui++]-1))
|
||||
;
|
||||
cx.total += extra;
|
||||
printf("Creating B to A tables\n");
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
if (cx.verb) {
|
||||
printf("Creating B to A tables\n");
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("b2a_table", 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (wr_icco->create_lut_xforms(
|
||||
|
||||
+49
-15
@@ -431,12 +431,17 @@ void in_a2b_clut(void *cntx, double out[3], double *in, int itn) {
|
||||
}
|
||||
DBG(("convert PCS to PCS' got %f %f %f\n",out[0],out[1],out[2]))
|
||||
|
||||
if (p->verb && itn == 0) { /* Output percent intervals */
|
||||
if ((p->verb || json_progress) && itn == 0) { /* Output percent intervals */
|
||||
int pc;
|
||||
p->count++;
|
||||
pc = (int)(p->count * 100.0/p->total + 0.5);
|
||||
if (pc != p->last) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
if (p->verb) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("a2b_table", pc);
|
||||
}
|
||||
p->last = pc;
|
||||
}
|
||||
}
|
||||
@@ -658,12 +663,17 @@ void out_b2a_clut(void *cntx, double *out, double in[3], int itn) {
|
||||
|
||||
DBG(("out_b2a_clut returning DEV' %s\n",icmPdv(p->ochan, out)))
|
||||
|
||||
if (p->verb && itn == 0) { /* Output percent intervals */
|
||||
if ((p->verb || json_progress) && itn == 0) { /* Output percent intervals */
|
||||
int pc;
|
||||
p->count++;
|
||||
pc = (int)(p->count * 100.0/p->total + 0.5);
|
||||
if (pc != p->last) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
if (p->verb) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("b2a_table", pc);
|
||||
}
|
||||
p->last = pc;
|
||||
}
|
||||
}
|
||||
@@ -728,12 +738,17 @@ static void PCSp_bdist(void *cntx, double out[1], double in[3], int tn
|
||||
out[0] = (gdist + 20.0)/40.0;
|
||||
//printf("~1 bdist returning %f\n",out[0]);
|
||||
|
||||
if (p->verb) { /* Output percent intervals */
|
||||
if (p->verb || json_progress) { /* Output percent intervals */
|
||||
int pc;
|
||||
p->count++;
|
||||
pc = (int)(p->count * 100.0/p->total + 0.5);
|
||||
if (pc != p->last) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
if (p->verb) {
|
||||
printf("%c%2d%%",cr_char,pc); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("gamut_table", pc);
|
||||
}
|
||||
p->last = pc;
|
||||
}
|
||||
}
|
||||
@@ -2551,6 +2566,7 @@ make_output_icc(
|
||||
if (csgamp == NULL) {
|
||||
if (verb)
|
||||
printf(" Finding Source Colorspace Perceptual Gamut\n");
|
||||
emit_json_progress("gamut_mapping", 10);
|
||||
|
||||
if ((csgamp = cx.ixp->get_gamut(cx.ixp, gres)) == NULL)
|
||||
error ("%d, %s",src_xicc->e.c, src_xicc->e.m);
|
||||
@@ -2567,6 +2583,7 @@ make_output_icc(
|
||||
|
||||
if (verb)
|
||||
printf(" Finding Source Colorspace Saturation Gamut\n");
|
||||
emit_json_progress("gamut_mapping", 25);
|
||||
|
||||
if ((csgams = ixs->get_gamut(ixs, gres)) == NULL)
|
||||
error ("%d, %s",src_xicc->e.c, src_xicc->e.m);
|
||||
@@ -2614,6 +2631,7 @@ make_output_icc(
|
||||
/* Creat the destination gamut surface */
|
||||
if (verb)
|
||||
printf(" Finding Destination Gamut\n");
|
||||
emit_json_progress("gamut_mapping", 40);
|
||||
|
||||
if ((ogam = cx.ox->get_gamut(cx.ox, gres)) == NULL)
|
||||
error ("%d, %s",wr_xicc->e.c, wr_xicc->e.m);
|
||||
@@ -2657,6 +2675,7 @@ make_output_icc(
|
||||
|
||||
if (verb)
|
||||
printf(" Creating Gamut match\n");
|
||||
emit_json_progress("gamut_mapping", 75);
|
||||
|
||||
/* The real range of Lab 0..100,-128..128,1-28..128 cube */
|
||||
/* when mapped to CAM is ridiculously large (ie. */
|
||||
@@ -2673,6 +2692,7 @@ make_output_icc(
|
||||
);
|
||||
if (cx.pmap == NULL)
|
||||
error ("Failed to make perceptual gamut map transform");
|
||||
emit_json_progress("gamut_mapping", 100);
|
||||
|
||||
|
||||
if (sepsat) {
|
||||
@@ -2784,7 +2804,7 @@ make_output_icc(
|
||||
for (i = 0; i < cx.ochan; i++)
|
||||
a2bgres[i] = a2bres;
|
||||
|
||||
if (cx.verb) {
|
||||
if (cx.verb || json_progress) {
|
||||
unsigned int ui;
|
||||
int extra;
|
||||
cx.count = 0;
|
||||
@@ -2797,9 +2817,13 @@ make_output_icc(
|
||||
;
|
||||
cx.total += extra;
|
||||
#endif
|
||||
printf("Creating inverse gamut mapped A to B tables\n");
|
||||
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
if (cx.verb) {
|
||||
printf("Creating inverse gamut mapped A to B tables\n");
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("a2b_table", 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_IGM_ONE
|
||||
@@ -2879,7 +2903,7 @@ make_output_icc(
|
||||
/* for perceptual and saturation intents */
|
||||
/* Use helper function to do the hard work. */
|
||||
|
||||
if (cx.verb) {
|
||||
if (cx.verb || json_progress) {
|
||||
unsigned int ui;
|
||||
int extra;
|
||||
cx.count = 0;
|
||||
@@ -2892,8 +2916,13 @@ make_output_icc(
|
||||
;
|
||||
cx.total += extra;
|
||||
#endif
|
||||
printf("Creating B to A tables\n");
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
if (cx.verb) {
|
||||
printf("Creating B to A tables\n");
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("b2a_table", 0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ONE
|
||||
@@ -3137,13 +3166,18 @@ make_output_icc(
|
||||
for (i = 0; i < cx.ichan; i++)
|
||||
clutres[i] = b2ares;
|
||||
|
||||
if (cx.verb) {
|
||||
if (cx.verb || json_progress) {
|
||||
unsigned int ui;
|
||||
cx.count = 0;
|
||||
cx.last = -1;
|
||||
for (cx.total = 1, ui = 0; ui < cx.ichan; cx.total *= clutres[ui++])
|
||||
;
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
if (cx.verb) {
|
||||
printf(" 0%%"); fflush(stdout);
|
||||
}
|
||||
if (json_progress) {
|
||||
emit_json_progress("gamut_table", 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -173,6 +173,8 @@ void calc_bc(edatas *ed) {
|
||||
|
||||
void usage(void);
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i,j,k;
|
||||
|
||||
@@ -60,6 +60,8 @@ usage(void) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#include "ui.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fa,nfa; /* current argument we're looking at */
|
||||
int verb = 0;
|
||||
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user