Compare commits
40
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0672ab7fea | ||
|
|
f837314f5c | ||
|
|
e80e41beb9 | ||
|
|
851c7eece3 | ||
|
|
b67c7ca318 | ||
|
|
7744518b87 | ||
|
|
c5c06f5dc6 | ||
|
|
18c6a4c89d | ||
|
|
c4cc3de0ec | ||
|
|
931d92cddf | ||
|
|
16eb647b1a | ||
|
|
20bce9dff4 | ||
|
|
edeb6dcf67 | ||
|
|
cb5e740688 | ||
|
|
5392458515 | ||
|
|
39cad74c43 | ||
|
|
d271bb603d | ||
|
|
d1bf83928d | ||
|
|
e194514264 | ||
|
|
2261ebd331 | ||
|
|
de3065f4cc | ||
|
|
9c3982354d | ||
|
|
86e692ecda | ||
|
|
f30d16816f | ||
|
|
cf93305fdd | ||
|
|
1eb72e865b | ||
|
|
e0f86eec29 | ||
|
|
c196912bed | ||
|
|
ebbc675297 | ||
|
|
21d59d891c | ||
|
|
7b3ebf4c87 | ||
|
|
cc61e2aa4c | ||
|
|
a07a5d638d | ||
|
|
5b75dd4284 | ||
|
|
fb6b37bade | ||
|
|
b02df94744 | ||
|
|
429c772e4a | ||
|
|
d843716e8b | ||
|
|
b763dd78d1 | ||
|
|
c88187b200 |
@@ -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
|
||||||
@@ -63,6 +63,15 @@ jobs:
|
|||||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||||
mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip"
|
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
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: macos-15-intel
|
- os: macos-26-intel
|
||||||
arch: x86_64
|
arch: x86_64
|
||||||
machtype: x86_64-apple-darwin
|
machtype: x86_64-apple-darwin
|
||||||
artifact: macOS_x86_64_bin
|
artifact: macOS_x86_64_bin
|
||||||
- os: macos-15
|
- os: macos-latest
|
||||||
arch: arm64
|
arch: arm64
|
||||||
machtype: arm64-apple-darwin
|
machtype: arm64-apple-darwin
|
||||||
artifact: macOS_arm64_bin
|
artifact: macOS_arm64_bin
|
||||||
@@ -43,6 +43,16 @@ jobs:
|
|||||||
export CCOPTFLAG="-O0"
|
export CCOPTFLAG="-O0"
|
||||||
jam -q -d2 -fJambase -j1 -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true install
|
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
|
- name: Smoke Tests
|
||||||
env:
|
env:
|
||||||
ARGYLL_NOT_INTERACTIVE: "1"
|
ARGYLL_NOT_INTERACTIVE: "1"
|
||||||
@@ -64,6 +74,12 @@ jobs:
|
|||||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||||
mv Argyll_V*_${{ matrix.artifact }}.tgz "Argyll_${TAG}_${SHORT_SHA}_${{ matrix.artifact }}.tgz"
|
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
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -77,3 +93,103 @@ jobs:
|
|||||||
name: Release ${{ github.ref_name }}
|
name: Release ${{ github.ref_name }}
|
||||||
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
body: "Release ${{ github.ref_name }} built from commit ${{ github.sha }}"
|
||||||
files: Argyll_*_${{ matrix.artifact }}.tgz
|
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
|
||||||
|
|||||||
@@ -65,6 +65,15 @@ jobs:
|
|||||||
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
echo "SHORT_SHA=${SHORT_SHA}" >> $GITHUB_ENV
|
||||||
mv Argyll_V*_win64_exe.zip "Argyll_${TAG}_${SHORT_SHA}_win64_exe.zip"
|
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
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
<h1>[V3.4.1 -> V3.5.0] 4th February 2026<br>
|
<h1>[V3.4.1 -> V3.5.0] 4th February 2026<br>
|
||||||
</h1>
|
</h1>
|
||||||
<ul>
|
<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 MSWindows ARM release.</li>
|
||||||
<li>Added Mac ARM release.</li>
|
<li>Added Mac ARM release.</li>
|
||||||
<li>Removed Mac PowerPC build from release.</li>
|
<li>Removed Mac PowerPC build from release.</li>
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ channels
|
|||||||
|
|
||||||
|
|
||||||
Dither 8 bit TIFF values down from 16 bit<br>
|
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>
|
<a href="#Q">-Q nbits</a>
|
||||||
Quantize
|
Quantize
|
||||||
test
|
test
|
||||||
@@ -758,6 +759,12 @@ A3
|
|||||||
to use it to verify the overall operation of the printing system), then you
|
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>
|
can use the <b>-U</b> flag to disable this.<br>
|
||||||
<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
|
<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
|
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
|
specified in millimeters. Limitations of the instrument may limit the
|
||||||
|
|||||||
+51
-23
@@ -7,7 +7,7 @@ echo "Script to invoke Jam and then package the binary release."
|
|||||||
PRODUCT=Argyll
|
PRODUCT=Argyll
|
||||||
|
|
||||||
# Set the environment string VERSION from the #define, ie 1.0.0
|
# 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:
|
# Typical environment variables:
|
||||||
# (NOTE some systems don't export these ENV vars. by default !!!)
|
# (NOTE some systems don't export these ENV vars. by default !!!)
|
||||||
@@ -113,6 +113,13 @@ else if [ "${OSTYPE#*darwin*}" != "$OSTYPE" ] ; then
|
|||||||
echo "We're on MacOS arm64!"
|
echo "We're on MacOS arm64!"
|
||||||
PACKAGE=${PRODUCT}_V${VERSION}_macOS_arm64_bin.tgz
|
PACKAGE=${PRODUCT}_V${VERSION}_macOS_arm64_bin.tgz
|
||||||
export MACOSX_DEPLOYMENT_TARGET="11.0" # Minimum target platform version
|
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
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -145,35 +152,56 @@ fi
|
|||||||
|
|
||||||
echo "Making GNU $PRODUCT binary distribution $PACKAGE for Version $VERSION"
|
echo "Making GNU $PRODUCT binary distribution $PACKAGE for Version $VERSION"
|
||||||
|
|
||||||
# Clean up so we get a solid build
|
if [ X$NO_BUILD = "X" ] ; then
|
||||||
# .sp come from profile, .cht from scanin and .ti3 from spectro
|
# Clean up so we get a solid build
|
||||||
rm -f bin/*.exe bin/*.dll
|
# .sp come from profile, .cht from scanin and .ti3 from spectro
|
||||||
rm -f ref/*.sp ref/*.cht ref/*.ti2
|
rm -f bin/*.exe bin/*.dll
|
||||||
|
rm -f ref/*.sp ref/*.cht ref/*.ti2
|
||||||
|
|
||||||
if [ X$CROSS_COMPILE = "X" ] ; then # If not cross compiling
|
if [ X$CROSS_COMPILE = "X" ] ; then # If not cross compiling
|
||||||
echo "Cleaning before build ..."
|
echo "Cleaning before build ..."
|
||||||
if ! jam -fJambase -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true clean ; then
|
if ! jam -fJambase -sBUILTIN_TIFF=true -sBUILTIN_JPEG=true -sBUILTIN_PNG=true -sBUILTIN_Z=true -sBUILTIN_SSL=true clean ; then
|
||||||
echo "Clean failed!"
|
echo "Clean failed!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure it's built and installed
|
# Apply ad-hoc code signatures to macOS Mach-O binaries before staging
|
||||||
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
|
if [ "${OSTYPE#*darwin*}" != "$OSTYPE" ] ; then
|
||||||
echo "Build failed!"
|
echo "=== Applying ad-hoc code signatures to macOS Mach-O binaries ==="
|
||||||
exit 1
|
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
|
fi
|
||||||
|
|
||||||
rm -rf $TOPDIR
|
rm -rf $TOPDIR
|
||||||
mkdir $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
|
# 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 topfiles; for i in `tr -d '\r' < binfiles`; do topfiles="$topfiles ${i}"; done
|
||||||
unset docfiles; for i in `cat doc/afiles`; do docfiles="$docfiles doc/${i}"; done
|
unset docfiles; for i in `tr -d '\r' < doc/afiles`; do docfiles="$docfiles doc/${i}"; done
|
||||||
unset usbfiles;
|
unset usbfiles;
|
||||||
for j in ${USBDIRS}; do
|
for j in ${USBDIRS}; do
|
||||||
if [ ${j} ]; then
|
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
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -183,16 +211,16 @@ allfiles="${topfiles} bin/* ref/* ${docfiles} ${usbfiles}"
|
|||||||
for i in ${allfiles}; do
|
for i in ${allfiles}; do
|
||||||
path=${i%/*} # extract path without filename
|
path=${i%/*} # extract path without filename
|
||||||
file=${i##*/} # extract filename
|
file=${i##*/} # extract filename
|
||||||
if [ $path = $i ] ; then
|
if [ "$path" = "$i" ] ; then
|
||||||
path=
|
path=
|
||||||
fi
|
fi
|
||||||
if [ X$path != "X" ] ; then
|
if [ X"$path" != "X" ] ; then
|
||||||
mkdir -p $TOPDIR/${path}
|
mkdir -p "$TOPDIR/${path}"
|
||||||
fi
|
fi
|
||||||
if [ X${file} = "Xafiles" ] ; then
|
if [ X"${file}" = "Xafiles" ] ; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
cp $i $TOPDIR/$i
|
cp "$i" "$TOPDIR/$i" || { echo "Failed to copy $i to $TOPDIR/$i"; exit 1; }
|
||||||
done
|
done
|
||||||
|
|
||||||
# Create the package
|
# Create the package
|
||||||
|
|||||||
+13
-12
@@ -203,36 +203,37 @@ static int con_char(int wait) {
|
|||||||
/* We assume pipe has been set to NOWAIT mode. */
|
/* We assume pipe has been set to NOWAIT mode. */
|
||||||
} else if (stdin_type == FILE_TYPE_PIPE) {
|
} else if (stdin_type == FILE_TYPE_PIPE) {
|
||||||
int i, bib;
|
int i, bib;
|
||||||
//fprintf(stderr,"~1 top of pipe\n");
|
DWORD bytes_avail = 0;
|
||||||
|
|
||||||
|
/* Check available bytes in pipe before blocking */
|
||||||
|
if (!PeekNamedPipe(stdinh, NULL, 0, NULL, &bytes_avail, NULL) || bytes_avail == 0) {
|
||||||
|
if (!wait) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (bib = 0; bib < 10;) {
|
for (bib = 0; bib < 10;) {
|
||||||
//fprintf(stderr,"~1 got %d in buf\n",bib);
|
if (!wait) {
|
||||||
|
if (!PeekNamedPipe(stdinh, NULL, 0, NULL, &bytes_avail, NULL) || bytes_avail == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ((!ReadFile(stdinh, buf + bib, 10 - bib, &bread, NULL) || bread == 0)
|
if ((!ReadFile(stdinh, buf + bib, 10 - bib, &bread, NULL) || bread == 0)
|
||||||
&& !wait) {
|
&& !wait) {
|
||||||
//fprintf(stderr,"~1 no chars waiting\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bib += bread;
|
bib += bread;
|
||||||
|
|
||||||
for (i = 0; i < bib; i++) {
|
for (i = 0; i < bib; i++) {
|
||||||
if (buf[i] == '\n' || buf[i] == '\r' || buf[i] == 0x3) {
|
if (buf[i] == '\n' || buf[i] == '\r' || buf[i] == 0x3) {
|
||||||
//fprintf(stderr,"~1 found lf at ix %d\n",i);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < bib) {
|
if (i < bib) {
|
||||||
//fprintf(stderr,"~1 found lf\n");
|
|
||||||
break; /* Found '\n' */
|
break; /* Found '\n' */
|
||||||
}
|
}
|
||||||
Sleep(100); /* Wait for a line ending in '\n' */
|
Sleep(100); /* Wait for a line ending in '\n' */
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (bread > 0) {
|
|
||||||
//fprintf(stderr,"~1 read %d: ",bread);
|
|
||||||
//for (i = 0; i < bread; i++)
|
|
||||||
//fprintf(stderr," 0x%x",buf[i]);
|
|
||||||
//fprintf(stderr,"\n//");
|
|
||||||
//}
|
|
||||||
rv = buf[0];
|
rv = buf[0];
|
||||||
|
|
||||||
/* Assume a file. This will have very limited functionality. */
|
/* Assume a file. This will have very limited functionality. */
|
||||||
|
|||||||
@@ -948,6 +948,8 @@ static void
|
|||||||
i1pro_del(inst *pp) {
|
i1pro_del(inst *pp) {
|
||||||
i1pro *p = (i1pro *)pp;
|
i1pro *p = (i1pro *)pp;
|
||||||
|
|
||||||
|
/* Shut down instrument hardware and close the port, then free state */
|
||||||
|
i1pro_close_port(p);
|
||||||
del_i1proimp(p);
|
del_i1proimp(p);
|
||||||
if (p->icom != NULL)
|
if (p->icom != NULL)
|
||||||
p->icom->del(p->icom);
|
p->icom->del(p->icom);
|
||||||
|
|||||||
+119
-31
@@ -389,8 +389,106 @@ i1pro_code add_i1proimp(i1pro *p) {
|
|||||||
return I1PRO_OK;
|
return I1PRO_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shutdown instrument, and then destroy */
|
/* Stop background threads (switch monitoring & delayed trigger) */
|
||||||
/* implementation structure */
|
static void
|
||||||
|
i1pro_stop_threads(i1pro *p) {
|
||||||
|
i1proimp *m;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (p == NULL || p->m == NULL)
|
||||||
|
return;
|
||||||
|
m = (i1proimp *)p->m;
|
||||||
|
|
||||||
|
/* Stop the switch monitoring thread first so it isn't using the */
|
||||||
|
/* communication channel while we shut down the instrument. */
|
||||||
|
if (m->th != NULL) {
|
||||||
|
m->th_term = 1; /* Tell thread to exit on error */
|
||||||
|
|
||||||
|
/* Ask the instrument to stop sending switch events and cancel */
|
||||||
|
/* any outstanding switch read. Only do this if the port is still */
|
||||||
|
/* open and the required method pointers are valid. */
|
||||||
|
if (p->icom != NULL && p->icom->is_open
|
||||||
|
&& p->icom->usb_control != NULL
|
||||||
|
&& p->icom->usb_cancel_io != NULL) {
|
||||||
|
i1pro_terminate_switch(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give the thread a chance to exit cleanly (up to 5 seconds). */
|
||||||
|
for (i = 0; m->th_termed == 0 && i < 100; i++)
|
||||||
|
msec_sleep(50);
|
||||||
|
|
||||||
|
if (m->th_termed == 0) {
|
||||||
|
a1logd(p->log,3,"i1pro switch thread did not terminate, forcing\n");
|
||||||
|
if (m->th->terminate != NULL)
|
||||||
|
m->th->terminate(m->th);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m->th->wait != NULL)
|
||||||
|
m->th->wait(m->th);
|
||||||
|
if (m->th->del != NULL)
|
||||||
|
m->th->del(m->th);
|
||||||
|
m->th = NULL;
|
||||||
|
|
||||||
|
usb_uninit_cancel(&m->sw_cancel); /* Don't need cancel token now */
|
||||||
|
usb_uninit_cancel(&m->rd_sync); /* Don't need sync token now */
|
||||||
|
a1logd(p->log,5,"i1pro switch thread terminated\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop the delayed trigger thread if it is still running */
|
||||||
|
if (m->trig_thread != NULL) {
|
||||||
|
if (m->trig_thread->wait != NULL)
|
||||||
|
m->trig_thread->wait(m->trig_thread);
|
||||||
|
if (m->trig_thread->del != NULL)
|
||||||
|
m->trig_thread->del(m->trig_thread);
|
||||||
|
m->trig_thread = NULL;
|
||||||
|
a1logd(p->log,5,"i1pro trigger thread terminated\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stop any pending I/O, shut down the instrument hardware, and close the */
|
||||||
|
/* communication port. This is separate from freeing the implementation data. */
|
||||||
|
i1pro_code
|
||||||
|
i1pro_close_port(i1pro *p) {
|
||||||
|
i1pro_code ev = I1PRO_OK;
|
||||||
|
i1proimp *m;
|
||||||
|
|
||||||
|
a1logd(p->log,3,"i1pro_close_port: called\n");
|
||||||
|
|
||||||
|
if (p->m == NULL)
|
||||||
|
return I1PRO_OK;
|
||||||
|
m = (i1proimp *)p->m;
|
||||||
|
|
||||||
|
/* Stop the switch monitoring thread and trigger thread first so they */
|
||||||
|
/* aren't using the communication channel while we shut down the instrument. */
|
||||||
|
i1pro_stop_threads(p);
|
||||||
|
|
||||||
|
/* Update usage log/calibration for Rev A..D before closing the port */
|
||||||
|
if (p->dtype != instI1Pro2 && p->icom != NULL && p->icom->is_open
|
||||||
|
&& p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
|
||||||
|
i1pro_code uev;
|
||||||
|
if ((uev = i1pro_update_log(p)) != I1PRO_OK) {
|
||||||
|
a1logd(p->log,2,"i1pro_update_log: Updating the cal and log parameters to"
|
||||||
|
" EEProm failed failed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn off i1Pro2/Rev E indicator LEDs before closing the port. */
|
||||||
|
/* Only attempt the write if the port is still actively open and the */
|
||||||
|
/* required USB method pointers are valid. Rev A..D do not have LEDs. */
|
||||||
|
if (p->dtype == instI1Pro2 && p->icom != NULL && p->icom->is_open
|
||||||
|
&& p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
|
||||||
|
i1pro2_indLEDoff(p); /* Ignore error - we're shutting down */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the underlying communication port */
|
||||||
|
if (p->icom != NULL && p->icom->is_open && p->icom->close_port != NULL) {
|
||||||
|
p->icom->close_port(p->icom);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy implementation structure */
|
||||||
void del_i1proimp(i1pro *p) {
|
void del_i1proimp(i1pro *p) {
|
||||||
|
|
||||||
a1logd(p->log,5,"i1pro_del called\n");
|
a1logd(p->log,5,"i1pro_del called\n");
|
||||||
@@ -404,38 +502,28 @@ void del_i1proimp(i1pro *p) {
|
|||||||
int i, j;
|
int i, j;
|
||||||
i1proimp *m = (i1proimp *)p->m;
|
i1proimp *m = (i1proimp *)p->m;
|
||||||
i1pro_state *s;
|
i1pro_state *s;
|
||||||
i1pro_code ev;
|
|
||||||
|
|
||||||
if (p->dtype != instI1Pro2 && (ev = i1pro_update_log(p)) != I1PRO_OK) {
|
/* Defensive guard: ensure background threads are terminated and joined */
|
||||||
a1logd(p->log,2,"i1pro_update_log: Updating the cal and log parameters to"
|
/* before freeing state, in case i1pro_close_port() was not called. */
|
||||||
" EEProm failed failed\n");
|
i1pro_stop_threads(p);
|
||||||
|
|
||||||
|
/* Defensive guard: update usage log/cal for Rev A..D if port is still open */
|
||||||
|
if (p->dtype != instI1Pro2 && p->icom != NULL && p->icom->is_open
|
||||||
|
&& p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
|
||||||
|
i1pro_code uev;
|
||||||
|
if ((uev = i1pro_update_log(p)) != I1PRO_OK) {
|
||||||
|
a1logd(p->log,2,"i1pro_update_log: Updating the cal and log parameters to"
|
||||||
|
" EEProm failed failed\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* i1pro_terminate_switch() seems to fail on a rev A & Rev C ?? */
|
/* Defensive guard: if the com port is still open and this is an */
|
||||||
if (m->th != NULL) { /* Terminate switch monitor thread */
|
/* i1Pro2, make sure the indicator LEDs are turned off before any */
|
||||||
m->th_term = 1; /* Tell thread to exit on error */
|
/* memory is freed. In normal teardown i1pro_close_port() has */
|
||||||
i1pro_terminate_switch(p);
|
/* already done this, but the guard protects any direct call paths. */
|
||||||
|
if (p->dtype == instI1Pro2 && p->icom != NULL && p->icom->is_open
|
||||||
for (i = 0; m->th_termed == 0 && i < 5; i++)
|
&& p->icom->usb_control != NULL && p->icom->usb_write != NULL) {
|
||||||
msec_sleep(50); /* Wait for thread to terminate */
|
i1pro2_indLEDoff(p);
|
||||||
if (i >= 5) {
|
|
||||||
a1logd(p->log,5,"i1pro switch thread termination failed\n");
|
|
||||||
m->th->terminate(m->th); /* Try and force thread to terminate */
|
|
||||||
}
|
|
||||||
/* Strange Mac M2/rosetta bug ?? */
|
|
||||||
if (m->th->del == NULL) {
|
|
||||||
a1logd(p->log,1,"i1pro_del: ,m->th-del is NULL!!!");
|
|
||||||
} else {
|
|
||||||
m->th->del(m->th);
|
|
||||||
}
|
|
||||||
usb_uninit_cancel(&m->sw_cancel); /* Don't need cancel token now */
|
|
||||||
usb_uninit_cancel(&m->rd_sync); /* Don't need sync token now */
|
|
||||||
a1logd(p->log,5,"i1pro switch thread terminated\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m->trig_thread != NULL) {
|
|
||||||
m->trig_thread->del(m->trig_thread);
|
|
||||||
a1logd(p->log,5,"i1pro trigger thread terminated\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free any per mode data */
|
/* Free any per mode data */
|
||||||
|
|||||||
@@ -348,6 +348,9 @@ i1pro_code add_i1proimp(i1pro *p);
|
|||||||
/* Destroy implementation structure */
|
/* Destroy implementation structure */
|
||||||
void del_i1proimp(i1pro *p);
|
void del_i1proimp(i1pro *p);
|
||||||
|
|
||||||
|
/* Close instrument (stop threads, update log, turn off LEDs, close coms) */
|
||||||
|
i1pro_code i1pro_close_port(i1pro *p);
|
||||||
|
|
||||||
/* ============================================================ */
|
/* ============================================================ */
|
||||||
/* Error codes returned from i1pro_imp */
|
/* Error codes returned from i1pro_imp */
|
||||||
|
|
||||||
|
|||||||
+63
-9
@@ -463,6 +463,29 @@ static void ps_hexagon(trend *ss,
|
|||||||
fprintf(s->of,"%f %f %f %f hex\n",w,h,x,y);
|
fprintf(s->of,"%f %f %f %f hex\n",w,h,x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper to escape characters in PostScript string literals */
|
||||||
|
static void ps_escape_str(char *dst, int maxdst, const char *src) {
|
||||||
|
int di = 0;
|
||||||
|
if (dst == NULL || maxdst <= 0) return;
|
||||||
|
if (src == NULL) { dst[0] = '\0'; return; }
|
||||||
|
while (*src != '\0' && di < maxdst - 2) {
|
||||||
|
if (*src == '(' || *src == ')' || *src == '\\') {
|
||||||
|
if (di < maxdst - 3) {
|
||||||
|
dst[di++] = '\\';
|
||||||
|
dst[di++] = *src++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (*src == '\r' || *src == '\n') {
|
||||||
|
dst[di++] = ' ';
|
||||||
|
src++;
|
||||||
|
} else {
|
||||||
|
dst[di++] = *src++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst[di] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/* A centered string */
|
/* A centered string */
|
||||||
static void ps_string(trend *ss,
|
static void ps_string(trend *ss,
|
||||||
double x, double y, /* Bot Left Corner of rectangle in mm from origin */
|
double x, double y, /* Bot Left Corner of rectangle in mm from origin */
|
||||||
@@ -470,15 +493,17 @@ static void ps_string(trend *ss,
|
|||||||
char *str /* String */
|
char *str /* String */
|
||||||
) {
|
) {
|
||||||
ps_trend *s = (ps_trend *)ss;
|
ps_trend *s = (ps_trend *)ss;
|
||||||
|
char esc_str[2048];
|
||||||
|
|
||||||
if (fabs(w) < 1e-6 || fabs(h) < 1e-6)
|
if (fabs(w) < 1e-6 || fabs(h) < 1e-6 || str == NULL || str[0] == '\000')
|
||||||
return; /* Skip zero sized string */
|
return; /* Skip zero sized or empty string */
|
||||||
|
ps_escape_str(esc_str, sizeof(esc_str), str);
|
||||||
x = mm2pnt(x);
|
x = mm2pnt(x);
|
||||||
y = mm2pnt(y);
|
y = mm2pnt(y);
|
||||||
w = mm2pnt(w);
|
w = mm2pnt(w);
|
||||||
h = mm2pnt(h);
|
h = mm2pnt(h);
|
||||||
fprintf(s->of,"%f scaleTimes\n",h * 0.75);
|
fprintf(s->of,"%f scaleTimes\n",h * 0.75);
|
||||||
fprintf(s->of,"(%s) %f %f centerShow\n",str,x+w/2.0,y+h/2.0);
|
fprintf(s->of,"(%s) %f %f centerShow\n",esc_str,x+w/2.0,y+h/2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A vertically centered string */
|
/* A vertically centered string */
|
||||||
@@ -488,15 +513,17 @@ static void ps_vstring(trend *ss,
|
|||||||
char *str /* String */
|
char *str /* String */
|
||||||
) {
|
) {
|
||||||
ps_trend *s = (ps_trend *)ss;
|
ps_trend *s = (ps_trend *)ss;
|
||||||
|
char esc_str[2048];
|
||||||
|
|
||||||
if (fabs(w) < 1e-6 || fabs(h) < 1e-6)
|
if (fabs(w) < 1e-6 || fabs(h) < 1e-6 || str == NULL || str[0] == '\000')
|
||||||
return; /* Skip zero sized string */
|
return; /* Skip zero sized or empty string */
|
||||||
|
ps_escape_str(esc_str, sizeof(esc_str), str);
|
||||||
x = mm2pnt(x);
|
x = mm2pnt(x);
|
||||||
y = mm2pnt(y);
|
y = mm2pnt(y);
|
||||||
w = mm2pnt(w);
|
w = mm2pnt(w);
|
||||||
h = mm2pnt(h);
|
h = mm2pnt(h);
|
||||||
fprintf(s->of,"%f scaleTimes\n",w * 0.75);
|
fprintf(s->of,"%f scaleTimes\n",w * 0.75);
|
||||||
fprintf(s->of,"(%s) %f %f vcenterShow\n",str,x-w/2.0,y+h/2.0);
|
fprintf(s->of,"(%s) %f %f vcenterShow\n",esc_str,x-w/2.0,y+h/2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A dotted line */
|
/* A dotted line */
|
||||||
@@ -872,6 +899,8 @@ static void tiff_string(trend *ss,
|
|||||||
tiff_trend *s = (tiff_trend *)ss;
|
tiff_trend *s = (tiff_trend *)ss;
|
||||||
double sw = 0.0, sh = 0.0;
|
double sw = 0.0, sh = 0.0;
|
||||||
|
|
||||||
|
if (fabs(w) < 1e-6 || fabs(h) < 1e-6 || str == NULL || str[0] == '\000')
|
||||||
|
return; /* Skip zero sized or empty string */
|
||||||
sh = h * 0.57;
|
sh = h * 0.57;
|
||||||
meas_string2d(s->r,&sw,NULL,timesr_b,str,sh,0);
|
meas_string2d(s->r,&sw,NULL,timesr_b,str,sh,0);
|
||||||
/* Center the string within the recangle */
|
/* Center the string within the recangle */
|
||||||
@@ -889,6 +918,8 @@ static void tiff_vstring(trend *ss,
|
|||||||
tiff_trend *s = (tiff_trend *)ss;
|
tiff_trend *s = (tiff_trend *)ss;
|
||||||
double sw = 0.0, sh = 0.0;
|
double sw = 0.0, sh = 0.0;
|
||||||
|
|
||||||
|
if (fabs(w) < 1e-6 || fabs(h) < 1e-6 || str == NULL || str[0] == '\000')
|
||||||
|
return; /* Skip zero sized or empty string */
|
||||||
x -= w; /* Make it bot left corner */
|
x -= w; /* Make it bot left corner */
|
||||||
sw = w * 0.57;
|
sw = w * 0.57;
|
||||||
meas_string2d(s->r,NULL, &sh,timesr_b,str,sw,3);
|
meas_string2d(s->r,NULL, &sh,timesr_b,str,sw,3);
|
||||||
@@ -2265,6 +2296,9 @@ int *p_npat /* Return number of patches including padding */
|
|||||||
if (scanc & 2) /* Scan compatiblity */
|
if (scanc & 2) /* Scan compatiblity */
|
||||||
sxwi = pwid/2.0; /* First row patches extra width */
|
sxwi = pwid/2.0; /* First row patches extra width */
|
||||||
|
|
||||||
|
if (label == NULL || label[0] == '\000')
|
||||||
|
dopglabel = 0; /* Omit per-page labelling */
|
||||||
|
|
||||||
/* Compute limits for this page size */
|
/* Compute limits for this page size */
|
||||||
/* Figure the available space for patches */
|
/* Figure the available space for patches */
|
||||||
mints = bord + txhisl + lcar; /* Minimum top space due to border, text and clear area */
|
mints = bord + txhisl + lcar; /* Minimum top space due to border, text and clear area */
|
||||||
@@ -3009,6 +3043,7 @@ void usage(char *diag, ...) {
|
|||||||
fprintf(stderr," -C Don't use TIFF compression\n");
|
fprintf(stderr," -C Don't use TIFF compression\n");
|
||||||
fprintf(stderr," -N Use TIFF alpha N channels more than 4\n");
|
fprintf(stderr," -N Use TIFF alpha N channels more than 4\n");
|
||||||
fprintf(stderr," -D Dither 8 bit TIFF values down from 16 bit\n");
|
fprintf(stderr," -D Dither 8 bit TIFF values down from 16 bit\n");
|
||||||
|
fprintf(stderr," -d label Custom chart description/label string, or \"\" to omit labelling\n");
|
||||||
fprintf(stderr," -Q nbits Quantize test values to fit in nbits\n");
|
fprintf(stderr," -Q nbits Quantize test values to fit in nbits\n");
|
||||||
fprintf(stderr," -R rsnum Use given random start number\n");
|
fprintf(stderr," -R rsnum Use given random start number\n");
|
||||||
fprintf(stderr," -K file.cal Apply printer calibration to patch values and include in .ti2\n");
|
fprintf(stderr," -K file.cal Apply printer calibration to patch values and include in .ti2\n");
|
||||||
@@ -3070,7 +3105,9 @@ int main(int argc, char *argv[]) {
|
|||||||
int nchan = 0; /* Number of device chanels */
|
int nchan = 0; /* Number of device chanels */
|
||||||
int i;
|
int i;
|
||||||
int si, fi, wi; /* Sample id index, field index, keyWord index */
|
int si, fi, wi; /* Sample id index, field index, keyWord index */
|
||||||
char label[400]; /* Space for chart label */
|
char *custom_label = NULL; /* Custom chart label string */
|
||||||
|
int custom_label_set = 0; /* Flag, custom label was specified */
|
||||||
|
char label[1024]; /* Space for chart label */
|
||||||
double marg = DEF_MARGINE; /* Margin from paper edge in mm */
|
double marg = DEF_MARGINE; /* Margin from paper edge in mm */
|
||||||
int nosubmarg = 0; /* Don't subtract it from raster */
|
int nosubmarg = 0; /* Don't subtract it from raster */
|
||||||
int nolpcbord = 0; /* NZ to suppress left paper clip border */
|
int nolpcbord = 0; /* NZ to suppress left paper clip border */
|
||||||
@@ -3302,6 +3339,13 @@ int main(int argc, char *argv[]) {
|
|||||||
else if (argv[fa][1] == 'D') {
|
else if (argv[fa][1] == 'D') {
|
||||||
tiffdith = 1;
|
tiffdith = 1;
|
||||||
}
|
}
|
||||||
|
/* Custom chart label string */
|
||||||
|
else if (argv[fa][1] == 'd') {
|
||||||
|
fa = nfa;
|
||||||
|
if (na == NULL) usage("Expected argument to -d");
|
||||||
|
custom_label = na;
|
||||||
|
custom_label_set = 1;
|
||||||
|
}
|
||||||
/* Don't use TIFF compression */
|
/* Don't use TIFF compression */
|
||||||
else if (argv[fa][1] == 'C') {
|
else if (argv[fa][1] == 'C') {
|
||||||
tiffcomp = 0;
|
tiffcomp = 0;
|
||||||
@@ -3789,8 +3833,18 @@ int main(int argc, char *argv[]) {
|
|||||||
pcol = pcold; /* Density spacer alues */
|
pcol = pcold; /* Density spacer alues */
|
||||||
|
|
||||||
|
|
||||||
sprintf(label, "ArgyllCMS - Chart \"%s\" (%s %d) %s",
|
if (custom_label_set) {
|
||||||
psname, rand ? "Random Start" : "Chart ID", rstart, atm);
|
if (custom_label[0] != '\000') {
|
||||||
|
strncpy(label, custom_label, sizeof(label) - 1);
|
||||||
|
label[sizeof(label) - 1] = '\000';
|
||||||
|
ocg->add_kword(ocg, 0, "CHART_LABEL", custom_label, NULL);
|
||||||
|
} else {
|
||||||
|
label[0] = '\000';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sprintf(label, "ArgyllCMS - Chart \"%s\" (%s %d) %s",
|
||||||
|
psname, rand ? "Random Start" : "Chart ID", rstart, atm);
|
||||||
|
}
|
||||||
generate_file(itype, itype_mod, psname, cols, npat, applycal ? cal : NULL, label,
|
generate_file(itype, itype_mod, psname, cols, npat, applycal ? cal : NULL, label,
|
||||||
pap != NULL ? pap->w : cwidth, pap != NULL ? pap->h : cheight,
|
pap != NULL ? pap->w : cwidth, pap != NULL ? pap->h : cheight,
|
||||||
marg, nosubmarg, nollimit, nolpcbord, rand, rstart, saix, paix, ixord,
|
marg, nosubmarg, nollimit, nolpcbord, rand, rstart, saix, paix, ixord,
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user