From 484b0c2fd9e35219c0cb6f5f85adcf0556988624 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Thu, 18 Mar 2004 19:01:35 +0000 Subject: [PATCH] Merged 1571. --- librmff/librmff.h | 23 ++++++++-- librmff/rmff.c | 113 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 103 insertions(+), 33 deletions(-) diff --git a/librmff/librmff.h b/librmff/librmff.h index ea16651f1..8df83cedf 100644 --- a/librmff/librmff.h +++ b/librmff/librmff.h @@ -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 diff --git a/librmff/rmff.c b/librmff/rmff.c index 4e8e6ab10..caf89cd46 100644 --- a/librmff/rmff.c +++ b/librmff/rmff.c @@ -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); +}