## Utilities Utilities — Various helper and utility functions. |

## Functions

#define | MIRAGE_CAST_DATA()
#define | MIRAGE_CAST_PTR()
guint8 | mirage_helper_ascii2isrc ()
gint | mirage_helper_bcd2hex ()
guint16 | mirage_helper_calculate_crc16 ()
guint32 | mirage_helper_calculate_crc32_fast ()
guint32 | mirage_helper_calculate_crc32_standard ()
MirageSectorType | mirage_helper_determine_sector_type ()
const gchar * | mirage_helper_encoding_from_bom ()
gchar * | mirage_helper_find_data_file ()
const gchar * | mirage_helper_get_suffix ()
gboolean | mirage_helper_has_suffix ()
gint | mirage_helper_hex2bcd ()
guint16 * | mirage_helper_init_crc16_lut ()
guint32 * | mirage_helper_init_crc32_lut ()
guint8 * | mirage_helper_init_ecma_130b_scrambler_lut ()
gchar | mirage_helper_isrc2ascii ()
void | mirage_helper_lba2msf ()
gchar * | mirage_helper_lba2msf_str ()
gint | mirage_helper_msf2lba ()
gint | mirage_helper_msf2lba_str ()
void | mirage_helper_sector_edc_ecc_compute_ecc_block ()
void | mirage_helper_sector_edc_ecc_compute_edc_block ()
gint | mirage_helper_strcasecmp ()
gint | mirage_helper_strncasecmp ()
gchar * | mirage_helper_format_string ()
gchar * | mirage_helper_format_stringd ()
gchar * | mirage_helper_format_stringv ()
void | mirage_helper_subchannel_deinterleave ()
void | mirage_helper_subchannel_interleave ()
guint16 | mirage_helper_subchannel_q_calculate_crc ()
void | mirage_helper_subchannel_q_decode_isrc ()
void | mirage_helper_subchannel_q_decode_mcn ()
void | mirage_helper_subchannel_q_encode_isrc ()
void | mirage_helper_subchannel_q_encode_mcn ()
gboolean | mirage_helper_validate_isrc ()

## Types and Values

enum | MirageSubChannel

## Includes

    #include <mirage-utils.h>

## Description

These functions cover various functionality. They are exported because, while primarily designed to be used within libMirage, they could also prove useful to other applications.

## Functions

### MIRAGE_CAST_DATA()

    #define MIRAGE_CAST_DATA(buf,off,type) (*((type *)(buf+off)))

A macro for easy retrieval of data from (unsigned integer) buffer. Mostly to be used in binary image parsers, for example, to retrieve guint32 or guint16 value from buffer.

#### Parameters

buf | buffer to get data from |
off | offset in buffer at which to get data |
type | data type (i.e. 'guint64') |

### MIRAGE_CAST_PTR()

    #define MIRAGE_CAST_PTR(buf,off,type) ((type)(buf+off))

A macro for easy placing of pointers within (unsigned integer) buffer. Mostly to be used in binary image parsers, for example, to retrieve a string or a structure from buffer.

#### Parameters

buf | buffer to place pointer in |
off | offset in buffer at which to place pointer |
type | pointer type (i.e. 'gchar *') |

### mirage_helper_ascii2isrc ()

    guint8
    mirage_helper_ascii2isrc (gchar c);

Converts ASCII character `c` into ISRC character.

#### Parameters

c | ASCII character. | [in]

#### Returns

ISRC character

### mirage_helper_bcd2hex ()

    gint
    mirage_helper_bcd2hex (gint bcd);

Converts bcd-encoded integer into hex-encoded integer.

#### Parameters

bcd | bcd-encoded integer. | [in]

#### Returns

hex-encoded integer

### mirage_helper_calculate_crc16 ()

    guint16
    mirage_helper_calculate_crc16 (const guint8 *data,
                                   guint length,
                                   const guint16 *crctab,
                                   gboolean reflected,
                                   gboolean invert);

Calculates the CRC-16 checksum of the data stored in `data` .

#### Parameters

data | buffer containing data. | [in][array length=length]
length | length of data. | [in]
crctab | pointer to CRC polynomial table. | [in][array fixed-size=256]
reflected | whether to use the reflected algorithm. | [in]
invert | whether the result should be inverted. | [in]

