1use std::borrow::Cow;
2use std::ffi::CStr;
3
4use libde265_sys::de265_error as de;
5use thiserror::Error;
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Error)]
8#[non_exhaustive]
9pub enum DeError {
10 #[error("Error: No such file")]
11 ErrorNoSuchFile,
12 #[error("Error: Coefficient out of image bounds")]
13 ErrorCoefficientOutOfImageBounds,
14 #[error("Error: Checksum mismatch")]
15 ErrorChecksumMismatch,
16 #[error("Error: CTB outside image area")]
17 ErrorCtbOutsideImageArea,
18 #[error("Error: Out of memory")]
19 ErrorOutOfMemory,
20 #[error("Error: Coded parameter out of range")]
21 ErrorCodedParameterOutOfRange,
22 #[error("Error: Image buffer full")]
23 ErrorImageBufferFull,
24 #[error("Error: Cannot start threadpool")]
25 ErrorCannotStartThreadpool,
26 #[error("Error: Library initialization failed")]
27 ErrorLibraryInitializationFailed,
28 #[error("Error: Library not initialized")]
29 ErrorLibraryNotInitialized,
30 #[error("Error: Waiting for input data")]
31 ErrorWaitingForInputData,
32 #[error("Error: Cannot process SEI")]
33 ErrorCannotProcessSei,
34 #[error("Error: Parameter parsing error")]
35 ErrorParameterParsing,
36 #[error("Error: No initial slice header")]
37 ErrorNoInitialSliceHeader,
38 #[error("Error: Premature end of slice")]
39 ErrorPrematureEndOfSlice,
40 #[error("Error: Unspecified decoding error")]
41 ErrorUnspecifiedDecodingError,
42 #[error("Error: Not implemented yet")]
43 ErrorNotImplementedYet,
44 #[error("Warning: No WPP - cannot use multithreading")]
45 WarningNoWppCannotUseMultithreading,
46 #[error("Warning: Warning buffer full")]
47 WarningWarningBufferFull,
48 #[error("Warning: Premature end of slice segment")]
49 WarningPrematureEndOfSliceSegment,
50 #[error("Warning: Incorrect entry point offset")]
51 WarningIncorrectEntryPointOffset,
52 #[error("Warning: CTB outside image area")]
53 WarningCtbOutsideImageArea,
54 #[error("Warning: SPS header invalid")]
55 WarningSpsHeaderInvalid,
56 #[error("Warning: PPS header invalid")]
57 WarningPpsHeaderInvalid,
58 #[error("Warning: Slice header invalid")]
59 WarningSliceHeaderInvalid,
60 #[error("Warning: Incorrect motion vector scaling")]
61 WarningIncorrectMotionVectorScaling,
62 #[error("Warning: Non-existing PPS referenced")]
63 WarningNonexistingPpsReferenced,
64 #[error("Warning: Non-existing SPS referenced")]
65 WarningNonexistingSpsReferenced,
66 #[error("Warning: Both prediction flags zero")]
67 WarningBothPredFlagsZero,
68 #[error("Warning: Non-existing reference picture accessed")]
69 WarningNonexistingReferencePictureAccessed,
70 #[error("Warning: Number of MVP not equal to number of MVQ")]
71 WarningNumMvpNotEqualToNumMvq,
72 #[error("Warning: Number of short term reference picture sets out of range")]
73 WarningNumberOfShortTermRefPicSetsOutOfRange,
74 #[error("Warning: Short term reference picture set out of range")]
75 WarningShortTermRefPicSetOutOfRange,
76 #[error("Warning: Faulty reference picture list")]
77 WarningFaultyReferencePictureList,
78 #[error("Warning: EOSS bit not set")]
79 WarningEossBitNotSet,
80 #[error("Warning: Maximum number of reference pictures exceeded")]
81 WarningMaxNumRefPicsExceeded,
82 #[error("Warning: Invalid chroma format")]
83 WarningInvalidChromaFormat,
84 #[error("Warning: Slice segment address invalid")]
85 WarningSliceSegmentAddressInvalid,
86 #[error("Warning: Dependent slice with address zero")]
87 WarningDependentSliceWithAddressZero,
88 #[error("Warning: Number of threads limited to maximum")]
89 WarningNumberOfThreadsLimitedToMaximum,
90 #[error("Warning: Non-existing LT reference candidate in slice header")]
91 WarningNonExistingLtReferenceCandidateInSliceHeader,
92 #[error("Warning: Cannot apply SAO - out of memory")]
93 WarningCannotApplySaoOutOfMemory,
94 #[error("Warning: SPS missing - cannot decode SEI")]
95 WarningSpsMissingCannotDecodeSei,
96 #[error("Warning: Collocated motion vector outside image area")]
97 WarningCollocatedMotionVectorOutsideImageArea,
98 #[error("Warning: PCM bit depth too large")]
99 WarningPcmBitDepthTooLarge,
100 #[error("Warning: Reference image bit depth does not match")]
101 WarningReferenceImageBitDepthDoesNotMatch,
102 #[error("Warning: Reference image size does not match SPS")]
103 WarningReferenceImageSizeDoesNotMatchSps,
104 #[error("Warning: Chroma of current image does not match SPS")]
105 WarningChromaOfCurrentImageDoesNotMatchSps,
106 #[error("Warning: Bit depth of current image does not match SPS")]
107 WarningBitDepthOfCurrentImageDoesNotMatchSps,
108 #[error("Warning: Reference image chroma format does not match")]
109 WarningReferenceImageChromaFormatDoesNotMatch,
110 #[error("Warning: Invalid slice header index access")]
111 WarningInvalidSliceHeaderIndexAccess,
112 #[error("{}", get_error_text(*.0))]
113 Unknown(u32),
114}
115
116pub type Result<T> = std::result::Result<T, DeError>;
117
118impl DeError {
119 pub fn from_raw(raw: de::Type) -> Result<()> {
120 let error = match raw {
121 de::DE265_OK => return Ok(()),
122 de::DE265_ERROR_NO_SUCH_FILE => Self::ErrorNoSuchFile,
123 de::DE265_ERROR_COEFFICIENT_OUT_OF_IMAGE_BOUNDS => {
124 Self::ErrorCoefficientOutOfImageBounds
125 }
126 de::DE265_ERROR_CHECKSUM_MISMATCH => Self::ErrorChecksumMismatch,
127 de::DE265_ERROR_CTB_OUTSIDE_IMAGE_AREA => Self::ErrorCtbOutsideImageArea,
128 de::DE265_ERROR_OUT_OF_MEMORY => Self::ErrorOutOfMemory,
129 de::DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE => Self::ErrorCodedParameterOutOfRange,
130 de::DE265_ERROR_IMAGE_BUFFER_FULL => Self::ErrorImageBufferFull,
131 de::DE265_ERROR_CANNOT_START_THREADPOOL => Self::ErrorCannotStartThreadpool,
132 de::DE265_ERROR_LIBRARY_INITIALIZATION_FAILED => Self::ErrorLibraryInitializationFailed,
133 de::DE265_ERROR_LIBRARY_NOT_INITIALIZED => Self::ErrorLibraryNotInitialized,
134 de::DE265_ERROR_WAITING_FOR_INPUT_DATA => Self::ErrorWaitingForInputData,
135 de::DE265_ERROR_CANNOT_PROCESS_SEI => Self::ErrorCannotProcessSei,
136 de::DE265_ERROR_PARAMETER_PARSING => Self::ErrorParameterParsing,
137 de::DE265_ERROR_NO_INITIAL_SLICE_HEADER => Self::ErrorNoInitialSliceHeader,
138 de::DE265_ERROR_PREMATURE_END_OF_SLICE => Self::ErrorPrematureEndOfSlice,
139 de::DE265_ERROR_UNSPECIFIED_DECODING_ERROR => Self::ErrorUnspecifiedDecodingError,
140 de::DE265_ERROR_NOT_IMPLEMENTED_YET => Self::ErrorNotImplementedYet,
141 de::DE265_WARNING_NO_WPP_CANNOT_USE_MULTITHREADING => {
142 Self::WarningNoWppCannotUseMultithreading
143 }
144 de::DE265_WARNING_WARNING_BUFFER_FULL => Self::WarningWarningBufferFull,
145 de::DE265_WARNING_PREMATURE_END_OF_SLICE_SEGMENT => {
146 Self::WarningPrematureEndOfSliceSegment
147 }
148 de::DE265_WARNING_INCORRECT_ENTRY_POINT_OFFSET => {
149 Self::WarningIncorrectEntryPointOffset
150 }
151 de::DE265_WARNING_CTB_OUTSIDE_IMAGE_AREA => Self::WarningCtbOutsideImageArea,
152 de::DE265_WARNING_SPS_HEADER_INVALID => Self::WarningSpsHeaderInvalid,
153 de::DE265_WARNING_PPS_HEADER_INVALID => Self::WarningPpsHeaderInvalid,
154 de::DE265_WARNING_SLICEHEADER_INVALID => Self::WarningSliceHeaderInvalid,
155 de::DE265_WARNING_INCORRECT_MOTION_VECTOR_SCALING => {
156 Self::WarningIncorrectMotionVectorScaling
157 }
158 de::DE265_WARNING_NONEXISTING_PPS_REFERENCED => Self::WarningNonexistingPpsReferenced,
159 de::DE265_WARNING_NONEXISTING_SPS_REFERENCED => Self::WarningNonexistingSpsReferenced,
160 de::DE265_WARNING_BOTH_PREDFLAGS_ZERO => Self::WarningBothPredFlagsZero,
161 de::DE265_WARNING_NONEXISTING_REFERENCE_PICTURE_ACCESSED => {
162 Self::WarningNonexistingReferencePictureAccessed
163 }
164 de::DE265_WARNING_NUMMVP_NOT_EQUAL_TO_NUMMVQ => Self::WarningNumMvpNotEqualToNumMvq,
165 de::DE265_WARNING_NUMBER_OF_SHORT_TERM_REF_PIC_SETS_OUT_OF_RANGE => {
166 Self::WarningNumberOfShortTermRefPicSetsOutOfRange
167 }
168 de::DE265_WARNING_SHORT_TERM_REF_PIC_SET_OUT_OF_RANGE => {
169 Self::WarningShortTermRefPicSetOutOfRange
170 }
171 de::DE265_WARNING_FAULTY_REFERENCE_PICTURE_LIST => {
172 Self::WarningFaultyReferencePictureList
173 }
174 de::DE265_WARNING_EOSS_BIT_NOT_SET => Self::WarningEossBitNotSet,
175 de::DE265_WARNING_MAX_NUM_REF_PICS_EXCEEDED => Self::WarningMaxNumRefPicsExceeded,
176 de::DE265_WARNING_INVALID_CHROMA_FORMAT => Self::WarningInvalidChromaFormat,
177 de::DE265_WARNING_SLICE_SEGMENT_ADDRESS_INVALID => {
178 Self::WarningSliceSegmentAddressInvalid
179 }
180 de::DE265_WARNING_DEPENDENT_SLICE_WITH_ADDRESS_ZERO => {
181 Self::WarningDependentSliceWithAddressZero
182 }
183 de::DE265_WARNING_NUMBER_OF_THREADS_LIMITED_TO_MAXIMUM => {
184 Self::WarningNumberOfThreadsLimitedToMaximum
185 }
186 de::DE265_NON_EXISTING_LT_REFERENCE_CANDIDATE_IN_SLICE_HEADER => {
187 Self::WarningNonExistingLtReferenceCandidateInSliceHeader
188 }
189 de::DE265_WARNING_CANNOT_APPLY_SAO_OUT_OF_MEMORY => {
190 Self::WarningCannotApplySaoOutOfMemory
191 }
192 de::DE265_WARNING_SPS_MISSING_CANNOT_DECODE_SEI => {
193 Self::WarningSpsMissingCannotDecodeSei
194 }
195 de::DE265_WARNING_COLLOCATED_MOTION_VECTOR_OUTSIDE_IMAGE_AREA => {
196 Self::WarningCollocatedMotionVectorOutsideImageArea
197 }
198 de::DE265_WARNING_PCM_BITDEPTH_TOO_LARGE => Self::WarningPcmBitDepthTooLarge,
199 de::DE265_WARNING_REFERENCE_IMAGE_BIT_DEPTH_DOES_NOT_MATCH => {
200 Self::WarningReferenceImageBitDepthDoesNotMatch
201 }
202 de::DE265_WARNING_REFERENCE_IMAGE_SIZE_DOES_NOT_MATCH_SPS => {
203 Self::WarningReferenceImageSizeDoesNotMatchSps
204 }
205 de::DE265_WARNING_CHROMA_OF_CURRENT_IMAGE_DOES_NOT_MATCH_SPS => {
206 Self::WarningChromaOfCurrentImageDoesNotMatchSps
207 }
208 de::DE265_WARNING_BIT_DEPTH_OF_CURRENT_IMAGE_DOES_NOT_MATCH_SPS => {
209 Self::WarningBitDepthOfCurrentImageDoesNotMatchSps
210 }
211 de::DE265_WARNING_REFERENCE_IMAGE_CHROMA_FORMAT_DOES_NOT_MATCH => {
212 Self::WarningReferenceImageChromaFormatDoesNotMatch
213 }
214 de::DE265_WARNING_INVALID_SLICE_HEADER_INDEX_ACCESS => {
215 Self::WarningInvalidSliceHeaderIndexAccess
216 }
217 unknown => Self::Unknown(unknown),
218 };
219 Err(error)
220 }
221}
222
223pub fn get_error_text(err_code: u32) -> Cow<'static, str> {
224 let text_ptr = unsafe { libde265_sys::de265_get_error_text(err_code) };
225 if !text_ptr.is_null() {
226 if let Ok(text) = unsafe { CStr::from_ptr(text_ptr) }.to_str() {
227 return Cow::Borrowed(text);
228 }
229 }
230 Cow::Owned(format!("Unknown result code: {err_code}"))
231}