From 0dcad55131d72e3557446e7113b04023475def35 Mon Sep 17 00:00:00 2001 From: Ranjithkumar K Date: Fri, 29 May 2026 23:08:28 +0530 Subject: [PATCH 1/3] Fix build & test compilation on case-insensitive (Apple) filesystems The executable target was named 'jpegls', which collides with the library target 'JPEGLS' on case-insensitive APFS: the CLI's object files landed in the library's build dir and linking failed. Rename the executable target to 'jpeglscli' (the product/binary stays 'jpegls'). PR #113 had only renamed the source path, not the target. Also fix the test target, which did not compile on Apple Silicon: - replace 46 uses of the non-existent '#guard(...)' macro with 'guard ... else { return }' (skip-if-Metal-unsupported, the intended meaning) - add missing 'try' on 8 rethrows 'measure { ... }' call sites Guard stray compiler intermediates (*.o/*.d/*.dia/*.swiftdeps, .vscode/) in .gitignore so broken builds don't litter the repo root. Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 7 ++++ Package.swift | 4 +-- .../GPUComputePhase15ExtendedTests.swift | 20 ++++++------ .../JPEGLSTests/GPUComputePhase15Tests.swift | 28 ++++++++-------- Tests/JPEGLSTests/MetalAcceleratorTests.swift | 28 ++++++++-------- .../MetalPerformanceBenchmarks.swift | 32 +++++++++---------- 6 files changed, 63 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index ff94bcd..a849f92 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,10 @@ *.xcworkspace/ Package.resolved default.profraw + +# Stray compiler intermediates (emitted to CWD by older broken builds) +*.o +*.d +*.dia +*.swiftdeps +.vscode/ diff --git a/Package.swift b/Package.swift index 16365d8..7c8307f 100644 --- a/Package.swift +++ b/Package.swift @@ -15,7 +15,7 @@ let package = Package( ), .executable( name: "jpegls", - targets: ["jpegls"] + targets: ["jpeglscli"] ), ], dependencies: [ @@ -32,7 +32,7 @@ let package = Package( ] ), .executableTarget( - name: "jpegls", + name: "jpeglscli", dependencies: [ "JPEGLS", .product(name: "ArgumentParser", package: "swift-argument-parser"), diff --git a/Tests/JPEGLSTests/GPUComputePhase15ExtendedTests.swift b/Tests/JPEGLSTests/GPUComputePhase15ExtendedTests.swift index 07a1f38..a5017db 100644 --- a/Tests/JPEGLSTests/GPUComputePhase15ExtendedTests.swift +++ b/Tests/JPEGLSTests/GPUComputePhase15ExtendedTests.swift @@ -496,7 +496,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encodingPipeline — small batch lossless (NEAR=0)") func testEncodingPipelineSmallBatchLossless() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let a: [Int32] = [100, 200, 50] let b: [Int32] = [110, 190, 60] @@ -513,7 +513,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encodingPipeline — small batch near-lossless (NEAR=3)") func testEncodingPipelineSmallBatchNearLossless() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let a: [Int32] = [100, 200, 50] let b: [Int32] = [110, 190, 60] @@ -535,7 +535,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encodingPipeline — NEAR=3 gradients near zero → q=0") func testEncodingPipelineNear3GradientsNearZero() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() // b[i]-c[i] = 1, a[i]-c[i] = 0, c[i]-a[i] = 0 → all within NEAR=3 → q=0 // d1 = b - c = 11 - 10 = 1 (≤ NEAR=3) @@ -555,7 +555,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encodingPipeline — quantised gradients match NEAR=0 for large gradients") func testEncodingPipelineQuantisedGradientsLarge() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() // With NEAR=0, the encoding pipeline should produce same quantisation // as the standalone quantizeGradientsBatch call. @@ -577,7 +577,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encodingPipeline — empty arrays") func testEncodingPipelineEmpty() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let (pred, err, q1, q2, q3) = try accelerator.computeEncodingPipelineBatch( a: [], b: [], c: [], x: [], near: 0, t1: 3, t2: 7, t3: 21) @@ -588,7 +588,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: decodingPipeline — reconstructs pixels from errors (small batch)") func testDecodingPipelineSmallBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let a: [Int32] = [100, 200, 50] let b: [Int32] = [110, 190, 60] @@ -609,7 +609,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: decodingPipeline — empty arrays") func testDecodingPipelineEmpty() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let result = try accelerator.computeDecodingPipelineBatch( a: [], b: [], c: [], errval: []) @@ -620,7 +620,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encode → decode round-trip (lossless, small batch)") func testEncodeDecodeLosslessRoundTripSmall() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let a: [Int32] = [100, 200, 50, 150] let b: [Int32] = [110, 190, 60, 140] @@ -636,7 +636,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encode → decode round-trip (lossless, large batch, GPU path)") func testEncodeDecodeLosslessRoundTripLarge() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = MetalAccelerator.gpuThreshold * 2 var a = [Int32](repeating: 0, count: count) @@ -658,7 +658,7 @@ struct MetalEncodingDecodingPipelineTests { @Test("Metal: encoding pipeline matches standalone gradient + MED + quantise calls") func testEncodingPipelineMatchesStandaloneOps() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = MetalAccelerator.gpuThreshold * 2 var a = [Int32](repeating: 0, count: count) diff --git a/Tests/JPEGLSTests/GPUComputePhase15Tests.swift b/Tests/JPEGLSTests/GPUComputePhase15Tests.swift index 5953af4..86e6b45 100644 --- a/Tests/JPEGLSTests/GPUComputePhase15Tests.swift +++ b/Tests/JPEGLSTests/GPUComputePhase15Tests.swift @@ -448,7 +448,7 @@ struct MetalPhase15Tests { @Test("Metal: quantizeGradientsBatch — small batch (CPU fallback)") func testQuantizeGradientsSmallBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let t1: Int32 = 3, t2: Int32 = 7, t3: Int32 = 21 let d: [Int32] = [-30, -10, -5, -1, 0, 1, 5, 10, 30] @@ -462,7 +462,7 @@ struct MetalPhase15Tests { @Test("Metal: quantizeGradientsBatch — large batch (GPU)") func testQuantizeGradientsLargeBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let t1: Int32 = 3, t2: Int32 = 7, t3: Int32 = 21 let count = MetalAccelerator.gpuThreshold * 2 @@ -478,7 +478,7 @@ struct MetalPhase15Tests { @Test("Metal: quantizeGradientsBatch — empty arrays") func testQuantizeGradientsEmpty() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let (q1, q2, q3) = try accelerator.quantizeGradientsBatch( d1: [], d2: [], d3: [], t1: 3, t2: 7, t3: 21) @@ -487,7 +487,7 @@ struct MetalPhase15Tests { @Test("Metal: quantizeGradientsBatch matches Vulkan CPU fallback") func testQuantizeGradientsBitExact() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAcc = try MetalAccelerator() let vulkanAcc = VulkanAccelerator() let t1: Int32 = 3, t2: Int32 = 7, t3: Int32 = 21 @@ -513,7 +513,7 @@ struct MetalPhase15Tests { @Test("Metal: HP1 forward transform — small batch (CPU fallback)") func testHP1ForwardSmallBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let r: [Int32] = [200, 100] let g: [Int32] = [100, 50] @@ -527,7 +527,7 @@ struct MetalPhase15Tests { @Test("Metal: HP1 inverse round-trips — small batch (CPU fallback)") func testHP1RoundTripSmallBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let r: [Int32] = [200, 100, 50] let g: [Int32] = [100, 50, 30] @@ -541,7 +541,7 @@ struct MetalPhase15Tests { @Test("Metal: HP1 forward transform — large batch (GPU)") func testHP1ForwardLargeBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = MetalAccelerator.gpuThreshold * 2 let r = [Int32](repeating: 200, count: count) @@ -556,7 +556,7 @@ struct MetalPhase15Tests { @Test("Metal: HP1 large batch round-trips correctly (GPU)") func testHP1RoundTripLargeBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = MetalAccelerator.gpuThreshold * 2 var r = [Int32](repeating: 0, count: count) @@ -578,7 +578,7 @@ struct MetalPhase15Tests { @Test("Metal: HP2 inverse round-trips correctly — large batch (GPU)") func testHP2RoundTripLargeBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = MetalAccelerator.gpuThreshold * 2 var r = [Int32](repeating: 0, count: count) @@ -600,7 +600,7 @@ struct MetalPhase15Tests { @Test("Metal: HP3 inverse round-trips correctly — large batch (GPU)") func testHP3RoundTripLargeBatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = MetalAccelerator.gpuThreshold * 2 var r = [Int32](repeating: 0, count: count) @@ -622,7 +622,7 @@ struct MetalPhase15Tests { @Test("Metal: .none forward transform returns input unchanged") func testIdentityForward() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let r: [Int32] = [10, 20, 30] let g: [Int32] = [40, 50, 60] @@ -636,7 +636,7 @@ struct MetalPhase15Tests { @Test("Metal colour transforms match Vulkan CPU results — HP1 large batch") func testColourTransformBitExactHP1() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAcc = try MetalAccelerator() let vulkanAcc = VulkanAccelerator() let count = MetalAccelerator.gpuThreshold * 2 @@ -657,7 +657,7 @@ struct MetalPhase15Tests { @Test("Metal colour transforms match Vulkan CPU results — HP2 large batch") func testColourTransformBitExactHP2() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAcc = try MetalAccelerator() let vulkanAcc = VulkanAccelerator() let count = MetalAccelerator.gpuThreshold * 2 @@ -678,7 +678,7 @@ struct MetalPhase15Tests { @Test("Metal colour transforms match Vulkan CPU results — HP3 large batch") func testColourTransformBitExactHP3() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAcc = try MetalAccelerator() let vulkanAcc = VulkanAccelerator() let count = MetalAccelerator.gpuThreshold * 2 diff --git a/Tests/JPEGLSTests/MetalAcceleratorTests.swift b/Tests/JPEGLSTests/MetalAcceleratorTests.swift index 576d755..7c58340 100644 --- a/Tests/JPEGLSTests/MetalAcceleratorTests.swift +++ b/Tests/JPEGLSTests/MetalAcceleratorTests.swift @@ -34,7 +34,7 @@ struct MetalAcceleratorTests { @Test("Compute gradients for single pixel batch") func testSinglePixelGradients() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -56,7 +56,7 @@ struct MetalAcceleratorTests { @Test("Compute gradients for small batch (CPU fallback)") func testSmallBatchGradients() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -76,7 +76,7 @@ struct MetalAcceleratorTests { @Test("Compute gradients for large batch (GPU)") func testLargeBatchGradients() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -105,7 +105,7 @@ struct MetalAcceleratorTests { @Test("Compute gradients with negative values") func testGradientsWithNegativeValues() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -125,7 +125,7 @@ struct MetalAcceleratorTests { @Test("Compute gradients with boundary values") func testGradientsWithBoundaryValues() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -146,7 +146,7 @@ struct MetalAcceleratorTests { @Test("Compute gradients with empty arrays") func testGradientsWithEmptyArrays() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -165,7 +165,7 @@ struct MetalAcceleratorTests { @Test("Compute MED prediction for single pixel") func testSinglePixelMEDPrediction() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -193,7 +193,7 @@ struct MetalAcceleratorTests { @Test("Compute MED prediction for small batch (CPU fallback)") func testSmallBatchMEDPrediction() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -211,7 +211,7 @@ struct MetalAcceleratorTests { @Test("Compute MED prediction for large batch (GPU)") func testLargeBatchMEDPrediction() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -267,7 +267,7 @@ struct MetalAcceleratorTests { @Test("Compute MED prediction with equal pixel values") func testMEDPredictionWithEqualValues() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -283,7 +283,7 @@ struct MetalAcceleratorTests { @Test("Compute MED prediction with zero values") func testMEDPredictionWithZeroValues() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -298,7 +298,7 @@ struct MetalAcceleratorTests { @Test("Compute MED prediction with empty arrays") func testMEDPredictionWithEmptyArrays() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() @@ -315,7 +315,7 @@ struct MetalAcceleratorTests { @Test("Metal gradients match scalar implementation") func testGradientsBitExactMatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAccelerator = try MetalAccelerator() let scalarAccelerator = ScalarAccelerator() @@ -354,7 +354,7 @@ struct MetalAcceleratorTests { @Test("Metal MED predictions match scalar implementation") func testMEDPredictionBitExactMatch() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAccelerator = try MetalAccelerator() let scalarAccelerator = ScalarAccelerator() diff --git a/Tests/JPEGLSTests/MetalPerformanceBenchmarks.swift b/Tests/JPEGLSTests/MetalPerformanceBenchmarks.swift index ac08f0e..7f4f06d 100644 --- a/Tests/JPEGLSTests/MetalPerformanceBenchmarks.swift +++ b/Tests/JPEGLSTests/MetalPerformanceBenchmarks.swift @@ -60,7 +60,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: Metal gradient computation - 512×512 (below threshold)") func benchmarkGradients512x512() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = 512 * 512 // 262,144 pixels (below GPU threshold) @@ -72,7 +72,7 @@ struct MetalPerformanceBenchmarks { } // Measure - let (minTime, maxTime, avgTime) = measure { + let (minTime, maxTime, avgTime) = try measure { _ = try accelerator.computeGradientsBatch(a: a, b: b, c: c) } @@ -93,7 +93,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: Metal gradient computation - 1024×1024 (at threshold)") func benchmarkGradients1024x1024() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = 1024 * 1024 // 1,048,576 pixels (just above GPU threshold) @@ -105,7 +105,7 @@ struct MetalPerformanceBenchmarks { } // Measure - let (minTime, maxTime, avgTime) = measure { + let (minTime, maxTime, avgTime) = try measure { _ = try accelerator.computeGradientsBatch(a: a, b: b, c: c) } @@ -126,7 +126,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: Metal gradient computation - 2048×2048 (large image)") func benchmarkGradients2048x2048() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = 2048 * 2048 // 4,194,304 pixels @@ -138,7 +138,7 @@ struct MetalPerformanceBenchmarks { } // Measure - let (minTime, maxTime, avgTime) = measure { + let (minTime, maxTime, avgTime) = try measure { _ = try accelerator.computeGradientsBatch(a: a, b: b, c: c) } @@ -161,7 +161,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: Metal gradient computation - 4096×4096 (very large)") func benchmarkGradients4096x4096() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = 4096 * 4096 // 16,777,216 pixels @@ -173,7 +173,7 @@ struct MetalPerformanceBenchmarks { } // Measure - let (minTime, maxTime, avgTime) = measure { + let (minTime, maxTime, avgTime) = try measure { _ = try accelerator.computeGradientsBatch(a: a, b: b, c: c) } @@ -198,7 +198,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: Metal MED prediction - 1024×1024") func benchmarkMEDPrediction1024x1024() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = 1024 * 1024 @@ -210,7 +210,7 @@ struct MetalPerformanceBenchmarks { } // Measure - let (minTime, maxTime, avgTime) = measure { + let (minTime, maxTime, avgTime) = try measure { _ = try accelerator.computeMEDPredictionBatch(a: a, b: b, c: c) } @@ -230,7 +230,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: Metal MED prediction - 2048×2048") func benchmarkMEDPrediction2048x2048() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let accelerator = try MetalAccelerator() let count = 2048 * 2048 @@ -242,7 +242,7 @@ struct MetalPerformanceBenchmarks { } // Measure - let (minTime, maxTime, avgTime) = measure { + let (minTime, maxTime, avgTime) = try measure { _ = try accelerator.computeMEDPredictionBatch(a: a, b: b, c: c) } @@ -264,7 +264,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: CPU vs GPU comparison - 2048×2048 gradients") func benchmarkCPUvsGPUGradients() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAccelerator = try MetalAccelerator() let scalarAccelerator = ScalarAccelerator() @@ -276,7 +276,7 @@ struct MetalPerformanceBenchmarks { _ = try metalAccelerator.computeGradientsBatch(a: a, b: b, c: c) } - let (_, _, gpuTime) = measure { + let (_, _, gpuTime) = try measure { _ = try metalAccelerator.computeGradientsBatch(a: a, b: b, c: c) } @@ -311,7 +311,7 @@ struct MetalPerformanceBenchmarks { @Test("Benchmark: CPU vs GPU comparison - 2048×2048 MED prediction") func benchmarkCPUvsGPUMEDPrediction() throws { - #guard(MetalAccelerator.isSupported) + guard MetalAccelerator.isSupported else { return } let metalAccelerator = try MetalAccelerator() let scalarAccelerator = ScalarAccelerator() @@ -323,7 +323,7 @@ struct MetalPerformanceBenchmarks { _ = try metalAccelerator.computeMEDPredictionBatch(a: a, b: b, c: c) } - let (_, _, gpuTime) = measure { + let (_, _, gpuTime) = try measure { _ = try metalAccelerator.computeMEDPredictionBatch(a: a, b: b, c: c) } From cb9486d0d2771439ab2d493dc907d11c553ea84f Mon Sep 17 00:00:00 2001 From: Ranjithkumar K Date: Fri, 29 May 2026 23:08:38 +0530 Subject: [PATCH 2/3] Add DICOM test-data harness: bench-dicom round-trip over a corpus Validate the JPEG-LS codec against real medical imaging data. - DICOMSupport: a minimal DICOM Part-10 reader (Explicit/Implicit VR LE, native + encapsulated Pixel Data, sequence skipping). Lives in the CLI target to keep the JPEGLS library DICOM-independent. Extracts geometry, pixel format, and the first native unsigned grayscale frame. - BenchDICOM (jpegls bench-dicom ): walks a corpus by modality, runs encode -> decode -> bit-exact verify, and reports compression ratio and encode/decode throughput. Cleanly separates skip (non-grayscale), err (unreadable), and fail (encoded-but-not-lossless). Baseline on the radiology corpus (pure-Swift codec): all CT/DX/MG/MR/PX/XA frames round-trip losslessly; ratios ~2-25:1. Co-Authored-By: Claude Opus 4.8 (1M context) --- Sources/jpeglscli/BenchDICOMCommand.swift | 245 +++++++++++++++++ Sources/jpeglscli/DICOMSupport.swift | 313 ++++++++++++++++++++++ Sources/jpeglscli/main.swift | 2 +- 3 files changed, 559 insertions(+), 1 deletion(-) create mode 100644 Sources/jpeglscli/BenchDICOMCommand.swift create mode 100644 Sources/jpeglscli/DICOMSupport.swift diff --git a/Sources/jpeglscli/BenchDICOMCommand.swift b/Sources/jpeglscli/BenchDICOMCommand.swift new file mode 100644 index 0000000..841ce4f --- /dev/null +++ b/Sources/jpeglscli/BenchDICOMCommand.swift @@ -0,0 +1,245 @@ +import ArgumentParser +import Foundation +import JPEGLS + +extension JPEGLSCLITool { + /// Walk a tree of DICOM files, encode each native grayscale frame to + /// JPEG-LS, decode it back, verify the round-trip is bit-exact, and report + /// compression ratio and throughput grouped by modality. + /// + /// Intended for validating the codec against real medical-imaging data + /// (the radiology DICOM corpus). It is both a conformance check + /// (lossless == every reconstructed sample matches the original) and a + /// performance baseline (MB/s encode / decode per modality). + struct BenchDICOM: ParsableCommand { + static let configuration = CommandConfiguration( + commandName: "bench-dicom", + abstract: "Round-trip & benchmark JPEG-LS over a DICOM image corpus", + discussion: """ + Recursively scans a directory for .dcm files, groups them by the + top-level folder (treated as the modality, e.g. CT/DX/MG/MR/PX/US/XA), + and for every native (uncompressed) unsigned grayscale frame: + + encode (lossless) → decode → verify bit-exact → record ratio + timing + + Non-encodable frames (encapsulated/compressed, signed, or colour) + are counted and skipped. Results are aggregated per modality. + + Examples: + jpegls bench-dicom "/path/to/Radiology DICOM Data" + jpegls bench-dicom CORPUS --limit 5 + jpegls bench-dicom CORPUS --modality CT,DX --max-pixels 4000000 + jpegls bench-dicom CORPUS --limit 10 --json + """ + ) + + @Argument(help: "Root directory to scan recursively for .dcm files") + var root: String + + @Option(name: .long, help: "Max frames to process per modality (0 = no limit; default 3)") + var limit: Int = 3 + + @Option(name: .long, help: "Skip frames larger than this many pixels (0 = no cap)") + var maxPixels: Int = 0 + + @Option(name: .long, help: "Comma-separated modality filter (e.g. CT,DX); default: all") + var modality: String? + + @Option(name: .long, help: "Near-lossless parameter (0 = lossless; default 0)") + var near: Int = 0 + + @Flag(name: .long, help: "Emit machine-readable JSON instead of a table") + var json: Bool = false + + // MARK: - Per-frame / per-modality accumulators + + struct FrameResult { + var modality: String + var width: Int + var height: Int + var bitsStored: Int + var originalBytes: Int + var compressedBytes: Int + var encodeSeconds: Double + var decodeSeconds: Double + var lossless: Bool + } + + struct ModalityStats { + var processed = 0 // encoded + decoded + var skipped = 0 // parsed, but not a native unsigned grayscale frame + var errors = 0 // could not read / parse the DICOM file at all + var failures = 0 // encoded but the round-trip was NOT bit-exact + var originalBytes = 0 + var compressedBytes = 0 + var encodeSeconds = 0.0 + var decodeSeconds = 0.0 + var pixels = 0 + } + + mutating func run() throws { + let rootURL = URL(fileURLWithPath: root, isDirectory: true) + var isDir: ObjCBool = false + guard FileManager.default.fileExists(atPath: rootURL.path, isDirectory: &isDir), isDir.boolValue else { + throw ValidationError("Not a directory: \(root)") + } + + let modalityFilter: Set? = modality.map { + Set($0.split(separator: ",").map { $0.trimmingCharacters(in: .whitespaces) }) + } + + // Collect .dcm paths grouped by modality (first path component under root). + var byModality: [String: [URL]] = [:] + let rootComponents = rootURL.standardizedFileURL.pathComponents + guard let walker = FileManager.default.enumerator( + at: rootURL, + includingPropertiesForKeys: nil, + options: [.skipsHiddenFiles] + ) else { + throw ValidationError("Cannot enumerate \(root)") + } + for case let url as URL in walker { + guard url.pathExtension.lowercased() == "dcm" else { continue } + let comps = url.standardizedFileURL.pathComponents + let mod = comps.count > rootComponents.count ? comps[rootComponents.count] : "(root)" + if let f = modalityFilter, !f.contains(mod) { continue } + byModality[mod, default: []].append(url) + } + + if byModality.isEmpty { + throw ValidationError("No .dcm files found under \(root)") + } + + var stats: [String: ModalityStats] = [:] + var frames: [FrameResult] = [] + let encoder = JPEGLSEncoder() + let decoder = JPEGLSDecoder() + + for mod in byModality.keys.sorted() { + let urls = byModality[mod]!.sorted { $0.path < $1.path } + var s = ModalityStats() + if !json { FileHandle.standardError.write(Data("Scanning \(mod) (\(urls.count) files)…\n".utf8)) } + + for url in urls { + if limit > 0 && s.processed >= limit { break } + + guard let data = try? Data(contentsOf: url), + let img = try? DICOMSupport.parse(data) else { + s.errors += 1 + continue + } + + guard let (pixels, bps) = DICOMSupport.grayscaleFrame(img) else { + s.skipped += 1 + continue + } + + let pixelCount = img.columns * img.rows + if maxPixels > 0 && pixelCount > maxPixels { + s.skipped += 1 + continue + } + + do { + let imageData = try MultiComponentImageData.grayscale(pixels: pixels, bitsPerSample: bps) + let config = try JPEGLSEncoder.Configuration(near: near) + + let t0 = DispatchTime.now().uptimeNanoseconds + let encoded = try encoder.encode(imageData, configuration: config) + let t1 = DispatchTime.now().uptimeNanoseconds + let decoded = try decoder.decode(encoded) + let t2 = DispatchTime.now().uptimeNanoseconds + + let lossless = (near == 0) && pixelsEqual(decoded.components.first?.pixels, pixels) + let originalBytes = img.columns * img.rows * img.bytesPerSample + let encS = Double(t1 - t0) / 1e9 + let decS = Double(t2 - t1) / 1e9 + + s.processed += 1 + s.originalBytes += originalBytes + s.compressedBytes += encoded.count + s.encodeSeconds += encS + s.decodeSeconds += decS + s.pixels += pixelCount + if near == 0 && !lossless { s.failures += 1 } + + frames.append(FrameResult( + modality: mod, width: img.columns, height: img.rows, + bitsStored: img.bitsStored, originalBytes: originalBytes, + compressedBytes: encoded.count, encodeSeconds: encS, + decodeSeconds: decS, lossless: lossless + )) + } catch { + s.failures += 1 + } + } + stats[mod] = s + } + + if json { + printJSON(stats: stats, frames: frames) + } else { + printTable(stats: stats) + } + } + + // MARK: - Helpers + + private func pixelsEqual(_ a: [[Int]]?, _ b: [[Int]]) -> Bool { + guard let a = a, a.count == b.count else { return false } + for r in 0.. 0 { + print("⚠️ \(t.failures) frame(s) failed the lossless round-trip.") + } else if t.processed > 0 { + print("✓ All \(t.processed) processed frame(s) round-tripped losslessly.") + } + print("(skip = non-grayscale/encapsulated frames; err = unreadable DICOM)") + } + + private func printRow(_ mod: String, _ s: ModalityStats) { + let ratio = s.compressedBytes > 0 ? Double(s.originalBytes) / Double(s.compressedBytes) : 0 + let encMBs = s.encodeSeconds > 0 ? (Double(s.originalBytes) / 1_000_000.0) / s.encodeSeconds : 0 + let decMBs = s.decodeSeconds > 0 ? (Double(s.originalBytes) / 1_000_000.0) / s.decodeSeconds : 0 + let mp = Double(s.pixels) / 1_000_000.0 + print(String(format: "%-8@ %7d %6d %6d %6d %8.2f:1 %8.1f %10.1f %10.1f", + mod as NSString, s.processed, s.skipped, s.errors, s.failures, ratio, mp, encMBs, decMBs)) + } + + private func printJSON(stats: [String: ModalityStats], frames: [FrameResult]) { + var modObjs: [String] = [] + for mod in stats.keys.sorted() { + let s = stats[mod]! + let ratio = s.compressedBytes > 0 ? Double(s.originalBytes) / Double(s.compressedBytes) : 0 + modObjs.append(""" + {"modality":"\(mod)","frames":\(s.processed),"skipped":\(s.skipped),"errors":\(s.errors),"failures":\(s.failures),"originalBytes":\(s.originalBytes),"compressedBytes":\(s.compressedBytes),"ratio":\(String(format: "%.4f", ratio)),"encodeSeconds":\(String(format: "%.4f", s.encodeSeconds)),"decodeSeconds":\(String(format: "%.4f", s.decodeSeconds))} + """) + } + print("{\"near\":\(near),\"modalities\":[\(modObjs.joined(separator: ","))]}") + } + } +} diff --git a/Sources/jpeglscli/DICOMSupport.swift b/Sources/jpeglscli/DICOMSupport.swift new file mode 100644 index 0000000..9ceb7bd --- /dev/null +++ b/Sources/jpeglscli/DICOMSupport.swift @@ -0,0 +1,313 @@ +import Foundation +import JPEGLS + +/// Minimal DICOM Part-10 reader, scoped to what the JPEG-LS test/benchmark +/// harness needs: image geometry, pixel format, and the Pixel Data element. +/// +/// This deliberately lives in the CLI target — the `JPEGLS` library is, by +/// design, DICOM-independent. The parser understands Explicit and Implicit VR +/// Little Endian datasets (the meta group is always Explicit VR LE) and both +/// native (uncompressed) and encapsulated Pixel Data. It does **not** aim to be +/// a general DICOM toolkit: it reads only the handful of tags required to drive +/// a lossless round-trip, and skips everything else (including sequences). +/// +/// Known limitation: a small number of multi-frame Ultrasound files use +/// Implicit VR LE datasets with deeply nested private sequences that defeat +/// purely sequential parsing; `parse` throws for those. Callers (e.g. the +/// `bench-dicom` harness) treat such files as unreadable and skip them rather +/// than failing — they are not a JPEG-LS conformance signal. +enum DICOMSupport { + + // MARK: - Public model + + /// A decoded DICOM image header plus its raw Pixel Data bytes. + struct Image: Sendable { + var rows: Int // (0028,0010) + var columns: Int // (0028,0011) + var samplesPerPixel: Int // (0028,0002), default 1 + var bitsAllocated: Int // (0028,0100) + var bitsStored: Int // (0028,0101) + var highBit: Int // (0028,0102) + var pixelRepresentation: Int // (0028,0103): 0 = unsigned, 1 = signed + var planarConfiguration: Int // (0028,0006): 0 = interleaved, 1 = planar + var numberOfFrames: Int // (0028,0008), default 1 + var photometric: String // (0028,0004) + var transferSyntaxUID: String // (0002,0010) + var isEncapsulated: Bool + /// Native pixel bytes (uncompressed), or the concatenated codestream + /// fragments (encapsulated). + var pixelData: Data + + var isSigned: Bool { pixelRepresentation == 1 } + var bytesPerSample: Int { (bitsAllocated + 7) / 8 } + + /// Whether this frame can be fed to the JPEG-LS encoder for a lossless + /// round-trip: native (uncompressed), unsigned, ≤16-bit samples. + var isEncodableLossless: Bool { + !isEncapsulated && !isSigned && bitsAllocated <= 16 && bitsStored >= 1 + && rows > 0 && columns > 0 && samplesPerPixel >= 1 + } + } + + enum DICOMError: Error, CustomStringConvertible { + case notDICOM + case truncated + case missingPixelData + case unsupported(String) + + var description: String { + switch self { + case .notDICOM: return "not a DICOM Part-10 file (missing 'DICM' magic)" + case .truncated: return "DICOM stream ended unexpectedly" + case .missingPixelData: return "no Pixel Data (7FE0,0010) element found" + case .unsupported(let s): return "unsupported DICOM feature: \(s)" + } + } + } + + // Well-known transfer syntaxes. + static let implicitVRLittleEndian = "1.2.840.10008.1.2" + static let explicitVRLittleEndian = "1.2.840.10008.1.2.1" + + // VRs that carry a 32-bit length (with 2 reserved bytes) in Explicit VR. + private static let longFormVRs: Set = { + let strs = ["OB", "OW", "OF", "OD", "OL", "OV", "SQ", "UC", "UR", "UT", "UN"] + return Set(strs.map { vrCode($0) }) + }() + + private static func vrCode(_ s: String) -> UInt16 { + let b = Array(s.utf8) + return UInt16(b[0]) | (UInt16(b[1]) << 8) + } + + // MARK: - Parse + + static func parse(_ data: Data) throws -> Image { + let bytes = [UInt8](data) + // Part-10 preamble: 128-byte preamble + "DICM". + guard bytes.count > 132, + bytes[128] == 0x44, bytes[129] == 0x49, + bytes[130] == 0x43, bytes[131] == 0x4D else { + throw DICOMError.notDICOM + } + + var cursor = 132 + + // --- File Meta Information (group 0002): always Explicit VR LE. --- + var transferSyntax = implicitVRLittleEndian + while cursor + 8 <= bytes.count { + let group = readU16(bytes, cursor) + if group != 0x0002 { break } // end of meta group + let element = readU16(bytes, cursor + 2) + let (length, valueOffset) = readExplicitVRHeader(bytes, cursor) + if group == 0x0002, element == 0x0010 { + transferSyntax = readString(bytes, valueOffset, length) + } + cursor = valueOffset + Int(length) + } + + // Every transfer syntax *except* Implicit VR LE encodes the dataset in + // Explicit VR Little Endian — including the encapsulated JPEG / JPEG-LS + // / RLE syntaxes. Only "1.2.840.10008.1.2" is implicit. + let explicit = (transferSyntax != implicitVRLittleEndian) + // Anything that isn't one of the two native LE syntaxes is encapsulated + // (JPEG / JPEG-LS / RLE …). Encapsulated Pixel Data has undefined length. + let encapsulated = !(transferSyntax == implicitVRLittleEndian || transferSyntax == explicitVRLittleEndian) + + // --- Main dataset. --- + var img = Image( + rows: 0, columns: 0, samplesPerPixel: 1, + bitsAllocated: 0, bitsStored: 0, highBit: 0, + pixelRepresentation: 0, planarConfiguration: 0, numberOfFrames: 1, + photometric: "", transferSyntaxUID: transferSyntax, + isEncapsulated: encapsulated, pixelData: Data() + ) + + var sawPixelData = false + while cursor + 8 <= bytes.count { + let group = readU16(bytes, cursor) + let element = readU16(bytes, cursor + 2) + + let length: UInt32 + let valueOffset: Int + if explicit { + (length, valueOffset) = readExplicitVRHeader(bytes, cursor) + } else { + length = readU32(bytes, cursor + 4) + valueOffset = cursor + 8 + } + + // Pixel Data. + if group == 0x7FE0, element == 0x0010 { + if length == 0xFFFF_FFFF { + // Encapsulated: items = Basic Offset Table then fragments. + img.pixelData = readEncapsulatedFragments(bytes, valueOffset) + img.isEncapsulated = true + } else { + let end = min(valueOffset + Int(length), bytes.count) + img.pixelData = Data(bytes[valueOffset.. 0x7FE0 { break } + } + + guard sawPixelData else { throw DICOMError.missingPixelData } + return img + } + + // MARK: - Pixel extraction + + /// Build a single-component `[row][col]` integer array from the first frame + /// of a native, unsigned grayscale image, plus the bit depth to encode at. + /// + /// Returns `nil` if the image isn't a native unsigned grayscale frame. + static func grayscaleFrame(_ img: Image) -> (pixels: [[Int]], bitsPerSample: Int)? { + guard img.isEncodableLossless, img.samplesPerPixel == 1 else { return nil } + + let w = img.columns, h = img.rows + let bps = img.bytesPerSample + let frameBytes = w * h * bps + guard img.pixelData.count >= frameBytes else { return nil } + + var pixels = [[Int]](repeating: [Int](repeating: 0, count: w), count: h) + var maxVal = 0 + // Mask to the stored bits so any padding in the high bits is ignored. + let storedMask = img.bitsStored >= 16 ? 0xFFFF : ((1 << img.bitsStored) - 1) + + img.pixelData.withUnsafeBytes { (raw: UnsafeRawBufferPointer) in + let base = raw.baseAddress! + for row in 0.. maxVal { maxVal = value } + } + } + } + + // JPEG-LS bit depth must cover the actual sample range, and be ≥ 2. + var bits = max(2, img.bitsStored) + while (1 << bits) - 1 < maxVal && bits < 16 { bits += 1 } + return (pixels, bits) + } + + // MARK: - Low-level readers + + private static func readU16(_ b: [UInt8], _ i: Int) -> UInt16 { + UInt16(b[i]) | (UInt16(b[i + 1]) << 8) + } + + private static func readU32(_ b: [UInt8], _ i: Int) -> UInt32 { + UInt32(b[i]) | (UInt32(b[i + 1]) << 8) | (UInt32(b[i + 2]) << 16) | (UInt32(b[i + 3]) << 24) + } + + private static func readString(_ b: [UInt8], _ off: Int, _ length: UInt32) -> String { + let end = min(off + Int(length), b.count) + guard off <= end else { return "" } + let slice = b[off.. (UInt32, Int) { + let vr = readU16(b, start + 4) + if longFormVRs.contains(vr) { + // VR(2) + reserved(2) + length(4) + let length = readU32(b, start + 8) + return (length, start + 12) + } else { + // VR(2) + length(2) + let length = UInt32(readU16(b, start + 6)) + return (length, start + 8) + } + } + + /// Given the offset just past an undefined-length element header, skip the + /// entire sequence (handling nested items / sequences) and return the offset + /// immediately following its Sequence Delimitation Item (FFFE,E0DD). + private static func skipUndefinedLengthSequence(_ b: [UInt8], _ start: Int) -> Int { + var i = start + var depth = 1 + while i + 8 <= b.count && depth > 0 { + let group = readU16(b, i) + let element = readU16(b, i + 2) + let length = readU32(b, i + 4) + i += 8 + if group == 0xFFFE && element == 0xE0DD { // sequence delimiter + depth -= 1 + } else if group == 0xFFFE && element == 0xE000 { // item + if length == 0xFFFF_FFFF { + depth += 1 // undefined-length item: descend + } else { + i += Int(length) // defined-length item: skip + } + } else if length != 0xFFFF_FFFF { + i += Int(length) + } else { + depth += 1 + } + } + return i + } + + /// Read encapsulated Pixel Data fragments: skip the Basic Offset Table item, + /// then concatenate all fragment items up to the Sequence Delimitation Item. + private static func readEncapsulatedFragments(_ b: [UInt8], _ start: Int) -> Data { + var i = start + var out = Data() + var first = true + while i + 8 <= b.count { + let group = readU16(b, i) + let element = readU16(b, i + 2) + let length = readU32(b, i + 4) + i += 8 + if group == 0xFFFE && element == 0xE0DD { break } // sequence delimiter + guard group == 0xFFFE && element == 0xE000 else { break } + let end = min(i + Int(length), b.count) + if first { + first = false // Basic Offset Table — skip its contents + } else { + out.append(contentsOf: b[i.. --help' for detailed help on any command. """, version: "0.1.0", - subcommands: [Encode.self, Decode.self, Info.self, Verify.self, Batch.self, Compare.self, Convert.self, Benchmark.self, Completion.self], + subcommands: [Encode.self, Decode.self, Info.self, Verify.self, Batch.self, Compare.self, Convert.self, Benchmark.self, BenchDICOM.self, Completion.self], defaultSubcommand: nil ) } From e17db456c31dedc235c9026dd1da4f0f4d11ee07 Mon Sep 17 00:00:00 2001 From: Ranjithkumar K Date: Fri, 29 May 2026 23:08:58 +0530 Subject: [PATCH 3/3] Organize repo: move docs into docs/, man page into man/ The root held 19 loose markdown files plus a tracked coverage artifact. Tidy it to a conventional layout (README + CHANGELOG stay at root): - move 17 guides/specs into docs/ (flat, so all 49 inter-doc links stay valid) - move jpegls.1 into man/ - remove the tracked default.profraw build artifact (303 KB) - add docs/README.md as a categorized index Update every reference so all 89 relative links resolve: README doc links get a docs/ prefix and its tree/man-page paths are fixed; moved docs use ../ for root targets and .github; CHANGELOG and copilot-instructions point at the new locations; two test comments point at docs/MILESTONES.md. Historical CHANGELOG prose mentioning old filenames is left as-is (release record). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/copilot-instructions.md | 12 +++-- CHANGELOG.md | 4 +- README.md | 50 ++++++++++-------- ...JPEGLSRoundTripInteroperabilityTests.swift | 2 +- .../Phase16OptimisationTests.swift | 2 +- default.profraw | Bin 303200 -> 0 bytes APPKIT_EXAMPLES.md => docs/APPKIT_EXAMPLES.md | 0 .../CONFORMANCE_MATRIX.md | 0 .../DECODER_BUG_INVESTIGATION.md | 0 .../DECODER_IMPLEMENTATION_SPEC.md | 0 .../DICOMKIT_INTEGRATION.md | 0 GETTING_STARTED.md => docs/GETTING_STARTED.md | 4 +- .../METAL_GPU_ACCELERATION.md | 0 MILESTONES.md => docs/MILESTONES.md | 0 .../PERFORMANCE_TUNING.md | 0 docs/README.md | 31 +++++++++++ .../RELEASE_NOTES_TEMPLATE.md | 2 +- .../SERVER_SIDE_EXAMPLES.md | 2 +- .../SWIFTUI_EXAMPLES.md | 0 TROUBLESHOOTING.md => docs/TROUBLESHOOTING.md | 2 +- USAGE_EXAMPLES.md => docs/USAGE_EXAMPLES.md | 4 +- VERSIONING.md => docs/VERSIONING.md | 0 .../VULKAN_GPU_ACCELERATION.md | 0 .../X86_64_REMOVAL_GUIDE.md | 0 jpegls.1 => man/jpegls.1 | 0 25 files changed, 77 insertions(+), 38 deletions(-) delete mode 100644 default.profraw rename APPKIT_EXAMPLES.md => docs/APPKIT_EXAMPLES.md (100%) rename CONFORMANCE_MATRIX.md => docs/CONFORMANCE_MATRIX.md (100%) rename DECODER_BUG_INVESTIGATION.md => docs/DECODER_BUG_INVESTIGATION.md (100%) rename DECODER_IMPLEMENTATION_SPEC.md => docs/DECODER_IMPLEMENTATION_SPEC.md (100%) rename DICOMKIT_INTEGRATION.md => docs/DICOMKIT_INTEGRATION.md (100%) rename GETTING_STARTED.md => docs/GETTING_STARTED.md (98%) rename METAL_GPU_ACCELERATION.md => docs/METAL_GPU_ACCELERATION.md (100%) rename MILESTONES.md => docs/MILESTONES.md (100%) rename PERFORMANCE_TUNING.md => docs/PERFORMANCE_TUNING.md (100%) create mode 100644 docs/README.md rename RELEASE_NOTES_TEMPLATE.md => docs/RELEASE_NOTES_TEMPLATE.md (98%) rename SERVER_SIDE_EXAMPLES.md => docs/SERVER_SIDE_EXAMPLES.md (99%) rename SWIFTUI_EXAMPLES.md => docs/SWIFTUI_EXAMPLES.md (100%) rename TROUBLESHOOTING.md => docs/TROUBLESHOOTING.md (99%) rename USAGE_EXAMPLES.md => docs/USAGE_EXAMPLES.md (99%) rename VERSIONING.md => docs/VERSIONING.md (100%) rename VULKAN_GPU_ACCELERATION.md => docs/VULKAN_GPU_ACCELERATION.md (100%) rename X86_64_REMOVAL_GUIDE.md => docs/X86_64_REMOVAL_GUIDE.md (100%) rename jpegls.1 => man/jpegls.1 (100%) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6a2e4a8..7a6956d 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -35,7 +35,7 @@ validation, string manipulation, and mathematical operations. - When code changes are made, the following documents **must** be updated: - **README.md**: Update to reflect any new features, API changes, or usage instructions. - - **MILESTONES.md**: Update to reflect progress on project milestones and goals. + - **docs/MILESTONES.md**: Update to reflect progress on project milestones and goals. - All public types and methods must have documentation comments using `///` syntax. - Include usage examples in documentation comments where helpful. @@ -52,8 +52,12 @@ JLSwift/ │ ├── copilot-instructions.md # This file │ └── workflows/ │ └── ci.yml # CI pipeline with coverage enforcement -├── README.md # Project documentation -└── MILESTONES.md # Project milestones and roadmap +├── README.md # Project overview (repo home) +├── CHANGELOG.md # Release history +├── docs/ # Guides, specs, and reference docs +│ └── MILESTONES.md # Project milestones and roadmap (+ others) +└── man/ + └── jpegls.1 # CLI man page ``` ## Build and Test Commands @@ -96,7 +100,7 @@ Before submitting or approving a PR, verify: 1. All tests pass (`swift test`). 2. Test coverage is above 95%. 3. README.md is updated if features or APIs changed. -4. MILESTONES.md is updated if milestone progress changed. +4. docs/MILESTONES.md is updated if milestone progress changed. 5. All public APIs have documentation comments. 6. Code follows Swift 6.2+ best practices and concurrency model. 7. Automatic code review has been run and feedback addressed. diff --git a/CHANGELOG.md b/CHANGELOG.md index 15b762d..dc27742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,7 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - USAGE_EXAMPLES.md with 25+ real-world standalone examples - SWIFTUI_EXAMPLES.md with SwiftUI integration patterns for iOS/macOS - APPKIT_EXAMPLES.md with AppKit integration patterns for macOS -- Man page documentation (jpegls.1) in groff format +- Man page documentation (man/jpegls.1) in groff format - Man page installation instructions in README ### Changed @@ -300,7 +300,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Release Notes Format -See [RELEASE_NOTES_TEMPLATE.md](RELEASE_NOTES_TEMPLATE.md) for the release notes template used for GitHub releases. +See [RELEASE_NOTES_TEMPLATE.md](docs/RELEASE_NOTES_TEMPLATE.md) for the release notes template used for GitHub releases. ## Version History diff --git a/README.md b/README.md index ee8766e..4fc20eb 100644 --- a/README.md +++ b/README.md @@ -543,12 +543,12 @@ Complete documentation for the `jpegls` command-line tool is available as a Unix ```bash # System-wide installation (requires sudo) -sudo cp jpegls.1 /usr/local/share/man/man1/ +sudo cp man/jpegls.1 /usr/local/share/man/man1/ sudo mandb # Update man page database (on Linux) # User installation (no sudo required) mkdir -p ~/.local/share/man/man1 -cp jpegls.1 ~/.local/share/man/man1/ +cp man/jpegls.1 ~/.local/share/man/man1/ # Add to ~/.bashrc or ~/.zshrc: export MANPATH="$HOME/.local/share/man:$MANPATH" ``` @@ -559,7 +559,7 @@ cp jpegls.1 ~/.local/share/man/man1/ man jpegls # Or view directly without installation -man ./jpegls.1 +man ./man/jpegls.1 ``` The man page includes: @@ -577,7 +577,7 @@ The man page includes: | 1.2.840.10008.1.2.4.80 | JPEG-LS Lossless Image Compression | | 1.2.840.10008.1.2.4.81 | JPEG-LS Lossy (Near-Lossless) Image Compression | -See [MILESTONES.md](MILESTONES.md) for the detailed development roadmap. +See [MILESTONES.md](docs/MILESTONES.md) for the detailed development roadmap. ## Building & Testing @@ -714,7 +714,7 @@ JLSwift includes comprehensive conformance testing using reference files from th The conformance tests are located in `Tests/JPEGLSTests/CharLSConformanceTests.swift` with reference fixtures in `Tests/JPEGLSTests/TestFixtures/`. These tests ensure compatibility with the JPEG-LS standard (ISO/IEC 14495-1:1999 / ITU-T.87) and provide a foundation for bit-exact comparison with CharLS output. -A full standards conformance matrix (`CONFORMANCE_MATRIX.md`) documents the mapping between every normative section of ITU-T.87 and its implementation in JLSwift, including all deviations found and fixed during Milestone 10 (Phases 10.1–10.4). +A full standards conformance matrix (`docs/CONFORMANCE_MATRIX.md`) documents the mapping between every normative section of ITU-T.87 and its implementation in JLSwift, including all deviations found and fixed during Milestone 10 (Phases 10.1–10.4). ### Code Coverage Requirement @@ -740,7 +740,11 @@ JLSwift/ │ └── workflows/ │ └── ci.yml # CI pipeline (build → test with caching & concurrency) ├── README.md # This file -└── MILESTONES.md # Project roadmap +├── CHANGELOG.md # Release history +├── docs/ # Guides, specs, and reference docs (see docs/README.md) +│ └── MILESTONES.md # Project roadmap (+ guides, specs) +└── man/ + └── jpegls.1 # CLI man page ``` ## Documentation @@ -748,19 +752,19 @@ JLSwift/ | Document | Description | |----------|-------------| | [README.md](README.md) | Project overview and usage guide (this file) | -| [GETTING_STARTED.md](GETTING_STARTED.md) | Quick start guide with examples and common patterns | -| [USAGE_EXAMPLES.md](USAGE_EXAMPLES.md) | Comprehensive real-world usage examples | -| [SWIFTUI_EXAMPLES.md](SWIFTUI_EXAMPLES.md) | SwiftUI integration guide with image loading examples | -| [APPKIT_EXAMPLES.md](APPKIT_EXAMPLES.md) | AppKit integration guide for macOS applications | -| [SERVER_SIDE_EXAMPLES.md](SERVER_SIDE_EXAMPLES.md) | Server-side Swift integration guide (Vapor, Hummingbird, NIO) | -| [DICOMKIT_INTEGRATION.md](DICOMKIT_INTEGRATION.md) | DICOMkit integration guide for DICOM imaging workflows | -| [PERFORMANCE_TUNING.md](PERFORMANCE_TUNING.md) | Performance optimisation and benchmarking guide | -| [METAL_GPU_ACCELERATION.md](METAL_GPU_ACCELERATION.md) | Metal GPU acceleration guide for large images | -| [TROUBLESHOOTING.md](TROUBLESHOOTING.md) | Common issues and solutions | -| [VERSIONING.md](VERSIONING.md) | Semantic versioning strategy and release guidelines | +| [GETTING_STARTED.md](docs/GETTING_STARTED.md) | Quick start guide with examples and common patterns | +| [USAGE_EXAMPLES.md](docs/USAGE_EXAMPLES.md) | Comprehensive real-world usage examples | +| [SWIFTUI_EXAMPLES.md](docs/SWIFTUI_EXAMPLES.md) | SwiftUI integration guide with image loading examples | +| [APPKIT_EXAMPLES.md](docs/APPKIT_EXAMPLES.md) | AppKit integration guide for macOS applications | +| [SERVER_SIDE_EXAMPLES.md](docs/SERVER_SIDE_EXAMPLES.md) | Server-side Swift integration guide (Vapor, Hummingbird, NIO) | +| [DICOMKIT_INTEGRATION.md](docs/DICOMKIT_INTEGRATION.md) | DICOMkit integration guide for DICOM imaging workflows | +| [PERFORMANCE_TUNING.md](docs/PERFORMANCE_TUNING.md) | Performance optimisation and benchmarking guide | +| [METAL_GPU_ACCELERATION.md](docs/METAL_GPU_ACCELERATION.md) | Metal GPU acceleration guide for large images | +| [TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) | Common issues and solutions | +| [VERSIONING.md](docs/VERSIONING.md) | Semantic versioning strategy and release guidelines | | [CHANGELOG.md](CHANGELOG.md) | Complete history of changes and releases | -| [MILESTONES.md](MILESTONES.md) | Project milestones and development roadmap | -| [X86_64_REMOVAL_GUIDE.md](X86_64_REMOVAL_GUIDE.md) | Step-by-step guide for removing x86-64 support | +| [MILESTONES.md](docs/MILESTONES.md) | Project milestones and development roadmap | +| [X86_64_REMOVAL_GUIDE.md](docs/X86_64_REMOVAL_GUIDE.md) | Step-by-step guide for removing x86-64 support | | [Copilot Instructions](.github/copilot-instructions.md) | Coding guidelines for contributors | ### API Documentation @@ -774,9 +778,9 @@ swift package generate-documentation ### User Guides -- **[Getting Started](GETTING_STARTED.md)**: Installation, quick start, and basic usage examples -- **[Performance Tuning](PERFORMANCE_TUNING.md)**: Hardware acceleration, memory optimisation, and profiling -- **[Troubleshooting](TROUBLESHOOTING.md)**: Solutions to common problems and debugging tips +- **[Getting Started](docs/GETTING_STARTED.md)**: Installation, quick start, and basic usage examples +- **[Performance Tuning](docs/PERFORMANCE_TUNING.md)**: Hardware acceleration, memory optimisation, and profiling +- **[Troubleshooting](docs/TROUBLESHOOTING.md)**: Solutions to common problems and debugging tips ## Contributing @@ -785,7 +789,7 @@ When contributing to JLSwift, please follow these guidelines: 1. **Code Style**: Follow the [Swift API Design Guidelines](https://www.swift.org/documentation/api-design-guidelines/) 2. **Testing**: All public APIs must have corresponding unit tests with >95% coverage 3. **Documentation**: All public types and methods must have documentation comments -4. **Documentation Updates**: Update README.md and MILESTONES.md when features or APIs change +4. **Documentation Updates**: Update README.md and docs/MILESTONES.md when features or APIs change 5. **British English**: All comments, documentation, help text, and error messages must use British English (e.g., colour, optimise, initialise, behaviour, organisation). Public API identifiers (type names, method names, property names) retain their original American spelling. ### Pull Request Checklist @@ -793,7 +797,7 @@ When contributing to JLSwift, please follow these guidelines: - [ ] All tests pass (`swift test`) - [ ] Test coverage is above 95% - [ ] README.md is updated if features or APIs changed -- [ ] MILESTONES.md is updated if milestone progress changed +- [ ] docs/MILESTONES.md is updated if milestone progress changed - [ ] All public APIs have documentation comments - [ ] Code follows Swift 6.2+ best practices diff --git a/Tests/JPEGLSTests/JPEGLSRoundTripInteroperabilityTests.swift b/Tests/JPEGLSTests/JPEGLSRoundTripInteroperabilityTests.swift index 485ee63..da0c2b5 100644 --- a/Tests/JPEGLSTests/JPEGLSRoundTripInteroperabilityTests.swift +++ b/Tests/JPEGLSTests/JPEGLSRoundTripInteroperabilityTests.swift @@ -12,7 +12,7 @@ // // Note: Near-lossless encoder round-trip tests are limited to small images (≤8×8) // due to a known pre-existing encoder issue. The decoder is correct (validated by -// CharLS bit-exact comparison tests). See Phase 8.1 / Phase 12.1 in MILESTONES.md. +// CharLS bit-exact comparison tests). See Phase 8.1 / Phase 12.1 in docs/MILESTONES.md. // // Note: Test patterns avoid purely flat (constant-value) images >8×8 and gradient // patterns that produce flat transformed components after HP1/HP3 colour transforms, diff --git a/Tests/JPEGLSTests/Phase16OptimisationTests.swift b/Tests/JPEGLSTests/Phase16OptimisationTests.swift index 875bbfc..5719a1e 100644 --- a/Tests/JPEGLSTests/Phase16OptimisationTests.swift +++ b/Tests/JPEGLSTests/Phase16OptimisationTests.swift @@ -7,7 +7,7 @@ import Foundation /// Validates that the Milestone 16 performance improvements produce bit-exact /// output equivalent to the reference implementations and report measurable /// speed gains. Tests cover: -/// - Phase 16.1: Baseline measurements (documented in MILESTONES.md) +/// - Phase 16.1: Baseline measurements (documented in docs/MILESTONES.md) /// - Phase 16.2: Algorithmic optimisations (CLZ Golomb-Rice, gradient table) /// - Phase 16.3: Memory & I/O optimisations (batch bit writes, buffer pre-sizing) diff --git a/default.profraw b/default.profraw deleted file mode 100644 index 4c6737dfd5f55c8bd6072fe6e3c43dc7d0274197..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 303200 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

iLd$I_`B+IpFn_olhc#3@(41a~f6X6*%kF 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