#### Returns

CRC-16 checksum of data

### mirage_helper_calculate_crc32_fast ()

    guint32
    mirage_helper_calculate_crc32_fast (const guint8 *data,
                                        guint length,
                                        const guint32 *crctab,
                                        gboolean reflected,
                                        gboolean invert);

Calculates the CRC-32 checksum of the data stored in `data` . This is fast slice-by-8 implementation that processes 8 bytes at a time, and requires `crctab` to be allocating using `mirage_helper_init_crc32_lut()` with slice parameter set to 8.

#### Parameters

data | buffer containing data. | [in][array length=length]
length | length of data. | [in]
crctab | pointer to CRC polynomial table. | [in][array fixed-size=2048]
reflected | whether to use the reflected algorithm. | [in]
invert | whether the initial value and result should be inverted. | [in]

#### Returns

CRC-32 checksum of data

### mirage_helper_calculate_crc32_standard ()

    guint32
    mirage_helper_calculate_crc32_standard
                                   (const guint8 *data,
                                    guint length,
                                    const guint32 *crctab,
                                    gboolean reflected,
                                    gboolean invert);

Calculates the CRC-32 checksum of the data stored in `data` . This is standard inplementation that processes 1 byte at a time, and requires `crctab` to be allocated using `mirage_helper_init_crc32_lut()` with slice parameter set to 1.

#### Parameters

data | buffer containing data. | [in][array length=length]
length | length of data. | [in]
crctab | pointer to CRC polynomial table. | [in][array fixed-size=256]
reflected | whether to use the reflected algorithm. | [in]
invert | whether the initial value and result should be inverted. | [in]

#### Returns

CRC-32 checksum of data

### mirage_helper_determine_sector_type ()

    MirageSectorType
    mirage_helper_determine_sector_type (const guint8 *buf);

Determines sector type from its data, based on first 16 bytes, which correspond to sync pattern and header.

This function is intened to be used in image parsers, for determining track mode in cases when full (2352-byte) sector data is available.

#### Parameters

buf | buffer containing at least first 16 bytes of sector's data. | [in]

#### Returns

sector type (one of `MirageSectorType`)

### mirage_helper_encoding_from_bom ()

    const gchar *
    mirage_helper_encoding_from_bom (const guint8 *buffer);

Tries to decode BOM provided in `buffer` , and based on the result returns the following encodings: UTF-32BE, UTF32-LE, UTF-16LE, UTF-16BE or UTF-8 (if BOM is not valid).

#### Parameters

buffer | a 4-byte buffer containing BOM. | [in][transfer none][array fixed-size=4]

#### Returns

the name of encoding, or `NULL` if UTF-8 is assumed. The string is statically stored and should not be modified.

[transfer none]

### mirage_helper_find_data_file ()

    gchar *
    mirage_helper_find_data_file (const gchar *filename,
                                  const gchar *path);

Attempts to find a file with filename `filename` and path `path` . `filename` can be file's basename or an absolute path. `path` can be either directory path (in this case, it must end with '/') or a filename (i.e. of file descriptor).

If `filename` is an absolute path, its existence is first checked. If it does not exist, search (see below) is performed in `filename` 's dirname. If still no match is found and `path` is not `NULL`, `path` 's dirname is combined with `filename` 's basename, and the combination's existence is checked. If that fails as well, search (see below) is performed in `path` 's dirname. Searching in the directory is performed as follows. Directory is opened and its content is case-insensitively compared to `filename` 's basename. All filenames whose beginning match `filename` are considered, and the shortest one is returned. This way, all possible case variations (i.e. file.iso, FILE.ISO, FiLe.IsO, etc.) are taken into account. This function can return a filename with additional suffices, but only if a file without those extra suffices does not exist. E.g., if search is done for 'data.img', and only 'data.img.gz' exists, it will be returned. However, if both 'data.img' and 'data.img.gz' exist, the former will be returned. The returned string should be freed when no longer needed.

#### Parameters

filename | declared filename. | [in]
path | path where to look for file (can be a filename), or `NULL`. | [in][allow-none]

