Merged 1571.

This commit is contained in:
Moritz Bunkus 2004-03-18 19:01:35 +00:00
parent 51ced57715
commit 484b0c2fd9
2 changed files with 103 additions and 33 deletions

View File

@ -177,14 +177,14 @@ typedef struct rmff_file_t {
mb_file_io_t *io;
void *handle;
char *name;
int open_mode;
int64_t size;
int headers_read;
rmff_prop_t prop_header;
int prop_header_found;
rmff_cont_t cont_header;
int cont_header_found;
int cont_header_present;
int64_t first_data_header_offset;
int64_t next_data_header_offset;
uint32_t num_packets_in_chunk;
@ -269,6 +269,7 @@ void rmff_close_file(rmff_file_t *file);
int rmff_read_headers(rmff_file_t *file);
/** \brief Retrieves the size of the next frame.
*
* \param file The file to read from.
* \returns the size of the following frame or one of the \c RMFF_ERR_*
* constants on error.
@ -277,6 +278,7 @@ int rmff_get_next_frame_size(rmff_file_t *file);
/** \brief Reads the next frame from the file.
* The frame must be released by rmff_release_frame(rmff_frame_t*).
*
* \param file The file to read from.
* \param buffer A buffer to read the frame into. This parameter may be
* \c NULL in which case the buffer will be allocated by the library.
@ -290,11 +292,26 @@ rmff_frame_t *rmff_read_next_frame(rmff_file_t *file, void *buffer);
/** \brief Frees all resources associated with a frame.
* If the frame buffer was allocated by the library it will be freed as well.
*
* \param frame The frame to free.
*/
void rmff_release_frame(rmff_frame_t *frame);
/** \brief Sets the contents of the CONT file header.
* Frees the old contents if any and allocates copies of the given
* strings. If the CONT header should be written to the file
* in rmff_write_headers(rmff_file_t*) then the \c cont_header_found
* member must be set to 1.
*
* \param file The file whose CONT header should be set.
* \param title The file's title, e.g. "Muriel's Wedding"
* \param author The file's author, e.g. "P.J. Hogan"
* \param copyright The copyright assigned to the file.
* \param comment A free-style comment.
*/
void rmff_set_cont_header(rmff_file_t *file, const char *title,
const char *author, const char *copyright,
const char *comment);
/** \brief The error code of the last function call.
* Contains the last error code for a function that failed. If a function

View File

@ -242,35 +242,20 @@ _saferealloc(void *mem,
return mem;
}
rmff_file_t *
rmff_open_file(const char *path,
int mode) {
return rmff_open_file_with_io(path, mode, &std_mb_file_io);
}
rmff_file_t *
rmff_open_file_with_io(const char *path,
int mode,
mb_file_io_t *io) {
static rmff_file_t *
open_file_for_reading(const char *path,
mb_file_io_t *io) {
rmff_file_t *file;
void *file_h;
char buf[5];
char signature[5];
if ((path == NULL) || (io == NULL) ||
((mode != RMFF_OPEN_MODE_READING) && (mode != RMFF_OPEN_MODE_WRITING)))
return (rmff_file_t *)set_error(RMFF_ERR_PARAMETERS, NULL, 0);
if (mode == RMFF_OPEN_MODE_READING)
mode = MB_OPEN_MODE_READING;
else
mode = MB_OPEN_MODE_WRITING;
file_h = io->open(path, mode);
file_h = io->open(path, MB_OPEN_MODE_READING);
if (file_h == NULL)
return NULL;
buf[4] = 0;
if ((io->read(file_h, buf, 4) != 4) ||
strcmp(buf, ".RMF")) {
signature[4] = 0;
if ((io->read(file_h, signature, 4) != 4) ||
strcmp(signature, ".RMF")) {
io->close(file_h);
return (rmff_file_t *)set_error(RMFF_ERR_NOT_RMFF, NULL, 0);
}
@ -282,10 +267,57 @@ rmff_open_file_with_io(const char *path,
io->seek(file_h, 0, SEEK_END);
file->size = io->tell(file_h);
io->seek(file_h, 4, SEEK_SET);
file->open_mode = RMFF_OPEN_MODE_READING;
return file;
}
static rmff_file_t *
open_file_for_writing(const char *path,
mb_file_io_t *io) {
rmff_file_t *file;
void *file_h;
const char *signature = ".RMF";
file_h = io->open(path, MB_OPEN_MODE_WRITING);
if (file_h == NULL)
return NULL;
if (io->write(file_h, signature, 4) != 4) {
io->close(file_h);
return (rmff_file_t *)set_error(RMFF_ERR_IO, NULL, 0);
}
file = (rmff_file_t *)safecalloc(sizeof(rmff_file_t));
file->handle = file_h;
file->name = safestrdup(path);
file->io = io;
file->size = -1;
file->open_mode = RMFF_OPEN_MODE_WRITING;
return file;
}
rmff_file_t *
rmff_open_file(const char *path,
int mode) {
return rmff_open_file_with_io(path, mode, &std_mb_file_io);
}
rmff_file_t *
rmff_open_file_with_io(const char *path,
int mode,
mb_file_io_t *io) {
if ((path == NULL) || (io == NULL) ||
((mode != RMFF_OPEN_MODE_READING) && (mode != RMFF_OPEN_MODE_WRITING)))
return (rmff_file_t *)set_error(RMFF_ERR_PARAMETERS, NULL, 0);
if (mode == RMFF_OPEN_MODE_READING)
return open_file_for_reading(path, io);
else
return open_file_for_writing(path, io);
}
void
rmff_free_track_data(rmff_track_t *track) {
if (track == NULL)
@ -330,8 +362,9 @@ rmff_read_headers(rmff_file_t *file) {
rmff_track_t track;
real_video_props_t *rvp;
real_audio_v4_props_t *ra4p;
int prop_header_found;
if (file == NULL)
if ((file == NULL) || (file->open_mode != RMFF_OPEN_MODE_READING))
return set_error(RMFF_ERR_PARAMETERS, NULL, RMFF_ERR_PARAMETERS);
if (file->headers_read)
return 0;
@ -347,6 +380,7 @@ rmff_read_headers(rmff_file_t *file) {
skip(4); /* num_headers */
prop = &file->prop_header;
prop_header_found = 0;
cont = &file->cont_header;
while (1) {
rmff_last_error = RMFF_ERR_OK;
@ -368,10 +402,10 @@ rmff_read_headers(rmff_file_t *file) {
read_uint32_be_to(&prop->data_offset);
read_uint16_be_to(&prop->num_streams);
read_uint16_be_to(&prop->flags);
file->prop_header_found = 1;
prop_header_found = 1;
} else if (object_id == rmffFOURCC('C', 'O', 'N', 'T')) {
if (file->cont_header_found) {
if (file->cont_header_present) {
safefree(cont->title);
safefree(cont->author);
safefree(cont->copyright);
@ -399,7 +433,7 @@ rmff_read_headers(rmff_file_t *file) {
cont->comment = (char *)safemalloc(size + 1);
io->read(fh, cont->comment, size);
}
file->cont_header_found = 1;
file->cont_header_present = 1;
} else if (object_id == rmffFOURCC('M', 'D', 'P', 'R')) {
memset(&track, 0, sizeof(rmff_track_t));
@ -464,7 +498,7 @@ rmff_read_headers(rmff_file_t *file) {
}
}
if (file->prop_header_found && (file->first_data_header_offset > 0)) {
if (prop_header_found && (file->first_data_header_offset > 0)) {
file->headers_read = 1;
return 0;
}
@ -481,7 +515,7 @@ rmff_get_next_frame_size(rmff_file_t *file) {
int64_t old_pos;
if ((file == NULL) || (!file->headers_read) || (file->io == NULL) ||
(file->handle == NULL))
(file->handle == NULL) || (file->open_mode != RMFF_OPEN_MODE_READING))
return set_error(RMFF_ERR_PARAMETERS, NULL, RMFF_ERR_PARAMETERS);
io = file->io;
fh = file->handle;
@ -514,7 +548,7 @@ rmff_read_next_frame(rmff_file_t *file,
void *fh;
if ((file == NULL) || (!file->headers_read) || (file->io == NULL) ||
(file->handle == NULL))
(file->handle == NULL) || (file->open_mode != RMFF_OPEN_MODE_READING))
return (rmff_frame_t *)set_error(RMFF_ERR_PARAMETERS, NULL, 0);
io = file->io;
fh = file->handle;
@ -562,3 +596,22 @@ rmff_release_frame(rmff_frame_t *frame) {
safefree(frame->data);
safefree(frame);
}
void
rmff_set_cont_header(rmff_file_t *file,
const char *title,
const char *author,
const char *copyright,
const char *comment) {
if (file == NULL)
return;
safefree(file->cont_header.title);
safefree(file->cont_header.author);
safefree(file->cont_header.copyright);
safefree(file->cont_header.comment);
file->cont_header.title = safestrdup(title);
file->cont_header.author = safestrdup(author);
file->cont_header.copyright = safestrdup(copyright);
file->cont_header.comment = safestrdup(comment);
}