libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
cst.c
Go to the documentation of this file.
1/*
2 * This file is part of the Aaru Data Preservation Suite.
3 * Copyright (c) 2019-2025 Natalia Portillo.
4 *
5 * This library is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2.1 of the
8 * License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <stdint.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include "aaruformat.h"
24
35AARU_EXPORT int32_t AARU_CALL aaruf_cst_transform(const uint8_t *interleaved, uint8_t *sequential, const size_t length)
36{
37 uint8_t *p = NULL;
38 uint8_t *q = NULL;
39 uint8_t *r = NULL;
40 uint8_t *s = NULL;
41 uint8_t *t = NULL;
42 uint8_t *u = NULL;
43 uint8_t *v = NULL;
44 uint8_t *w = NULL;
45 size_t q_start = 0;
46 size_t r_start = 0;
47 size_t s_start = 0;
48 size_t t_start = 0;
49 size_t u_start = 0;
50 size_t v_start = 0;
51 size_t w_start = 0;
52 size_t i = 0;
53
54 if(interleaved == NULL || sequential == NULL) return AARUF_ERROR_BUFFER_TOO_SMALL;
55
56 p = malloc(length / 8);
57 q = malloc(length / 8);
58 r = malloc(length / 8);
59 s = malloc(length / 8);
60 t = malloc(length / 8);
61 u = malloc(length / 8);
62 v = malloc(length / 8);
63 w = malloc(length / 8);
64
65 if(p == NULL || q == NULL || r == NULL || s == NULL || t == NULL || u == NULL || v == NULL || w == NULL)
66 {
67 free(p);
68 free(q);
69 free(r);
70 free(s);
71 free(t);
72 free(u);
73 free(v);
74 free(w);
76 }
77
78 for(i = 0; i < length; i += 8)
79 {
80 p[i / 8] = (uint8_t)(interleaved[i] & 0x80);
81 p[i / 8] += (interleaved[i + 1] & 0x80) >> 1;
82 p[i / 8] += (interleaved[i + 2] & 0x80) >> 2;
83 p[i / 8] += (interleaved[i + 3] & 0x80) >> 3;
84 p[i / 8] += (interleaved[i + 4] & 0x80) >> 4;
85 p[i / 8] += (interleaved[i + 5] & 0x80) >> 5;
86 p[i / 8] += (interleaved[i + 6] & 0x80) >> 6;
87 p[i / 8] += (interleaved[i + 7] & 0x80) >> 7;
88
89 q[i / 8] = (uint8_t)((interleaved[i] & 0x40) << 1);
90 q[i / 8] += interleaved[i + 1] & 0x40;
91 q[i / 8] += (interleaved[i + 2] & 0x40) >> 1;
92 q[i / 8] += (interleaved[i + 3] & 0x40) >> 2;
93 q[i / 8] += (interleaved[i + 4] & 0x40) >> 3;
94 q[i / 8] += (interleaved[i + 5] & 0x40) >> 4;
95 q[i / 8] += (interleaved[i + 6] & 0x40) >> 5;
96 q[i / 8] += (interleaved[i + 7] & 0x40) >> 6;
97
98 r[i / 8] = (uint8_t)((interleaved[i] & 0x20) << 2);
99 r[i / 8] += (interleaved[i + 1] & 0x20) << 1;
100 r[i / 8] += interleaved[i + 2] & 0x20;
101 r[i / 8] += (interleaved[i + 3] & 0x20) >> 1;
102 r[i / 8] += (interleaved[i + 4] & 0x20) >> 2;
103 r[i / 8] += (interleaved[i + 5] & 0x20) >> 3;
104 r[i / 8] += (interleaved[i + 6] & 0x20) >> 4;
105 r[i / 8] += (interleaved[i + 7] & 0x20) >> 5;
106
107 s[i / 8] = (uint8_t)((interleaved[i] & 0x10) << 3);
108 s[i / 8] += (interleaved[i + 1] & 0x10) << 2;
109 s[i / 8] += (interleaved[i + 2] & 0x10) << 1;
110 s[i / 8] += interleaved[i + 3] & 0x10;
111 s[i / 8] += (interleaved[i + 4] & 0x10) >> 1;
112 s[i / 8] += (interleaved[i + 5] & 0x10) >> 2;
113 s[i / 8] += (interleaved[i + 6] & 0x10) >> 3;
114 s[i / 8] += (interleaved[i + 7] & 0x10) >> 4;
115
116 t[i / 8] = (uint8_t)((interleaved[i] & 0x08) << 4);
117 t[i / 8] += (interleaved[i + 1] & 0x08) << 3;
118 t[i / 8] += (interleaved[i + 2] & 0x08) << 2;
119 t[i / 8] += (interleaved[i + 3] & 0x08) << 1;
120 t[i / 8] += interleaved[i + 4] & 0x08;
121 t[i / 8] += (interleaved[i + 5] & 0x08) >> 1;
122 t[i / 8] += (interleaved[i + 6] & 0x08) >> 2;
123 t[i / 8] += (interleaved[i + 7] & 0x08) >> 3;
124
125 u[i / 8] = (uint8_t)((interleaved[i] & 0x04) << 5);
126 u[i / 8] += (interleaved[i + 1] & 0x04) << 4;
127 u[i / 8] += (interleaved[i + 2] & 0x04) << 3;
128 u[i / 8] += (interleaved[i + 3] & 0x04) << 2;
129 u[i / 8] += (interleaved[i + 4] & 0x04) << 1;
130 u[i / 8] += interleaved[i + 5] & 0x04;
131 u[i / 8] += (interleaved[i + 6] & 0x04) >> 1;
132 u[i / 8] += (interleaved[i + 7] & 0x04) >> 2;
133
134 v[i / 8] = (uint8_t)((interleaved[i] & 0x02) << 6);
135 v[i / 8] += (interleaved[i + 1] & 0x02) << 5;
136 v[i / 8] += (interleaved[i + 2] & 0x02) << 4;
137 v[i / 8] += (interleaved[i + 3] & 0x02) << 3;
138 v[i / 8] += (interleaved[i + 4] & 0x02) << 2;
139 v[i / 8] += (interleaved[i + 5] & 0x02) << 1;
140 v[i / 8] += interleaved[i + 6] & 0x02;
141 v[i / 8] += (interleaved[i + 7] & 0x02) >> 1;
142
143 w[i / 8] = (uint8_t)((interleaved[i] & 0x01) << 7);
144 w[i / 8] += (interleaved[i + 1] & 0x01) << 6;
145 w[i / 8] += (interleaved[i + 2] & 0x01) << 5;
146 w[i / 8] += (interleaved[i + 3] & 0x01) << 4;
147 w[i / 8] += (interleaved[i + 4] & 0x01) << 3;
148 w[i / 8] += (interleaved[i + 5] & 0x01) << 2;
149 w[i / 8] += (interleaved[i + 6] & 0x01) << 1;
150 w[i / 8] += interleaved[i + 7] & 0x01;
151 }
152
153 q_start = length / 8 * 1;
154 r_start = length / 8 * 2;
155 s_start = length / 8 * 3;
156 t_start = length / 8 * 4;
157 u_start = length / 8 * 5;
158 v_start = length / 8 * 6;
159 w_start = length / 8 * 7;
160
161 for(i = 0; i < length / 8; i++)
162 {
163 sequential[i] = p[i];
164 sequential[q_start + i] = q[i];
165 sequential[r_start + i] = r[i];
166 sequential[s_start + i] = s[i];
167 sequential[t_start + i] = t[i];
168 sequential[u_start + i] = u[i];
169 sequential[v_start + i] = v[i];
170 sequential[w_start + i] = w[i];
171 }
172
173 free(p);
174 free(q);
175 free(r);
176 free(s);
177 free(t);
178 free(u);
179 free(v);
180 free(w);
181
182 return AARUF_STATUS_OK;
183}
184
193AARU_EXPORT int32_t AARU_CALL aaruf_cst_untransform(const uint8_t *sequential, uint8_t *interleaved,
194 const size_t length)
195{
196 size_t i;
197
198 if(interleaved == NULL || sequential == NULL) return AARUF_ERROR_BUFFER_TOO_SMALL;
199
200 uint8_t *p = malloc(length / 8);
201 uint8_t *q = malloc(length / 8);
202 uint8_t *r = malloc(length / 8);
203 uint8_t *s = malloc(length / 8);
204 uint8_t *t = malloc(length / 8);
205 uint8_t *u = malloc(length / 8);
206 uint8_t *v = malloc(length / 8);
207 uint8_t *w = malloc(length / 8);
208
209 if(p == NULL || q == NULL || r == NULL || s == NULL || t == NULL || u == NULL || v == NULL || w == NULL)
210 {
211 free(p);
212 free(q);
213 free(r);
214 free(s);
215 free(t);
216 free(u);
217 free(v);
218 free(w);
220 }
221
222 size_t q_start = length / 8 * 1;
223 size_t r_start = length / 8 * 2;
224 size_t s_start = length / 8 * 3;
225 size_t t_start = length / 8 * 4;
226 size_t u_start = length / 8 * 5;
227 size_t v_start = length / 8 * 6;
228 size_t w_start = length / 8 * 7;
229
230 for(i = 0; i < length / 8; i++)
231 {
232 p[i] = sequential[i];
233 q[i] = sequential[q_start + i];
234 r[i] = sequential[r_start + i];
235 s[i] = sequential[s_start + i];
236 t[i] = sequential[t_start + i];
237 u[i] = sequential[u_start + i];
238 v[i] = sequential[v_start + i];
239 w[i] = sequential[w_start + i];
240 }
241
242 memset(interleaved, 0, length);
243
244 for(i = 0; i < length; i += 8)
245 {
246 interleaved[i] += (p[i / 8] & 0x80) == 0x80 ? 0x80 : 0;
247 interleaved[i + 1] += (p[i / 8] & 0x40) == 0x40 ? 0x80 : 0;
248 interleaved[i + 2] += (p[i / 8] & 0x20) == 0x20 ? 0x80 : 0;
249 interleaved[i + 3] += (p[i / 8] & 0x10) == 0x10 ? 0x80 : 0;
250 interleaved[i + 4] += (p[i / 8] & 0x08) == 0x08 ? 0x80 : 0;
251 interleaved[i + 5] += (p[i / 8] & 0x04) == 0x04 ? 0x80 : 0;
252 interleaved[i + 6] += (p[i / 8] & 0x02) == 0x02 ? 0x80 : 0;
253 interleaved[i + 7] += (p[i / 8] & 0x01) == 0x01 ? 0x80 : 0;
254
255 interleaved[i] += (q[i / 8] & 0x80) == 0x80 ? 0x40 : 0;
256 interleaved[i + 1] += (q[i / 8] & 0x40) == 0x40 ? 0x40 : 0;
257 interleaved[i + 2] += (q[i / 8] & 0x20) == 0x20 ? 0x40 : 0;
258 interleaved[i + 3] += (q[i / 8] & 0x10) == 0x10 ? 0x40 : 0;
259 interleaved[i + 4] += (q[i / 8] & 0x08) == 0x08 ? 0x40 : 0;
260 interleaved[i + 5] += (q[i / 8] & 0x04) == 0x04 ? 0x40 : 0;
261 interleaved[i + 6] += (q[i / 8] & 0x02) == 0x02 ? 0x40 : 0;
262 interleaved[i + 7] += (q[i / 8] & 0x01) == 0x01 ? 0x40 : 0;
263
264 interleaved[i] += (r[i / 8] & 0x80) == 0x80 ? 0x20 : 0;
265 interleaved[i + 1] += (r[i / 8] & 0x40) == 0x40 ? 0x20 : 0;
266 interleaved[i + 2] += (r[i / 8] & 0x20) == 0x20 ? 0x20 : 0;
267 interleaved[i + 3] += (r[i / 8] & 0x10) == 0x10 ? 0x20 : 0;
268 interleaved[i + 4] += (r[i / 8] & 0x08) == 0x08 ? 0x20 : 0;
269 interleaved[i + 5] += (r[i / 8] & 0x04) == 0x04 ? 0x20 : 0;
270 interleaved[i + 6] += (r[i / 8] & 0x02) == 0x02 ? 0x20 : 0;
271 interleaved[i + 7] += (r[i / 8] & 0x01) == 0x01 ? 0x20 : 0;
272
273 interleaved[i] += (s[i / 8] & 0x80) == 0x80 ? 0x10 : 0;
274 interleaved[i + 1] += (s[i / 8] & 0x40) == 0x40 ? 0x10 : 0;
275 interleaved[i + 2] += (s[i / 8] & 0x20) == 0x20 ? 0x10 : 0;
276 interleaved[i + 3] += (s[i / 8] & 0x10) == 0x10 ? 0x10 : 0;
277 interleaved[i + 4] += (s[i / 8] & 0x08) == 0x08 ? 0x10 : 0;
278 interleaved[i + 5] += (s[i / 8] & 0x04) == 0x04 ? 0x10 : 0;
279 interleaved[i + 6] += (s[i / 8] & 0x02) == 0x02 ? 0x10 : 0;
280 interleaved[i + 7] += (s[i / 8] & 0x01) == 0x01 ? 0x10 : 0;
281
282 interleaved[i] += (t[i / 8] & 0x80) == 0x80 ? 0x08 : 0;
283 interleaved[i + 1] += (t[i / 8] & 0x40) == 0x40 ? 0x08 : 0;
284 interleaved[i + 2] += (t[i / 8] & 0x20) == 0x20 ? 0x08 : 0;
285 interleaved[i + 3] += (t[i / 8] & 0x10) == 0x10 ? 0x08 : 0;
286 interleaved[i + 4] += (t[i / 8] & 0x08) == 0x08 ? 0x08 : 0;
287 interleaved[i + 5] += (t[i / 8] & 0x04) == 0x04 ? 0x08 : 0;
288 interleaved[i + 6] += (t[i / 8] & 0x02) == 0x02 ? 0x08 : 0;
289 interleaved[i + 7] += (t[i / 8] & 0x01) == 0x01 ? 0x08 : 0;
290
291 interleaved[i] += (u[i / 8] & 0x80) == 0x80 ? 0x04 : 0;
292 interleaved[i + 1] += (u[i / 8] & 0x40) == 0x40 ? 0x04 : 0;
293 interleaved[i + 2] += (u[i / 8] & 0x20) == 0x20 ? 0x04 : 0;
294 interleaved[i + 3] += (u[i / 8] & 0x10) == 0x10 ? 0x04 : 0;
295 interleaved[i + 4] += (u[i / 8] & 0x08) == 0x08 ? 0x04 : 0;
296 interleaved[i + 5] += (u[i / 8] & 0x04) == 0x04 ? 0x04 : 0;
297 interleaved[i + 6] += (u[i / 8] & 0x02) == 0x02 ? 0x04 : 0;
298 interleaved[i + 7] += (u[i / 8] & 0x01) == 0x01 ? 0x04 : 0;
299
300 interleaved[i] += (v[i / 8] & 0x80) == 0x80 ? 0x02 : 0;
301 interleaved[i + 1] += (v[i / 8] & 0x40) == 0x40 ? 0x02 : 0;
302 interleaved[i + 2] += (v[i / 8] & 0x20) == 0x20 ? 0x02 : 0;
303 interleaved[i + 3] += (v[i / 8] & 0x10) == 0x10 ? 0x02 : 0;
304 interleaved[i + 4] += (v[i / 8] & 0x08) == 0x08 ? 0x02 : 0;
305 interleaved[i + 5] += (v[i / 8] & 0x04) == 0x04 ? 0x02 : 0;
306 interleaved[i + 6] += (v[i / 8] & 0x02) == 0x02 ? 0x02 : 0;
307 interleaved[i + 7] += (v[i / 8] & 0x01) == 0x01 ? 0x02 : 0;
308
309 interleaved[i] += (w[i / 8] & 0x80) == 0x80 ? 0x01 : 0;
310 interleaved[i + 1] += (w[i / 8] & 0x40) == 0x40 ? 0x01 : 0;
311 interleaved[i + 2] += (w[i / 8] & 0x20) == 0x20 ? 0x01 : 0;
312 interleaved[i + 3] += (w[i / 8] & 0x10) == 0x10 ? 0x01 : 0;
313 interleaved[i + 4] += (w[i / 8] & 0x08) == 0x08 ? 0x01 : 0;
314 interleaved[i + 5] += (w[i / 8] & 0x04) == 0x04 ? 0x01 : 0;
315 interleaved[i + 6] += (w[i / 8] & 0x02) == 0x02 ? 0x01 : 0;
316 interleaved[i + 7] += (w[i / 8] & 0x01) == 0x01 ? 0x01 : 0;
317 }
318
319 free(p);
320 free(q);
321 free(r);
322 free(s);
323 free(t);
324 free(u);
325 free(v);
326 free(w);
327
328 return AARUF_STATUS_OK;
329}
int32_t aaruf_cst_untransform(const uint8_t *sequential, uint8_t *interleaved, const size_t length)
Reverses the CST (Claunia's Subchannel Transform) transformation from sequential to interleaved data.
Definition cst.c:193
int32_t aaruf_cst_transform(const uint8_t *interleaved, uint8_t *sequential, const size_t length)
Transforms interleaved subchannel data to sequential format.
Definition cst.c:35
#define AARU_CALL
Definition decls.h:45
#define AARU_EXPORT
Definition decls.h:54
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
Definition errors.h:75
#define AARUF_ERROR_NOT_ENOUGH_MEMORY
Memory allocation failure (critical).
Definition errors.h:48
#define AARUF_ERROR_BUFFER_TOO_SMALL
Caller-supplied buffer insufficient for data.
Definition errors.h:49