#### Returns

a newly allocated string containing the fullpath of file, or `NULL`.

### mirage_helper_get_suffix ()

    const gchar *
    mirage_helper_get_suffix (const gchar *filename);

Retrieves suffix from `filename` .

#### Parameters

filename | filename. | [in]

#### Returns

pointer to character in `filename` at which the suffix starts.

[transfer none]

### mirage_helper_has_suffix ()

    gboolean
    mirage_helper_has_suffix (const gchar *filename,
                              const gchar *suffix);

Checks whether file name `filename` ends with suffix `suffix` .

#### Parameters

filename | filename. | [in]
suffix | suffix. | [in]

#### Returns

`TRUE` if `filename` contains suffix `suffix` , `FALSE` if not

### mirage_helper_hex2bcd ()

    gint
    mirage_helper_hex2bcd (gint hex);

Converts hex-encoded integer into bcd-encoded integer.

#### Parameters

hex | hex-encoded integer. | [in]

#### Returns

bcd-encoded integer

### mirage_helper_init_crc16_lut ()

    guint16 *
    mirage_helper_init_crc16_lut (guint16 genpoly);

Calculates a look-up table for CRC16 based on the generator polynomial.

#### Parameters

genpoly | generator polynomial. | [in]

#### Returns

Pointer to the CRC16 look-up table or NULL on failure.

### mirage_helper_init_crc32_lut ()

    guint32 *
    mirage_helper_init_crc32_lut (guint32 genpoly,
                                  guint slices);

Calculates a look-up table for CRC32 based on the generator polynomial. The size of the lookup table depends on `slices` . The standard algorithm processes 1 byte at a time and has a look-up table size of 1KiB, whereas The slice-by-4 and slice-by-8 algorithms use 4 and 8 KiB look-up tables that are derived from the initial look-up table.

#### Parameters

genpoly | generator polynomial. | [in]
slices | number of bytes to process at once. | [in]

#### Returns

Pointer to the CRC32 look-up table or NULL on failure.

### mirage_helper_init_ecma_130b_scrambler_lut ()

    guint8 *
    mirage_helper_init_ecma_130b_scrambler_lut
                                   (void);

Calculates a look-up table for sector data scrambler from ECMA-130, Annex B. The look-up table consists of 2340 entries, each being a scramble byte for corresponding byte in sector data.

#### Returns

Pointer to the generated scrambler look-up table or NULL on failure.

### mirage_helper_isrc2ascii ()

    gchar
    mirage_helper_isrc2ascii (guint8 c);

Converts ISRC character `c` into ASCII character.

#### Parameters

c | ISRC character. | [in]

#### Returns

ACSII character

### mirage_helper_lba2msf ()

    void
    mirage_helper_lba2msf (gint lba,
                           gboolean diff,
                           guint8 *m,
                           guint8 *s,
                           guint8 *f);

Converts LBA sector address stored in `lba` into MSF address, storing each field into `m` , `s` and `f` , respectively.

If `diff` is `TRUE`, 150 frames difference is accounted for; this should be used when converting absolute addresses. When converting relative addresses (or lengths), `diff` should be set to `FALSE`.

#### Parameters

lba | LBA address. | [in]
diff | account for the difference. | [in]
m | location to store minutes, or `NULL`. | [out][allow-none]
s | location to store seconds, or `NULL`. | [out][allow-none]
f | location to store frames, or `NULL`. | [out][allow-none]

### mirage_helper_lba2msf_str ()

    gchar *
    mirage_helper_lba2msf_str (gint lba,
                               gboolean diff);

Converts LBA sector address stored in `lba` into MSF address.

If `diff` is `TRUE`, 150 frames difference is accounted for; this should be used when converting absolute addresses. When converting relative addresses (or lengths), `diff` should be set to `FALSE`.

#### Parameters

lba | LBA address. | [in]
diff | account for the difference. | [in]

#### Returns

a newly-allocated string containing MSF address; it should be freed with `g_free()` when no longer needed.

### mirage_helper_msf2lba ()

    gint
    mirage_helper_msf2lba (guint8 m,
                           guint8 s,
                           guint8 f,
                           gboolean diff);

