diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bc7efd7..c2749a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and stale roadmap entries have been removed from the public documentation set. Staged workspace version: `0.13.2`. +- `AdapterErrorKind::Decode`, `BackendErrorKind::Decode` and + `BackendError::decode` classify GPU Tier-1 device decode failures. Metal FAIL + statuses now use the existing `Error::Decode` and `J2kError::Backend` + wrappers instead of `Error::MetalKernel`, so their display starts with + `backend failed (decode):`; the diagnostic keeps the classic or HT path, + status, detail and batch source index. CUDA keeps its typed source and job + attribution. Unsupported statuses, raw runtime failures and combined + cleanup or release failures keep their existing classes. - Classic code-blocks with BYPASS, per-pass termination, context resets or segmentation symbols use the packed-column passes, including raw segments. Vertically causal blocks retain the per-coefficient passes. Clean and corrupt diff --git a/crates/j2k-core/src/error.rs b/crates/j2k-core/src/error.rs index 3180824c..0537db7a 100644 --- a/crates/j2k-core/src/error.rs +++ b/crates/j2k-core/src/error.rs @@ -131,6 +131,8 @@ pub enum AdapterErrorKind { Buffer, /// Error is an unsupported backend, request, input, or host capability. Unsupported, + /// Backend execution failed while decoding accepted input. + Decode, } /// Variant mapping supplied by GPU adapter error enums. @@ -138,7 +140,8 @@ pub trait AdapterErrorParts { /// Return the wrapped codec/fallback error, when this adapter error has one. fn source_codec_error(&self) -> Option<&dyn CodecError>; - /// Return the adapter-local classification for non-codec variants. + /// Return the adapter-local classification, including backend decode + /// execution failures. fn adapter_error_kind(&self) -> AdapterErrorKind; } diff --git a/crates/j2k-cuda/src/error.rs b/crates/j2k-cuda/src/error.rs index cf75cdcc..2df28f72 100644 --- a/crates/j2k-cuda/src/error.rs +++ b/crates/j2k-cuda/src/error.rs @@ -12,6 +12,10 @@ use j2k_native::DecodeError as NativeDecodeError; pub use native_source::NativeBackendError; +#[cfg(feature = "cuda-runtime")] +// Mirrors STATUS_FAILED in classic decode and HT_STATUS_FAIL in HT decode. +const TIER1_STATUS_FAIL: u32 = 1; + /// Error returned by the CUDA JPEG 2000 adapter. #[derive(Debug, thiserror::Error)] #[non_exhaustive] @@ -205,6 +209,15 @@ impl AdapterErrorParts for Error { | Self::HostAllocationTooLarge { .. } | Self::HtJobChunkPlan(_) => AdapterErrorKind::Other, #[cfg(feature = "cuda-runtime")] + Self::CudaTier1JobFailed { + source: + j2k_cuda_runtime::CudaError::KernelJobStatus { + code: TIER1_STATUS_FAIL, + .. + }, + .. + } => AdapterErrorKind::Decode, + #[cfg(feature = "cuda-runtime")] Self::CudaRuntime { .. } | Self::CudaTier1JobFailed { .. } | Self::CudaCleanupFailed { .. } => AdapterErrorKind::Other, @@ -254,6 +267,8 @@ pub(crate) fn native_decode_error(error: NativeDecodeError) -> Error { #[cfg(test)] mod tests { use j2k_core::CodecError; + #[cfg(feature = "cuda-runtime")] + use j2k_core::{AdapterErrorKind, AdapterErrorParts}; use j2k_native::{ DecodeError as NativeDecodeError, DecodingError as NativeDecodingError, DirectPlanUnsupportedReason as NativeDirectPlanUnsupportedReason, @@ -395,4 +410,77 @@ mod tests { assert!(rendered.contains("synchronization failure")); assert!(!combined.is_unsupported()); } + + #[cfg(feature = "cuda-runtime")] + #[test] + fn tier1_job_failure_has_decode_class_without_reclassifying_runtime_or_cleanup() { + let source = CudaError::KernelJobStatus { + kernel: "test_tier1", + job_index: 3, + code: 1, + detail: 5, + }; + let error = Error::CudaTier1JobFailed { + source_index: 7, + original_job_index: 3, + source, + }; + assert_eq!(error.adapter_error_kind(), AdapterErrorKind::Decode); + assert!(matches!( + &error, + Error::CudaTier1JobFailed { + source_index: 7, + original_job_index: 3, + source: CudaError::KernelJobStatus { + code: 1, + detail: 5, + .. + } + } + )); + + let raw_runtime = Error::CudaRuntime { + source: CudaError::KernelJobStatus { + kernel: "test_tier1", + job_index: 3, + code: 1, + detail: 5, + }, + }; + assert_eq!(raw_runtime.adapter_error_kind(), AdapterErrorKind::Other); + let cleanup = combine_cuda_cleanup_errors(error, runtime_error("cleanup failed")); + assert_eq!(cleanup.adapter_error_kind(), AdapterErrorKind::Other); + + let unsupported = Error::CudaTier1JobFailed { + source_index: 7, + original_job_index: 3, + source: CudaError::KernelJobStatus { + kernel: "test_tier1", + job_index: 3, + code: 2, + detail: 9, + }, + }; + assert_eq!(unsupported.adapter_error_kind(), AdapterErrorKind::Other); + + let release_failure = Error::CudaTier1JobFailed { + source_index: 7, + original_job_index: 3, + source: CudaError::ResourceReleaseFailed { + primary: Box::new(CudaError::KernelJobStatus { + kernel: "test_tier1", + job_index: 3, + code: 1, + detail: 5, + }), + release: Box::new(CudaError::StatePoisoned { + message: "release failed".to_string(), + }), + }, + }; + assert_eq!( + release_failure.adapter_error_kind(), + AdapterErrorKind::Other + ); + } } diff --git a/crates/j2k-metal/src/engine/direct_status.rs b/crates/j2k-metal/src/engine/direct_status.rs index dad19e7f..699990f0 100644 --- a/crates/j2k-metal/src/engine/direct_status.rs +++ b/crates/j2k-metal/src/engine/direct_status.rs @@ -2,6 +2,7 @@ use crate::metal_types::Buffer; +use crate::error::adapter_decode_error; use crate::{buffer_pool::PooledBuffer, Error, MetalDirectFallbackReason}; use super::abi::{ @@ -227,13 +228,15 @@ fn decode_classic_status_error_for_source( reason: MetalDirectFallbackReason::UnsupportedRuntimeInput, }; } - let kind = match status.code { - J2K_CLASSIC_STATUS_FAIL => "decode failure", - _ => "unexpected classic kernel status", - }; + if status.code == J2K_CLASSIC_STATUS_FAIL { + return Error::Decode(adapter_decode_error(format!( + "classic J2K Metal kernel decode failure{source} (code={}, detail={})", + status.code, status.detail + ))); + } Error::MetalKernel { message: format!( - "classic J2K Metal kernel {kind}{source} (detail={})", + "classic J2K Metal kernel unexpected classic kernel status{source} (detail={})", status.detail ), } @@ -267,38 +270,109 @@ fn decode_ht_status_error_for_source(status: J2kHtStatus, source_index: Option "decode failure", - _ => "unexpected HT kernel status", - }; + if status.code == J2K_HT_STATUS_FAIL { + return Error::Decode(adapter_decode_error(format!( + "HTJ2K Metal kernel decode failure{source} (code={}, detail={})", + status.code, status.detail + ))); + } Error::MetalKernel { message: format!( - "HTJ2K Metal kernel {kind}{source} (detail={})", + "HTJ2K Metal kernel unexpected HT kernel status{source} (detail={})", status.detail ), } } #[cfg(test)] -mod ht_source_tests { - use super::{decode_ht_status_error_for_source, Error, J2kHtStatus, J2K_HT_STATUS_FAIL}; +mod tier1_decode_status_tests { + use j2k::{BackendErrorKind, J2kError}; + use j2k_core::{AdapterErrorKind, AdapterErrorParts}; + + use super::{ + decode_classic_status_error_for_source, decode_ht_status_error_for_source, Error, + J2kClassicStatus, J2kHtStatus, J2K_CLASSIC_STATUS_FAIL, J2K_CLASSIC_STATUS_UNSUPPORTED, + J2K_HT_STATUS_FAIL, + }; + + fn assert_decode_failure(error: Error, coding: &str, detail: u32, source_index: usize) { + assert_eq!(error.adapter_error_kind(), AdapterErrorKind::Decode); + let Error::Decode(J2kError::Backend(backend)) = error else { + panic!("Tier-1 status failure must keep the existing facade decode wrapper"); + }; + assert_eq!(backend.kind(), BackendErrorKind::Decode); + assert!(backend.message().contains(coding)); + assert!(backend + .message() + .contains(&format!("source {source_index}"))); + assert!(backend.message().contains("code=1")); + assert!(backend.message().contains(&format!("detail={detail}"))); + } + + #[test] + fn classic_status_failure_keeps_decode_class_and_source_attribution() { + assert_decode_failure( + decode_classic_status_error_for_source( + J2kClassicStatus { + code: J2K_CLASSIC_STATUS_FAIL, + detail: 10, + ..J2kClassicStatus::default() + }, + Some(7), + ), + "classic", + 10, + 7, + ); + } + + #[test] + fn ht_status_failure_keeps_decode_class_and_source_attribution() { + assert_decode_failure( + decode_ht_status_error_for_source( + J2kHtStatus { + code: J2K_HT_STATUS_FAIL, + detail: 5, + ..J2kHtStatus::default() + }, + Some(9), + ), + "HTJ2K", + 5, + 9, + ); + } #[test] - fn ht_status_failure_names_the_responsible_batch_source() { - let error = decode_ht_status_error_for_source( + fn unsupported_and_unknown_statuses_keep_their_existing_classes() { + let unsupported = decode_classic_status_error_for_source( + J2kClassicStatus { + code: J2K_CLASSIC_STATUS_UNSUPPORTED, + detail: 3, + ..J2kClassicStatus::default() + }, + Some(4), + ); + assert!(matches!(unsupported, Error::MetalDirectFallback { .. })); + assert_eq!( + unsupported.adapter_error_kind(), + AdapterErrorKind::Unsupported + ); + + let unknown = decode_ht_status_error_for_source( J2kHtStatus { - code: J2K_HT_STATUS_FAIL, + code: u32::MAX, detail: 17, ..J2kHtStatus::default() }, Some(9), ); - assert!(matches!( - error, - Error::MetalKernel { message } + unknown, + Error::MetalKernel { ref message } if message.contains("source 9") && message.contains("detail=17") )); + assert_eq!(unknown.adapter_error_kind(), AdapterErrorKind::Other); } } @@ -336,6 +410,7 @@ mod mct_status_tests { #[cfg(test)] mod retirement_tests { use core::mem::size_of; + use j2k::{BackendErrorKind, J2kError}; use super::{ retire_direct_status_checks, DirectStatusCheck, DirectStatusRetirementMode, Error, @@ -392,7 +467,9 @@ mod retirement_tests { .expect_err("first status must fail validation"); assert!(matches!( error, - Error::MetalKernel { message } if message.contains("detail=41") + Error::Decode(J2kError::Backend(backend)) + if backend.kind() == BackendErrorKind::Decode + && backend.message().contains("detail=41") )); assert_eq!( runtime diff --git a/crates/j2k-metal/src/error.rs b/crates/j2k-metal/src/error.rs index d1dcd5f7..1ffbad66 100644 --- a/crates/j2k-metal/src/error.rs +++ b/crates/j2k-metal/src/error.rs @@ -2,9 +2,9 @@ mod native_source; -use j2k::J2kError; #[cfg(target_os = "macos")] -use j2k::{BackendError, BackendErrorKind}; +use j2k::BackendError; +use j2k::{BackendErrorKind, J2kError}; use j2k_core::{ adapter_error_is_buffer_error, adapter_error_is_not_implemented, adapter_error_is_truncated, adapter_error_is_unsupported, AdapterErrorKind, AdapterErrorParts, BackendRequest, @@ -19,7 +19,7 @@ pub use native_source::NativeBackendError; #[derive(Debug, thiserror::Error)] /// Errors returned by the Metal J2K backend. pub enum Error { - /// Error returned by the CPU or native J2K decoder. + /// Error returned while decoding through the shared facade contract. #[error(transparent)] Decode(#[from] J2kError), /// Native decoder failure produced while preparing Metal-resident work. @@ -221,6 +221,9 @@ impl AdapterErrorParts for Error { fn adapter_error_kind(&self) -> AdapterErrorKind { match self { Self::Buffer(_) => AdapterErrorKind::Buffer, + Self::Decode(J2kError::Backend(error)) if error.kind() == BackendErrorKind::Decode => { + AdapterErrorKind::Decode + } Self::UnsupportedBackend { .. } | Self::UnsupportedMetalRequest { .. } | Self::MetalUnavailable @@ -313,9 +316,15 @@ pub(crate) fn adapter_backend_error(message: impl Into) -> J2kError { J2kError::Backend(BackendError::new(BackendErrorKind::Other, message)) } +#[cfg(target_os = "macos")] +pub(crate) fn adapter_decode_error(message: impl Into) -> J2kError { + J2kError::Backend(BackendError::decode(message)) +} + #[cfg(test)] mod tests { - use j2k_core::CodecError; + use j2k::{BackendError, BackendErrorKind, J2kError}; + use j2k_core::{AdapterErrorKind, AdapterErrorParts, CodecError}; use j2k_metal_support::MetalSupportError; use j2k_native::{ DecodeError as NativeDecodeError, DecodingError as NativeDecodingError, @@ -458,6 +467,18 @@ mod tests { assert!(error.is_unsupported()); } + #[test] + fn facade_decode_class_is_selective_for_backend_decode_failures() { + let decode = Error::Decode(J2kError::Backend(BackendError::decode("Tier-1 failed"))); + assert_eq!(decode.adapter_error_kind(), AdapterErrorKind::Decode); + + let other = Error::Decode(J2kError::Backend(BackendError::new( + BackendErrorKind::Other, + "device setup failed", + ))); + assert_eq!(other.adapter_error_kind(), AdapterErrorKind::Other); + } + #[test] fn persistent_session_classification_is_owned_by_metal_error() { assert!(Error::MetalUnavailable.session_is_unusable()); diff --git a/crates/j2k/src/error.rs b/crates/j2k/src/error.rs index cf5c73ed..db919c21 100644 --- a/crates/j2k/src/error.rs +++ b/crates/j2k/src/error.rs @@ -27,6 +27,8 @@ pub enum BackendErrorKind { Validation, /// Failure indicates an internal facade/cache invariant violation. InternalInvariant, + /// Backend execution failed while decoding accepted input. + Decode, } impl core::fmt::Display for BackendErrorKind { @@ -39,6 +41,7 @@ impl core::fmt::Display for BackendErrorKind { Self::Buffer => f.write_str("buffer"), Self::Validation => f.write_str("validation"), Self::InternalInvariant => f.write_str("internal-invariant"), + Self::Decode => f.write_str("decode"), } } } @@ -80,6 +83,11 @@ impl BackendError { Self::new(BackendErrorKind::Buffer, message) } + /// Construct a backend decode-execution failure. + pub fn decode(message: impl Into) -> Self { + Self::new(BackendErrorKind::Decode, message) + } + /// Return the machine-readable failure class. pub const fn kind(&self) -> BackendErrorKind { self.kind @@ -681,6 +689,7 @@ mod tests { let truncated = J2kError::Backend(BackendError::truncated("entropy data")); let not_implemented = J2kError::Backend(BackendError::not_implemented("JPX path")); let buffer = J2kError::Backend(BackendError::buffer("output pitch")); + let decode = J2kError::Backend(BackendError::decode("Tier-1 status 1")); let other = J2kError::Backend(BackendError::new( BackendErrorKind::Other, "kernel launch failed", @@ -690,6 +699,11 @@ mod tests { assert!(truncated.is_truncated()); assert!(not_implemented.is_not_implemented()); assert!(buffer.is_buffer_error()); + let J2kError::Backend(decode) = decode else { + panic!("decode constructor returns a backend error"); + }; + assert_eq!(decode.kind(), BackendErrorKind::Decode); + assert_eq!(decode.message(), "Tier-1 status 1"); assert!(!other.is_unsupported()); assert!(!other.is_truncated()); assert!(!other.is_not_implemented()); diff --git a/xtask/api/stable-api-1.0.public-api.txt b/xtask/api/stable-api-1.0.public-api.txt index 49def898..9f3b45b9 100644 --- a/xtask/api/stable-api-1.0.public-api.txt +++ b/xtask/api/stable-api-1.0.public-api.txt @@ -176,6 +176,7 @@ pub enum j2k::J2kRateTarget pub enum j2k::J2kToHtj2kMode pub enum j2k::ReversibleTransform pub fn j2k::BackendError::buffer(impl core::convert::Into) -> Self +pub fn j2k::BackendError::decode(impl core::convert::Into) -> Self pub fn j2k::BackendError::message(&self) -> &str pub fn j2k::BackendError::new(j2k::BackendErrorKind, impl core::convert::Into) -> Self pub fn j2k::BackendError::not_implemented(impl core::convert::Into) -> Self @@ -380,6 +381,7 @@ pub fn j2k::release_tile_batch_workspaces() pub fn j2k::retained_tile_batch_workspace_bytes() -> usize pub fn j2k::wrap_j2k_codestream(&[u8], j2k::J2kFileWrapOptions<'_>) -> core::result::Result, j2k::J2kError> pub j2k::BackendErrorKind::Buffer +pub j2k::BackendErrorKind::Decode pub j2k::BackendErrorKind::InternalInvariant pub j2k::BackendErrorKind::NotImplemented pub j2k::BackendErrorKind::Other @@ -1020,6 +1022,7 @@ pub fn j2k_core::accelerator::GpuAbi::as_bytes(&Self) -> &[u8] pub fn j2k_core::accelerator::GpuAbi::slice_as_bytes(&[Self]) -> &[u8] pub fn j2k_core::accelerator::GpuAbi::slice_as_bytes_mut(&mut [Self]) -> &mut [u8] pub j2k_core::AdapterErrorKind::Buffer +pub j2k_core::AdapterErrorKind::Decode pub j2k_core::AdapterErrorKind::Other pub j2k_core::AdapterErrorKind::Unsupported pub j2k_core::BackendCapabilities::cpu: j2k_core::CpuFeatures diff --git a/xtask/release-evidence/public-api/public-api-review-0.13.2.yml b/xtask/release-evidence/public-api/public-api-review-0.13.2.yml index b636c35a..a5536d87 100644 --- a/xtask/release-evidence/public-api/public-api-review-0.13.2.yml +++ b/xtask/release-evidence/public-api/public-api-review-0.13.2.yml @@ -6,10 +6,10 @@ break_ledger: [] reviews: j2k-core: removed_fingerprint: "none" - added_fingerprint: "none" + added_fingerprint: "fnv1a64:1783cd7e6f188540" hidden_count: 226 hidden_fingerprint: "fnv1a64:487523cc4e7f504e" - rationale: "Compared the complete ordinary API inventory against v0.13.1; no signatures were added, removed, or changed." + rationale: "Adds AdapterErrorKind::Decode to an existing non-exhaustive enum for backend decode-execution failures. The variant is appended, preserving existing discriminants. AdapterErrorParts method signatures and the existing codec-error boolean helpers are unchanged; existing wildcard matches remain valid." hidden_rationale: "Compared the complete hidden API inventory against v0.13.1; it is unchanged." j2k-profile: removed_fingerprint: "none" @@ -104,10 +104,10 @@ reviews: hidden_rationale: "Compared the complete hidden API inventory against v0.13.1; it is unchanged." j2k: removed_fingerprint: "none" - added_fingerprint: "fnv1a64:363048555efa46de" + added_fingerprint: "fnv1a64:78b9622111db3437" hidden_count: 108 hidden_fingerprint: "fnv1a64:01e74ad6c3ff416e" - rationale: "Compared the complete ordinary API inventory against v0.13.1. Adds J2kError::ResourceLimit { requested, cap, source } to an already non-exhaustive enum; no existing item changes and existing variant discriminants are preserved. Budget and image-size failures now use this variant instead of NativeDecode, retaining the structured native cause. Callers specifically handling budget failures through NativeDecode should also handle ResourceLimit. Batches prepared by CpuBatchDecoder report items whose output allocation or planned execution cannot fit as indexed preparation errors and exclude those items from the prepared groups. Backend-neutral prepare_batch and prepare_batch_from_images retain whole-call output-cap failures for a single oversized image when subsequently decoded on the CPU. On either preparation path, a group whose combined output exceeds the allocation cap still fails the whole decode call. These correct admission timing within the CPU-owned preparation paths and preserve the existing per-item failure model; successful decode output and signatures are unchanged. The public error documentation and changelog describe the refinements." + rationale: "Compared the complete ordinary API inventory against v0.13.1. Adds J2kError::ResourceLimit { requested, cap, source } to an already non-exhaustive enum; no existing item changes and existing variant discriminants are preserved. Budget and image-size failures now use this variant instead of NativeDecode, retaining the structured native cause. Callers specifically handling budget failures through NativeDecode should also handle ResourceLimit. Batches prepared by CpuBatchDecoder report items whose output allocation or planned execution cannot fit as indexed preparation errors and exclude those items from the prepared groups. Backend-neutral prepare_batch and prepare_batch_from_images retain whole-call output-cap failures for a single oversized image when subsequently decoded on the CPU. On either preparation path, a group whose combined output exceeds the allocation cap still fails the whole decode call. These correct admission timing within the CPU-owned preparation paths and preserve the existing per-item failure model; successful decode output and signatures are unchanged. Adds BackendErrorKind::Decode at the end of its existing non-exhaustive enum and BackendError::decode for failures during backend decode execution. Existing discriminants and constructors are preserved. The public error documentation and changelog describe the refinements." hidden_rationale: "Compared the complete hidden API inventory against v0.13.1; it is unchanged." j2k-transcode: removed_fingerprint: "none" @@ -135,7 +135,7 @@ reviews: added_fingerprint: "none" hidden_count: 321 hidden_fingerprint: "fnv1a64:41513c1e93413909" - rationale: "Compared the complete ordinary API inventory against v0.13.1; no signatures were added, removed, or changed." + rationale: "No ordinary signatures or error variants were added, removed, or changed. Classic and HT Tier-1 FAIL statuses now use the existing Error::Decode(J2kError::Backend) wrapper with BackendErrorKind::Decode instead of Error::MetalKernel. Their display prefix becomes backend failed (decode):; the diagnostic retains the coding path, status code, detail and batch source index. Unsupported and unknown statuses, runtime failures, cleanup failures, session retirement and fallback classification keep their existing behavior. This is a documented refinement of failure classification, not a new Metal error variant." hidden_rationale: "Compared the complete hidden API inventory against v0.13.1; it is unchanged." j2k-transcode-metal: removed_fingerprint: "none" @@ -156,7 +156,7 @@ reviews: added_fingerprint: "none" hidden_count: 193 hidden_fingerprint: "fnv1a64:8a9b0ac701f08d00" - rationale: "Compared the complete ordinary API inventory against v0.13.1; no signatures were added, removed, or changed." + rationale: "No ordinary signatures or error variants were added, removed, or changed. AdapterErrorParts reports Decode only for a CudaTier1JobFailed with a direct bare KernelJobStatus source whose code is the classic/HT FAIL value 1. The typed CUDA source and job attribution remain available. Unsupported or unknown statuses, raw runtime errors and nested completion, release or adapter-cleanup failures retain their existing classes and fallback behavior." hidden_rationale: "Compared the complete hidden API inventory against v0.13.1; it is unchanged." j2k-ml: removed_fingerprint: "none" diff --git a/xtask/release-evidence/public-api/reviewed-public-api-diff-0.13.2.md b/xtask/release-evidence/public-api/reviewed-public-api-diff-0.13.2.md index 66b39142..2fcd0488 100644 --- a/xtask/release-evidence/public-api/reviewed-public-api-diff-0.13.2.md +++ b/xtask/release-evidence/public-api/reviewed-public-api-diff-0.13.2.md @@ -11,7 +11,7 @@ This report is generated by `cargo xtask semver --write-report`. Normal `cargo x | Package | Baseline | Candidate | Computed release type | Added | Removed/changed | Removed fingerprint | Added fingerprint | Rustdoc-hidden items | Hidden inventory fingerprint | | --- | --- | --- | --- | ---: | ---: | --- | --- | ---: | --- | -| `j2k-core` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 226 | `fnv1a64:487523cc4e7f504e` | +| `j2k-core` | `0.13.1` | `0.13.2` | `minor` | 1 | 0 | `none` | `fnv1a64:1783cd7e6f188540` | 226 | `fnv1a64:487523cc4e7f504e` | | `j2k-profile` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 117 | `fnv1a64:a1546f56ae38f2e3` | | `j2k-types` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 111 | `fnv1a64:6eaf63f068893d17` | | `j2k-codec-math` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 0 | `none` | @@ -25,7 +25,7 @@ This report is generated by `cargo xtask semver --write-report`. Normal `cargo x | `j2k-native` | `0.13.1` | `0.13.2` | `minor` | 3 | 0 | `none` | `fnv1a64:22b943651a07318e` | 586 | `fnv1a64:733f3aa607999371` | | `j2k-jpeg` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 701 | `fnv1a64:bd0cf738a0f96592` | | `j2k-tilecodec` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 32 | `fnv1a64:eb677842559d9b0e` | -| `j2k` | `0.13.1` | `0.13.2` | `minor` | 4 | 0 | `none` | `fnv1a64:363048555efa46de` | 108 | `fnv1a64:01e74ad6c3ff416e` | +| `j2k` | `0.13.1` | `0.13.2` | `minor` | 6 | 0 | `none` | `fnv1a64:78b9622111db3437` | 108 | `fnv1a64:01e74ad6c3ff416e` | | `j2k-transcode` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 458 | `fnv1a64:449a76476549c1e2` | | `j2k-transcode-cuda` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 20 | `fnv1a64:be22ca1d5e12b043` | | `j2k-jpeg-metal` | `0.13.1` | `0.13.2` | `minor` | 0 | 0 | `none` | `none` | 83 | `fnv1a64:79397ffc221464c3` | @@ -40,7 +40,7 @@ This report is generated by `cargo xtask semver --write-report`. Normal `cargo x ### `j2k-core` -Baseline items: 526. Candidate items: 526. Computed release type: `minor`. Rustdoc-hidden candidate items: 226. Full hidden-inventory fingerprint: `fnv1a64:487523cc4e7f504e`. +Baseline items: 526. Candidate items: 527. Computed release type: `minor`. Rustdoc-hidden candidate items: 226. Full hidden-inventory fingerprint: `fnv1a64:487523cc4e7f504e`. #### Removed or changed baseline API items @@ -48,7 +48,9 @@ None. #### Added candidate API items -None. +```text +pub j2k_core::AdapterErrorKind::Decode +``` ### `j2k-profile` @@ -212,7 +214,7 @@ None. ### `j2k` -Baseline items: 804. Candidate items: 808. Computed release type: `minor`. Rustdoc-hidden candidate items: 108. Full hidden-inventory fingerprint: `fnv1a64:01e74ad6c3ff416e`. +Baseline items: 804. Candidate items: 810. Computed release type: `minor`. Rustdoc-hidden candidate items: 108. Full hidden-inventory fingerprint: `fnv1a64:01e74ad6c3ff416e`. #### Removed or changed baseline API items @@ -221,6 +223,8 @@ None. #### Added candidate API items ```text +pub fn j2k::BackendError::decode(impl core::convert::Into) -> Self +pub j2k::BackendErrorKind::Decode pub j2k::J2kError::ResourceLimit pub j2k::J2kError::ResourceLimit::cap: core::option::Option pub j2k::J2kError::ResourceLimit::requested: core::option::Option