track_t *track_from_path(const char *path) { AVFormatContext *avctx = NULL; track_t *track; if (avformat_open_input(&avctx, path, NULL, NULL)) { return NULL; } if (!is_valid_audio_file(avctx)) { return NULL; } track = track_create(path, avctx, -1); avformat_close_input(&avctx); return track; }
static bool cdi_parse_track(FILE *f, const char *fn, uint32_t version, uint8_t track, uint8_t session, uint32_t *offs) { static const uint8_t mark[10] = { 0, 0, 1, 0, 0, 0, ~0, ~0, ~0, ~0 }; uint8_t buf[89]; int i; if (fread(buf, 1, 4, f) != 4) { msg_perror(fn); return false; } if (get_le32(buf) != 0 && fseek(f, 8, SEEK_CUR) < 0) { msg_perror(fn); return false; } if (fread(buf, 1, 25, f) != 25) { msg_perror(fn); return false; } if (memcmp(buf, mark, 10) || memcmp(buf+10, mark, 10)) { msg_error("Track start mark not identified\n"); return false; } if (buf[24] > 0 && fseek(f, buf[24], SEEK_CUR) < 0) { msg_perror(fn); return false; } if (fread(buf, 1, 23, f) != 23) { msg_perror(fn); return false; } if (get_le32(buf+19) == 0x80000000UL && fseek(f, 8, SEEK_CUR) < 0) { msg_perror(fn); return false; } if (fread(buf, 1, 89, f) != 89) { msg_perror(fn); return false; } struct track *t = track_create(); if (!t) return false; t->track_nr = track; t->session_nr = session - 1; t->track_ctl = buf[60]; t->start_sector = get_le32(buf+32)+150; uint32_t pregap = get_le32(buf+2); uint32_t length = get_le32(buf+6); uint32_t tot_length = get_le32(buf+36); uint32_t secsize; switch (buf[56]) { case 0: secsize = 2048; break; case 1: secsize = 2336; break; case 2: secsize = 2352; break; default: msg_error("Unknown sector size encountered\n"); return false; } enum track_type type; switch (buf[16]) { case 0: if (secsize != 2352) { msg_error("Invalid sector size for audio track\n"); return false; } type = TRACK_RAW_2352; break; case 1: if (secsize != 2048) { msg_error("Invalid sector size for mode 1 track\n"); return false; } type = TRACK_MODE_1_2048; break; case 2: if (secsize == 2336) type = TRACK_MODE_2_2336; else if (secsize == 2048) type = TRACK_XA_FORM_1_2048; else { msg_error("Invalid sector size for mode 2 track\n"); return false; } break; default: msg_error("Invalid track mode\n"); return false; } if (!track_data_from_file(t, type, secsize, f, *offs + pregap * secsize, length)) return false; *offs += tot_length * secsize; if (version != CDI_VERSION_2) { if (fread(buf, 1, 9, f) != 9) { msg_perror(fn); return false; } if (get_le32(buf+5) == (uint32_t)(~0UL) && fseek(f, 78, SEEK_CUR) < 0) { msg_perror(fn); return false; } } return true; }