Converts MSF sector address stored in `m` , `s` and `f` into LBA address.

If `diff` is `TRUE`, 150 frames difference is accounted for; this should be used when converting absolute addresses. When converting relative addresses (or lengths), `diff` should be set to `FALSE`.

#### Parameters

m | minutes. | [in]
s | seconds. | [in]
f | frames. | [in]
diff | difference. | [in]

#### Returns

integer representing LBA address

### mirage_helper_msf2lba_str ()

    gint
    mirage_helper_msf2lba_str (const gchar *msf,
                               gboolean diff);

Converts MSF sector address stored in `msf` string into LBA address.

If `diff` is `TRUE`, 150 frames difference is accounted for; this should be used when converting absolute addresses. When converting relative addresses (or lengths), `diff` should be set to `FALSE`.

#### Parameters

msf | MSF string. | [in]
diff | difference. | [in]

#### Returns

integer representing LBA address or -1 on failure.

### mirage_helper_sector_edc_ecc_compute_ecc_block ()

    void
    mirage_helper_sector_edc_ecc_compute_ecc_block
                                   (const guint8 *src,
                                    guint32 major_count,
                                    guint32 minor_count,
                                    guint32 major_mult,
                                    guint32 minor_inc,
                                    guint8 *dest);

Calculates ECC (error correction code) for data in `src` and writes the result into `dest` . The code assumes 2352 byte sectors. It can calculate both P and Q layer of ECC data, depending on `major_count` , `minor_count` , `major_mult` and minor_inc.

To calculate ECC (first P, then Q layer) for different types of sectors and store it into sector data, use:

- Mode 1 sector:

      mirage_helper_sector_edc_ecc_compute_ecc_block(sector_buffer+0xC, 86, 24, 2, 86, sector_buffer+0x81C);
      mirage_helper_sector_edc_ecc_compute_ecc_block(sector_buffer+0xC, 52, 43, 86, 88, sector_buffer+0x8C8);

- Mode 2 Form 1 sector:

      mirage_helper_sector_edc_ecc_compute_ecc_block(sector_buffer+0xC, 86, 24, 2, 86, sector_buffer+0x81C); \n
      mirage_helper_sector_edc_ecc_compute_ecc_block(sector_buffer+0xC, 52, 43, 86, 88, sector_buffer+0x8C8);

(This is assuming all other sector data, including EDC, is already stored in sector_buffer and that sector_buffer is 2532 bytes long)

#### Parameters

src | data to calculate ECC data for. | [in]
major_count | major count. | [in]
minor_count | minor count. | [in]
major_mult | major multiplicator. | [in]
minor_inc | minor increment. | [in]
dest | buffer to write calculated ECC data into. | [out caller-allocates]

### mirage_helper_sector_edc_ecc_compute_edc_block ()

    void
    mirage_helper_sector_edc_ecc_compute_edc_block
                                   (const guint8 *src,
                                    guint16 size,
                                    guint8 *dest);

Calculates EDC (error detection code) for data in `src` of length `size` and writes the result into `dest` .

To calculate EDC for different types of sectors and store it into sector data, use:

- Mode 1 sector:

      mirage_helper_sector_edc_ecc_compute_edc_block(sector_buffer+0x00, 0x810, sector_buffer+0x810);

- Mode 2 Form 1 sector:

      mirage_helper_sector_edc_ecc_compute_edc_block(sector_buffer+0x10, 0x808, sector_buffer+0x818);

- Mode 2 Form 2 sector:

      mirage_helper_sector_edc_ecc_compute_edc_block(sector_buffer+0x10, 0x91C, sector_buffer+0x92C);

(This is assuming all other sector data is already stored in sector_buffer and that sector_buffer is 2532 bytes long)

#### Parameters

src | data to calculate EDC data for. | [in][array length=size]
size | size of data in `src` . | [in]
dest | buffer to write calculated EDC data into (4 bytes). | [out caller-allocates][array fixed-size=4]

### mirage_helper_strcasecmp ()

    gint
    mirage_helper_strcasecmp (const gchar *str1,
                              const gchar *str2);

