libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
data.c
Go to the documentation of this file.
1/*
2 * This file is part of the Aaru Data Preservation Suite.
3 * Copyright (c) 2019-2026 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 <inttypes.h>
20#include <stdint.h>
21#include <stdio.h>
22#include <stdlib.h>
23
24#include "aaruformat.h"
25#include "erasure_internal.h"
26#include "internal.h"
27#include "log.h"
28#include "uthash.h"
29
72
74{
75 TRACE("Entering process_data_block(%p, %p)", ctx, entry);
76 BlockHeader block_header;
77 int pos = 0;
78 size_t read_bytes = 0;
79 size_t lzma_size = 0;
80 uint8_t *cmp_data = NULL;
81 uint8_t *cst_data = NULL;
82 mediaTagEntry *old_media_tag = NULL;
83 mediaTagEntry *media_tag = NULL;
84 uint8_t *data = NULL;
85 uint8_t lzma_properties[LZMA_PROPERTIES_LENGTH];
86
87 // Check if the context, index entry, and image stream are valid
88 if(ctx == NULL || entry == NULL || ctx->imageStream == NULL)
89 {
90 FATAL("Invalid context or image stream.");
92 }
93
94 // Seek to block
95 pos = aaruf_fseek(ctx->imageStream, (aaru_off_t)entry->offset, SEEK_SET);
96 if(pos < 0 || aaruf_ftell(ctx->imageStream) != (aaru_off_t)entry->offset)
97 {
98 FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
99
101 }
102
103 // Even if those two checks shall have been done before
104
105 // NOP block, skip
106 if(entry->dataType == kDataTypeNone || (entry->dataType == kDataTypeUserData && ctx->header.biggestSectorSize > 0))
107 {
108 TRACE("NoData block found, skipping");
109 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
110 return AARUF_STATUS_OK;
111 }
112
113 TRACE("Reading block header at position %" PRIu64, entry->offset);
114 read_bytes = fread(&block_header, 1, sizeof(BlockHeader), ctx->imageStream);
115
116 if(read_bytes != sizeof(BlockHeader))
117 {
118 FATAL("Could not read block header at %" PRIu64, entry->offset);
119
120 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
121 return AARUF_STATUS_OK;
122 }
123
124 ctx->image_info.ImageSize += block_header.cmpLength;
125
126 // Unused, skip
127 if(entry->dataType == kDataTypeUserData)
128 {
129 if(block_header.sectorSize > ctx->image_info.SectorSize)
130 {
131 TRACE("Setting sector size to %" PRIu64 " bytes", block_header.sectorSize);
132 ctx->image_info.SectorSize = block_header.sectorSize;
133 }
134
135 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
136 return AARUF_STATUS_OK;
137 }
138
139 if(block_header.identifier != entry->blockType)
140 {
141 TRACE("Incorrect identifier for data block at position %" PRIu64, entry->offset);
142
143 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
144 return AARUF_STATUS_OK;
145 }
146
147 if(block_header.type != entry->dataType)
148 {
149 TRACE("Expected block with data type %4.4s at position %" PRIu64 " but found data type %4.4s",
150 (char *)&entry->blockType, entry->offset, (char *)&block_header.type);
151
152 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
153 return AARUF_STATUS_OK;
154 }
155
156 TRACE("Found data block with type %4.4s at position %" PRIu64, (char *)&entry->blockType, entry->offset);
157
158 if(block_header.compression == kCompressionLzma || block_header.compression == kCompressionLzmaCst)
159 {
160 int error_no = 0;
161 if(block_header.compression == kCompressionLzmaCst && block_header.type != kDataTypeCdSubchannel)
162 {
163 TRACE("Invalid compression type %u for block with data type %u, continuing...", block_header.compression,
164 block_header.type);
165
166 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
167 return AARUF_STATUS_OK;
168 }
169
170 if(block_header.cmpLength < LZMA_PROPERTIES_LENGTH)
171 {
172 TRACE("Compressed block length %" PRIu32 " too small for LZMA properties, continuing...",
173 block_header.cmpLength);
174 TRACE("Exiting process_data_block() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
176 }
177
178 lzma_size = block_header.cmpLength - LZMA_PROPERTIES_LENGTH;
179
180 cmp_data = (lzma_size == 0) ? NULL : (uint8_t *)malloc(lzma_size);
181 if(lzma_size != 0 && cmp_data == NULL)
182 {
183 TRACE("Cannot allocate memory for block, continuing...");
184
185 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
186 return AARUF_STATUS_OK;
187 }
188
189 if(block_header.length != 0)
190 {
191 data = (uint8_t *)malloc(block_header.length);
192 if(data == NULL)
193 {
194 TRACE("Cannot allocate memory for block, continuing...");
195 free(cmp_data);
196
197 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
198 return AARUF_STATUS_OK;
199 }
200 }
201 else
202 data = NULL;
203
204 read_bytes = fread(lzma_properties, 1, LZMA_PROPERTIES_LENGTH, ctx->imageStream);
205 if(read_bytes != LZMA_PROPERTIES_LENGTH)
206 {
207 TRACE("Could not read LZMA properties, continuing...");
208 free(cmp_data);
209 free(data);
210
211 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
212 return AARUF_STATUS_OK;
213 }
214
215 if(lzma_size != 0)
216 {
217 read_bytes = fread(cmp_data, 1, lzma_size, ctx->imageStream);
218 if(read_bytes != lzma_size)
219 {
220 TRACE("Could not read compressed block, continuing...");
221 free(cmp_data);
222 free(data);
223
224 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
225 return AARUF_STATUS_OK;
226 }
227 }
228
229 if(block_header.length != 0)
230 {
231 read_bytes = block_header.length;
232 error_no = aaruf_lzma_decode_buffer(data, &read_bytes, cmp_data, &lzma_size, lzma_properties,
234
235 if(error_no != 0)
236 {
237 TRACE("Got error %d from LZMA, continuing...", error_no);
238 free(cmp_data);
239 free(data);
240
241 TRACE("Exiting process_data_block() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
243 }
244
245 if(read_bytes != block_header.length)
246 {
247 TRACE("Error decompressing block, expected %" PRIu32 " bytes but got %zu bytes, continuing...",
248 block_header.length, read_bytes);
249 free(cmp_data);
250 free(data);
251
252 TRACE("Exiting process_data_block() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
254 }
255 }
256 else if(lzma_size != 0)
257 {
258 TRACE("Compressed payload present for zero-length block, continuing...");
259 free(cmp_data);
260
261 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
262 return AARUF_STATUS_OK;
263 }
264
265 if(block_header.compression == kCompressionLzmaCst && block_header.length != 0)
266 {
267 cst_data = (uint8_t *)malloc(block_header.length);
268 if(cst_data == NULL)
269 {
270 TRACE("Cannot allocate memory for block, continuing...");
271 free(cmp_data);
272 free(data);
273
274 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
275 return AARUF_STATUS_OK;
276 }
277
278 aaruf_cst_untransform(data, cst_data, block_header.length);
279 free(data);
280 data = cst_data;
281 cst_data = NULL;
282 }
283
284 free(cmp_data);
285 }
286 else if(block_header.compression == kCompressionZstd || block_header.compression == kCompressionZstdCst)
287 {
288 if(block_header.compression == kCompressionZstdCst && block_header.type != kDataTypeCdSubchannel)
289 {
290 TRACE("Invalid compression type %u for block with data type %u, continuing...", block_header.compression,
291 block_header.type);
292 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
293 return AARUF_STATUS_OK;
294 }
295
296 cmp_data = (block_header.cmpLength == 0) ? NULL : (uint8_t *)malloc(block_header.cmpLength);
297 if(block_header.cmpLength != 0 && cmp_data == NULL)
298 {
299 TRACE("Cannot allocate memory for compressed block, continuing...");
300 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
301 return AARUF_STATUS_OK;
302 }
303
304 if(block_header.length != 0)
305 {
306 data = (uint8_t *)malloc(block_header.length);
307 if(data == NULL)
308 {
309 TRACE("Cannot allocate memory for block, continuing...");
310 free(cmp_data);
311 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
312 return AARUF_STATUS_OK;
313 }
314 }
315 else
316 data = NULL;
317
318 if(block_header.cmpLength != 0)
319 {
320 read_bytes = fread(cmp_data, 1, block_header.cmpLength, ctx->imageStream);
321 if(read_bytes != block_header.cmpLength)
322 {
323 TRACE("Could not read compressed block, continuing...");
324 free(cmp_data);
325 free(data);
326 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
327 return AARUF_STATUS_OK;
328 }
329 }
330
331 if(block_header.length != 0)
332 {
333 size_t decoded = aaruf_zstd_decode_buffer(data, block_header.length, cmp_data, block_header.cmpLength);
334
335 if(decoded != block_header.length)
336 {
337 TRACE("Error decompressing zstd block, expected %" PRIu32 " bytes but got %zu bytes, continuing...",
338 block_header.length, decoded);
339 free(cmp_data);
340 free(data);
341 TRACE("Exiting process_data_block() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
343 }
344 }
345
346 free(cmp_data);
347
348 if(block_header.compression == kCompressionZstdCst && block_header.length != 0)
349 {
350 cst_data = (uint8_t *)malloc(block_header.length);
351 if(cst_data == NULL)
352 {
353 TRACE("Cannot allocate memory for CST untransform, continuing...");
354 free(data);
355 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
356 return AARUF_STATUS_OK;
357 }
358
359 aaruf_cst_untransform(data, cst_data, block_header.length);
360 free(data);
361 data = cst_data;
362 cst_data = NULL;
363 }
364 }
365 else if(block_header.compression == kCompressionNone)
366 {
367 if(block_header.length != 0)
368 {
369 data = (uint8_t *)malloc(block_header.length);
370 if(data == NULL)
371 {
372 TRACE("Cannot allocate memory for block, continuing...");
373
374 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
375 return AARUF_STATUS_OK;
376 }
377 }
378 else
379 data = NULL;
380
381 read_bytes = (block_header.length == 0) ? 0 : fread(data, 1, block_header.length, ctx->imageStream);
382
383 if(block_header.length != 0 && read_bytes != block_header.length)
384 {
385 free(data);
386 TRACE("Could not read block, continuing...");
387
388 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
389 return AARUF_STATUS_OK;
390 }
391 }
392 else
393 {
394 TRACE("Found unknown compression type %d, continuing...", block_header.compression);
395
396 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
397 return AARUF_STATUS_OK;
398 }
399
400 if(block_header.length > 0)
401 {
402 uint64_t crc64 = aaruf_crc64_data(data, block_header.length);
403
404 // Due to how C# wrote it, it is effectively reversed
405 if(ctx->header.imageMajorVersion <= AARUF_VERSION_V1) crc64 = bswap_64(crc64);
406
407 if(crc64 != block_header.crc64)
408 {
409 TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64, crc64, block_header.crc64);
410 free(data);
411 data = NULL;
412
413 /* Attempt erasure coding recovery */
414 uint8_t *recovered = NULL;
415 uint32_t rec_size = 0;
416 if(ec_recover_meta_block(ctx, entry->offset, &recovered, &rec_size) == AARUF_STATUS_OK && recovered)
417 {
418 TRACE("EC recovery succeeded for block at offset %" PRIu64, entry->offset);
419 /* Re-parse: recovered contains raw on-disk bytes (BlockHeader + payload) */
420 if(rec_size > sizeof(BlockHeader))
421 {
422 BlockHeader rec_hdr;
423 memcpy(&rec_hdr, recovered, sizeof(BlockHeader));
424 uint32_t payload_offset = sizeof(BlockHeader);
425
427 payload_offset += LZMA_PROPERTIES_LENGTH;
428
429 uint8_t *rec_payload = recovered + payload_offset;
430 uint32_t rec_payload_size = rec_size - payload_offset;
431
432 /* Decompress if needed */
433 if(rec_hdr.compression == kCompressionNone)
434 {
435 data = (uint8_t *)malloc(rec_hdr.length);
436 if(data) memcpy(data, rec_payload, rec_hdr.length);
437 }
438 else if(rec_hdr.compression == kCompressionLzma)
439 {
440 data = (uint8_t *)malloc(rec_hdr.length);
441 if(data)
442 {
443 size_t out_sz = rec_hdr.length;
444 size_t src_sz = rec_payload_size;
445 aaruf_lzma_decode_buffer(data, &out_sz, rec_payload, &src_sz,
446 recovered + sizeof(BlockHeader), LZMA_PROPERTIES_LENGTH);
447 }
448 }
449 else if(rec_hdr.compression == kCompressionZstd)
450 {
451 data = (uint8_t *)malloc(rec_hdr.length);
452 if(data)
453 aaruf_zstd_decode_buffer(data, rec_hdr.length, rec_payload, rec_payload_size);
454 }
455
456 /* Update block_header with recovered values */
457 if(data) memcpy(&block_header, &rec_hdr, sizeof(BlockHeader));
458 }
459 free(recovered);
460 }
461
462 if(!data)
463 {
464 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
465 return AARUF_STATUS_OK;
466 }
467 }
468 }
469
470 // Check if it's not a media tag, but a sector tag, and fill the appropriate table then
471 switch(entry->dataType)
472 {
476 else
477 {
478 ctx->sector_prefix = data;
479 ctx->sector_prefix_length = block_header.length;
480 }
481
484
485 break;
489 ctx->sector_suffix_corrected = data;
490 else
491 {
492 ctx->sector_suffix = data;
493 ctx->sector_suffix_length = block_header.length;
494 }
495
501 break;
503 ctx->sector_subchannel = data;
505 break;
507 ctx->sector_subchannel = data;
509 break;
511 ctx->sector_subchannel = data;
513 break;
515 ctx->sector_subchannel = data;
517 break;
519 ctx->mode2_subheaders = data;
520 break;
522 ctx->sector_id = data;
525 break;
527 ctx->sector_ied = data;
529 break;
531 ctx->sector_cpr_mai = data;
533 break;
535 ctx->sector_edc = data;
537 break;
539 ctx->sector_decrypted_title_key = data;
541 break;
543 ctx->sector_edc = data;
545 break;
546 default:
547 media_tag = (mediaTagEntry *)malloc(sizeof(mediaTagEntry));
548
549 if(media_tag == NULL)
550 {
551 TRACE("Cannot allocate memory for media tag entry.");
552 free(data);
553 data = NULL;
554 break;
555 }
556 memset(media_tag, 0, sizeof(mediaTagEntry));
557
558 media_tag->type = aaruf_get_media_tag_type_for_datatype(block_header.type);
559 media_tag->data = data;
560 media_tag->length = block_header.length;
561
562 HASH_REPLACE_INT(ctx->mediaTags, type, media_tag, old_media_tag);
563
564 if(old_media_tag != NULL)
565 {
566 TRACE("Replaced media tag with type %d", old_media_tag->type);
567 free(old_media_tag->data);
568 free(old_media_tag);
569 old_media_tag = NULL;
570 }
571
572 break;
573 }
574
575 TRACE("Exiting process_data_block() = AARUF_STATUS_OK");
576 return AARUF_STATUS_OK;
577}
#define LZMA_PROPERTIES_LENGTH
Size in bytes of the fixed LZMA properties header (lc/lp/pb + dictionary size).
Definition consts.h:86
#define AARUF_VERSION_V1
First on‑disk version (C# implementation).
Definition consts.h:71
uint64_t aaruf_crc64_data(const uint8_t *data, uint32_t len)
Definition crc64.c:160
int32_t aaruf_lzma_decode_buffer(uint8_t *dst_buffer, size_t *dst_size, const uint8_t *src_buffer, size_t *src_size, const uint8_t *props, size_t props_size)
Decodes an LZMA-compressed buffer.
Definition lzma.c:39
int32_t aaruf_get_media_tag_type_for_datatype(int32_t type)
Converts an image data type to an Aaru media tag type.
Definition helpers.c:39
size_t aaruf_zstd_decode_buffer(uint8_t *dst_buffer, size_t dst_size, const uint8_t *src_buffer, size_t src_size)
Decodes a Zstandard-compressed buffer.
Definition zstd.c:34
int32_t aaruf_cst_untransform(const uint8_t *sequential, uint8_t *interleaved, size_t length)
Reverses the CST (Claunia's Subchannel Transform) transformation from sequential to interleaved data.
Definition cst.c:193
#define bswap_64(x)
Definition endian.h:81
@ kDataTypeDvdTitleKeyDecrypted
Decrypted DVD Title Key.
Definition enums.h:129
@ kDataTypeDvdSectorId
DVD Identification Data (ID).
Definition enums.h:130
@ kDataTypeAppleSonyTag
Apple Sony (12‑byte) tag.
Definition enums.h:120
@ kDataTypeCdSectorSuffix
Compact Disc sector suffix (EDC, ECC P, ECC Q).
Definition enums.h:117
@ kDataTypeNone
No data.
Definition enums.h:47
@ kDataTypeCdSubchannel
Compact Disc subchannel data.
Definition enums.h:118
@ kDataTypeCdSectorSuffixCorrected
Compact Disc sector suffix (EDC, ECC P, ECC Q) corrected-only stored.
Definition enums.h:124
@ kDataTypeBdSectorEdc
Blu-ray Sector EDC.
Definition enums.h:150
@ kDataTypeDvdSectorIed
DVD ID Error Detection Code (IED).
Definition enums.h:131
@ kDataTypeDvdSectorCprMai
DVD Copyright Management Information (CPR_MAI).
Definition enums.h:128
@ kDataTypePriamDataTowerTag
Priam Data Tower (24‑byte) tag.
Definition enums.h:121
@ kDataTypeUserData
User (main) data.
Definition enums.h:48
@ kDataTypeDvdSectorEdc
DVD Error Detection Code (EDC).
Definition enums.h:132
@ kDataTypeAppleProfileTag
Apple Profile (20‑byte) tag.
Definition enums.h:119
@ kDataTypeCdSubHeader
Compact Disc MODE 2 subheader.
Definition enums.h:125
@ kDataTypeCdSectorPrefix
Compact Disc sector prefix (sync, header).
Definition enums.h:116
@ kDataTypeCdSectorPrefixCorrected
Compact Disc sector prefix (sync, header) corrected-only stored.
Definition enums.h:123
@ kCompressionLzmaCst
LZMA applied to Claunia Subchannel Transform processed data.
Definition enums.h:36
@ kCompressionLzma
LZMA compression.
Definition enums.h:34
@ kCompressionNone
Not compressed.
Definition enums.h:33
@ kCompressionZstd
Zstandard compression.
Definition enums.h:37
@ kCompressionZstdCst
Zstandard applied to Claunia Subchannel Transform processed data.
Definition enums.h:38
int32_t ec_recover_meta_block(aaruformat_context *ctx, uint64_t block_offset, uint8_t **recovered_data, uint32_t *recovered_size)
Attempt to recover a metadata/media-tag block at a given file offset.
Definition erasure.c:909
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
Definition errors.h:82
#define AARUF_ERROR_CANNOT_READ_BLOCK
Generic block read failure (seek/read error).
Definition errors.h:46
#define AARUF_ERROR_NOT_AARUFORMAT
Input file/stream failed magic or structural validation.
Definition errors.h:40
#define AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK
Decompression routine failed or size mismatch.
Definition errors.h:56
@ kSectorTagBdSectorEdc
Blu-ray sector EDC, 4 bytes.
Definition aaru.h:982
@ kSectorTagCdHeader
4-byte CD header (minute, second, frame, mode)
Definition aaru.h:962
@ kSectorTagCdSync
12-byte CD sync pattern (00 FF*10 00)
Definition aaru.h:961
@ kSectorTagCdSubHeader
Mode 2 Form subheader (8 bytes: copy, submode, channel).
Definition aaru.h:963
@ kSectorTagDvdCmi
DVD Copyright Management Information (CSS).
Definition aaru.h:972
@ kSectorTagDvdSectorIed
DVD sector ID error detection, 2 bytes.
Definition aaru.h:978
@ kSectorTagCdSubchannel
96 raw subchannel bytes (P-W)
Definition aaru.h:968
@ kSectorTagAppleSony
Apple's Sony sector tags, 12 bytes (address prolog + checksum).
Definition aaru.h:960
@ kSectorTagCdEdc
32-bit CRC (EDC)
Definition aaru.h:964
@ kSectorTagAppleProfile
Apple's Profile sector tags, 20 bytes.
Definition aaru.h:980
@ kSectorTagCdEccP
172 bytes Reed-Solomon ECC (P)
Definition aaru.h:965
@ kSectorTagDvdSectorInformation
DVD sector information, 1 bytes.
Definition aaru.h:976
@ kSectorTagDvdSectorEdc
DVD sector EDC, 4 bytes.
Definition aaru.h:979
@ kSectorTagDvdSectorNumber
DVD sector number, 3 bytes.
Definition aaru.h:977
@ kSectorTagPriamDataTower
Priam DataTower sector tags, 24 bytes.
Definition aaru.h:981
@ kSectorTagCdEccQ
104 bytes Reed-Solomon ECC (Q)
Definition aaru.h:966
@ kSectorTagCdEcc
Combined P+Q ECC (276 bytes).
Definition aaru.h:967
@ kSectorTagDvdTitleKeyDecrypted
Decrypted DVD sector title key, 5 bytes.
Definition aaru.h:975
int32_t process_data_block(aaruformat_context *ctx, IndexEntry *entry)
Processes a data block from the image stream.
Definition data.c:73
static int aaruf_fseek(FILE *stream, aaru_off_t offset, int origin)
Definition internal.h:46
static aaru_off_t aaruf_ftell(FILE *stream)
Definition internal.h:52
int64_t aaru_off_t
Definition internal.h:42
#define FATAL(fmt,...)
Definition log.h:40
#define TRACE(fmt,...)
Definition log.h:25
uint16_t biggestSectorSize
size of biggest sector in the image (in bytes).
Definition header.h:120
uint8_t imageMajorVersion
Container format major version.
Definition header.h:110
Header preceding the compressed data payload of a data block (BlockType::DataBlock).
Definition data.h:71
uint32_t cmpLength
Size in bytes of the compressed payload immediately following this header.
Definition data.h:76
uint32_t length
Size in bytes of the uncompressed payload resulting after decompression.
Definition data.h:77
uint32_t identifier
Block identifier, must be BlockType::DataBlock.
Definition data.h:72
uint32_t sectorSize
Size in bytes of each logical sector represented in this block.
Definition data.h:75
uint64_t crc64
CRC64-ECMA of the uncompressed payload (length bytes).
Definition data.h:79
uint16_t type
Logical data classification (value from DataType).
Definition data.h:73
uint16_t compression
Compression algorithm used (value from CompressionType).
Definition data.h:74
uint32_t SectorSize
Size of each logical sector in bytes (512, 2048, 2352, 4096, etc.).
Definition aaru.h:939
uint64_t ImageSize
Size of the image payload in bytes (excludes headers/metadata).
Definition aaru.h:937
Single index entry describing a block's type, (optional) data classification, and file offset.
Definition index.h:109
uint32_t blockType
Block identifier of the referenced block (value from BlockType).
Definition index.h:110
uint64_t offset
Absolute byte offset in the image where the referenced block header begins.
Definition index.h:112
uint16_t dataType
Data classification (value from DataType) or unused for untyped blocks.
Definition index.h:111
Master context representing an open or in‑creation Aaru image.
Definition context.h:178
size_t sector_suffix_length
Length of sector_suffix.
Definition context.h:295
uint8_t * sector_cpr_mai
DVD sector CPR_MAI (6 bytes) if present.
Definition context.h:214
uint8_t * sector_prefix_corrected
Corrected variant (post error correction) if stored.
Definition context.h:207
uint8_t * sector_ied
DVD sector IED (2 bytes) if present.
Definition context.h:213
uint8_t * sector_prefix
Raw per-sector prefix (e.g., sync+header) uncorrected.
Definition context.h:206
uint8_t * sector_edc
DVD or Blu-ray sector EDC (4 bytes) if present (see DvdSectorEdc / BdSectorEdc data types).
Definition context.h:215
uint8_t * sector_suffix
Raw per-sector suffix (EDC/ECC) uncorrected.
Definition context.h:208
AaruHeaderV2 header
Parsed container header (v2).
Definition context.h:181
size_t sector_prefix_length
Length of sector_prefix.
Definition context.h:294
mediaTagEntry * mediaTags
Hash table of extra media tags (uthash root).
Definition context.h:274
uint8_t * sector_decrypted_title_key
DVD decrypted title key (5 bytes) if present.
Definition context.h:216
uint8_t * sector_subchannel
Raw 96-byte subchannel (if captured).
Definition context.h:210
FILE * imageStream
Underlying FILE* stream (binary mode).
Definition context.h:182
uint8_t * mode2_subheaders
MODE2 Form1/Form2 8-byte subheaders (concatenated).
Definition context.h:211
ImageInfo image_info
Exposed high-level image info summary.
Definition context.h:270
uint8_t * sector_id
DVD sector ID (4 bytes) if present.
Definition context.h:212
bool * readableSectorTags
Per-sector boolean array (optical tags read successfully?).
Definition context.h:273
uint8_t * sector_suffix_corrected
Corrected suffix if stored separately.
Definition context.h:209
Hash table entry for an arbitrary media tag (e.g., proprietary drive/medium descriptor).
Definition context.h:125
uint8_t * data
Tag data blob (opaque to library core); length bytes long.
Definition context.h:126
int32_t type
Numeric type identifier.
Definition context.h:127
uint32_t length
Length in bytes of data.
Definition context.h:128