static int mmd3_test(HIO_HANDLE *f, char *t, const int start) { char id[4]; uint32 offset, len; if (hio_read(id, 1, 4, f) < 4) return -1; if (memcmp(id, "MMD2", 4) && memcmp(id, "MMD3", 4)) return -1; hio_seek(f, 28, SEEK_CUR); offset = hio_read32b(f); /* expdata_offset */ if (offset) { hio_seek(f, start + offset + 44, SEEK_SET); offset = hio_read32b(f); len = hio_read32b(f); hio_seek(f, start + offset, SEEK_SET); read_title(f, t, len); } else { read_title(f, t, 0); } return 0; }
static int read_abk_song(HIO_HANDLE *f, struct abk_song *song, uint32 songs_section_offset) { int i; uint32 song_section; /* move to the start of the songs data section */ hio_seek(f, songs_section_offset, SEEK_SET); if (hio_read16b(f) != 1) { /* we only support a single song. * in a an abk file for now */ return -1; } song_section = hio_read32b(f); hio_seek(f, songs_section_offset + song_section, SEEK_SET); for (i=0; i<AMOS_ABK_CHANNELS; i++) { song->playlist_offset[i] = hio_read16b(f) + songs_section_offset + song_section; } song->tempo = hio_read16b(f); /* unused. just progress the file pointer forward */ (void) hio_read16b(f); hio_read(song->song_name, 1, AMOS_STRING_LEN, f); return 0; }
static int mod_test(HIO_HANDLE *f, char *t, const int start) { int i; char buf[4]; hio_seek(f, start + 1080, SEEK_SET); if (hio_read(buf, 1, 4, f) < 4) return -1; if (!strncmp(buf + 2, "CH", 2) && isdigit((int)buf[0]) && isdigit((int)buf[1])) { i = (buf[0] - '0') * 10 + buf[1] - '0'; if (i > 0 && i <= 32) { goto found; } } if (!strncmp(buf + 1, "CHN", 3) && isdigit((int)*buf)) { if (*buf >= '0' && *buf <='9') { goto found; } } if (memcmp(buf, "M.K.", 4)) return -1; found: hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); return 0; }
int mmd_load_hybrid_instrument(HIO_HANDLE *f, struct module_data *m, int i, int smp_idx, struct SynthInstr *synth, struct InstrExt *exp_smp, struct MMD0sample *sample) { struct xmp_module *mod = &m->mod; struct xmp_instrument *xxi = &mod->xxi[i]; struct xmp_subinstrument *sub; struct xmp_sample *xxs; int length, type; int pos = hio_tell(f); synth->defaultdecay = hio_read8(f); hio_seek(f, 3, SEEK_CUR); synth->rep = hio_read16b(f); synth->replen = hio_read16b(f); synth->voltbllen = hio_read16b(f); synth->wftbllen = hio_read16b(f); synth->volspeed = hio_read8(f); synth->wfspeed = hio_read8(f); synth->wforms = hio_read16b(f); hio_read(synth->voltbl, 1, 128, f);; hio_read(synth->wftbl, 1, 128, f);; hio_seek(f, pos - 6 + hio_read32b(f), SEEK_SET); length = hio_read32b(f); type = hio_read16b(f); if (med_new_instrument_extras(xxi) != 0) return -1; xxi->nsm = 1; if (subinstrument_alloc(mod, i, 1) < 0) return -1; MED_INSTRUMENT_EXTRAS((*xxi))->vts = synth->volspeed; MED_INSTRUMENT_EXTRAS((*xxi))->wts = synth->wfspeed; sub = &xxi->sub[0]; sub->pan = 0x80; sub->vol = sample->svol; sub->xpo = sample->strans; sub->sid = smp_idx; sub->fin = exp_smp->finetune; xxs = &mod->xxs[smp_idx]; xxs->len = length; xxs->lps = 2 * sample->rep; xxs->lpe = xxs->lps + 2 * sample->replen; xxs->flg = sample->replen > 1 ? XMP_SAMPLE_LOOP : 0; if (load_sample(m, f, 0, xxs, NULL) < 0) return -1; return 0; }
static int s3m_test(HIO_HANDLE *f, char *t, const int start) { hio_seek(f, start + 44, SEEK_SET); if (hio_read32b(f) != MAGIC_SCRM) return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 28); return 0; }
static int load_module(xmp_context opaque, HIO_HANDLE *h, struct list_head *tmpfiles_list) { struct context_data *ctx = (struct context_data *)opaque; struct module_data *m = &ctx->m; int i, ret; int test_result, load_result; load_prologue(ctx); D_(D_WARN "load"); test_result = load_result = -1; for (i = 0; format_loader[i] != NULL; i++) { hio_seek(h, 0, SEEK_SET); test_result = format_loader[i]->test(h, NULL, 0); if (test_result == 0) { hio_seek(h, 0, SEEK_SET); D_(D_WARN "load format: %s", format_loader[i]->name); load_result = format_loader[i]->loader(m, h, 0); break; } } if (test_result == 0 && load_result == 0) set_md5sum(h, m->md5); hio_close(h); if (tmpfiles_list != NULL) unlink_tempfiles(tmpfiles_list); if (test_result < 0) { free(m->basename); free(m->dirname); return -XMP_ERROR_FORMAT; } if (load_result < 0) { xmp_release_module(opaque); return -XMP_ERROR_LOAD; } str_adj(m->mod.name); load_epilogue(ctx); ret = prepare_scan(ctx); if (ret < 0) return ret; scan_sequences(ctx); ctx->state = XMP_STATE_LOADED; return 0; }
static int composite_load(struct module_data *m, HIO_HANDLE *f, const int start) { struct format_loader **loader; for (loader = format_loader; *loader; ++loader) { if (0 == (*loader)->test(f, 0, start)) { hio_seek(f, 0, SEEK_SET); D_(D_WARN "load format: %s", (*loader)->name); return (*loader)->loader(m, f, start); } hio_seek(f, 0, SEEK_SET); } return -1; }
static int gdm_test(HIO_HANDLE *f, char *t, const int start) { if (hio_read32b(f) != MAGIC_GDM) return -1; hio_seek(f, start + 0x47, SEEK_SET); if (hio_read32b(f) != MAGIC_GMFS) return -1; hio_seek(f, start + 4, SEEK_SET); libxmp_read_title(f, t, 32); return 0; }
static int hmn_test(HIO_HANDLE * f, char *t, const int start) { int magic; hio_seek(f, start + 1080, SEEK_SET); magic = hio_read32b(f); if (magic != MAGIC_FEST && magic != MAGIC_MK) return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); return 0; }
static int stc_test(HIO_HANDLE * f, char *t, const int start) { int pos_ptr, orn_ptr, pat_ptr; int i, len, max_pat; hio_seek(f, start, SEEK_SET); if (hio_read8(f) > 0x20) /* Check tempo */ return -1; pos_ptr = hio_read16l(f); /* Positions pointer */ orn_ptr = hio_read16l(f); /* Ornaments pointer */ pat_ptr = hio_read16l(f); /* Patterns pointer */ if (pos_ptr < 138 || orn_ptr < 138 || pat_ptr < 138) return -1; hio_seek(f, start + pos_ptr, SEEK_SET); len = hio_read8(f) + 1; for (max_pat = i = 0; i < len; i++) { int pat = hio_read8(f); if (pat > MAX_PAT) /* Check orders */ return -1; if (pat > max_pat) max_pat = pat; hio_read8(f); } hio_seek(f, pat_ptr, SEEK_SET); for (i = 0; i < max_pat; i++) { int num = hio_read8(f); /* Check track pointers */ if (num != (i + 1)) return -1; hio_read16l(f); hio_read16l(f); hio_read16l(f); } if (hio_read8(f) != 0xff) return -1; hio_seek(f, start + 7, SEEK_SET); read_title(f, t, 18); return 0; }
/** * @brief read the ABK playlist out from the file stream. This method malloc's some memory for the playlist * and can realloc if the playlist is very long. * @param f the stream to read from * @param playlist_offset the offset to the playlist sections. * @param playlist this structure is populated with the result. */ static void read_abk_playlist(HIO_HANDLE *f, uint32 playlist_offset, struct abk_playlist *playlist) { uint16 playdata; int arraysize; arraysize = 64; /* clear the length */ playlist->length = 0; /* move to the start of the songs data section. */ hio_seek(f, playlist_offset, SEEK_SET); playlist->pattern = (uint16 *) malloc(arraysize * sizeof(uint16)); playdata = hio_read16b(f); while((playdata != 0xFFFF) && (playdata != 0xFFFE)) { /* i hate doing a realloc in a loop but i'd rather not traverse the list twice.*/ if (playlist->length >= arraysize) { arraysize *= 2; playlist->pattern = (uint16 *) realloc(playlist->pattern , arraysize * sizeof(uint16)); } playlist->pattern[playlist->length++] = playdata; playdata = hio_read16b(f); }; }
static int pt3_test(HIO_HANDLE *f, char *t, const int start) { if (hio_read32b(f) != MAGIC_FORM) return -1; hio_read32b(f); /* skip size */ if (hio_read32b(f) != MAGIC_MODL) return -1; if (hio_read32b(f) != MAGIC_VERS) return -1; hio_read32b(f); /* skip size */ hio_seek(f, 10, SEEK_CUR); if (hio_read32b(f) == MAGIC_INFO) { hio_read32b(f); /* skip size */ read_title(f, t, 32); } else { read_title(f, t, 0); } return 0; }
static int amd_test(HIO_HANDLE *f, char *t, const int start) { char buf[9]; hio_seek(f, start + 1062, SEEK_SET); if (hio_read(buf, 1, 9, f) < 9) return -1; if (memcmp(buf, "<o", 2) || memcmp(buf + 6, "RoR", 3)) return -1; hio_seek(f, start + 0, SEEK_SET); libxmp_read_title(f, t, 24); return 0; }
static int sfx_test(HIO_HANDLE *f, char *t, const int start) { uint32 a, b; hio_seek(f, 4 * 15, SEEK_CUR); a = hio_read32b(f); hio_seek(f, 4 * 15, SEEK_CUR); b = hio_read32b(f); if (a != MAGIC_SONG && b != MAGIC_SONG) return -1; read_title(f, t, 0); return 0; }
static int chip_test(HIO_HANDLE *f, char *t, const int start) { char buf[4]; hio_seek(f, start + 952, SEEK_SET); if (hio_read(buf, 1, 4, f) < 4) return -1; /* Also RASP? */ if (memcmp(buf, "KRIS", 4) != 0) return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); return 0; }
static int ssn_test(HIO_HANDLE *f, char *t, const int start) { uint16 id; id = hio_read16b(f); if (id != 0x6966 && id != 0x4a4e) return -1; hio_seek(f, 238, SEEK_CUR); if (hio_read8(f) != 0xff) return -1; hio_seek(f, start + 2, SEEK_SET); read_title(f, t, 36); return 0; }
static int digi_test(HIO_HANDLE *f, char *t, const int start) { char buf[20]; if (hio_read(buf, 1, 20, f) < 20) return -1; if (memcmp(buf, "DIGI Booster module", 19)) return -1; hio_seek(f, 156, SEEK_CUR); hio_seek(f, 3 * 4 * 32, SEEK_CUR); hio_seek(f, 2 * 1 * 32, SEEK_CUR); read_title(f, t, 32); return 0; }
static int mgt_test(HIO_HANDLE *f, char *t, const int start) { int sng_ptr; if (hio_read24b(f) != MAGIC_MGT) return -1; hio_read8(f); if (hio_read32b(f) != MAGIC_MCS) return -1; hio_seek(f, 18, SEEK_CUR); sng_ptr = hio_read32b(f); hio_seek(f, start + sng_ptr, SEEK_SET); read_title(f, t, 32); return 0; }
static int composite_test(HIO_HANDLE *f, char *t, const int start) { struct format_loader **loader; for (loader = format_loader; *loader; ++loader) { if (0 == (*loader)->test(f, t, start)) return 0; hio_seek(f, 0, SEEK_SET); } return -1; }
static int dmf_test(HIO_HANDLE * f, char *t, const int start) { if (hio_read32b(f) != MAGIC_DDMF) return -1; hio_seek(f, 9, SEEK_CUR); read_title(f, t, 30); return 0; }
static int stx_test(HIO_HANDLE *f, char *t, const int start) { char buf[8]; hio_seek(f, start + 20, SEEK_SET); if (hio_read(buf, 1, 8, f) < 8) return -1; if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8)) return -1; hio_seek(f, start + 60, SEEK_SET); if (hio_read(buf, 1, 4, f) < 4) return -1; if (memcmp(buf, "SCRM", 4)) return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); return 0; }
static int no_test(HIO_HANDLE *f, char *t, const int start) { int nsize, pat, chn; int i; hio_seek(f, start, SEEK_CUR); if (hio_read32b(f) != 0x4e4f0000) /* NO 0x00 0x00 */ return -1; nsize = hio_read8(f); if (nsize != 20) return -1; /* test title */ for (i = 0; i < nsize; i++) { if (hio_read8(f) == 0) return -1; } hio_seek(f, 9, SEEK_CUR); /* test number of patterns */ pat = hio_read8(f); if (pat == 0) return -1; hio_read8(f); /* test number of channels */ chn = hio_read8(f); if (chn <= 0 || chn > 16) return -1; hio_seek(f, start + 5, SEEK_SET); libxmp_read_title(f, t, nsize); return 0; }
int pw_wizardry(HIO_HANDLE *file_in, FILE *file_out, char **name) { int in_size; uint8 *data; char title[21]; int i; in_size = hio_size(file_in); /* printf ("input file size : %d\n", in_size); */ if (in_size < MIN_FILE_LENGHT) return -2; /* alloc mem */ data = (uint8 *)malloc (in_size + 4096); /* slack added */ if (data == NULL) { /*perror("Couldn't allocate memory");*/ return -1; } hio_read(data, in_size, 1, file_in); /********************************************************************/ /************************** SEARCH ******************************/ /********************************************************************/ for (i = 0; pw_format[i] != NULL; i++) { D_("checking format: %s", pw_format[i]->name); if (pw_format[i]->test(data, title, in_size) >= 0) break; } if (pw_format[i] == NULL) { free(data); return -1; } hio_seek(file_in, 0, SEEK_SET); if (pw_format[i]->depack(file_in, file_out) < 0) { free(data); return -1; } fflush(file_out); free(data); if (name != NULL) { *name = pw_format[i]->name; } return 0; }
static int stm_test(HIO_HANDLE *f, char *t, const int start) { char buf[8]; hio_seek(f, start + 20, SEEK_SET); if (hio_read(buf, 1, 8, f) < 8) return -1; if (memcmp(buf, "!Scream!", 8) && memcmp(buf, "BMOD2STM", 8)) return -1; hio_read8(f); if (hio_read8(f) != STM_TYPE_MODULE) return -1; if (hio_read8(f) < 1) /* We don't want STX files */ return -1; hio_seek(f, start + 0, SEEK_SET); read_title(f, t, 20); return 0; }
static int get_inst_cnt(struct module_data *m, int size, HIO_HANDLE *f, void *parm) { struct xmp_module *mod = &m->mod; int i; hio_read8(f); /* 00 */ i = hio_read8(f) + 1; /* instrument number */ if (i > mod->ins) mod->ins = i; hio_seek(f, 28, SEEK_CUR); /* skip name */ mod->smp += hio_read8(f); return 0; }
static void set_md5sum(HIO_HANDLE *f, unsigned char *digest) { unsigned char buf[BUFLEN]; MD5_CTX ctx; int bytes_read; if (hio_size(f) <= 0) { memset(digest, 0, 16); return; } hio_seek(f, 0, SEEK_SET); MD5Init(&ctx); while ((bytes_read = hio_read(buf, 1, BUFLEN, f)) > 0) { MD5Update(&ctx, buf, bytes_read); } MD5Final(digest, &ctx); }
static int okt_load(struct module_data *m, HIO_HANDLE * f, const int start) { iff_handle handle; struct local_data data; int ret; LOAD_INIT(); hio_seek(f, 8, SEEK_CUR); /* OKTASONG */ handle = iff_new(); if (handle == NULL) return -1; memset(&data, 0, sizeof(struct local_data)); /* IFF chunk IDs */ ret = iff_register(handle, "CMOD", get_cmod); ret |= iff_register(handle, "SAMP", get_samp); ret |= iff_register(handle, "SPEE", get_spee); ret |= iff_register(handle, "SLEN", get_slen); ret |= iff_register(handle, "PLEN", get_plen); ret |= iff_register(handle, "PATT", get_patt); ret |= iff_register(handle, "PBOD", get_pbod); ret |= iff_register(handle, "SBOD", get_sbod); if (ret != 0) return -1; set_type(m, "Oktalyzer"); MODULE_INFO(); /* Load IFF chunks */ if (iff_load(handle, m, f, &data) < 0) { iff_release(handle); return -1; } iff_release(handle); return 0; }
static int module_load(HIO_HANDLE* h, struct context_data *ctx, const struct format_loader* format) { struct module_data *m = &ctx->m; hio_seek(h, 0, SEEK_SET); if (format->loader(m, h, 0) < 0) return -XMP_ERROR_LOAD; str_adj(m->mod.name); str_adj(m->mod.author); load_epilogue(ctx); if (prepare_scan(ctx) < 0) return -XMP_ERROR_LOAD; scan_sequences(ctx); ctx->state = XMP_STATE_LOADED; set_md5sum(h, m->md5); return 0; }
static int hsc_test(HIO_HANDLE *f, char *t, const int start) { int p, i, r, c; uint8 buf[1200]; hio_seek(f, 128 * 12, SEEK_CUR); if (hio_read(buf, 1, 51, f) != 51) return -1; for (p = i = 0; i < 51; i++) { if (buf[i] == 0xff) break; if (buf[i] > p) p = buf[i]; } if (!i || !p || i > 50 || p > 50) /* Test number of patterns */ return -1; for (i = 0; i < p; i++) { hio_read(buf, 1, 64 * 9 * 2, f); for (r = 0; r < 64; r++) { for (c = 0; c < 9; c++) { uint8 n = buf[r * 9 * 2 + c * 2]; uint8 m = buf[r * 9 * 2 + c * 2 + 1]; if (m > 0x06 && m < 0x10 && n != 0x80) /* Test effects 07..0f */ return -1; if (MSN(m) > 6 && MSN(m) < 10) /* Test effects 7x .. 9x */ return -1; } } } libxmp_read_title(f, t, 0); return 0; }
int load_sample(struct module_data *m, HIO_HANDLE *f, int flags, struct xmp_sample *xxs, void *buffer) { int bytelen, extralen, unroll_extralen, i; /* Adlib FM patches */ if (flags & SAMPLE_FLAG_ADLIB) { const int size = 11; if (flags & SAMPLE_FLAG_HSC) { convert_hsc_to_sbi(buffer); } xxs->data = malloc(size + 4); if (xxs->data == NULL) return -1; *(uint32 *)xxs->data = 0; xxs->data += 4; memcpy(xxs->data, buffer, size); xxs->flg |= XMP_SAMPLE_SYNTH; xxs->len = size; return 0; } /* Empty samples */ if (xxs->len == 0) { return 0; } /* Skip sample loading * FIXME: fails for ADPCM samples */ if (m && m->smpctl & XMP_SMPCTL_SKIP) { if (~flags & SAMPLE_FLAG_NOLOAD) hio_seek(f, xxs->len, SEEK_CUR); return 0; } /* Loop parameters sanity check */ if (xxs->lpe > xxs->len) { xxs->lpe = xxs->len; } if (xxs->lps >= xxs->len || xxs->lps >= xxs->lpe) { xxs->lps = xxs->lpe = 0; xxs->flg &= ~(XMP_SAMPLE_LOOP | XMP_SAMPLE_LOOP_BIDIR); } /* Patches with samples * Allocate extra sample for interpolation. */ bytelen = xxs->len; extralen = 4; unroll_extralen = 0; /* Disable birectional loop flag if sample is not looped */ if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) { if (~xxs->flg & XMP_SAMPLE_LOOP) xxs->flg &= ~XMP_SAMPLE_LOOP_BIDIR; } /* Unroll bidirectional loops */ if (xxs->flg & XMP_SAMPLE_LOOP_BIDIR) { unroll_extralen = (xxs->lpe - xxs->lps) - (xxs->len - xxs->lpe); if (unroll_extralen < 0) { unroll_extralen = 0; } } if (xxs->flg & XMP_SAMPLE_16BIT) { bytelen *= 2; extralen *= 2; unroll_extralen *= 2; } /* add guard bytes before the buffer for higher order interpolation */ xxs->data = malloc(bytelen + extralen + unroll_extralen + 4); if (xxs->data == NULL) return -1; *(uint32 *)xxs->data = 0; xxs->data += 4; if (flags & SAMPLE_FLAG_NOLOAD) { memcpy(xxs->data, buffer, bytelen); } else { uint8 buf[5]; long pos = hio_tell(f); int num = hio_read(buf, 1, 5, f); hio_seek(f, pos, SEEK_SET); if (num == 5 && !memcmp(buf, "ADPCM", 5)) { int x2 = bytelen >> 1; char table[16]; hio_seek(f, 5, SEEK_CUR); /* Skip "ADPCM" */ hio_read(table, 1, 16, f); hio_read(xxs->data + x2, 1, x2, f); adpcm4_decoder((uint8 *)xxs->data + x2, (uint8 *)xxs->data, table, bytelen); } else {