Replacement function for g_strcasecmp/strcasecmp, which can properly handle UTF-8. Glib docs state this is only an approximation, albeit it should be a fairly good one.

It compares the two strings `str1` and `str2` , ignoring the case of the characters. It returns an integer less than, equal to, or greater than zero if `str1` is found, respectively, to be less than, to match, or be greater than `str2` .

#### Parameters

str1 | first string. | [in]
str2 | second string. | [in]

#### Returns

an integer less than, equal to, or greater than zero if `str1` is found, respectively, to be less than, to match, or be greater than `str2` .

### mirage_helper_strncasecmp ()

    gint
    mirage_helper_strncasecmp (const gchar *str1,
                               const gchar *str2,
                               gint len);

Replacement function for g_strncasecmp/strncasecmp, which can properly handle UTF-8. Glib docs state this is only an approximation, albeit it should be a fairly good one.

It compares first `len` characters of string `str1` and `str2` , ignoring the case of the characters. It returns an integer less than, equal to, or greater than zero if first `len` characters of `str1` is found, respectively, to be less than, to match, or be greater than first `len` characters of `str2` .

#### Parameters

str1 | first string. | [in]
str2 | second string. | [in]
len | length of string to compare. | [in]

#### Returns

an integer less than, equal to, or greater than zero if first `len` characters of `str1` is found, respectively, to be less than, to match, or be greater than first `len` characters of `str2` .

### mirage_helper_format_string ()

    gchar *
    mirage_helper_format_string (const gchar *format,
                                 ...);

General-purpose string formatter with token replacement. Similarly to sprintf, the tokens begin with percent character, but instead of denoting format type, the tokens denote placeholders for user-defined replacements. Sprintf-like field width and precision modifiers are supported for formatting the replacements. If replacement is not specified for a replacement token found in format, then the token is removed in the output string.

If replacement does not exist and the token to be replaced is preceded by other word-caracters (see GRegex documentation for details), in addition to the replacement token, all those word characters are removed together with the leading non-word character.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Example: formatting a filename
    output = mirage_helper_format_string("%b-%02s-track%t.%e",
        "b", g_variant_new_string("some_image"),
        "s", g_variant_new_int16(1),
        "t", g_variant_new_int16(3),
        "e", g_variant_new_string("iso"), NULL);
    // output = "some_image-01-track3.iso"

    // Example: removal of preceding characters when replacement does not exist
    output = mirage_helper_format_string("%b-%02s-track%t.%e",
        "b", g_variant_new_string("some_image"),
        "s", g_variant_new_int16(1),
        "e", g_variant_new_string("iso"), NULL);
    // output = "some_image-01.iso"

`Varargs` is a `NULL`-terminated list of replacement token/value pairs, where a replacement token/value pair is a pair of string and a GVariant.

#### Parameters

format | format string. | [in]
... | `NULL`-terminated list of replacement token/value pairs. | [in]

#### Returns

string with all replacement tokens either replaced or removed. The string should be freed using `g_free()` when no longer needed.

[transfer full]

### mirage_helper_format_stringd ()

    gchar *
    mirage_helper_format_stringd (const gchar *format,
                                  GHashTable *dictionary);

Dictionary-version of `mirage_helper_format_string()`.

`dictionary` is a GHashTable where keys are replacement token strings and each value is a GVariant containing corresponding token replacement value.

#### Parameters

format | format string. | [in]
dictionary | a GHashTable containing replacement token/value pairs. | [in]

#### Returns

string with all replacement tokens either replaced or removed. The string should be freed using `g_free()` when no longer needed.

[transfer full]

### mirage_helper_format_stringv ()

    gchar *
    mirage_helper_format_stringv (const gchar *format,
                                  va_list args);

Variable-argument-list-version of `mirage_helper_format_string()`.

`args` is a `NULL`-terminated list of replacement token/value pairs, where a replacement token/value pair is a pair of string and a GVariant.

#### Parameters

format | format string. | [in]
args | `NULL`-terminated list of replacement token/value pairs. | [in]

#### Returns

string with all replacement tokens either replaced or removed. The string should be freed using `g_free()` when no longer needed.

[transfer full]

