Utility functions

Utility functions — libMirage's helper and utility functions

Synopsis

#include <mirage.h>

enum                MIRAGE_SubChannel;
#define             MIRAGE_CAST_DATA                    (buf,
                                                         off,
                                                         type)
#define             MIRAGE_CAST_PTR                     (buf,
                                                         off,
                                                         type)
#define             MIRAGE_CHECK_ARG                    (arg)
#define             G_LIST_FOR_EACH                     (cursor,
                                                         list)
gchar *             mirage_helper_find_data_file        (const gchar *filename,
                                                         const gchar *path);
gchar *             mirage_helper_get_suffix            (const gchar *filename);
gboolean            mirage_helper_has_suffix            (const gchar *filename,
                                                         const gchar *suffix);
gint                mirage_helper_strcasecmp            (const gchar *str1,
                                                         const gchar *str2);
gint                mirage_helper_strncasecmp           (const gchar *str1,
                                                         const gchar *str2,
                                                         gint len);
void                mirage_helper_lba2msf               (gint lba,
                                                         gboolean diff,
                                                         guint8 *m,
                                                         guint8 *s,
                                                         guint8 *f);
gchar *             mirage_helper_lba2msf_str           (gint lba,
                                                         gboolean diff);
gint                mirage_helper_msf2lba               (guint8 m,
                                                         guint8 s,
                                                         guint8 f,
                                                         gboolean diff);
gint                mirage_helper_msf2lba_str           (const gchar *msf,
                                                         gboolean diff);
gint                mirage_helper_hex2bcd               (gint hex);
gint                mirage_helper_bcd2hex               (gint bcd);
guint8              mirage_helper_ascii2isrc            (gchar c);
gchar               mirage_helper_isrc2ascii            (guint8 c);
guint16             mirage_helper_subchannel_q_calculate_crc
                                                        (const guint8 *data);
void                mirage_helper_subchannel_q_encode_mcn
                                                        (guint8 *buf,
                                                         const gchar *mcn);
void                mirage_helper_subchannel_q_decode_mcn
                                                        (const guint8 *buf,
                                                         gchar *mcn);
void                mirage_helper_subchannel_q_encode_isrc
                                                        (guint8 *buf,
                                                         const gchar *isrc);
void                mirage_helper_subchannel_q_decode_isrc
                                                        (const guint8 *buf,
                                                         gchar *isrc);
void                mirage_helper_subchannel_interleave (gint subchan,
                                                         const guint8 *channel12,
                                                         guint8 *channel96);
void                mirage_helper_subchannel_deinterleave
                                                        (gint subchan,
                                                         const guint8 *channel96,
                                                         guint8 *channel12);
void                mirage_helper_sector_edc_ecc_compute_edc_block
                                                        (const guint8 *src,
                                                         guint16 size,
                                                         guint8 *dest);
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);

Description

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

Details

enum MIRAGE_SubChannel

typedef enum {
    SUBCHANNEL_W = 0,
    SUBCHANNEL_V = 1,
    SUBCHANNEL_U = 2,
    SUBCHANNEL_T = 3,
    SUBCHANNEL_S = 4,
    SUBCHANNEL_R = 5,
    SUBCHANNEL_Q = 6,
    SUBCHANNEL_P = 7,
} MIRAGE_SubChannel;

Subchannel type for interleaving/deinterleaving.

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

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.

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.

buf :

buffer to place pointer in

off :

offset in buffer at which to place pointer

type :

pointer type (i.e. 'gchar *')

MIRAGE_CHECK_ARG()

#define             MIRAGE_CHECK_ARG(arg)

A macro to be used within libMirage objects. It checks whether arg is valid pointer argument (non-NULL). If it is not, it returns false and error is set to MIRAGE_E_INVALIDARG. The existance of local variable error of type GError** is assumed.

arg :

argument to be checked

G_LIST_FOR_EACH()

#define             G_LIST_FOR_EACH(cursor,list)

A macro providing for loop on GList. cursor is a cursor of type GList*, and is used to store current element in the list. list is a GLib's double linked list that for loop should be performed on.

cursor :

cursor

list :

list

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 doesn't exist, path's dirname is combined with filename's basename, and the combination's existence is checked. If that fails as well, then directory, specified by path's dirname is opened and its content is case-insensitively compared to filename's basename. This way, all possible case variations are taken into account (i.e. file.iso, FILE.ISO, FiLe.IsO, etc.). If at any of above steps the result is positive, the resulting filename is returned as a newly allocated string.

The returned string should be freed when no longer needed.

filename :

declared filename

path :

path where to look for file (can be a filename)

Returns :

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

mirage_helper_get_suffix ()

gchar *             mirage_helper_get_suffix            (const gchar *filename);

Retrieves suffix from filename.

filename :

filename

Returns :

pointer to character in filename at which the suffix starts.

mirage_helper_has_suffix ()

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

Checks whether file name filename ends with suffix suffix.

filename :

filename

suffix :

suffix

Returns :

TRUE if filename contains suffix suffix, FALSE if not

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.

str1 :

first string

str2 :

second string

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.

str1 :

first string

str2 :

second string

len :

length of string to compare

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_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.

lba :

LBA address

diff :

account for the difference

m :

location to store minutes, or NULL

s :

location to store seconds, or NULL

f :

location to store frames, or NULL

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.

lba :

LBA address

diff :

account for the difference

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.

m :

minutes

s :

seconds

f :

frames

diff :

difference

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.

msf :

MSF string

diff :

difference

Returns :

integer representing LBA address

mirage_helper_hex2bcd ()

gint                mirage_helper_hex2bcd               (gint hex);

Converts hex-encoded integer into bcd-encoded integer.

hex :

hex-encoded integer

Returns :

bcd-encoded integer

mirage_helper_bcd2hex ()

gint                mirage_helper_bcd2hex               (gint bcd);

Converts bcd-encoded integer into hex-encoded integer.

bcd :

bcd-encoded integer

Returns :

hex-encoded integer

mirage_helper_ascii2isrc ()

guint8              mirage_helper_ascii2isrc            (gchar c);

Converts ASCII character c into ISRC character.

c :

ASCII character

Returns :

ISRC character

mirage_helper_isrc2ascii ()

gchar               mirage_helper_isrc2ascii            (guint8 c);

Converts ISRC character c into ASCII character.

c :

ISRC character

Returns :

ACSII character

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.

data :

buffer containing Q subchannel data

Returns :

CRC-16 checksum of Q subchannel data

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.

buf :

buffer to encode MCN into

mcn :

MCN string

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.

buf :

buffer containing encoded MCN

mcn :

string to decode MCN into

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.

buf :

buffer to encode ISRC into

isrc :

ISRC string

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.

buf :

buffer containing encoded ISRC

isrc :

string to decode ISRC into

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.

subchan :

subchannel type

channel12 :

buffer containing subchannel data to interleave

channel96 :

buffer to interleave subchannel data into

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.

subchan :

subchannel type

channel96 :

buffer containing subchannel data to deinterleave

channel12 :

buffer to deinterleave subchannel data into

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)

src :

data to calculate EDC data for

size :

size of data in src

dest :

buffer to write calculated EDC data into

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); 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)

src :

data to calculate ECC data for

major_count :

major count

minor_count :

minor count

major_mult :

major multiplicator

minor_inc :

minor increment

dest :

buffer to write calculated ECC data into