=== Deduplication Table (`DDT*`) *_DEPRECATED_*

The deduplication table is a sequential array of pointers, with each entry corresponding to a sector on the storage media.
These pointers map sector data to logical content blocks, enabling efficient elimination of duplicate data.
Every image must include at least one deduplication table of type `UserData`.

*Deprecation Notice*: This block is deprecated and *MUST NOT* be used in new image files.

==== Structure Definition

[source,c]
#define DDT_MAGIC 0X2A544444
/**Header for a deduplication table. Table follows it */
typedef struct DdtHeader
{
    uint32_t identifier;   ///< Block identifier, must be BlockType::DeDuplicationTable.
    uint16_t type;         ///< Data classification (\ref DataType) for sectors referenced by this table.
    uint16_t compression;  ///< Compression algorithm for the table body (\ref CompressionType).
    uint8_t  shift;        ///< Left shift applied to per-entry file offset component forming logicalEntryValue.
    uint64_t entries;      ///< Number of deduplication entries contained in (uncompressed) table.
    uint64_t cmpLength;    ///< Size in bytes of compressed entries payload.
    uint64_t length;       ///< Size in bytes of uncompressed entries payload.
    uint64_t cmpCrc64;     ///< CRC64-ECMA of the compressed payload.
    uint64_t crc64;        ///< CRC64-ECMA of the uncompressed payload.
} DdtHeader;

==== Field Descriptions

[cols="2,2,2,6",options="header"]
|===
|Type
|Size
|Name
|Description

|uint32_t
|4 bytes
|identifier
|The deduplication table identifier, always `DDT*`

|uint16_t
|2 bytes
|type
|The data type pointed by this table. See Annex B.

|uint16_t
|2 bytes
|compression
|The compression algorithm used in the table. See Annex C.

|uint8_t
|1 byte
|shift
|The shift used to calculate the position of a sector in a data block pointed by this table.

|uint64_t
|8 bytes
|entries
|How many pointers follow this header.

|uint32_t
|4 bytes
|cmpLength
|The size in bytes of the compressed table that follows this header.

|uint32_t
|4 bytes
|length
|The size in bytes of the table block when decompressed.

|uint64_t
|8 bytes
|cmpCrc64
|The CRC64-ECMA checksum of the compressed table that follows this header.

|uint64_t
|8 bytes
|crc64
|The CRC64-ECMA checksum of the decompressed table.
|===

==== Deduplication Table Entries

Each entry in the deduplication table references a specific data block and a particular item within that block.

===== Mapping Logic

- Entry 0 corresponds to data associated with LBA 0 of the media; subsequent entries map sequentially.
- The pointer value for an entry is computed using the formula:
+
[source]
pointer = (byte_offset_of_block << shift) + item_index_in_block
+
For example, a raw pointer value of `0x8003` in a table with a `shift` of 5 resolves as follows:
- Byte offset: `0x400` → `1024`
- Item index: `0x3` → `3`
- Therefore, the pointer targets item 3 within the data block located at byte offset `1024` in the file.

==== Special Case – Corrected Sector Tables

Deduplication tables of type `CdSectorPrefixCorrected` and `CdSectorSuffixCorrected` split the entry value using bitmasking:

- Pointer component: `entry & 0x00FFFFFF`
- Flags component: `entry & 0xFF000000`

===== Flags

[cols="2,1,6",options="header"]
|===
|Flag
|Value
|Description

|None
|`0x00000000`
|The suffix or prefix cannot be regenerated as is stored in the pointed data block.

|NotDumped
|`0x10000000`
|The sector has not been dumped. Ignore the pointer.

|Correct
|`0x20000000`
|The suffix (only for MODE 1 sectors) or prefix is correct and can be regenerated. Ignore the pointer.

|Mode2Form1Ok
|`0x30000000`
|The suffix for MODE 2 sectors is correct, can be regenerated, and corresponds to a MODE 2 Form 1 sector.

|Mode2Form2Ok
|`0x40000000`
|The suffix for MODE 2 sectors is correct, can be regenerated, and corresponds to a MODE 2 Form 2 sector with a valid CRC.

|Mode2Form2NoCrc
|`0x50000000`
|The suffix for MODE 2 sectors is correct, can be regenerated, and corresponds to a MODE 2 Form 2 sector with an empty CRC.
|===