### mirage_helper_subchannel_deinterleave ()

    void
    mirage_helper_subchannel_deinterleave (gint subchan,
                                           const guint8 *channel96,
                                           guint8 *channel12);

Deinterleaves subchannel data of type `subchan` from subchannel data stored in `channel96` and writes the resulting subhcannel data into `subchannel12` .

#### Parameters

subchan | subchannel type. | [in]
channel96 | buffer containing subchannel data to deinterleave (96 bytes). | [in][array fixed-size=96]
channel12 | buffer to deinterleave subchannel data into (12 bytes). | [out caller-allocates][array fixed-size=12]

### mirage_helper_subchannel_interleave ()

    void
    mirage_helper_subchannel_interleave (gint subchan,
                                         const guint8 *channel12,
                                         guint8 *channel96);

Interleaves subchannel data of type `subchan` stored in `channel12` into subchannel data stored in `subchannel96` .

#### Parameters

subchan | subchannel type. | [in]
channel12 | buffer containing subchannel data to interleave (12 bytes). | [in][array fixed-size=12]
channel96 | buffer to interleave subchannel data into (96 bytes). | [out caller-allocates][array fixed-size=96]

### mirage_helper_subchannel_q_calculate_crc ()

    guint16
    mirage_helper_subchannel_q_calculate_crc
                                   (const guint8 *data);

Calculates the CRC-16 checksum of the Q subchannel data stored in `data` .

#### Parameters

data | buffer containing Q subchannel data (10 bytes). | [in][array fixed-size=10]

#### Returns

CRC-16 checksum of Q subchannel data

### mirage_helper_subchannel_q_decode_isrc ()

    void
    mirage_helper_subchannel_q_decode_isrc
                                   (const guint8 *buf,
                                    gchar *isrc);

Decodes ISRC stored in `buf` into string `isrc` .

#### Parameters

buf | buffer containing encoded ISRC (8 bytes). | [in][array fixed-size=8]
isrc | string to decode ISRC into (12 bytes). | [out caller-allocates][array fixed-size=12]

### mirage_helper_subchannel_q_decode_mcn ()

    void
    mirage_helper_subchannel_q_decode_mcn (const guint8 *buf,
                                           gchar *mcn);

Decodes MCN stored in `buf` into string `mcn` .

#### Parameters

buf | buffer containing encoded MCN (7 bytes). | [in][array fixed-size=7]
mcn | string to decode MCN into (13 bytes). | [out caller-allocates][array fixed-size=13]

### mirage_helper_subchannel_q_encode_isrc ()

    void
    mirage_helper_subchannel_q_encode_isrc
                                   (guint8 *buf,
                                    const gchar *isrc);

Encodes ISRC string `isrc` into buffer `buf` .

#### Parameters

buf | buffer to encode ISRC into (8 bytes). | [out caller-allocates][array fixed-size=8]
isrc | ISRC string (12 bytes). | [in][array fixed-size=12]

### mirage_helper_subchannel_q_encode_mcn ()

    void
    mirage_helper_subchannel_q_encode_mcn (guint8 *buf,
                                           const gchar *mcn);

Encodes MCN string `mcn` into buffer `buf` .

#### Parameters

buf | buffer to encode MCN into (7 bytes). | [out caller-allocates][array fixed-size=7]
mcn | MCN string (13 bytes). | [in][array fixed-size=13]

### mirage_helper_validate_isrc ()

    gboolean
    mirage_helper_validate_isrc (const gchar *isrc);

Performs a limited validation of an ISRC string.

#### Parameters

isrc | An ASCII encoded ISRC string. | [in][array fixed-size=12]

#### Returns

TRUE or FALSE

## Types and Values

### enum MirageSubChannel

Subchannel type for interleaving/deinterleaving.

#### Members

SUBCHANNEL_W | W subchannel data |
SUBCHANNEL_V | V subchannel data |
SUBCHANNEL_U | U subchannel data |
SUBCHANNEL_T | T subchannel data |
SUBCHANNEL_S | S subchannel data |
SUBCHANNEL_R | R subchannel data |
SUBCHANNEL_Q | Q subchannel data |
SUBCHANNEL_P | P subchannel data |