status _af_iff_read_init (AFfilesetup setup, AFfilehandle file) { uint32_t type, size, formtype; size_t index; _Track *track; assert(file != NULL); assert(file->fh != NULL); af_fseek(file->fh, 0, SEEK_SET); af_fread(&type, 4, 1, file->fh); af_read_uint32_be(&size, file->fh); af_fread(&formtype, 4, 1, file->fh); if (memcmp(&type, "FORM", 4) != 0 || memcmp(&formtype, "8SVX", 4) != 0) return AF_FAIL; file->instrumentCount = 0; file->instruments = NULL; file->miscellaneousCount = 0; file->miscellaneous = NULL; /* IFF/8SVX files have only one track. */ track = _af_track_new(); file->trackCount = 1; file->tracks = track; /* Set the index to include the form type ('8SVX' in this case). */ index = 4; while (index < size) { uint32_t chunkid = 0, chunksize = 0; status result = AF_SUCCEED; af_fread(&chunkid, 4, 1, file->fh); af_read_uint32_be(&chunksize, file->fh); if (!memcmp("VHDR", &chunkid, 4)) { result = ParseVHDR(file, file->fh, chunkid, chunksize); } else if (!memcmp("BODY", &chunkid, 4)) { result = ParseBODY(file, file->fh, chunkid, chunksize); } else if (!memcmp("NAME", &chunkid, 4) || !memcmp("AUTH", &chunkid, 4) || !memcmp("(c) ", &chunkid, 4) || !memcmp("ANNO", &chunkid, 4)) { ParseMiscellaneous(file, file->fh, chunkid, chunksize); } if (result == AF_FAIL) return AF_FAIL; /* Increment the index by the size of the chunk plus the size of the chunk header. */ index += chunksize + 8; /* All chunks must be aligned on an even number of bytes. */ if ((index % 2) != 0) index++; /* Set the seek position to the beginning of the next chunk. */ af_fseek(file->fh, index + 8, SEEK_SET); } /* The file has been successfully parsed. */ return AF_SUCCEED; }
status _af_aiff_read_init (AFfilesetup setup, AFfilehandle file) { u_int32_t type, size, formtype; size_t index = 0; bool hasCOMM, hasFVER, hasSSND, hasMARK, hasINST; bool hasAESD, hasNAME, hasAUTH, hasCOPY; _Track *track; hasCOMM = AF_FALSE; hasFVER = AF_FALSE; hasSSND = AF_FALSE; hasMARK = AF_FALSE; hasINST = AF_FALSE; hasAESD = AF_FALSE; hasNAME = AF_FALSE; hasAUTH = AF_FALSE; hasCOPY = AF_FALSE; assert(file != NULL); assert(file->fh != NULL); af_fseek(file->fh, 0, SEEK_SET); af_fread(&type, 4, 1, file->fh); af_fread(&size, 4, 1, file->fh); size = BENDIAN_TO_HOST_INT32(size); af_fread(&formtype, 4, 1, file->fh); if (memcmp(&type, "FORM", 4) != 0 || (memcmp(&formtype, "AIFF", 4) && memcmp(&formtype, "AIFC", 4))) return AF_FAIL; #ifdef DEBUG printf("size: %d\n", size); #endif file->instrumentCount = 0; file->instruments = NULL; file->miscellaneousCount = 0; file->miscellaneous = NULL; /* AIFF files have only one track. */ track = _af_track_new(); file->trackCount = 1; file->tracks = track; /* Include the offset of the form type. */ index += 4; while (index < size) { u_int32_t chunkid = 0, chunksize = 0; status result = AF_SUCCEED; #ifdef DEBUG printf("index: %d\n", index); #endif af_fread(&chunkid, 4, 1, file->fh); af_fread(&chunksize, 4, 1, file->fh); chunksize = BENDIAN_TO_HOST_INT32(chunksize); #ifdef DEBUG _af_printid(chunkid); printf(" size: %d\n", chunksize); #endif if (!memcmp("COMM", &chunkid, 4)) { hasCOMM = AF_TRUE; result = ParseCOMM(file, file->fh, chunkid, chunksize); } else if (!memcmp("FVER", &chunkid, 4)) { hasFVER = AF_TRUE; ParseFVER(file, file->fh, chunkid, chunksize); } else if (!memcmp("INST", &chunkid, 4)) { hasINST = AF_TRUE; ParseINST(file, file->fh, chunkid, chunksize); } else if (!memcmp("MARK", &chunkid, 4)) { hasMARK = AF_TRUE; ParseMARK(file, file->fh, chunkid, chunksize); } else if (!memcmp("AESD", &chunkid, 4)) { hasAESD = AF_TRUE; ParseAESD(file, file->fh, chunkid, chunksize); } else if (!memcmp("NAME", &chunkid, 4) || !memcmp("AUTH", &chunkid, 4) || !memcmp("(c) ", &chunkid, 4) || !memcmp("ANNO", &chunkid, 4) || !memcmp("APPL", &chunkid, 4) || !memcmp("MIDI", &chunkid, 4)) { ParseMiscellaneous(file, file->fh, chunkid, chunksize); } /* The sound data chunk is required if there are more than zero sample frames. */ else if (!memcmp("SSND", &chunkid, 4)) { if (hasSSND) { _af_error(AF_BAD_AIFF_SSND, "AIFF file has more than one SSND chunk"); return AF_FAIL; } hasSSND = AF_TRUE; result = ParseSSND(file, file->fh, chunkid, chunksize); } if (result == AF_FAIL) return AF_FAIL; index += chunksize + 8; /* all chunks must be aligned on an even number of bytes */ if ((index % 2) != 0) index++; af_fseek(file->fh, index + 8, SEEK_SET); } if (!hasCOMM) { _af_error(AF_BAD_AIFF_COMM, "bad AIFF COMM chunk"); } /* The file has been successfully parsed. */ return AF_SUCCEED; }